รับไฟล์ทั้งหมดที่ได้รับการแก้ไขในสาขา git


209

มีวิธีดูไฟล์ที่มีการเปลี่ยนแปลงในสาขาหรือไม่?


4
มีความเป็นไปได้ที่ซ้ำกันของฉันจะหาไฟล์ที่ถูกแก้ไขในสาขาได้อย่างไร?
Matt Ball

2
พวกเขาไม่ใช่พนักงานของฉันพวกเขาเป็นเพื่อนร่วมงานของฉันและไม่ใช่พวกเขาโดยเฉพาะอย่างยิ่งกับคนทั่วไป แต่ใช่อ่านอีกครั้งโพสต์นี้มันดูเหมือนเกษตรเล็กน้อย :)
Raif

3
คุณสามารถใช้ github หรือ bitbucket, gitlab ได้หรือไม่? มีเครื่องมือในการจัดการสถานการณ์นี้อย่างแน่นอน นักพัฒนาทำให้คำขอดึง คุณได้รับคำขอและคุณจะสามารถเข้าถึงอินเทอร์เฟซที่ดีมากซึ่งจะแสดงความแตกต่างของการเปลี่ยนแปลงทั้งหมดที่เกิดขึ้นกับแต่ละไฟล์ คุณสามารถแสดงความคิดเห็นร้องขอการเปลี่ยนแปลง ฯลฯ เมื่อการเปลี่ยนแปลงดีคุณสามารถยอมรับคำขอซึ่งจะรวมการเปลี่ยนแปลงในสาขาที่ร้องขอ (โดยทั่วไปจะพัฒนา) นั่นคือวิธีปฏิบัติที่ดีที่สุดในการจัดการกับสถานการณ์นี้
Scott Wright

คำตอบ:


168

ทางเลือกอื่นสำหรับคำตอบโดย @Marco Ponti และหลีกเลี่ยงการชำระเงิน:

git diff --name-only <notMainDev> $(git merge-base <notMainDev> <mainDev>)

หากเชลล์เฉพาะของคุณไม่เข้าใจโครงสร้าง $ () ให้ใช้เครื่องหมายขีดแทน


1
อา! สนุกดีตอนนี้ถ้าฉันอยากจะพูดว่า <notMainDev> เป็นสาขาปัจจุบันที่ฉันอยู่ ที่ไม่ต้องระบุหรือไม่
Raif

29
git diff --name-only <some-other-branch><some-other-branch>จะแสดงสิ่งที่ไฟล์ที่แตกต่างกันระหว่างสาขาปัจจุบันของคุณและ ดังนั้นมันเป็นหลักคำสั่งเดียวกัน แต่ทราบว่าคุณสามารถใช้ในการค้นหาไฟล์ที่มีความแตกต่างกันระหว่างใด ๆสองสาขาถึงแม้ว่าพวกเขาจะไม่ได้เกี่ยวข้องกับระยะไกล ไม่ว่าการเปรียบเทียบนั้นจะมีประโยชน์หรือไม่ขึ้นอยู่กับโทโพโลยีของสาขาของคุณ ... นอกจากนี้โปรดทราบว่า<some-other-branch>จริงๆแล้วอาจมีการกระทำใด ๆ หรือสิ่งใดก็ตามที่สามารถแก้ไขให้เป็นหนึ่ง
twalberg

