ใช้ Git แสดงการกระทำทั้งหมดที่อยู่ในสาขาเดียว แต่ไม่ใช่ทั้งหมด


465

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


ในการแสดงรายการที่ขาดหายไประหว่างสองสาขาคุณสามารถใช้ compar-branches.py bitbucket.org/aakef/compare-git-branches
Bernd Schubert

ที่เกี่ยวข้อง: stackoverflow.com/q/1419623/1959808
Ioannis Filippidis

คำตอบ:


321

คุณอาจต้องการ

git branch --contains branch-to-delete

รายการนี้จะแสดงทุกสาขาที่มีการคอมมิทจาก "branch-to-delete" หากรายงานมากกว่า "branch-to-delete" แสดงว่าสาขานั้นถูกผสาน

ทางเลือกของคุณเป็นเพียงแค่รายการไวยากรณ์ซ้ำ เช่น git log one-branch..another-branchแสดงทุกสิ่งที่one-branchจำเป็นต้องมีทุกอย่างanother-branchมี

คุณอาจสนใจgit show-branchวิธีการดูว่ามีที่ไหน



1
บรรทัด 'หากรายงานบางสิ่งสาขาได้ถูกรวมเข้าด้วยกัน' อาจตีความผิด: หากgit branch --contains some-branchส่งคืนเฉพาะsome-branchก็จะส่งคืนบางสิ่ง แต่ไม่รวมเข้าด้วยกัน
ความสับสน

5
โปรดทราบว่าgit log foo..barจะแสดงความมุ่งมั่นระหว่างล่าสุดของบาร์และล่าสุดของ foo แต่ไม่ได้มุ่งมั่นอื่น ๆ หายไปจากเวลาย้อนหลังต่อไป หากต้องการดูทุกอย่างในบาร์ แต่ไม่ใช่ใน foo คุณควรใช้โซลูชันของ @ jimmyorr
Paul A Jungwirth

555

หากต้องการดูรายการที่กระทำอยู่ในสาขาหนึ่ง แต่ไม่ใช่รายการอื่นให้ใช้บันทึก git:

git log --no-merges oldbranch ^newbranch

... นั่นคือแสดงบันทึกการกระทำสำหรับการกระทำทั้งหมดใน oldbranch ที่ไม่ได้อยู่ใน newbranch คุณสามารถแสดงหลายสาขาเพื่อรวมและแยกตัวอย่างเช่น

git log  --no-merges oldbranch1 oldbranch2 ^newbranch1 ^newbranch2

หมายเหตุ: บน Windows ^เป็นรหัสปลดล็อคดังนั้นจึงจำเป็นต้องใช้ Escape อื่น^:

git log --no-merges oldbranch ^^newbranch

2
ฉันพบว่ามันกำลังมองหาคอมไพล์เปรียบเทียบการกระทำของสองสาขา
ผู้ใช้

25
นี่คือสิ่งที่ฉันกำลังมองหา แต่การใช้^คำนำหน้านี่ทำให้ฉันสับสน ในบริบทนี้มันหมายถึงการแยกสาขานั้น การใช้^เป็นคำต่อท้ายจะเป็นการอ้างอิงแบบสัมพัทธ์กับการกระทำหลักของสาขานั้น
Joe Flynn

4
ขอบคุณมากที่มีประโยชน์ ฉันอยากรู้ว่าทำไม - ไม่จำเป็นต้องรวมธง? แน่นอนหนึ่งต้องการเห็นการกระทำเหล่านั้นด้วยหรือไม่
Max MacLeod

2
ต้องการใช้ gitk กับสิ่งนี้หรือไม่? เพียงใช้gitk oldbranch ^newbranch --no-merges(ทดสอบด้วย git 1.8.1.1) บันทึก Side สำหรับฉัน^หมายความรวม HEAD newbranchกระทำของสาขา
แมตต์

2
@NazariiGudzovatyi - ใช่มี: "-cherry-pick" มีตัวเลือกมากมายสำหรับบันทึกในหน้าเอกสาร
romeara

91

วิธีแสดงคอมมิชชันใน oldbranch แต่ไม่ใช่ใน newbranch:

git log newbranch..oldbranch

หากต้องการแสดงผลต่างจากการกระทำเหล่านี้ (โปรดทราบว่ามีจุดสามจุด):

