ฉันจะเปลี่ยนชื่อการซ่อนคอมไพล์ได้อย่างไร?


202

ฉันมีที่ซ่อนที่มีชื่อไม่ถูกต้อง ฉันต้องการแก้ไขชื่อเพื่อให้ถูกต้อง

ฉันจะเปลี่ยนชื่อที่เก็บสะสมได้อย่างไร


5
ปรากฏขึ้นและบันทึกอีกครั้งด้วยชื่ออื่นหรือไม่?
Bartlomiej Lewandowski

5
การ popping และ stashing อีกครั้งไม่ใช่ตัวเลือกเสมอเนื่องจาก stash อาจขึ้นอยู่กับสถานะที่ล้าสมัยและส่งผลให้เกิดข้อขัดแย้งเมื่อ popping (รัฐที่ล้าสมัยไม่จำเป็นต้องมีอยู่ที่ใดในประวัติศาสตร์อีกต่อไป)
Tom

คำตอบ:


258

สมมติว่ารายการที่เก็บของคุณมีลักษณะดังนี้:

$ git stash list
stash@{0}: WIP on master: Add some very important feature 
stash@{1}: WIP on master: Fix some silly bug

ก่อนอื่นคุณต้องลบรายการที่ซ่อนซึ่งคุณต้องการเปลี่ยนชื่อ:

$ git stash drop stash@{1}
Dropped stash@{1} (af8fdeee49a03d1b4609f294635e7f0d622e03db)

ตอนนี้เพียงเพิ่มอีกครั้งด้วยข้อความใหม่โดยใช้ sha of commit ที่ส่งคืนหลังจากวาง:

$ git stash store -m "Very descriptive message" af8fdeee49a03d1b4609f294635e7f0d622e03db

และนั่นคือ:

$ git stash list
stash@{0}: Very descriptive message
stash@{1}: WIP on master: Add some very important feature

วิธีการแก้ปัญหานี้ต้องใช้ git 1.8.4 หรือใหม่กว่าและใช่มันทำงานกับไดเรกทอรีการทำงานที่สกปรกเช่นกัน


3
git show stash@{0}ยังคงแสดงข้อมูลเก่าหลังจากนั้น จะแก้ไขได้อย่างไร? (โปรดทราบว่าที่เก็บสะสมนั้นจะได้รับ SHA อื่น)
Tino

4
มันให้ความรู้สึกที่ดีกว่าที่จะได้รับกัญชาด้วยและเริ่มต้นด้วยgit show git stash storeจากนั้นgit stash listคุณจะเห็นที่เก็บของเก่าและของใหม่ git stash dropในที่สุดคุณสามารถทำความสะอาดขึ้นสะสมเก่าด้วย
hogi

6
git stash drop จะไม่สูญเสียการเปลี่ยนแปลง?
Shravya Boggarapu

4
@ShravyaBoggarapu, ไม่, คอมไพล์ไม่ได้ลบการคอมมิทจนกว่าgit gcจะรัน หลังจากที่stash dropคุณสามารถค้นหากระทำนี้โดยปกติไม่สามารถเข้าถึงได้กระทำโดยใช้git fsck | grep commitคำสั่ง
qzb

2
@ ÐerÆndiเพียงแค่ประยุกต์ใช้และบันทึกเป็นตัวเลือกที่ง่าย แต่จะไม่ทำงานเมื่อการเปลี่ยนแปลงไม่สามารถนำไปใช้ใหม่ได้เนื่องจากความขัดแย้ง ในขณะเดียวกันก็ปล่อยและจัดเก็บผลงานไม่ว่าในกรณีใด ๆ ฉันได้ทดสอบวิธีแก้ปัญหาของฉันอีกครั้ง - ใช้งานได้ดีกับเวอร์ชัน git ล่าสุด (2.17.0)
qzb

62

เว้นแต่คุณจะทำด้วยตนเองหรือมีส่วนร่วมในการปรับปรุง Git คุณสามารถใช้นามแฝง:

