ฉันจะเก็บกิ่งก้านสาขาของ Git ได้อย่างไร?


305

ฉันมีสาขาเก่าในที่เก็บ git ของฉันที่ไม่ได้อยู่ภายใต้การพัฒนาที่ใช้งานได้อีกต่อไป git branch -l -rผมอยากจะเก็บกิ่งไม้เพื่อที่พวกเขาจะไม่แสดงขึ้นโดยค่าเริ่มต้นเมื่อทำงาน ฉันไม่ต้องการลบเพราะฉันต้องการเก็บประวัติ ฉันจะทำสิ่งนี้ได้อย่างไร

ฉันรู้ว่าเป็นไปได้ที่จะสร้างการอ้างอิงนอกเหนือจากการอ้างอิง / หัว ตัวอย่างเช่นrefs/archive/old_branch. มีผลกระทบอะไรบ้างจากการทำเช่นนั้น?


git-rm ไม่ได้ลบทรัพยากรออกจากที่เก็บ แต่จะลบพวกมันออกจากดัชนีkernel.org/pub/software/scm/git/docs/git-rm.htmlคุณสามารถกู้คืนทรัพยากรเหล่านี้ได้อย่างง่ายดายโดยใช้git checkout [rev] file
Dana the Sane

1
ไม่ใช่ที่ฉันรู้ แต่ฉันใช้Attic/<branchname>แท็กที่มีน้ำหนักเบาเพื่อเก็บถาวรสาขา
Jakub Narębski

แท็กเป็นตัวเลือกที่รวดเร็วและปลอดภัยและมีเหตุผล
kch

คำตอบ:


401

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

หากคุณต้องการกลับไปที่สาขาเพียงตรวจสอบแท็ก มันจะคืนค่าสาขาอย่างมีประสิทธิภาพจากแท็ก

วิธีเก็บถาวรและลบสาขา:

git tag archive/<branchname> <branchname>
git branch -d <branchname>

ในการกู้คืนสาขาในภายหลัง:

git checkout -b <branchname> archive/<branchname>

ประวัติของสาขาจะได้รับการเก็บรักษาเหมือนเดิมเมื่อคุณติดแท็ก


11
ฉันเป็นมือใหม่ Git แต่ในการลองนี้ฉันคิดว่าคำสั่งที่เหมาะสมสำหรับการกู้คืนสาขาคือ:git checkout -b <branchname> archive/<branchname>
Steve

6
มีเหตุผลที่จะไม่ใช้แท็กวัตถุในกรณีนี้หรือไม่? ความสามารถในการดูว่าใครเก็บถาวรสาขาและเมื่อใดจะน่าสนใจ
Grégory Joseph

7
@ GrégoryJoseph: นั่นคือแท็กที่มีคำอธิบายประกอบ และใช่การใช้ที่สามารถทำให้รู้สึกมากฉันพูด
onnodb

22
โน้ตเล็ก ๆ , คุณอาจต้องการbranch -Dเนื่องจากมันอาจจะไม่ถูกรวมเข้าด้วยกันอย่างสมบูรณ์ถ้าคุณเก็บถาวรด้วยวิธีนี้
Arkadiy Kukarkin

5
ดีมาก. นี่คือการสอนที่สมบูรณ์พร้อมคำอธิบาย
guyaloni

123

หลักการของ Jeremy นั้นถูกต้อง แต่ IMHO คำสั่งที่เขาระบุนั้นไม่ถูกต้องนัก

ต่อไปนี้เป็นวิธีเก็บถาวรสาขาไปยังแท็กโดยไม่ต้องชำระเงินที่สาขา (และดังนั้นโดยไม่ต้องชำระเงินไปยังสาขาอื่นก่อนที่คุณจะสามารถลบสาขานั้น):

> git tag archive/<branchname> <branchname>
> git branch -D <branchname>

และนี่คือวิธีการคืนค่าสาขา:

> git checkout -b <branchname> archive/<branchname>

18
ฉันเดาว่าคุณยังไม่มีคะแนนเพียงพอ แต่มันจะดีกว่าเมื่อคุณแก้ไขคำตอบที่มีอยู่เดิม - +1 ต่อไปแม้ว่า :)
jkp

5
@jkp การแก้ไขรหัสและคำสั่งของผู้ใช้คนอื่นมักจะขมวดคิ้วเนื่องจากการเปลี่ยนแปลงเล็กน้อยในคำสั่ง git สามารถทำสิ่งที่แตกต่างกันอย่างมากและคุณอาจไม่เข้าใจว่าทำไมผู้เขียนดั้งเดิมเขียนสิ่งที่พวกเขาทำ ดีกว่าที่จะเพียงแค่ให้คำตอบของคุณเองหรือแสดงความคิดเห็น
Dan Bechard

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