git diff newbranch...oldbranch

นี่คือเอกสารที่มีภาพประกอบแผนภาพ https://git-scm.com/book/en/v2/Git-Tools-Revision-Selection#Commit-Ranges


ดูความคิดเห็นของ Paul A Jungwirthด้านบน ดูเหมือนว่าสิ่งนี้จะพลาดโอกาสเก่าแก่บ้างไหม?
แปรปรวนตัวแปร

2
ฉันไม่แน่ใจว่าคำมั่นสัญญาเก่าหมายถึงอะไร โดยทั่วไปจุดสองจุดจะขอให้ Git แก้ไขช่วงของการกระทำที่เข้าถึงได้จากการกระทำหนึ่ง แต่ไม่สามารถเข้าถึงได้จากการกระทำอื่น นี่คือเอกสารที่มีภาพประกอบdigram git-scm.com/book/en/v2/…
Xuan

1
และถ้าเราอยู่บนnewbranchหรือoldbranchเราสามารถทำgit log ..oldbranchหรือgit log newbranch..ตามลำดับ
YakovL

คำตอบของจิมมี่อร์ไม่ได้ผลสำหรับฉัน แต่อันนี้ขอบคุณสองจุด..ระหว่างชื่อผู้อ้างอิง ฉันยังใช้--cherry-pickตัวเลือกเพื่อซ่อนคอมมิชชันที่มีอยู่ในทั้งสองสาขา แต่มีแฮชที่แตกต่างกันเพราะพวกเขาเลือกเชอร์รี่จากสาขาหนึ่งไปอีกสาขา
flawyte

58

สำหรับผู้ที่ยังคงมองหาคำตอบง่ายๆลองดูที่git cherryเชอร์รี่คอมไพล์มันเปรียบเทียบความแตกต่างจริงแทนที่จะกระทำการแฮช นั่นหมายความว่ามันรองรับการกระทำที่เชอร์รี่เลือกหรือถูกปฏิเสธ

ก่อนชำระเงินสาขาที่คุณต้องการลบ:

git checkout [branch-to-delete]

จากนั้นใช้ git cherry เพื่อเปรียบเทียบกับสาขาการพัฒนาหลักของคุณ:

git cherry -v master

ตัวอย่างผลลัพธ์:

+ 8a14709d08c99c36e907e47f9c4dacebeff46ecb Commit message
+ b30ccc3fb38d3d64c5fef079a761c7e0a5c7da81 Another commit message
- 85867e38712de930864c5edb7856342e1358b2a0 Yet another message

หมายเหตุ: -vแฟล็กคือการรวมข้อความการส่งพร้อมกับแฮช SHA

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

สำหรับการกระทำที่ไม่อยู่ในหลักเพียงรวมเชอร์รี่พิคกับ grep:

git cherry -v master | grep "^\+"

ตัวอย่างผลลัพธ์:

+ 8a14709d08c99c36e907e47f9c4dacebeff46ecb Commit message
+ b30ccc3fb38d3d64c5fef079a761c7e0a5c7da81 Another commit message

ฉันได้ลองแล้ว แต่ยังคงรายงานว่ามีข้อผูกพันมากมายใน fb (สาขาฟีเจอร์) ที่ไม่ได้อยู่ใน mb (สาขาหลัก) อย่างไรก็ตามถ้าฉันอยู่ใน FB และทำ git diff mb ฉันไม่เห็นความแตกต่าง ฉันใช้ rebase และบีบทุกอย่าง ฉันเกือบจะแน่ใจว่านี่คือเหตุผล แต่ฉันแค่อยากจะแน่ใจ หากเป็นกรณีนี้ฉันจะหลีกเลี่ยงการบีบถ้าเป็นไปได้ ฉันอยู่ใน "ไม่มีค่ายข้อมูลสูญหาย" ฉันสงสัยว่ามันจะเป็นไปได้หรือไม่ที่จะเพิ่มโหมดการแสดงผลเข้าสู่ระบบที่สามารถแสดงการผสานราวกับว่าพวกเขาเป็น rebases เพื่อรักษาประวัติให้สะอาดและยังไม่สูญเสียข้อมูล
Outis Von Nemo

