git stash -> hợp nhất thay đổi stash với các thay đổi hiện tại


185

Tôi đã thực hiện một số thay đổi cho chi nhánh của mình và nhận ra rằng tôi đã quên tôi đã thực hiện một số thay đổi cần thiết khác cho chi nhánh nói trên. Những gì tôi muốn là một cách để hợp nhất các thay đổi được lưu trữ của tôi với các thay đổi hiện tại.

Có cách nào để làm việc này không?

Để thuận tiện hơn, cuối cùng tôi đã từ bỏ và cam kết trước những thay đổi hiện tại của mình, sau đó là những thay đổi của tôi, nhưng tôi muốn đưa chúng vào trong một cú trượt ngã.


Có thể là bản sao của stackoverflow.com/q/1360712/72178
ks1322

câu trả lời của joshua nên là câu trả lời được chấp nhận. Bài đăng stackoverflow này là liên kết google đầu tiên cho câu hỏi này, hãy đưa ra câu trả lời đúng cho internet!
Jérôme

Câu trả lời:


270

Tôi chỉ phát hiện ra rằng nếu các thay đổi không được cam kết của bạn được thêm vào chỉ mục (nghĩa là "dàn dựng", sử dụng git add ...), thì git stash apply(và, có lẽ, git stash pop) sẽ thực sự hợp nhất. Nếu không có xung đột, bạn là vàng. Nếu không, giải quyết chúng như bình thường với git mergetoolhoặc bằng tay với trình chỉnh sửa.

Để rõ ràng, đây là quá trình tôi đang nói về:

mkdir test-repo && cd test-repo && git init
echo test > test.txt
git add test.txt && git commit -m "Initial version"

# here's the interesting part:

# make a local change and stash it:
echo test2 > test.txt
git stash

# make a different local change:
echo test3 > test.txt

# try to apply the previous changes:
git stash apply
# git complains "Cannot apply to a dirty working tree, please stage your changes"

# add "test3" changes to the index, then re-try the stash:
git add test.txt
git stash apply
# git says: "Auto-merging test.txt"
# git says: "CONFLICT (content): Merge conflict in test.txt"

... đó có lẽ là những gì bạn đang tìm kiếm.


tl; dr

Chạy git addtrước.


8
Một hack như vậy, nhưng hey, nó hoạt động và dường như là cách duy nhất để làm điều này. Tôi ước có git stash apply --forcehoặc một cái gì đó.
Matt Kantor

12
Trên thực tế, đó không phải là một hack - đó là một cải tiến so với những gì bạn muốn, vì bạn có thể dễ dàng trở lại các thay đổi trong chỉ mục.
hoffmanc

2
Wow, hành vi này thực sự có ý định của git?
edi9999 17/2/2016

9
Tôi không nghĩ rằng có bất cứ điều gì từng có ý định của người Viking bởi git. Linh cảm của tôi là bây giờ bất cứ điều gì git làm điều đó là tình cờ.
Profpatsch

5
Đây là giải pháp hoàn hảo. Tôi vừa mới làm git add ., git stash applysau đó git resetđể áp dụng stash cho các thay đổi làm việc của tôi và hợp nhất mà không phải thực hiện các cam kết.
Stephen Smith

69

Chạy git stash pophoặc git stash applyvề cơ bản là hợp nhất. Bạn không cần phải cam kết các thay đổi hiện tại của mình trừ khi các tệp được thay đổi trong ngăn chứa cũng được thay đổi trong bản sao làm việc, trong trường hợp đó bạn sẽ thấy thông báo lỗi này:

error: Your local changes to the following files would be overwritten by merge:
       file.txt
Please, commit your changes or stash them before you can merge.
Aborting

Trong trường hợp đó, bạn không thể áp dụng stash cho các thay đổi hiện tại của mình trong một bước. Bạn có thể thực hiện các thay đổi, áp dụng stash, xác nhận lại và xóa hai cam kết đó bằng cách sử dụng git rebasenếu bạn thực sự không muốn hai lần xác nhận, nhưng điều đó có thể gây ra nhiều rắc rối hơn.


1
Tôi đã nhận được thông báo đó - những thay đổi không xung đột nhưng chia sẻ cùng một tệp, bất kỳ xung quanh nào sử dụng stash / áp dụng?
Bemis

1
Xin lỗi, đó là những gì tôi muốn nói là "hợp nhất xung đột", nhưng đó là lựa chọn từ kém. Tôi nghĩ rằng thông báo lỗi là cuối cùng: nếu các tệp được thay đổi trong bản sao làm việc cũng bị thay đổi trong ngăn chứa, bạn không thể áp dụng ngăn đó. Tôi đã cập nhật câu trả lời của mình với một cách giải quyết có thể.
Brandan

3
Tôi sẽ không coi đây là một câu trả lời trong mọi trường hợp. Bạn có thể đã chỉ lưu một phần của một tập hợp các thay đổi trong một tệp cụ thể vì bạn muốn kiểm tra một cái gì đó trong khi phát triển. Và bạn có thể không muốn cam kết nội dung hiện tại của tệp tại thời điểm này (hoặc hoàn toàn không) như là WIP. Đây là một vấn đề thực sự với git rằng các thay đổi được lưu trữ không thể được hợp nhất vào chi nhánh hiện tại của bạn
Thomas Watson

