วัตถุประสงค์การใช้งานสำหรับ git stash คืออะไร?


143

ถ้าฉันทำงานในสาขา A และต้องทำงานในสาขา B อย่างกะทันหันก่อนที่จะพร้อมที่จะทำข้อตกลงกับสาขา A ฉันจะซ่อนการเปลี่ยนแปลงของฉันใน A ชำระเงิน B ทำงานที่นั่นจากนั้นชำระเงิน A และใช้ที่เก็บ

ถ้าฉันทำงานกับ A และฉันต้องการหยุดทำงานในวันนั้นฉันควรเก็บงานของฉันไว้แล้วจึงนำมาใช้ในวันถัดไป (เมื่อฉันกลับมาทำงานต่อ) หรือฉันควรจะทิ้งสิ่งต่างๆไว้ตามที่เป็นอยู่ - ไฟล์ที่แก้ไขโดยไม่มีข้อผูกมัดใน ไดเร็กทอรีการทำงาน? ฉันไม่เห็นว่าทำไมฉันต้องใช้ที่ซ่อนในกรณีนี้ยกเว้นว่ามีประโยชน์ด้านความปลอดภัยอยู่บ้าง

นอกจากนี้อีกสถานการณ์หนึ่ง: ฉันทำงานทั้งที่ทำงานและที่บ้าน ถ้าฉันยังไม่พร้อมกับภาระกิจเมื่อฉันต้องการกลับบ้านฉันจะเก็บงานของฉันไว้แล้วส่งไปที่ GitHub แล้วดึงที่ซ่อนที่บ้านได้ไหม


3
ส่วนใหญ่ขึ้นอยู่กับนโยบายของ บริษัท ของคุณถ้ามี คุณจะเลือกคำตอบที่ "ยอมรับ" อย่างไร?
Daemon Painter

1
คำถามนี้เป็นเพียงการขอความคิดเห็น (ฉันควรใช้ git ด้วยวิธีนี้หรือวิธีนั้น ?) จึงควรปิดหรือแก้ไข
TylerH

คำตอบ:


163

Stash เป็นเพียงวิธีการอำนวยความสะดวก เนื่องจากสาขามีราคาถูกมากและง่ายต่อการจัดการในคอมไพล์โดยส่วนตัวแล้วฉันมักชอบสร้างสาขาชั่วคราวใหม่มากกว่าการเก็บ แต่เป็นเรื่องของรสชาติเป็นส่วนใหญ่

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

# Assume the latest commit was already done
# start working on the next patch, and discovered I was missing something

# stash away the current mess I made
git stash save

# some changes in the working dir

# and now add them to the last commit:
git add -u
git commit --amend

# back to work!
git stash pop

2
สิ่งที่คุณเพิ่มที่ขาดหายไปจะรวมเข้ากับที่ซ่อนเมื่อคุณปลดมันออกหรือไม่? (ฉันยังคงสั่นคลอนว่าไทม์ไลน์ทำงานอย่างไรในคอมไพล์ - ฉันคิดว่าคุณเขียนทับประวัติศาสตร์ ??)
Kiki Jewell

@KikiJewell popped การเปลี่ยนแปลงถูกนำไปใช้กับดัชนี - พวกเขาไม่ได้กระทำ ดังนั้นหากคุณgit stash popสองครั้งคุณจะสูญเสียความแตกต่างระหว่างชุดการเปลี่ยนแปลงทั้งสองชุดนั้น
Mureinik

ณ ปลายเดือนตุลาคมปี 2017 ได้มีการอภิปรายอย่างกว้างขวางใน Git git stash pushรายชื่อผู้รับจดหมายขัดแย้งซ่อนคอมไพล์คำสั่งบันทึกจะถูกเลิกในความโปรดปรานของทางเลือกที่มีอยู่ เหตุผลหลักคือการgit stash pushแนะนำตัวเลือกในการซ่อน pathspec ที่เลือกบางอย่างgit stash saveไม่รองรับ
Krishna Gupta

@ มูเรนิกคิดยังไงกับสาขาใหม่กับสาขา git stash?
Pacerier

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

41

ฉันจะแบ่งคำตอบในสามย่อหน้า

ส่วนที่ 1:

git stash(เพื่อบันทึกการเปลี่ยนแปลงที่ยังไม่ได้ผูกมัดของคุณใน "ที่เก็บ" หมายเหตุ:สิ่งนี้จะลบการเปลี่ยนแปลงออกจากโครงสร้างการทำงาน!)

git checkout some_branch(เปลี่ยนเป็นสาขาที่ต้องการ - ในกรณีนี้some_branch)

git stash list (รายการที่เก็บ)

คุณสามารถดู:
stash @ {0}: WIP บน {branch_name}: {SHA-1 of last คอมมิต} {last commit of you branch}
stash @ {0}: WIP on master: 085b095c6 การแก้ไขสำหรับการทดสอบ

git stash apply (เพื่อใช้ที่ซ่อนกับต้นไม้การทำงานในสาขาปัจจุบัน)

git stash apply stash@{12}(หากคุณมีที่เก็บหลายอันคุณสามารถเลือกได้ว่าจะใช้ที่เก็บซ่อนใด - ในกรณีนี้เราใช้ที่เก็บซ่อน12)

git stash drop stash@{0}(เพื่อลบออกจากรายการที่เก็บ - ในกรณีนี้ที่ซ่อน0)