git config --global alias.stash-rename '!_() { rev=$(git rev-parse $1) && git stash drop $1 || exit 1 ; git diff-index --quiet HEAD; s=$?; [ $s != 0 ] && git stash save "tmp stash from stash-rename"; git stash apply $rev && shift && git stash save "$@" && [ $s != 0 ] && git stash pop stash@{1}; }; _'

การใช้งาน: " git stash-rename <stash> [save options] [<message>]"

ด้วย[save options]ตัวเลือกใด ๆ ของgit stash save:[-p|--patch] [-k|--[no-]keep-index] [-q|--quiet] [-u|--include-untracked] [-a|--all]

ตัวอย่าง:

$ git stash list
stash@{0}: On master: Pep8 format
stash@{1}: On master: co other than master with local changes
stash@{2}: On master: tests with deployAtEnd

# Let's say I want to rename the stash@{2} adding an issue reference:
$ git stash-rename stash@{2} NXP-13971-deployAtEnd

$ git stash list
stash@{0}: On master: NXP-13971-deployAtEnd
stash@{1}: On master: Pep8 format
stash@{2}: On master: co other than master with local changes

สิ่งนี้จะใช้ได้แม้ว่าคุณจะมีการเปลี่ยนแปลงแบบไม่มีการกำหนดภายใน :)

แก้ไข 2016/02/22

สคริปต์แบบง่ายเครดิตไปยังqzb , https://stackoverflow.com/a/35549615/515973

git config --global alias.stash-rename '!_() { rev=$(git rev-parse $1) && git stash drop $1 || exit 1 ; git stash store -m "$2" $rev; }; _'

การใช้งาน: " git stash-rename <stash> [<message>]"


1
! น่ากลัว ยิ่งเย็นลงถ้าคุณทำได้git stash-rename 'tests with deployAtEnd' 'NXP-13971-deployAtEnd'
mikemaccana

3
ดังนั้นคำตอบคือ 1) สำเนาการทำงานที่สะอาด 2) ใช้ stash ที่คุณต้องการเปลี่ยนชื่อ 3) ปล่อยจากรายการ stash 4) สร้าง stash ใหม่พร้อมข้อความที่ถูกต้อง
gcb

2
เพื่อชี้แจงคุณกำลังเปลี่ยนชื่อที่ซ่อนสุดท้ายและหลังจากการกระทำดังกล่าวมันจะกลายเป็นที่ซ่อนด้านบน?
onebree

2
ฉันลบ stash เพื่อเปลี่ยนชื่อบันทึกการเปลี่ยนแปลงปัจจุบันถ้ามีสร้างที่ซ่อนที่ถูกลบใหม่ด้วยชื่อที่ต้องการและใช้การเปลี่ยนแปลงปัจจุบันอีกครั้งหากมี
Julien Carsique

3
รุ่นนี้จะตรวจสอบเพื่อให้แน่ใจว่ามีการขัดแย้งทั้งสองอยู่ที่นั่นดังนั้นจึงไม่เพียงแค่วางที่เก็บข้อมูลครั้งสุดท้ายของคุณโดยไม่ตั้งใจ นอกจากนี้ยังต้องใช้หมายเลขที่เก็บเท่านั้นไม่ใช่การstash@{0}อ้างอิงทั้งหมด gist.github.com/jdforsythe/f248bf6c72fc020225cc3e315a32e922 git config --global alias.stash-rename '!_() { if [ -z \"$1\" ] || [ -z \"$2\" ]; then echo \"git stash-rename 0 NewName\" && echo \"\" && git stash list && exit 1; else stash=\"stash@{$1}\"; rev=$(git rev-parse \"${stash}\"); git stash drop \"${stash}\" || exit 1; git stash store -m \"$2\" \"$rev\" || exit 1; git stash list; fi }; _'
jdforsythe

6

มันง่ายมาก ก่อนอื่นให้ยกเลิกการซ่อนสุดท้ายด้วย:

git stash pop

หลังจากนี้คุณสามารถบันทึกการสะสมด้วยชื่อที่กำหนดเองด้วยวิธีนี้:

git stash save "your explanatory name"

ฉันหวังว่ามันจะมีประโยชน์สำหรับคุณ :)