1
ไม่แน่ใจเกี่ยวกับสถานการณ์ที่แน่นอนของคุณที่นี่ แต่ถ้าคุณบีบหลายคอมมิตเข้าด้วยกันและเปรียบเทียบกับสาขาอื่นที่แยกคอมมิชชันสิ่งนี้จะไม่ทำงานแน่นอน ในกรณีนี้คุณอาจต้องการใช้diffยูทิลิตีunix เพื่อเปรียบเทียบไฟล์ต่างๆ หรือคุณสามารถสร้างสาขาชั่วคราวและสควอชทั้งหมดกระทำในสิ่งที่คล้ายกับสิ่งที่คุณทำกับสาขาเดิมแล้วใช้สิ่งนี้ซึ่งฉันคิดว่าจะทำงาน
Tim S

50

ในขณะที่บางคำตอบที่โพสต์ที่นี่จะช่วยค้นหาสิ่งที่คุณต้องการคำสั่งย่อยของสาขา gitต่อไปนี้เป็นทางออกที่เหมาะสมสำหรับงานของคุณ

- น้ำท่วมจะใช้ในการค้นหาสาขาทั้งหมดที่สามารถลบได้อย่างปลอดภัยเนื่องจากหัวหน้าเหล่านั้นจะถูกเก็บไว้อย่างเต็มที่โดย HEAD

ในขณะที่masterหนึ่งสามารถเรียกใช้คำสั่งเพื่อระบุสาขาหนึ่งที่สามารถลบได้อย่างปลอดภัยเช่น:

git branch --merged
  develop
  fpg_download_links
* master
  master_merge_static

# Delete local and remote tracking branches you don't want
git branch -d fpg_download_links
git push origin :fpg_download_links
git branch -d master_merge_static
git push origin :master_merge_static

# There is also a flag to specify remote branches in the output
git branch --remotes --merged

16

คำตอบของ jimmyorrไม่ทำงานบน Windows มันช่วยในการใช้--notแทนที่จะเป็น^เช่นนั้น:

git log oldbranch --not newbranch --no-merges

4
ถูกต้อง +1 หมายเหตุว่าที่^ได้รับการสนับสนุนบน Windows แต่จะต้องมีการหลบหนีซึ่งใน Windows เป็น (อีก) :^ git log oldbranch ^^newbranch --no-merges
VonC

3
หากต้องการระบุอย่างเฉพาะเจาะจงจะทำงานใน Windows ในคอนโซล Powershell แต่ต้องใช้ "^" พิเศษใน CMD
Rod

7

หากเป็นสาขาเดียวที่คุณต้องการตรวจสอบตัวอย่างเช่นหากคุณต้องการให้สาขา 'B' นั้นถูกรวมเข้ากับสาขา 'A' คุณสามารถทำสิ่งต่อไปนี้ได้:

$ git checkout A
$ git branch -d B

git branch -d <branchname> มีความปลอดภัยที่ "สาขาจะต้องผสานอย่างเต็มที่ใน HEAD"

ข้อควรระวัง : สิ่งนี้จะลบสาขา B หากรวมเข้ากับ A


3

คุณสามารถใช้สคริปต์ง่าย ๆ นี้เพื่อดูการกระทำที่ไม่ได้ผสาน

#!/bin/bash
# Show commits that exists only on branch and not in current
# Usage:
#   git branch-notmerge <branchname>
#
# Setup git alias
#   git config alias.branch-notmerge [path/to/this/script]
grep -Fvf <(git log --pretty=format:'%H - %s') <(git log $1 --pretty=format:'%H - %s')

คุณสามารถใช้เครื่องมือgit-wtfที่จะแสดงสถานะของสาขา


0

เพียงใช้git cherryเพื่อเลือกข้อผูกพันทั้งหมดในสาขาnewFeature42ตัวอย่างเช่น:

git cherry -v master คุณลักษณะใหม่ 42


-5

เริ่มสร้างคำขอดึงผ่านบริการโฮสติ้ง git ที่คุณใช้ หากสาขาได้รับการผสานอย่างสมบูรณ์ในสาขาฐานคุณจะไม่สามารถสร้าง PR ใหม่ได้

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

ตัวอย่างเช่นใน GitHub:

ไม่มีอะไรให้เปรียบเทียบ

ไม่สามารถสร้าง PR สำหรับสาขาที่รวมเข้าด้วยกัน

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

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