git stash pop stash@{1} (เพื่อใช้ที่เก็บที่เลือกและวางจากรายการที่เก็บ)

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

ส่วนที่ 3:
คำสั่ง Stash สำหรับโลคัลซ่อนการเปลี่ยนแปลงของคุณ
หากคุณต้องการทำงานจากระยะไกลคุณต้องกระทำและผลักดัน


10

แนวคิดหลักคือ

ซ่อนการเปลี่ยนแปลงในไดเร็กทอรีการทำงานที่สกปรกออกไป

คำสั่ง Basicallly Stash เก็บการเปลี่ยนแปลงบางอย่างที่คุณไม่ต้องการหรือต้องการในขณะนี้ แต่คุณอาจต้องการมัน

ใช้git stashเมื่อคุณต้องการบันทึกสถานะปัจจุบันของไดเร็กทอรีการทำงานและดัชนี แต่ต้องการกลับไปที่ไดเร็กทอรีการทำงานที่สะอาด คำสั่งจะบันทึกการแก้ไขในเครื่องของคุณและย้อนกลับไดเร็กทอรีการทำงานเพื่อให้ตรงกับHEAD คอม มิต


8

คุณสามารถใช้คำสั่งต่อไปนี้:

  • เพื่อบันทึกการเปลี่ยนแปลงที่ไม่ได้ผูกมัดของคุณ

    git stash

  • เพื่อแสดงรายการที่เก็บบันทึกของคุณ

    git stash list

  • หากต้องการใช้ / รับการเปลี่ยนแปลงที่ไม่ถูกกำหนดกลับโดยที่ x คือ 0,1,2 ...

    git stash apply stash@{x}

บันทึก:

  • เพื่อใช้ที่ซ่อนและลบออกจากรายการที่ซ่อน

    git stash pop stash@{x}

  • เพื่อใช้ที่ซ่อนและเก็บไว้ในรายการที่ซ่อน

    git stash apply stash@{x}


4

หากคุณกดgit stashเมื่อคุณมีการเปลี่ยนแปลงในสำเนาที่ใช้งานได้ (ไม่ใช่ในพื้นที่จัดเตรียม) คอมไพล์จะสร้างวัตถุที่เก็บไว้และดันไปยังกองซ้อนของที่เก็บ (เช่นเดียวกับที่คุณทำgit checkout -- .แต่คุณจะไม่สูญเสียการเปลี่ยนแปลง) หลังจากนั้นคุณสามารถเปิดจากด้านบนสุดของสแต็ก


2

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


2
ไม่git stashจะไม่เปลี่ยนสาขาของคุณ โดยเฉพาะอย่างยิ่งจะไม่ "คืนกลับ" การเปลี่ยนแปลงที่มุ่งมั่น มันจะทิ้งการเปลี่ยนแปลงที่ไม่ได้ผูกมัดในไฟล์ของคุณ (ชั่วคราว) เท่านั้น - อาจดูจู้จี้จุกจิก แต่คำประเภทนี้มีความหมายพิเศษมากในบริบทของคอมไพล์ คุณไม่ควรผสมสิ่งเหล่านี้ขึ้น
michas

ขอบคุณที่ชี้ให้เห็น ฉันเปลี่ยนคำตอบตามนั้น
Severin

ในคอมไพล์ "สาขา" ถูกกำหนดให้เป็นชุดของคอมมิต git stashจะไม่แตะต้องการกระทำใด ๆ ดังนั้นจะไม่แก้ไขสาขาใด ๆ ทั้งสิ้น มันจะไม่ "ลบ" อะไรออกจากสาขาและจะไม่ "รีเซ็ต" แต่อย่างใด สาขายังคงเหมือนเดิมเฉพาะไฟล์ในโครงสร้างการทำงานเท่านั้นที่เปลี่ยนแปลง - สองสิ่งนี้แตกต่างกันโดยสิ้นเชิง
michas

จะไม่ทิ้ง แต่ "ซ่อน" การเปลี่ยนแปลงของคุณ! Git รักษาโครงสร้าง LIFO สำหรับการซ่อนดังนั้นการซ่อนจึงเป็นสิ่งที่ผลักดันและคุณสามารถปรากฏจากด้านบนของมันได้ คำว่า "ทิ้ง" หมายความว่าคุณจะสูญเสียอะไร แต่คุณจะไม่ทำ
gyorgyabraham

2

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

คุณไม่ต้องการยืนยันการเปลี่ยนแปลงทดสอบ

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

คุณไม่ต้องการสูญเสียการเปลี่ยนแปลงในเครื่องด้วยการฮาร์ดรีเซ็ต

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

ดังนั้นสำหรับคำตอบของ 'เมื่อไหร่ที่คุณควรซ่อน' คำตอบคือเมื่อคุณต้องการกลับไปที่จุดคอมมิตที่สะอาดด้วยแผนผังการทำงาน / ดัชนี / คอมมิตที่ซิงโครไนซ์ แต่คุณไม่ต้องการสูญเสียการเปลี่ยนแปลงในเครื่องของคุณใน กระบวนการ. เพียงแค่เก็บการเปลี่ยนแปลงของคุณไว้ในที่ซ่อนและคุณก็ทำได้ดี

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

Git stash และ GitHub

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

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

git diff > git-dif-file.diff

เปิดที่ซ่อน

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