วิธีการ "แสดงคอมไพล์" ผสานกระทำด้วยการรวมเอาท์พุท diff รวมแม้ทุกไฟล์ที่เปลี่ยนแปลงเห็นด้วยกับหนึ่งในผู้ปกครอง?


186

หลังจากทำการผสาน "แบบง่าย" (อันที่ไม่มีข้อขัดแย้ง) git showโดยปกติแล้วจะแสดงเฉพาะสิ่งที่ต้องการ

commit 0e1329e551a5700614a2a34d8101e92fd9f2cad6 (HEAD, master)
Merge: fc17405 ee2de56
Author: Tilman Vogel <email@email>
Date:   Tue Feb 22 00:27:17 2011 +0100

Merge branch 'testing' into master

นี่เป็นเพราะสำหรับการผสานให้git showใช้รูปแบบ diff ที่รวมกันซึ่งไม่ใช้ไฟล์ที่เห็นด้วยกับเวอร์ชันหลักอย่างใดอย่างหนึ่ง

มีวิธีการบังคับให้คอมไพล์ยังคงแสดงความแตกต่างทั้งหมดในโหมด diff รวมกันหรือไม่?

การทำgit show -mจะแสดงความแตกต่าง (ใช้ pairwise ต่างกันระหว่างเวอร์ชั่นใหม่และเวอร์ชั่นพาเรนต์ตามลำดับ) แต่ฉันต้องการที่จะให้มีความแตกต่างที่ทำเครื่องหมายด้วย +/- ในคอลัมน์ที่เกี่ยวข้องเช่นในโหมดรวม


1
@ Tilman Vogel: โปรดตรวจสอบคำตอบที่ได้รับการยอมรับ - ดูเหมือนว่ามีคำตอบที่ดีกว่า
Jayan

1
@Jayan ในขณะที่คำตอบอื่น ๆ ที่เป็นที่นิยมมากขึ้นเพราะพวกเขามีคำแนะนำที่เป็นประโยชน์พวกเขาไม่ได้ใกล้ชิดกับปัญหาของฉันเป็นจริงเพียงแค่ทำสองทางที่แตกต่างกัน ฉันกำลังมองหา diff สามทาง
Tilman Vogel

คำตอบ:


-3

git showไม่มีทางที่จะทำเช่นนี้กับไม่มี แต่แน่นอนจะดีบางครั้งและมันอาจจะเป็นเรื่องง่ายที่จะใช้ในรหัสที่มาคอมไพล์ (หลังจากทั้งหมดคุณก็ต้องบอกว่ามันไม่ได้ตัดออกจากสิ่งที่มันคิดว่าเป็นเอาท์พุทภายนอก) ดังนั้นแพทช์จะทำเช่นนั้น อาจจะได้รับการยอมรับจากผู้ดูแลคอมไพล์

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


12
โปรดอย่าพูดว่า "ไม่มีทางทำสิ่งนี้" อย่างชัดเจน - ดูคำตอบอื่น ๆ นี่เป็นสิ่งที่ทำให้เข้าใจผิดได้มาก
kgadek

1
git show HEAD ^ ... HEAD; # ต่อ @ โซลูชั่นของ hesham_EE
Michael Dimmitt

git show HEAD ~ 1 ... HEAD ~ 0 - ชื่อเท่านั้น # ไวยากรณ์ที่ดีกว่า สำหรับการทำซ้ำของ pr
Michael Dimmitt

256

ดูข้อความกระทำ:

commit 0e1329e551a5700614a2a34d8101e92fd9f2cad6 (HEAD, master)
Merge: fc17405 ee2de56
Author: Tilman Vogel <email@email>
Date:   Tue Feb 22 00:27:17 2011 +0100

Merge branch 'testing' into master

สังเกตเห็นสาย:

Merge: fc17405 ee2de56

นำรหัสทั้งสองนี้ไปทำและย้อนกลับ ดังนั้นในการรับ diff ที่คุณต้องการคุณจะทำ:

git diff ee2de56..fc17405

เพื่อแสดงเฉพาะชื่อไฟล์ที่เปลี่ยนแปลง:

git diff --name-only ee2de56..fc17405

และเพื่อแยกพวกเขาคุณสามารถเพิ่มไปยัง gitconfig ของคุณ:

exportfiles = !sh -c 'git diff $0 --name-only | "while read files; do mkdir -p \"$1/$(dirname $files)\"; cp -vf $files $1/$(dirname $files); done"'

จากนั้นใช้งานโดยทำ:

git exportfiles ee2de56..fc17405 /c/temp/myproject

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

6
ดูเหมือนว่าการแก้ไขของฉันถูกปฏิเสธ โดยสรุป: ความแตกต่างของคุณไม่แสดงสิ่งที่เพิ่มเติมมาจากสาขาใด และคุณไม่สามารถแยกแยะได้ว่ามีการเพิ่มการเปลี่ยนแปลงในครั้งที่สองหรือถูกลบในสาขาแรก
Tilman Vogel