21
Câu trả lời của Joshua Warner phải là câu trả lời đúng. Để hợp nhất một stash, giai đoạn thay đổi của bạn, áp dụng stash, xử lý mọi xung đột và sau đó (nếu muốn) bỏ qua các thay đổi của bạn.
Vroo

4
"Bạn có thể thực hiện các thay đổi, áp dụng stash, xác nhận lại và xóa hai cam kết đó bằng git rebase nếu bạn thực sự không muốn hai lần xác nhận, nhưng điều đó có thể gây ra nhiều rắc rối hơn." Thay vì điều này bạn có thể làm: Cam kết các thay đổi, áp dụng stash và sau đó git commit --amend.
gabe

27

Những gì tôi muốn là một cách để hợp nhất các thay đổi được lưu trữ của tôi với các thay đổi hiện tại

Đây là một lựa chọn khác để làm điều đó:

git stash show -p|git apply
git stash drop

git stash show -psẽ hiển thị các bản vá của stash lưu cuối cùng. git applysẽ áp dụng nó. Sau khi hợp nhất được thực hiện, stash hợp nhất có thể được loại bỏ với git stash drop.


1
Cảm ơn vì điều này - Tôi không biết tại sao git stash popkhông làm điều này trong trường hợp hợp nhất được áp dụng sạch sẽ ...
Iguananaut

Phiên bản mở rộng: git stash show -p --no-color | git apply --3way( --3way= rơi lại vào hợp nhất 3 chiều nếu bản vá không thành công).
DmitrySandalov

Nhưng git stash show -ptạo ra một sự khác biệt giữa nội dung được lưu trữ và cam kết trở lại khi mục nhập stash được tạo lần đầu tiên . Vì vậy, điều này sẽ ghi đè lên tệp làm việc thay đổi OP thực hiện.
Paul F. Wood

Tại sao ghi đè? Khác biệt được tạo ra git stash show -psẽ được hợp nhất bởi git apply, nếu có thể làm mà không có xung đột.
ks1322

1

Cách tôi làm điều này là git addtrước tiên git stash apply <stash code>. Đó là cách đơn giản nhất.


3
Làm thế nào đây không phải là một bản sao chính xác của tl; dr của câu trả lời được chấp nhận?
RomainValeri

0

Theo đề xuất của @Brandan, đây là những gì tôi cần làm để đi lại

error: Your local changes to the following files would be overwritten by merge:
       file.txt
Please, commit your changes or stash them before you can merge.
Aborting

Thực hiện theo quy trình này:

git status  # local changes to `file`
git stash list  # further changes to `file` we want to merge
git commit -m "WIP" file
git stash pop
git commit -m "WIP2" file
git rebase -i HEAD^^  # I always use interactive rebase -- I'm sure you could do this in a single command with the simplicity of this process -- basically squash HEAD into HEAD^
# mark the second commit to squash into the first using your EDITOR
git reset HEAD^

Và bạn sẽ được để lại các thay đổi cục bộ được hợp nhất hoàn toàn để filesẵn sàng thực hiện công việc / dọn dẹp thêm hoặc thực hiện một cam kết tốt. Hoặc, nếu bạn biết nội dung được hợp nhất filesẽ chính xác, bạn có thể viết một thông điệp phù hợp và bỏ qua git reset HEAD^.


0

Có thể, đó không phải là ý tưởng tồi tệ nhất để hợp nhất (thông qua Difftool) từ ... vâng ... một chi nhánh!

> current_branch=$(git status | head -n1 | cut -d' ' -f3)
> stash_branch="$current_branch-stash-$(date +%yy%mm%dd-%Hh%M)"
> git stash branch $stash_branch
> git checkout $current_branch
> git difftool $stash_branch

0

bạn co thể dê dang

  1. Cam kết những thay đổi hiện tại của bạn
  2. Hủy bỏ stash của bạn và giải quyết xung đột
  3. Cam kết thay đổi từ stash
  4. Thiết lập lại mềm để cam kết bạn đang đến (cam kết chính xác cuối cùng)

-1

Một lựa chọn khác là thực hiện một "git stash" khác về các thay đổi không được cam kết cục bộ, sau đó kết hợp hai stit git. Thật không may, git dường như không có cách nào dễ dàng kết hợp hai stash. Vì vậy, một tùy chọn là tạo hai tệp .diff và áp dụng cả hai - ít nhất đó không phải là một cam kết bổ sung và không liên quan đến quy trình mười bước: |

làm thế nào để: https://stackoverflow.com/a/9658688/32453


Nó biến vấn đề áp dụng một diff thành vấn đề áp dụng hai diff. Ngoài ra, giải pháp được chấp nhận không liên quan đến một cam kết, chỉ là một giai đoạn và nó chỉ là một lệnh duy nhất (git add). (Tôi không phải là người xuống cấp.)
Eike

Đối với tôi ít nhất nó cảm thấy đơn giản hơn, ít ma thuật voodoo hơn ... chúc mừng!
rogerdpack
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.