อืมฉันคิดว่าสิ่งที่ฉันหมายถึงคือฉันต้องการทำ git diff - name-only <notMainDev> $ (git merge-base <notMainDev> <MY_CURRENT_CO_BRANCH> แน่นอนที่ MY_CURRENT_CO_BRANCH
Raif

คุณสามารถทำเช่นนั้นได้เช่นกัน ที่จะหาจุดที่<notMainDev>และ<MY_CURRENT_CO_BRANCH>เมื่อเร็ว ๆ นี้มีบรรพบุรุษร่วมกันและเปรียบเทียบ<notMainDev>กับบรรพบุรุษที่ คุณจะต้องระบุชื่อสาขาปัจจุบันของคุณตามที่git merge-baseคาดไว้สองอาร์กิวเมนต์ - ไม่มีทางลัดอย่างน้อยในเวอร์ชันปัจจุบัน
twalberg

1
ตกลง! ฉันเข้าใจแล้ว. มารยาทของเพื่อนร่วมงานของฉันชื่อของเขาคืออะไร git merge-base <notMainDev> git branch | grep '\*' | awk '{print $2}' ที่จะได้รับการยอมรับสำหรับสาขาระหว่าง <notMainDev> และสาขาปัจจุบันของฉัน แล้วฉันจะทำคอมไพล์ diff --name เท่านั้น <notMainDev> $ (คอมไพล์ผสานฐาน <notMainDev> git branch | grep '\*' | awk '{print $2}')
Raif

147

สิ่งที่คุณต้องทำคือ:

git checkout <notMainDev>
git diff --name-only <mainDev>

นี่จะแสดงเฉพาะชื่อไฟล์ที่แตกต่างระหว่างสองกิ่ง


ว้าวอย่างรวดเร็วและตรงประเด็นมากเกินไป ขอบคุณ. btw ฉันรักคอมไพล์ มันรวดเร็วและตรงประเด็น
เสมอ

23
ฉันเชื่อว่ามันจะแสดงสิ่งต่าง ๆ ที่เปลี่ยนไป<mainDev>ตั้งแต่กิ่งก้านสาขาแตกต่างกันไป คุณอาจต้องการใช้git diff --name-only <sha-of-branch-point>แทนหรือดูคำตอบอื่นที่ฉันโพสต์ไว้เพื่อหลีกเลี่ยงการชำระเงิน
twalberg

ใช่นั่นเป็นความจริง @twalberg มันจะแสดงการเปลี่ยนแปลงเหล่านั้นหากแยกสาขา ฉันถือว่าสมมติว่าnotMainDevจะได้รับการปรับปรุงด้วย mainDev มุ่งมั่น ... ฉันมักจะพบว่ามีประโยชน์ในการเห็นความแตกต่างเหล่านั้นเช่นกัน
Marco Ponti

คุณไม่สามารถระบุ - ขวาเท่านั้นเพื่อแสดงเฉพาะไฟล์ที่เปลี่ยนแปลงทางด้านขวาได้หรือไม่
TheZenker

คุณได้รับ<sha-of-branch-point>พร้อมกับgit rev-parse <branch-name>
fc9.30

69

ประหลาดใจที่เรื่องนี้ยังไม่ได้รับการกล่าวถึง!

git diff master...branch

ดังนั้นดูการเปลี่ยนแปลงเฉพาะใน branch

เพื่อตรวจสอบการใช้งานสาขาปัจจุบัน

git diff master...

ขอบคุณ jqr

นี่คือมือสั้น ๆ สำหรับ

git diff $(git merge-base master branch) branch

ดังนั้นฐานการผสาน (การคอมมิชชันล่าสุดระหว่างกิ่ง) และปลายกิ่ง

การใช้ Origin / Master แทน Master เพียงอย่างเดียวจะช่วยในกรณีที่ Master ท้องถิ่นของคุณลงวันที่


4
ขณะนี้แสดงให้เห็นว่ามีการเปลี่ยนแปลงก็แสดงให้เห็นถึงการเปลี่ยนแปลงทั้งหมดมากกว่าสรุปของไฟล์ที่มีการเปลี่ยนแปลง ... ซึ่งเป็นสิ่งที่ทำให้ฉันหน้านี้ในสถานที่แรก :)
คริส Rutledge

1
จากนั้นเพิ่มแฟล็ก --name-only ให้กับสิ่งนี้ หรือ --short-stat
exussum

2
git diff --name-only master..หากคุณต้องการชื่อไฟล์ที่แตกต่างระหว่างสองสาขา
Adam

1
สิ่งนี้จะทำงานไม่ถูกต้องหากนายของคุณได้ทำสัญญาหลังจากที่คุณสร้างสาขาด้านข้างของคุณ
Simplylizz

2
@simplylizz ใช่มันเป็นเช่นนั้น นั่นคือสิ่งที่นี่คือการแก้
exussum

45

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

git whatchanged --name-only --pretty="" origin..HEAD

นี่เป็นเพียงรายการชื่อไฟล์และมีเพียงชื่อที่เปลี่ยนแปลงในสาขาปัจจุบัน