ที่เก็บข้อมูลที่เปลี่ยนชื่ออาจไม่ใช่เวอร์ชันล่าสุด
mikemaccana

ยกนิ้วตั้งแต่นี้ตรงไปตรงมามากขึ้น (เท่านั้น) สำหรับการสะสมล่าสุด
Kaihua

3

ฉันไม่คิดว่าเป็นไปได้ที่จะทำเช่นนั้น มีข้อเสนอสำหรับการเปลี่ยนชื่อที่เก็บสะสมแต่ยังไม่ได้ใช้งาน

ความคิดทั่วไปของฉันคือ:

  1. ใช้git reflog updateคำสั่งใหม่ที่ปรับปรุงข้อความที่เกี่ยวข้องกับรายการ reflog ที่เฉพาะเจาะจง ในการทำเช่นนี้update_reflog_ent()ฟังก์ชั่นใหม่(ในreflog.c ) จะเปลี่ยนข้อความที่เกี่ยวข้องกับรายการ reflog ที่เฉพาะเจาะจงเพื่อปรับปรุง update_reflog()ฟังก์ชั่นจะใช้for_each_reflog_ent()กับการupdate_reflog_entทำจริงการเปลี่ยนแปลง

  2. git stash renameคำสั่งก็จะต้องการเพียงที่จะเรียกgit reflog updateกับโทษที่เหมาะสมและข้อความใหม่

หรือคุณสามารถของหลักสูตรป๊อปสะสมและทำ git stash save [message]


3

เพื่อประโยชน์ของผู้อ่านนี่คือส่วนขยายของคำตอบที่ยอมรับและถูกต้องในปัจจุบัน

หากคุณไม่เพียง แต่ต้องการแก้ไขข้อความที่ซ่อนและยังต้องการแก้ไขข้อความการกระทำของที่เก็บเช่นนั้น

git stash list

และ

git log --oneline -1 stash

ทั้งสองเห็นด้วยกับสิ่งที่ปรากฏคุณต้องการอีกเล็กน้อย อาจมีวิธีที่ดีกว่าที่จะทำ แต่สูตรนี้ที่นี่เข้าใจง่ายฉันหวังว่า

ในการที่จะสามารถทำได้git commit --amendคุณจำเป็นต้องอยู่ใน TIP ของสาขา ดังนั้นการแก้ปัญหาคือ:

git checkout -b scratch stash@{1}
git stash drop stash@{1}
git commit --amend -m "$MESSAGE"
git stash store -m "$MESSAGE" HEAD
git checkout master
git branch -D scratch

อธิบาย:

  • สร้างสาขา "เริ่มต้นใหม่" (ยังไม่มีอยู่) จาก "ซ่อนคำถาม" และสลับไปที่
  • นำที่ซ่อนเก่าออก สิ่งนี้ปลอดภัยเนื่องจากเรายังมีสิ่งนี้ในสาขา
  • ใช้git commit --amendเพื่อแทนที่ข้อความคอมมิชชันการเปลี่ยน SHA ของ "stash in question"
  • จัดเก็บที่ซ่อนตามคำตอบของ qzb
  • เปลี่ยนกลับ (ซึ่งถือว่าคุณมาจาก "หลัก") และล้างข้อมูล

ข้อเสีย:

  • สวิตช์นี้จะหยุดทำงานชั่วคราว ดังนั้นสูตรนี้สามารถใช้ได้เฉพาะเมื่อgit status --porcelainสะอาด (อ่าน: ไม่ส่งออกอะไร)

  • มันจัดเรียงหมายเลขที่ซ่อนไว้อีกครั้งดังนั้นการเปลี่ยนที่เก็บจะกลายเป็น stash@{0}

  • คุณจำเป็นต้องใส่$MESSAGEสองครั้งหรือใช้ตัวแปรสภาพแวดล้อมบางอย่าง (ในตัวอย่างนี้MESSAGE)

  • คุณต้องค้นหาชื่อสาขาที่ไม่ได้ใช้

มีวิธีการทำเช่นนี้โดยไม่สลับสาขา แต่มันอยู่นอกเหนือขอบเขตของคำตอบนี้

