2009-06-19 47 views
154

Tôi có một bản vá nhỏ được lưu trong khoe của tôi. Tôi đã áp dụng nó cho bản sao làm việc của tôi bằng cách sử dụng git stash apply. Bây giờ, tôi muốn quay trở lại những thay đổi đó bằng cách áp dụng ngược miếng vá (loại giống như những gì git revert sẽ làm nhưng chống lại stash).Làm thế nào để đảo ngược áp dụng một stash?

Có ai biết cách thực hiện việc này không?

Làm rõ: Có các thay đổi khác trong bản sao làm việc của tôi. Trường hợp cụ thể của tôi khó mô tả nhưng bạn có thể tưởng tượng một số mã gỡ lỗi hoặc thử nghiệm có trong stash. Bây giờ nó được trộn lẫn trong bản sao làm việc của tôi với một số thay đổi khác và tôi muốn thấy hiệu ứng có và không có thay đổi từ stash.

Nó không giống như stash hỗ trợ hiện tại, nhưng git stash apply --reverse sẽ là một tính năng tuyệt vời.

+0

Có thay đổi nào trong cây đang hoạt động không phải là stash được áp dụng không? –

+0

Không thể chỉ tạo một bản vá được đảo ngược bằng cách phân biệt giữa bản sửa đổi hiện tại và phiên bản trước? Và sau đó áp dụng điều đó? – ralphtheninja

Trả lời

139

Theo git-stash manpage, "Một stash được biểu diễn như một cam kết mà cây ghi lại trạng thái của thư mục làm việc, và phụ huynh đầu tiên được cam kết tại HEAD khi stash đã được tạo ra," và git stash show -p cho chúng ta "những thay đổi ghi vào stash như một diff giữa nhà nước cất giấu và phụ huynh ban đầu của nó

Để giữ các thay đổi khác của bạn còn nguyên vẹn, sử dụng git stash show -p | patch --reverse như trong những điều sau đây:.

$ git init 
Initialized empty Git repository in /tmp/repo/.git/ 

$ echo Hello, world >messages 

$ git add messages 

$ git commit -am 'Initial commit' 
[master (root-commit)]: created 1ff2478: "Initial commit" 
1 files changed, 1 insertions(+), 0 deletions(-) 
create mode 100644 messages 

$ echo Hello again >>messages 

$ git stash 

$ git status 
# On branch master 
nothing to commit (working directory clean) 

$ git stash apply 
# On branch master 
# Changed but not updated: 
# (use "git add <file>..." to update what will be committed) 
# (use "git checkout -- <file>..." to discard changes in working directory) 
# 
#  modified: messages 
# 
no changes added to commit (use "git add" and/or "git commit -a") 

$ echo Howdy all >>messages 

$ git diff 
diff --git a/messages b/messages 
index a5c1966..eade523 100644 
--- a/messages 
+++ b/messages 
@@ -1 +1,3 @@ 
Hello, world 
+Hello again 
+Howdy all 

$ git stash show -p | patch --reverse 
patching file messages 
Hunk #1 succeeded at 1 with fuzz 1. 

$ git diff 
diff --git a/messages b/messages 
index a5c1966..364fc91 100644 
--- a/messages 
+++ b/messages 
@@ -1 +1,2 @@ 
Hello, world 
+Howdy all 

Edit:

Một cải tiến nhẹ vấn đề này là sử dụng git apply ở vị trí của miếng vá:

git stash show -p | git apply --reverse 

Ngoài ra, bạn cũng có thể sử dụng git apply -R như một kí hiệu để git apply --reverse.

Tôi đã tìm thấy điều này thực sự tiện dụng gần đây ...

+2

Tuyệt vời, cảm ơn. Có vẻ như đây có thể là một tính năng tuyệt vời cho stash. –

+5

Vâng, 'git apply -R' là một sự cải tiến, ít nhất là đối với tôi trên hộp cửa sổ của tôi với git bash khi' patch --reverse' gặp vấn đề trong việc định vị tập tin để vá (không có đầu mối thực sự nào thay thế được).1 và giải thích tốt – hakre