3
นี่ดูเหมือนจะเป็นคำตอบที่ง่ายที่สุดที่นี่เนื่องจากไม่ต้องการข้อมูลเพิ่มเติม เอาต์พุตดูเหมือนถูกต้องและง่ายต่อการจดจำมากกว่าคำตอบที่ยอมรับ!
RickMeasham

1
ขอบคุณนี่น่าสนใจใช้คำมากขึ้น จะให้ผลลัพธ์จากการกระทำแต่ละครั้งในลำดับย้อนกลับ git-whatchanged - แสดงบันทึกที่มีความแตกต่างกันในแต่ละ คอมมิชชัน
nealmcb

จากgit docs :New users are encouraged to use git-log instead. The whatchanged command is essentially the same as git-log but defaults to show the raw format diff output and to skip merges.
Derek S

21

ฉันชอบคำตอบของ @ twalberg แต่ฉันไม่ต้องการพิมพ์ชื่อสาขาปัจจุบันตลอดเวลา ดังนั้นฉันใช้สิ่งนี้:

git diff --name-only $(git merge-base master HEAD)

1
โซลูชันของคุณใช้งานได้สำหรับฉันและฉันได้รับรายการไฟล์ที่ฉันคาดว่าจะเห็น ฉันเป็น Git สามเณรและใช้git diff master... --name-onlyเมื่อทำงานในสาขาเป้าหมายและได้รับผลลัพธ์เดียวกัน คุณจะกรุณาแสดงความเห็นต่อสิ่งที่ดีหรือไม่ดีระหว่างคำตอบของคุณกับคำสั่งที่ฉันให้ไว้ได้ไหม
Hungerstar

คำสั่งของคุณจะทำงานเหมือนเดิมทุกประการหากมาสเตอร์ไม่มีการทำสัญญาใหม่ตั้งแต่สร้างสาขาของคุณ ฉันคิดว่าคำสั่งของฉันจะเทียบเท่าgit diff master.. --name-only(หมายเหตุมีเพียง 2 จุดแทน 3) เพื่อให้เข้าใจความหมายของจุดต่าง ๆ ให้ดูคำตอบนี้
Yep_It's_Me

! น่ากลัว ขอบคุณสำหรับการตอบกลับอย่างรวดเร็วและข้อมูลเชิงลึก ชื่นชมมาก
Hungerstar

12

git whatchanged น่าจะเป็นทางเลือกที่ดี


1
อะไรคือสิ่งที่ฉันกำลังมองหา
อ่อน

จากgit docs :New users are encouraged to use git-log instead. The whatchanged command is essentially the same as git-log but defaults to show the raw format diff output and to skip merges.
Derek S

9
git diff --name-only master...branch-name

ที่เราต้องการเปรียบเทียบ


ดูเหมือนว่าบางส่วนของคำตอบที่มีอยู่stackoverflow.com/a/41486181/11912
James Skemp

รูปแบบนี้จะเปรียบเทียบ HEAD of master กับสาขาปัจจุบัน คำตอบที่ได้รับการยอมรับเปรียบเทียบสถานะของต้นแบบที่จุดที่คุณคดเคี้ยว อาจมีคำตอบที่คุณค้นหาทั้งนี้ขึ้นอยู่กับสิ่งที่คุณต้องการรู้
Mark Stosberg

8

ถ้ามันง่ายอย่างนี้ล่ะ?

git changed

หากคุณยินดีที่จะสมมติว่าสาขาหลักเรียกว่า "master" และคุณสร้างสาขาอื่นจากต้นแบบคุณสามารถเพิ่มนามแฝงนี้ใน~/.gitconfigไฟล์ของคุณเพื่อให้ง่าย:

cbranch = !"git branch | grep '*' | cut -f2 -d' '"
changed = !"git diff --name-only $(git cbranch) $(git merge-base $(git cbranch) master)"

สมมติฐานเหล่านั้นจะทำงานสำหรับคนส่วนใหญ่ในสถานการณ์ส่วนใหญ่ แต่คุณต้องระวังว่าคุณกำลังทำพวกเขา

$()นอกจากนี้คุณต้องใช้เปลือกที่สนับสนุน มันมีโอกาสมากที่เปลือกของคุณสนับสนุนนี้


3
git show --stat origin/branch_name