45
ทางออกที่ดีกว่าคือgit diff fc17405...ee2de56- นี่จะแสดงการเปลี่ยนแปลงทั้งหมดใน ee2de56 ที่เข้าถึงได้จากคอมมิชชันที่ fc17405 ซึ่งฉันเชื่อว่าเป็นสิ่งที่คุณต้องการ สังเกตจุด 3 จุดแทนสองจุด
Kris Nuttycombe

1
@KrisNuttycombe 3 จุดและการสั่งซื้อ และความคิดเห็นของคุณคือสิ่งที่ฉันกำลังมองหาซึ่งฉันคิดว่าเป็นเหมือนสิ่งที่ OP ต้องการ
Izkata

@KrisNuttycombe วิธีนี้ใช้ไม่ได้git logซึ่งยังแสดงคอมมิททั้งหมดเหมือน..ตัวแปร ..และ...ทำเช่นเดียวกันสำหรับlogแต่diffพวกเขาแตกต่างกัน! ฉันจะรับรายการข้อผูกพันที่รวมเข้ากับสาขานี้ได้อย่างไร
Rudie

77

ทางออกที่ดีกว่า (กล่าวถึงโดย @KrisNuttycombe):

git diff fc17405...ee2de56

สำหรับการรวมกระทำ:

commit 0e1329e551a5700614a2a34d8101e92fd9f2cad6 (HEAD, master)
Merge: fc17405 ee2de56
Author: Tilman Vogel <email@email>
Date:   Tue Feb 22 00:27:17 2011 +0100

เพื่อแสดงให้เห็นการเปลี่ยนแปลงทั้งหมดในที่เข้าถึงได้จากกระทำบนee2de56 fc17405จดบันทึกลำดับการแฮชการกระทำ - เหมือนกับที่แสดงในข้อมูลการผสาน:Merge: fc17405 ee2de56

ยังทราบจุด 3 จุด...แทนสอง !

สำหรับรายการไฟล์ที่เปลี่ยนแปลงคุณสามารถใช้:

git diff fc17405...ee2de56 --name-only

นี่คือสิ่งที่ฉันเป็นหลังจาก +1
geedoubleya

นี่จะแสดงผลลัพธ์ของความขัดแย้งที่ผสานในขณะที่คำตอบอื่นไม่ได้
พ็อด

12

คุณสามารถสร้างสาขาได้ด้วยการตั้งค่า HEAD ให้เป็นหนึ่งการกระทำก่อนที่จะรวม จากนั้นคุณสามารถ:

git merge --squash testing

สิ่งนี้จะรวมเข้าด้วยกัน แต่ไม่ใช่การกระทำ แล้ว:

git diff

5

ดูเหมือนว่าตอบที่นี่: https://public-inbox.org/git/7vd392ezhx.fsf@alter.siamese.dyndns.org/

ดังนั้นในทำนองเดียวกันการวิ่ง

$ git diff --cc $ M $ M ^ 1 $ M ^ 2 $ (git ผสานฐาน $ M ^ 1 $ M ^ 2)

ควรแสดงชุดข้อมูลแก้ไขที่รวมกันซึ่งอธิบายสถานะที่ $ M เมื่อเทียบกับรัฐที่บันทึกไว้ในผู้ปกครองและฐานผสาน


คุณรู้หรือไม่ว่าเครื่องมือใด ๆ ที่สามารถกำหนดค่าให้แสดงในลักษณะที่แตกต่างกันอาจมีอยู่ในคอลัมน์ไม่กี่คอลัมน์ (เช่นในหน้าต่างการแก้ไขข้อขัดแย้งของ IntelliJ ผสาน) คำตอบของคุณคือฉันกำลังมองหา
Max

@ Max ไม่ฉันเกรงว่าฉันทำไม่ได้ Googling "n-way visual diff" มีลิงก์บางลิงก์ดังนั้นฉันจึงลองใช้
max630

4

ฉันคิดว่าคุณแค่ต้องการ 'git show -c $ ref' ลองใช้วิธีนี้กับที่เก็บ git บน a8e4a59 แสดง diff ที่รวมกัน (บวก / ลบตัวอักษรในหนึ่งใน 2 คอลัมน์) ในฐานะที่เป็นคู่มือ git-show กล่าวถึงมันค่อนข้างมอบหมายให้ 'git diff-tree' เพื่อให้ตัวเลือกเหล่านั้นดูมีประโยชน์


3
ไม่สำหรับการผสาน "แบบง่าย" git show -c $refจะแสดงผลลัพธ์เดียวกันกับที่ฉันยกมานั่นคือไม่มีความแตกต่าง -cเลือกโหมดที่แตกต่างรวมกันคล้ายกับโหมดเริ่มต้นสำหรับการกระทำผสานซึ่งเป็น '--cc' ดูและgit help show git help diff-treeทั้งสองละเว้นไฟล์ที่เห็นด้วยกับพาเรนต์เวอร์ชันใดไฟล์หนึ่ง
Tilman Vogel