ตัวอย่าง

git init scratch
cd scratch
for a in A B C D; do date >$a; git add $a; git commit -m $a; done
for a in X Y; do echo $a > Z; git stash save --all; done
git log --oneline --graph --decorate --all; git stash list

เอาท์พุต

*-.   e0e281b (refs/stash) WIP on master: 8bdcc32 D
|\ \  
| | * 4d62f52 untracked files on master: 8bdcc32 D
| * 096f158 index on master: 8bdcc32 D
|/  
* 8bdcc32 (HEAD, master) D
* c84c659 C
* 49bb2da B
* b1852c6 A
stash@{0}: WIP on master: 8bdcc32 D
stash@{1}: WIP on master: 8bdcc32 D

ตอนนี้โดยไม่เปลี่ยนการกระทำ (หมายเหตุ: SHA ในการติดตามจะแตกต่างกันที่ด้านข้างของคุณ):

git stash drop stash@{1}
git stash store -m ...changed... 2fbf9007dfdfb95ae269a19e13b8b9ca3e24181c
git log --oneline --graph --decorate --all; git stash list

เอาท์พุต

*-.   2fbf900 (refs/stash) WIP on master: 8bdcc32 D
|\ \  
| | * 246dc5c untracked files on master: 8bdcc32 D
| * 80c5ea0 index on master: 8bdcc32 D
|/  
* 8bdcc32 (HEAD, master) D
* c84c659 C
* 49bb2da B
* b1852c6 A
stash@{0}: ...changed...
stash@{1}: WIP on master: 8bdcc32 D

ในขณะที่คุณสามารถดูstash@{0}ยังคงแสดงให้เห็นว่าใน2fbf900 (refs/stash) WIP on master: 8bdcc32 D git logหากคุณดูอย่างระมัดระวังคุณจะเห็นว่าการกระทำหลายอย่างได้เปลี่ยน SHA นี่คือสาเหตุที่วิธีจัดการ stashes (ผู้ปกครองรวมอยู่ใน SHA และที่เก็บมี stashes ของพวกเขาเป็นผู้ปกครอง)

แก้ไขที่:

git checkout -b scratch stash
git stash drop
git commit --amend -m ...changed...
git stash store -m ...changed... HEAD
git checkout master
git branch -D scratch
git log --oneline --graph --decorate --all; git stash list

เอาท์พุต

*-.   4d55186 (refs/stash) ...changed...
|\ \  
| | * 246dc5c untracked files on master: 8bdcc32 D
| * 80c5ea0 index on master: 8bdcc32 D
|/  
* 8bdcc32 (HEAD, master) D
* c84c659 C
* 49bb2da B
* b1852c6 A
stash@{0}: ...changed...
stash@{1}: WIP on master: 8bdcc32 D

อย่างที่คุณเห็นrefs/stashก็มี SHA ที่เปลี่ยนแปลงเช่นกัน


มูลค่าการกล่าวขวัญ: สิ่งนี้ทำลายดัชนีที่ถูกบันทึกด้วยที่เก็บต้นฉบับแทนที่ด้วยดัชนีใหม่ที่ตรงกับการกระทำหลักของที่เก็บต้นฉบับ หากไม่มีใครวางแผนที่จะใช้ดัชนีที่บันทึกไว้เดิม (หรือตรงกับพาเรนต์ของที่เก็บต้นฉบับ) นี่ไม่ใช่ปัญหา
torek

1

นี่คือนามแฝงของ Julien ที่ได้รับการแก้ไขซึ่งช่วยให้คุณสามารถจัดการกับOn <branch>คำนำหน้าอย่างถูกต้องซึ่งมักจะมีชื่อต่อท้าย:

git config --global alias.stash-rename '!_() { newmsg="$1" && stash=${2:-"stash@{0}"} && newbranch="$3" && sha=$(git rev-parse "$stash") && olddesc="$(git stash list --format=%gs -1 "$stash")" && newdesc="$(if [[ "$newbranch" = "." ]]; then echo "$newmsg"; else if [[ -n "$newbranch" ]]; then echo "On $newbranch: $newmsg"; else if [[ "$olddesc" =~ ":" ]]; then echo "$(echo "$olddesc" | cut -f1 -d":"): $newmsg"; else echo "$newmsg"; fi; fi; fi)" && git stash drop "$stash" > /dev/null || exit 1; git stash store -m "$newdesc" "$sha" && git stash list; }; _'

