วิธีการย้อนกลับใช้สะสม?


233

ฉันมีแพทช์เล็ก ๆ เก็บไว้ในที่เก็บของฉัน git stash applyฉันได้ใช้มันเพื่อสำเนาการทำงานของฉันโดยใช้ ตอนนี้ฉันต้องการสำรองการเปลี่ยนแปลงเหล่านั้นโดยใช้การปรับปรุงแบบย้อนกลับ (แบบที่คล้ายกับสิ่งที่git revertจะทำ แต่กับการซ่อน)

ไม่มีใครรู้วิธีการทำเช่นนี้?

ชี้แจง:มีการเปลี่ยนแปลงอื่น ๆ ในสำเนาการทำงานของฉัน กรณีของฉันนั้นยากที่จะอธิบาย แต่คุณสามารถจินตนาการถึงการดีบักหรือรหัสการทดลองที่อยู่ในที่ซ่อน ตอนนี้มันรวมอยู่ในสำเนาการทำงานของฉันกับการเปลี่ยนแปลงอื่น ๆ และฉันต้องการดูผลที่มีและไม่มีการเปลี่ยนแปลงจากที่ซ่อน

ดูเหมือนจะไม่รองรับที่เก็บข้อมูลนี้ในปัจจุบัน แต่git stash apply --reverseจะเป็นคุณลักษณะที่ดี


1
ไม่เพียงแค่สร้างแพทช์ที่กลับด้านโดยทำให้การแก้ไขปัจจุบันและก่อนหน้าแตกต่างกันใช่ไหม แล้วใช้อันนั้นเหรอ?
ralphtheninja

มีการเปลี่ยนแปลงในแผนผังการทำงานนอกเหนือจากที่เก็บที่ใช้หรือไม่?
Greg Bacon

กำลังเพิ่มสิ่งนี้ที่นี่ ... ควรจะเป็นคำถามที่พบบ่อยไม่ใช่คำถาม ... stackoverflow.com/questions/59973103/
Don Thomas Boyle

คำตอบ:


188

อ้างอิงจากgit-stash manpage , "การซ่อนถูกแสดงเป็นคอมมิชชันซึ่งทรีบันทึกสถานะของไดเร็กตอรี่การทำงาน, และพาเรนต์แรกของมันคือคอมมิทHEADเมื่อสร้าง stash," และgit stash show -pให้เรา "การเปลี่ยนแปลงที่บันทึกใน stash เป็นส่วนต่างระหว่างสถานะ stashed และ parent ดั้งเดิม

เพื่อให้การเปลี่ยนแปลงอื่น ๆ ของคุณยังคงอยู่ให้ใช้git stash show -p | patch --reverseดังต่อไปนี้:

$ 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

แก้ไข:

การปรับปรุงแสงนี้จะใช้git applyแทนแพทช์:

git stash show -p | git apply --reverse

หรือคุณยังสามารถใช้เป็นชวเลขไปgit apply -Rgit apply --reverse

ฉันพบว่ามันมีประโยชน์จริง ๆ เมื่อเร็ว ๆ นี้ ...


2
เยี่ยมมากขอบคุณ ดูเหมือนว่านี่อาจเป็นคุณสมบัติที่ดีสำหรับการสะสม
Pat Notz

5
ใช่git apply -Rคือการปรับปรุงอย่างน้อยสำหรับฉันในกล่อง windows ของฉันกับทุบตี git ตามที่patch --reverseมีปัญหาในการค้นหาไฟล์ที่จะแก้ไข (ไม่มีเงื่อนงำจริงทำไมทางเลือกทำงาน) +1 และคำอธิบายที่ดี
hakre

มันจะไม่ดีกว่าเพื่อเพิ่มเพียงเช่นนี้--index git stash show -p | git apply --reverse --indexเนื่องจากคุณไม่จำเป็นต้องเพิ่มในดัชนีการเปลี่ยนแปลงที่ย้อนกลับ
theUnknown777

3
@ Greg เบคอนเดี๋ยวก่อนฉันได้พยายามที่จะไปผ่านสคริปต์ที่คุณระบุไว้ แต่แพทช์ล้มเหลวเมื่อฉันวิ่งไปพร้อมกับข้อความ:git stash show -p | git apply -R -v Checking patch messages... error: while searching for: Hello, world Hello again error: patch failed: messages:1คุณรู้หรือไม่ว่ามีอะไรผิดปกติ?
Max Koretskyi

5
ฉันได้รับข้อผิดพลาด: patch failed: /src/filename.java:46 ข้อผิดพลาด: src / filename.java patch ใช้ไม่ได้
Tim Boland

83

git stash[save]นำสถานะไดเรกทอรีทำงานของคุณและสถานะดัชนีของคุณและหยุดพวกเขาออกไปตั้งค่าดัชนีและพื้นที่ทำงานเป็นHEADรุ่น

git stash applyนำการเปลี่ยนแปลงเหล่านั้นกลับมาดังนั้นgit reset --hardจะลบอีกครั้ง

git stash popนำการเปลี่ยนแปลงเหล่านั้นกลับมาและลบการเปลี่ยนแปลงที่ถูกเก็บไว้ด้านบนดังนั้นgit stash [save]จะกลับสู่สถานะก่อนหน้า (ป๊อปอัป) ก่อนหน้านี้ในกรณีนี้



22

หน้า man git V1 มีการอ้างอิงเกี่ยวกับการยกเลิกการใช้ stash ส่วนที่ตัดตอนมาอยู่ด้านล่าง

หน้า man V2 git ที่ใหม่กว่านั้นไม่มีการอ้างอิงใด ๆ เกี่ยวกับการยกเลิกการใช้การซ่อน แต่ด้านล่างยังใช้งานได้ดี