a8e4a59แน่นอนไม่ได้ตกอยู่ในหมวดหมู่ของความมุ่งมั่นผสานฉันหมายถึง การรวมนี้กระทำแน่นอนมีหนึ่งไฟล์ที่แตกต่างจากทั้งรุ่นหลัก Documentation/git-fast-import.txtมีบางสิ่งที่เพิ่มจากผู้ปกครองคนหนึ่งและบางคนมาจากคนอื่น git diff-tree --ccผลนี้ในการส่งออกที่ไม่ว่างเปล่าจาก อย่างไรก็ตามจะแสดงเฉพาะการเปลี่ยนแปลงในกรณี "ขัดแย้ง" ผลลัพธ์การผสานทั้งหมด "สะอาด" ดูgit show -m a8e4a59ไม่แสดงเลย
Tilman Vogel

1
@TilmanVogel: ขอบคุณที่ชี้ให้เห็นว่าการผสานไฟล์ "ไม่น่าสนใจ" นั้นถูกปล่อยออกมาจากgit show -cเอาต์พุต ( man git-diff-treeจะพูดว่า "นอกจากนี้จะแสดงเฉพาะไฟล์ที่ได้รับการแก้ไขจากผู้ปกครองทุกคน" แต่สำหรับฉันคนหนึ่งไม่ได้เห็นอย่างนั้น)
Paul Whittaker

3

ในกรณีของคุณคุณต้อง

git diff HEAD^ HEAD^2

หรือเพียงแค่แฮชสำหรับคุณที่จะกระทำ:

git diff 0e1329e55^ 0e1329e55^2

4
ไม่นี่เป็นเพียงการกระจายสองทางธรรมดาระหว่างผู้ปกครองสองคน สิ่งที่ฉันขอคือโหมดที่แสดงความแตกต่างระหว่างgit merge-base HEAD^ HEAD^2และHEAD^กับHEAD^2ในสไตล์เดียวกับที่ทำกับไฟล์ที่ผสานกับความขัดแย้ง
Tilman Vogel

3

หากการรวมของคุณกระทำได้กระทำ 0e1329e5 ข้างต้นคุณสามารถรับส่วนต่างที่อยู่ในการผสานนี้ได้โดย:

git diff 0e1329e5^..0e1329e5

ฉันหวังว่านี่จะช่วยได้!


3

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

git diff HEAD~1..HEAD

หากคุณไม่ได้อยู่ที่การรวมการกระทำเพียงแค่แทนที่ HEAD ด้วยการรวมการกระทำ วิธีนี้ดูเหมือนง่ายและง่ายที่สุด


1
นี่ไม่ใช่เอาต์พุต "รวม diff" การได้รับความแตกต่างระหว่างผู้ปกครองแต่ละคู่กับ HEAD นั้นไม่ใช่ปัญหาที่นี่
Tilman Vogel

2

คุณสามารถใช้คำสั่ง diff-tree พร้อมกับแฟล็ก -c คำสั่งนี้แสดงให้คุณเห็นว่าไฟล์ใดที่มีการเปลี่ยนแปลงในการคอมมิทรวม

git diff-tree -c {merged_commit_sha}

ฉันได้คำอธิบายของแฟล็ก -c จากGit-Scm :

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


2
ดูเหมือนบทความที่ดีในหัวข้อนี้: haacked.com/archive/2014/02/21/reviewing-merge-commitsและอาจเป็นเช่นนี้: longair.net/blog/2009/04/16/git-fetch-and-merge
Devin G Rhode

1

ฉันสร้างวิธีการทั่วไปเพื่อทำการดำเนินการต่าง ๆ ตามความมุ่งมั่นของการผสาน

ขั้นตอนที่หนึ่ง : เพิ่มนามแฝงในคอมไพล์โดยแก้ไข~/.gitconfig:

[alias]
  range = "!. ~/.githelpers && run_on_merge_range"

ขั้นตอนที่สอง : ใน~/.githelpersกำหนดฟังก์ชั่นทุบตี:

run_on_merge_range() {
  cmd=$1; shift
  commit=$1; shift
  range=$(git show $commit | grep Merge: | awk '{print $2 "..." $3}')
  echo "git $cmd $range $@"
  if [ -z $range ]; then
    echo "No merge detected"
    exit 1
  fi
  git $cmd $range $@
}

ขั้นตอนที่สาม : กำไร!

git range log <merge SHA> --oneline
git range diff <merge SHA> --reverse -p
git range diff <merge SHA> --name-only

อาจมีห้องพักมากมายสำหรับการปรับปรุงที่นี่ฉันแค่ตีมันเข้าด้วยกันเพื่อผ่านสถานการณ์ที่น่ารำคาญ รู้สึกฟรีเพื่อเยาะเย้ยไวยากรณ์ bash ของฉันและ / หรือตรรกะ


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