ไวยากรณ์:

git stash-rename <new-name> [<stash> [<new-branch-name> | .]]

ตัวอย่างการใช้งาน:

repo[master] % touch tmp && git add tmp && git stash save first
Saved working directory and index state On master: first
HEAD is now at bd62064 Initial commit
repo[master] % touch tmp && git add tmp && git stash save second
Saved working directory and index state On master: second
HEAD is now at bd62064 Initial commit
repo[master] % git stash list
stash@{0}: On master: second
stash@{1}: On master: first
repo[master] % git stash-rename renamed
stash@{0}: On master: renamed
stash@{1}: On master: first
repo[master] % git stash-rename also-renamed stash@{1}
stash@{0}: On master: also-renamed
stash@{1}: On master: renamed
repo[master] % git stash-rename branch-changed stash@{0} new-branch
stash@{0}: On new-branch: branch-changed
stash@{1}: On master: renamed
repo[master] % git stash-rename branch-name-persists
stash@{0}: On new-branch: branch-name-persists
stash@{1}: On master: renamed
repo[master] % git stash-rename no-branch stash@{0} .
stash@{0}: no-branch
stash@{1}: On master: renamed
repo[master] % git stash-rename renamed
stash@{0}: renamed
stash@{1}: On master: renamed
repo[master] % git stash-rename readd-branch stash@{0} develop
stash@{0}: On develop: readd-branch
stash@{1}: On master: renamed

คำสั่งส่วนใหญ่ใช้สำหรับการแยกวิเคราะห์อาร์กิวเมนต์และหาสิ่งที่ควรทำกับชื่อสาขา gitเครื่องมือที่ใช้มีดังนี้

  • git rev-parse <stash> เพื่อค้นหา SHA ของที่เก็บ
  • git stash list --format=%gs -1 <stash>เพื่อค้นหาหัวข้อการอ้างอิงของที่เก็บ โปรดทราบว่านี่แตกต่างจากข้อความคอมมิตของ stash ซึ่งจะไม่เปลี่ยนแปลงโดยคำสั่งนี้ หัวเรื่อง reflog คือสิ่งที่ปรากฏในgit stash listและคุณสามารถเปลี่ยนเรื่อง reflog โดยไม่เปลี่ยนแฮชของคอมมิทที่เกี่ยวข้องกับ stashes อย่างไรก็ตามคุณสามารถค้นหาข้อความการส่งข้อความดั้งเดิมได้ดังนั้นอย่าใช้git stash-renameเพื่อลบข้อมูลที่ละเอียดอ่อน!
  • git stash drop <stash>เพื่อวางการอ้างอิงเก่าไปที่ที่เก็บ (แต่เรายังมี SHA ดังนั้นมันจึงไม่สูญหาย)
  • git stash store -m <new-message> <sha>เพื่อบันทึกการอ้างอิงใหม่ไปยัง stash ด้วยข้อมูลการคอมมิชชันเดียวกัน แต่หัวเรื่อง reflogอื่น
  • git stash listเพื่อแสดงรายการการหยุดทำงานหลังจากการดำเนินการเสร็จสิ้น โปรดทราบว่าการหยุดชั่วคราวใหม่จะถูกผลักไปยังจุดเริ่มต้นของรายการเสมอ มันจำเป็นต้องผลักดันstash ทั้งหมดก่อนที่จะซ่อนดอกเบี้ยเพื่อกู้คืนตำแหน่งเดิม

0

วิธีที่ง่ายที่สุด: pop stash ของคุณด้วย git stash pop แล้วบันทึกอีกครั้งด้วย git stash บันทึกชื่อของคุณ


ที่เก็บข้อมูลที่เปลี่ยนชื่ออาจไม่ใช่เวอร์ชันล่าสุด
mikemaccana
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.