การยกเลิกการใช้ Stash ในบางกรณีสถานการณ์การใช้งานที่คุณอาจต้องการใช้การเปลี่ยนแปลงที่เก็บไว้ทำงานบางอย่าง แต่แล้วยกเลิกการใช้การเปลี่ยนแปลงเหล่านั้นที่มาจากการสะสม Git ไม่ได้จัดเตรียมคำสั่ง un-Apply ที่เก็บไว้ แต่มันเป็นไปได้ที่จะได้รับผลกระทบโดยเพียงแค่ดึงแพทช์ที่เกี่ยวข้องกับที่เก็บของออกและใช้มันในสิ่งที่ตรงกันข้าม:

$ git stash show -p stash@{0} | git apply -R

อีกครั้งหากคุณไม่ได้ระบุที่เก็บไว้ Git จะถือว่าที่เก็บข้อมูลล่าสุด:

$ git stash show -p | git apply -R

คุณอาจต้องการสร้างนามแฝงและเพิ่มคำสั่ง stash-unapply ให้กับ Git ของคุณ ตัวอย่างเช่น:

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

1
สำหรับเหตุผลใดส่วนที่เป็นประโยชน์นี้คุณเชื่อมโยง "Un-ใช้ Stash" ถูกลบออกจากรุ่นที่ 2 -Latest รุ่นที่เหมาะสมในขณะนี้คือ 2.1.146, 2019-04-15-ของหนังสือเล่มนี้V2- Git เครื่องมือ - stashing และการทำความสะอาด อาจเป็นเพราะผู้เขียนคิดว่ามีวิธีที่ดีกว่าในการทำสิ่งที่ฉันไม่สามารถหาได้
Nad Alaba

@NadAlaba ขอบคุณสำหรับหัวขึ้นได้อัปเดตคำตอบเพื่อให้ทราบถึงความแตกต่างระหว่าง v1 และ v2 ... แปลกผู้เขียน git ลบส่วนที่เกี่ยวกับการยกเลิกการสะสม
Choco Smith

13

นี่เป็นเวลานานกว่ากำหนด แต่ถ้าฉันตีความปัญหาได้อย่างถูกต้องฉันได้พบวิธีแก้ปัญหาอย่างง่าย ๆ โปรดทราบว่านี่เป็นคำอธิบายในคำศัพท์ของฉัน:

git stash [save] จะบันทึกการเปลี่ยนแปลงปัจจุบันและตั้งสาขาปัจจุบันของคุณเป็น "สถานะสะอาด"

git stash list ให้สิ่งที่ชอบ: stash@{0}: On develop: saved testing-stuff

git apply stash@{0}จะตั้งสาขาปัจจุบันเหมือนเดิม stash [save]

git checkout .จะตั้งสาขาปัจจุบันเป็นหลัง stash [save]

รหัสที่บันทึกไว้ในที่เก็บข้อมูลจะไม่สูญหายไปสามารถพบได้git apply stash@{0}อีกครั้ง

อะไรก็ใช้ได้กับฉัน!


เพียงเพื่อให้แน่ใจว่าฉันใช้git stash apply --reverseครั้งแรกแล้วก็กลับไปgit stash apply stash@{x}เหมือนที่คุณพูดถึง ทำงานได้โดยไม่มีปัญหา
Carlos Garcia

3

วิธีการย้อนกลับใช้สะสม?

นอกจากสิ่งที่คนอื่นพูดถึงแล้ววิธีที่ง่ายที่สุดคือทำก่อน

git reset HEAD

จากนั้นเช็คเอาต์การเปลี่ยนแปลงในเครื่องทั้งหมด

git checkout . 

นี่เป็นวิธีที่ง่ายที่สุดตราบใดที่คุณไม่มีงานในท้องถิ่นที่คุณต้องการบันทึก หากคุณใช้การซ่อนที่ไม่ถูกต้องกับสาขาหรือข้อขัดแย้งการรวมที่คุณไม่ต้องการแก้ไขนี่เป็นวิธีที่ง่ายและรวดเร็วในการยกเลิกโดยการคืนค่าชุดการทำงานของคุณเป็นความมุ่งมั่นล่าสุดของสาขาอย่างสมบูรณ์
Shadoninja

2

นอกจากคำตอบ @Greg Bacon แล้วในกรณีที่ไฟล์ไบนารีถูกเพิ่มเข้าไปในดัชนีและเป็นส่วนหนึ่งของการสะสมโดยใช้

git stash show -p | git apply --reverse

อาจส่งผลให้

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

การเพิ่มการ--binaryแก้ไขปัญหา แต่น่าเสียดายที่ยังไม่ได้คิดออกว่าทำไมยัง

 git stash show -p --binary | git apply --reverse


0

นี่คือนอกเหนือจากคำตอบข้างต้น แต่เพิ่มการค้นหาสำหรับการซ่อน git ตามข้อความเนื่องจากหมายเลข stash สามารถเปลี่ยนแปลงได้เมื่อบันทึก stashes ใหม่ ฉันได้เขียนฟังก์ชัน bash สองสามรายการ:

apply(){
  if [ "$1" ]; then
    git stash apply `git stash list | grep -oPm1 "(.*)(?=:.*:.*$1.*)"`
  fi
}
remove(){
  if [ "$1" ]; then
    git stash show -p `git stash list | grep -oPm1 "(.*)(?=:.*:.*$1.*)"` | git apply -R
    git status
  fi
}
  1. สร้างที่ซ่อนพร้อมชื่อ (ข้อความ) $ git stash save "my stash"
  2. เพื่อชื่อ appply $ apply "my stash"
  3. หากต้องการลบที่ซ่อนชื่อ $ remove "my stash"
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.