นี่จะให้รายการของไฟล์ที่ถูกเพิ่มหรือแก้ไขภายใต้สาขานี้


2
นี่เป็นความผิดนี่จะแสดงเฉพาะไฟล์ที่เปลี่ยนไปใน head commit ของสาขานั้นไม่ใช่ทั้งสาขา
davidtbernal

2

git-treeด้วยเหตุผลบางอย่างที่ไม่มีใครกล่าวถึง ดูhttps://stackoverflow.com/a/424142/1657819

git-treeเป็นที่ต้องการเพราะมันเป็นคำสั่งการประปา ; ตั้งใจจะเขียนโปรแกรม (และสมมุติเร็วกว่า)

(สมมติว่าเป็นสาขาฐานmaster)

git diff-tree --no-commit-id --name-only -r master..branch-name

อย่างไรก็ตามสิ่งนี้จะแสดงไฟล์ทั้งหมดที่ได้รับผลกระทบในสาขาหากคุณต้องการดูไฟล์ที่แก้ไขอย่างชัดเจนเท่านั้นคุณสามารถใช้--diff-filter:

git diff-tree --no-commit-id --name-only -r master..branch-name --diff-filter=M

นอกจากนี้ยังสามารถใช้--name-statusแทน--name-onlyเพื่อดูสถานะของไฟล์ ( A/ M/ Dและอื่น ๆ )


นี่เป็นสิ่งที่ฉันต้องการสำหรับการเปลี่ยนไฟล์ในขณะที่ไม่รวมไฟล์ที่ถูกลบ rubocop --fail-level error $(git diff-tree --no-commit-id --name-only -r origin/master..HEAD --diff-filter=M)
HarlemSquirrel

1

คำตอบที่ยอมรับ - git diff --name-only <notMainDev> $(git merge-base <notMainDev> <mainDev>)- อยู่ใกล้มาก แต่ฉันสังเกตเห็นว่ามันมีสถานะไม่ถูกต้องสำหรับการลบ ฉันเพิ่มไฟล์ในสาขา แต่คำสั่งนี้ (โดยใช้--name-status) ให้ไฟล์ที่ฉันลบสถานะ "A" และไฟล์ที่ฉันเพิ่ม "D"

ฉันต้องใช้คำสั่งนี้แทน:

git diff --name-only $(git merge-base <notMainDev> <mainDev>)

0

การตัดออกจากสิ่งที่ @twalberg และ @iconoclast หากคุณใช้ cmd ด้วยเหตุผลใดก็ตามคุณสามารถใช้:

FOR /F "usebackq" %x IN (`"git branch | grep '*' | cut -f2 -d' '"`) DO FOR /F "usebackq" %y IN (`"git merge-base %x master"`) DO git diff --name-only %x %y

0

ไฟล์แบตช์ต่อไปนี้ขึ้นอยู่กับคำตอบของ twalberg แต่จะใช้ได้ใน Windows:

@ECHO OFF
C:                               :: <== OR USE A DIFFERENT DRIVE
CD \path\to\where\git\files\are  :: <== CHANGE TO THE ACTUAL PATH
SET /p b="Enter full path of an ALREADY MERGED branch to compare with origin/master: "
bash --login -i -c "git diff --name-only %b% $(git merge-base %b1% origin/drop2/master)"
PAUSE

ด้านบนจะถือว่าสาขาหลักคือ Origin / master และ Git bash นั้นถูกรวมไว้เมื่อติดตั้ง Git (และตำแหน่งของมันอยู่ในสภาพแวดล้อมของพา ธ ) ฉันต้องการแสดงความแตกต่างที่เกิดขึ้นจริงโดยใช้เครื่องมือ diff ที่กำหนดค่าไว้ (kdiff3) เพื่อแทนที่คำสั่ง bash ต่อไปนี้ด้านบน:

bash --login -i -c "git difftool --dir-diff %b% $(git merge-base %b1% origin/drop2/master)"

0

ฉันใช้grepดังนั้นฉันจะได้รับบรรทัดที่มีdiff --gitซึ่งเป็นเส้นทางของไฟล์:

git diff branchA branchB | grep 'diff --git'
// OUTPUTS ALL FILES WITH CHANGES, SIMPLE HA :)
diff --git a/package-lock.json b/package-lock.json
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.