+0

sẽ không tốt hơn nếu bạn thêm '--index' giống như' git stash show -p | git apply --reverse --index'. Vì bạn không còn cần phải thêm vào chỉ mục các thay đổi được hoàn nguyên trở lại. – theUnknown777

61

git stash[save] sẽ đưa trạng thái thư mục hoạt động của bạn và trạng thái chỉ mục của bạn và ngăn chúng đi, thiết lập chỉ mục và khu vực làm việc thành HEAD phiên bản.

git stash apply mang lại những thay đổi đó, vì vậy git reset --hard sẽ xóa chúng một lần nữa.

git stash pop mang lại những thay đổi đó và xóa thay đổi được lưu trữ hàng đầu, vì vậy, git stash [save] sẽ trở về trạng thái trước đó (trước khi bật) trong trường hợp này.

11

này dài hơn do, nhưng nếu tôi thâm vấn đề một cách chính xác tôi đã tìm thấy một giải pháp đơn giản, lưu ý, đây là một lời giải thích trong thuật ngữ của riêng tôi:

git stash [save] sẽ tiết kiệm đi những thay đổi hiện tại và thiết lập chi nhánh hiện tại của bạn đến "nhà nước trong sạch"

git stash list cho một cái gì đó như: [email protected]{0}: On develop: saved testing-stuff

git apply [email protected]{0} sẽ thiết lập chi nhánh hiện nay như trướcstash [save]

git checkout . sẽ thiết lập chi nhánh hiện nay như saustash [save]

Các mã được lưu trong stash không bị mất, nó có thể được tìm thấy bằng cách git apply [email protected]{0} một lần nữa.

Bất cứ khi nào, điều này phù hợp với tôi!

+0

Để chắc chắn, tôi đã áp dụng một dấu gạch chéo 'git áp dụng - -trước' đầu tiên và sau đó chỉ đơn giản là quay lại 'git stash áp dụng stash @ {x}' như bạn đề cập đến. Làm việc không có vấn đề gì. –

16

Cắt trực tiếp n dán từ git man page Được viết rõ ràng và thậm chí bao gồm bí danh;

Un-áp dụng một Stash Trong một số trường hợp sử dụng kịch bản bạn có thể muốn áp dụng thay đổi cất giấu, làm một số công việc, nhưng sau đó bỏ áp dụng những thay đổi mà ban đầu đến từ stash. Git không cung cấp một stash lệnh unapply như vậy, nhưng chúng ta có thể đạt được hiệu quả bằng cách đơn giản lấy các bản vá liên kết với một stash và áp dụng nó theo hướng ngược lại:

$ git stash show -p [email protected]{0} | git apply -R 

lần nữa, nếu bạn không chỉ định một stash , Git giả sử số lần truy cập gần đây nhất:

$ git stash show -p | git apply -R 

Bạn có thể muốn tạo bí danh và thêm lệnh stash-unapply vào Git một cách hiệu quả. Ví dụ:

$ git config --global alias.stash-unapply '!git stash show -p | git apply -R' 
$ git stash apply 
$ #... work work work 
$ git stash-unapply 
23
git checkout -f 

sẽ loại bỏ bất kỳ không cam kết thay đổi.

+1

cảm ơn, bạn giúp tôi từ sự thay đổi theo giai đoạn mà không phải là không thích hợp. –

0

Ngoài câu trả lời @ Greg Bacon, trong trường hợp tập tin nhị phân được thêm vào chỉ mục và là một phần của stash sử dụng

git stash show -p | git apply --reverse 

có thể dẫn đến

error: cannot apply binary patch to '<YOUR_NEW_FILE>' without full index line 
error: <YOUR_NEW_FILE>: patch does not apply 

Thêm --binary giải quyết vấn đề này , nhưng tiếc là đã không tìm ra lý do tại sao.

git stash show -p --binary | git apply --reverse 
Các vấn đề liên quan