22

git update-refใช่คุณสามารถสร้างโทษกับบางส่วนคำนำหน้าไม่ได้มาตรฐานโดยใช้ เช่น

  • เก็บถาวรสาขา: git update-ref refs/archive/old-topic topic && git branch -D topic
  • คืนค่าสาขา (ถ้าจำเป็น): git branch topic refs/archive/old-topic

refs ด้วยคำนำหน้าไม่ได้มาตรฐาน (ที่นี่refs/archive) จะไม่แสดงขึ้นบนปกติgit branch, มิได้git log ยังคงคุณสามารถแสดงรายการพวกเขาด้วยgit taggit for-each-ref

ฉันใช้นามแฝงต่อไปนี้:

[alias]
    add-archive = "!git update-ref refs/archive/$(date '+%Y%m%d-%s')"
    list-archive = for-each-ref --sort=-authordate --format='%(refname) %(objectname:short) %(contents:subject)' refs/archive/
    rem = !git add-archive
    lsrem = !git list-archive

นอกจากนี้คุณอาจต้องการกำหนดค่ารีโมทเช่นpush = +refs/archive/*:refs/archive/*กดสาขาที่เก็บถาวรโดยอัตโนมัติ (หรือgit push origin refs/archive/*:refs/archive/*สำหรับช็อตเดียว)

อีกวิธีหนึ่งคือการเขียน SHA1 บางแห่งก่อนที่จะลบสาขา แต่มีข้อ จำกัด กระทำได้โดยไม่ต้องเตะโทษใด ๆ จะGC'd หลังจาก 3 เดือน (หรือสองสามสัปดาห์โดยไม่ต้อง reflog ก)git gc --pruneให้อยู่คนเดียวคู่มือ การกระทำที่ชี้โดยผู้อ้างอิงปลอดภัยจาก GC

แก้ไข:พบการใช้ Perl ของแนวคิดเดียวกันโดย@ap :git-attic

แก้ไข ^ 2:พบบล็อกโพสต์ที่ Gitster ใช้เทคนิคเดียวกัน


3
ยอดเยี่ยมนอกเหนือจากคนอื่น ๆ ในหัวข้อนี้คุณตอบคำถามจริง
tzrlk

20

ฉันได้ขยายคำตอบของสตีฟเพื่อสะท้อนการเปลี่ยนแปลงของรีโมทฉันทำ

 git tag archive/<branchname> <branchname>
 git branch -D <branchname>
 git branch -d -r origin/<branchname>
 git push --tags
 git push origin :<branchname>

หากต้องการคืนค่าจากระยะไกลให้ดูคำถามนี้


18

คุณสามารถเก็บถาวรสาขาในที่เก็บอื่น ไม่ค่อยสง่างามเท่าไหร่ แต่ฉันว่ามันเป็นทางเลือกที่เหมาะสม

git push git://yourthing.com/myproject-archive-branches.git yourbranch
git branch -d yourbranch

4
คุณสามารถสร้างgit-bundleแทนที่จะเป็นที่เก็บแยกต่างหาก
Jakub Narębski

9

นี่คือนามแฝงสำหรับ:

arc    = "! f() { git tag archive/$1 $1 && git branch -D $1;}; f"

เพิ่มแบบนี้:

git config --global alias.arc '! f() { git tag archive/$1 $1 && git branch -D $1;}; f'

โปรดจำไว้ว่ามีgit archiveคำสั่งอยู่แล้วดังนั้นคุณจึงไม่สามารถใช้archiveเป็นชื่อนามแฝงได้

นอกจากนี้คุณสามารถกำหนดนามแฝงเพื่อดูรายการสาขา 'ที่เก็บถาวร':

arcl   = "! f() { git tag | grep '^archive/';}; f"

เกี่ยวกับการเพิ่มชื่อแทน


3
ด้วย git เวอร์ชันใหม่ (ตามที่แนะนำไว้ที่นี่ ) นามแฝงนี้จะทำให้เสร็จสมบูรณ์:!git tag archive/$1 $1 && git branch -D
ขาด

5

ฉันใช้นามแฝงต่อไปนี้เพื่อซ่อนสาขาที่เก็บถาวร:

[alias]
    br = branch --no-merge master # show only branches not merged into master
    bra = branch                  # show all branches

ดังนั้นgit brเพื่อแสดงสาขาการพัฒนาอย่างแข็งขันและgit braจะแสดงให้ทุกสาขารวมทั้ง"เก็บไว้"คน


5
ไม่ว่าสาขาจะถูกรวมเข้ากับข้อมูลหลักหรือไม่นั้นไม่เกี่ยวข้องกับสถานะการเก็บถาวร ตัวอย่างเช่นในทีมผู้พัฒนาของฉันเรามีสาขาไม่กี่แห่งที่สร้างขึ้นเพื่อทดสอบสิ่งต่างๆโดยเฉพาะ เราต้องการเก็บสาขาเหล่านั้นไว้ในที่เก็บถาวรของเรา แต่แน่นอนว่าเราไม่ต้องการรวมสาขาเหล่านั้นไว้ในหลัก
บาร์ต

4

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

นี่คือสองขั้นตอนง่าย ๆ ที่จะช่วยโบราณคดีและการพัฒนาอย่างมาก

  1. เชื่อมโยงแต่ละสาขางานกับปัญหาที่เกี่ยวข้องในตัวติดตามปัญหาโดยใช้หลักการตั้งชื่อแบบง่าย
  2. ใช้git merge --no-ffเพื่อผสานสาขางานเสมอ คุณต้องการรวมการกระทำและฟองประวัติศาสตร์แม้เพียงหนึ่งการกระทำ

แค่นั้นแหละ. ทำไม? เพราะในฐานะนักโบราณคดีรหัสฉันมักจะเริ่มต้นด้วยความต้องการที่จะรู้ว่างานที่ทำในสาขา บ่อยครั้งที่รหัสเสียงนี้ถูกเขียนขึ้นมาด้วยวิธีนี้ในเก้านรก! ฉันต้องเปลี่ยนรหัส แต่มีคุณสมบัติแปลก ๆ และฉันต้องไขปริศนาเพื่อหลีกเลี่ยงสิ่งที่สำคัญ

ขั้นตอนต่อไปคือgit blameการค้นหาการกระทำที่เกี่ยวข้องและหวังว่าข้อความบันทึกจะอธิบาย ถ้าฉันต้องขุดลึกลงไปฉันจะพบว่างานนั้นทำในสาขาและอ่านสาขาทั้งหมด (พร้อมด้วยคำอธิบายในตัวติดตามปัญหา)

สมมุติว่าให้git blameคะแนนกระทำ XYZ ฉันเปิดเบราว์เซอร์ประวัติ Git (gitk, GitX git log --decorate --graph, ฯลฯ ... ) ค้นหาคำสั่ง XYZ และดู ...

AA - BB - CC - DD - EE - FF - GG - II ...
     \                       /
      QQ - UU - XYZ - JJ - MM

มีสาขาของฉัน! ฉันรู้ว่า QQ, UU, XYZ, JJ และ MM เป็นส่วนหนึ่งของสาขาเดียวกันและฉันควรดูรายละเอียดข้อความบันทึกของพวกเขา ฉันรู้ว่า GG จะทำการรวมและมีชื่อสาขาที่หวังว่าจะเชื่อมโยงกับปัญหาในตัวติดตาม

ถ้าด้วยเหตุผลบางอย่างฉันต้องการค้นหาสาขาเก่าที่ฉันสามารถเรียกใช้git logและค้นหาชื่อสาขาในการคอมมิชชันผสาน มันเร็วพอแม้ที่เก็บข้อมูลขนาดใหญ่มาก

นั่นคือสิ่งที่ฉันหมายถึงเมื่อฉันพูดว่าสาขาที่เก็บถาวรตัวเอง

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


2
แต่ความยุ่งเหยิงล่ะ บางทีถ้ามีวิธีซ่อนกิ่งไม้ที่มีความสกปรกต่ำกว่า 10 ลูกบาศก์หลา
bvj

1
สิ่งนี้มีประโยชน์ แต่ไม่สามารถใช้ได้กับสาขาที่ไม่ได้รวม บางครั้งมีการทดสอบในสาขาและคุณต้องการเก็บเนื้อหาไว้ในกรณีที่การทดสอบบางอย่างมีประโยชน์ในภายหลัง
Neil Mayhew

1
@bvj ฉันคิดว่าคำตอบนี้แนะนำให้คุณควรลบสาขาที่รวมอยู่เสมอเพราะคุณสามารถกลับไปที่สาขาเหล่านั้นได้โดยใช้การรวมการกระทำ ฉันเห็นด้วยกับสิ่งนี้
Neil Mayhew

@NeilMayhew ใช่ฉันมีสาขาที่ยังไม่ได้เปิดประมาณ 10 สาขาที่เปิดอยู่ แต่ละงานเกี่ยวข้องกับงานเปิดดังนั้นฉันสามารถจำได้ว่าฉันทำอะไรอยู่ ฉันจะทำอะไรบางอย่างกับพวกเขาหรือพวกเขาล้าสมัยพวกเขาจะไม่เกี่ยวข้องอีกต่อไปและฉันจะลบพวกเขา ฉันทำงานในโครงการที่จมอยู่ในสาขา "ฉันอาจต้องการในภายหลัง" สาขาดังนั้นเราแทบจะไม่สามารถเห็นสิ่งที่เรากำลังทำอยู่ มันเป็นข้อแก้ตัวสำหรับผู้พัฒนาบางคนที่ไม่ต้องทำความสะอาดตัวเอง นิดหน่อย leeway เป็นเรื่องปกติ แต่อย่าปล่อยให้มันอยู่นอกการควบคุม
Schwern

@Schwern ฉันเห็นด้วย ฉันเคยทำงานในโครงการเช่นนั้นมาแล้ว ฉันคิดว่าการเปลี่ยนกิ่งเป็นแท็กเป็นวิธีที่ดีในการกำจัดความยุ่งเหยิงเนื่องจากรายการของแท็กจะเพิ่มขึ้นเรื่อย ๆ ในขณะที่รายการของสาขาไม่ควรจะดี การใช้การกำหนดเนมสเปซสำหรับแท็กทำให้รายการสามารถจัดการได้ง่ายขึ้น แต่แนวโน้มของ packrat จำเป็นต้องถูกต่อต้านอย่างแน่นอน นักพัฒนาควรรักษาความมุ่งมั่นในเครื่องของตัวเองเว้นแต่มีโอกาสดีที่คนอื่นจะใช้พวกเขาในที่สุด
Neil Mayhew

2

แนวทางของฉันคือเปลี่ยนชื่อทุกสาขาที่ฉันไม่สนใจด้วยคำนำหน้า "trash_" จากนั้นใช้:

git branch | grep -v trash

(ด้วยการโยงคีย์เชลล์)

เพื่อรักษาสีของสาขาที่ใช้งานอยู่คุณจะต้อง:

git branch --color=always | grep --color=never --invert-match trash

2
หากเปลี่ยนชื่อสาขาคุณอาจวางไว้ในเนมสเปซ "archive /"
qneill

1

คุณสามารถใช้สคริปต์ที่จะเก็บสาขาสำหรับคุณ

archbranch

มันจะสร้างแท็กให้กับคุณด้วยคำนำหน้าการเก็บถาวร / จากนั้นลบสาขา แต่ตรวจสอบรหัสก่อนที่จะใช้


การใช้งาน - $/your/location/of/script/archbranch [branchname] [defaultbranch]

หากคุณต้องการเรียกใช้สคริปต์โดยไม่ต้องเขียนที่ตั้งให้เพิ่มไปยังเส้นทางของคุณ

จากนั้นคุณสามารถโทรหาได้โดย

$ archbranch [branchname] [defaultbranch]

[defaultbranch]เป็นสาขาที่ว่ามันจะไปเมื่อเก็บเสร็จ มีปัญหาบางอย่างกับการเข้ารหัสสี แต่อื่น ๆ แล้วมันควรจะทำงาน ฉันใช้มันในโครงการมานาน แต่ก็ยังอยู่ระหว่างการพัฒนา


1
ตามความช่วยเหลือล้นสแต็คคุณจะต้องเปิดเผยความเกี่ยวข้องกับผลิตภัณฑ์ของคุณ
LittleBobbyTables - Au Revoir

โอ้ขอโทษไม่รู้ ฉันเป็นผู้เขียนสคริปต์
Banezaka

0

บางครั้งฉันเก็บสาขาเป็นดังนี้:

  1. สร้างไฟล์แพทช์เช่นformat-patch <branchName> <firstHash>^..<lastHash>(รับ firstHash และ lastHash git log <branchName>ใช้
  2. ย้ายไฟล์แพตช์ที่สร้างไปยังไดเรกทอรีบนไฟล์เซิร์ฟเวอร์
  3. ลบสาขาเช่น git branch -D <branchName>

"ใช้" แพตช์เมื่อคุณต้องการใช้สาขาอีกครั้ง; อย่างไรก็ตามการใช้ไฟล์แก้ไข (ดูgit am) อาจมีความท้าทายขึ้นอยู่กับสถานะของสาขาเป้าหมาย ในทางบวกวิธีการนี้มีประโยชน์ในการอนุญาตให้สาขาที่จะเก็บขยะและประหยัดพื้นที่ใน repo ของคุณ

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