คุณจะgit diff
แสดงความแตกต่างระหว่างการผูกมัดสองรายการได้อย่างไร
คุณจะgit diff
แสดงความแตกต่างระหว่างการผูกมัดสองรายการได้อย่างไร
คำตอบ:
คุณสามารถผ่าน 2 คอมมิตเพื่อคอมไพล์เช่น:
-> git diff 0da94be 59ff30c > my.patch
-> git apply my.patch
my.patch
จะสมัครสาขาอื่นได้อย่างไร
การถามถึงความแตกต่าง / ระหว่าง / สองการกระทำโดยไม่รวมการผูกมัดในระหว่างนั้นจะสมเหตุสมผล การคอมมิทเป็นเพียงสแน็ปช็อตของเนื้อหาของที่เก็บ ขอความแตกต่างระหว่างสองจำเป็นต้องรวมถึงพวกเขา ดังนั้นคำถามคือคุณต้องการอะไรจริงๆ
ตามที่ William แนะนำการเก็บเชอร์รี่สามารถมอบเดลต้าของการคอมมิชชันเดี่ยวให้คุณได้ นั่นคือ:
$ git checkout 012345
$ git cherry-pick -n abcdef
$ git diff --cached
สิ่งนี้จะกระทำ 'abcdef' เปรียบเทียบกับบรรพบุรุษทันทีจากนั้นนำความแตกต่างนั้นไปใช้กับ '012345' ความแตกต่างใหม่นี้จะปรากฏขึ้น - การเปลี่ยนแปลงเพียงอย่างเดียวคือบริบทมาจาก '012345' แทนที่จะเป็น 'บรรพบุรุษของ abcdef ทันที แน่นอนคุณอาจได้รับความขัดแย้งและอื่น ๆ ดังนั้นจึงไม่ใช่กระบวนการที่มีประโยชน์มากในกรณีส่วนใหญ่
หากคุณสนใจ abcdef เองคุณสามารถทำได้:
$ git log -u -1 abcdef
สิ่งนี้จะเปรียบเทียบ abcdef กับบรรพบุรุษที่อยู่คนเดียวและมักเป็นสิ่งที่คุณต้องการ
และแน่นอนว่า
$ git diff 012345..abcdef
ให้ความแตกต่างทั้งหมดระหว่างคุณทั้งสอง
มันจะช่วยให้ได้แนวคิดที่ดีขึ้นเกี่ยวกับสิ่งที่คุณกำลังพยายามบรรลุ - ดังที่ฉันได้กล่าวถึงการขอความแตกต่างระหว่างการกระทำสองอย่างโดยที่ไม่ได้ทำอะไรเลย
origin/featurebranch#HEAD
ที่จะlocal/featurebranch#HEAD
ช่วยเหลือคุณสามารถให้แน่ใจว่าคุณทำอะไรไม่ได้โคลนความขัดแย้งระหว่างความละเอียด
เพื่อเปรียบเทียบสองคอมไพล์ให้กระทำ 12345 และ abcdef เป็นแพตช์หนึ่งสามารถใช้คำสั่ง diff เป็น
diff <(git show 123456) <(git show abcdef)
git diff <(git show 123456) <(git show abcdef)
ไม่ทำงาน; diff <(...) <(...)
ทำ. (ฉันแค่ลองมัน)
git diff 123456 abcdef
@Menachem
diff
เอาท์พุทจากสองdiff
s สิ่งนี้เกี่ยวข้องกับการอ่านและการเปรียบเทียบอินพุตสองสตรีม diff
(GNU หรือ Unix diff
) สามารถทำสิ่งนั้นได้ในขณะที่git diff
ไม่สามารถทำได้ บางคนอาจสงสัยว่าทำไมเราจึงอยากทำเช่นนั้น ฉันกำลังทำสิ่งนี้อยู่ในตอนนี้ทำความสะอาดจุดรวมที่ไม่ดี
git diff <a-commit> <another-commit> path
ตัวอย่าง:
git diff commit1 commit2 config/routes.rb
มันแสดงให้เห็นถึงความแตกต่างในไฟล์นั้นระหว่างการกระทำเหล่านั้น
สำหรับการตรวจสอบการเปลี่ยนแปลงทั้งหมด:
git diff <commit_Id_1> <commit_Id_2>
สำหรับการตรวจสอบเฉพาะไฟล์ที่มีการเปลี่ยนแปลง / เพิ่ม / ลบ:
git diff <commit_Id_1> <commit_Id_2> --name-only
หมายเหตุ : สำหรับการตรวจสอบความแตกต่างโดยไม่ต้องกระทำระหว่างคุณไม่จำเป็นต้องใส่รหัสการกระทำ
สมมติว่าคุณมีสิ่งนี้
A
|
B A0
| |
C D
\ /
|
...
และคุณต้องการเพื่อให้แน่ใจว่าเป็นเช่นเดียวกับA
A0
นี่จะเป็นการหลอกลวง:
$ git diff B A > B-A.diff
$ git diff D A0 > D-A0.diff
$ diff B-A.diff D-A0.diff
สมมติว่าคุณต้องการเห็นความแตกต่างระหว่างการยอมรับ 012345 และ abcdef ต่อไปนี้ควรทำสิ่งที่คุณต้องการ:
$ git checkout 012345 $ git cherry-pick -n abcdef $ git diff --cached
เกี่ยวกับสิ่งนี้:
git diff abcdef 123456 | less
มันมีประโยชน์มากที่จะทำให้ท่อเล็กลงถ้าคุณต้องการเปรียบเทียบ diffs ที่แตกต่างกันมากมายในทันที
ตั้งแต่ Git 2.19 คุณสามารถใช้:
git range-diff rev1...rev2
- เปรียบเทียบต้นไม้สองต้นที่เริ่มโดยบรรพบุรุษร่วมกัน
หรือ
git range-diff rev1~..rev1 rev2~..rev2
- เปรียบเทียบการเปลี่ยนแปลงที่แนะนำโดย 2 คอมมิทที่ให้ไว้
alias
การตั้งค่าของฉันใน~/.bashrc
ไฟล์สำหรับgit diff
:
alias gdca='git diff --cached' # diff between your staged file and the last commit
alias gdcc='git diff HEAD{,^}' # diff between your latest two commits
alias
การตั้งค่าของฉันใน~/.zshrc
ไฟล์สำหรับgit diff
:
alias gdf='git diff HEAD{'^',}' # diff between your recent tow commits
ขอบคุณ @Jinmiao Luo
git diff HEAD~2 HEAD
การเปลี่ยนแปลงที่สมบูรณ์ระหว่างการส่งมอบครั้งที่ 2 ครั้งล่าสุดและปัจจุบัน
HEAD
สะดวก
ฉันเขียนสคริปต์ที่แสดงความแตกต่างระหว่างสองคอมมิทใช้งานได้ดีบน Ubuntu
https://gist.github.com/jacobabrahamb4/a60624d6274ece7a0bd2d141b53407bc
#!/usr/bin/env python
import sys, subprocess, os
TOOLS = ['bcompare', 'meld']
def getTool():
for tool in TOOLS:
try:
out = subprocess.check_output(['which', tool]).strip()
if tool in out:
return tool
except subprocess.CalledProcessError:
pass
return None
def printUsageAndExit():
print 'Usage: python bdiff.py <project> <commit_one> <commit_two>'
print 'Example: python bdiff.py <project> 0 1'
print 'Example: python bdiff.py <project> fhejk7fe d78ewg9we'
print 'Example: python bdiff.py <project> 0 d78ewg9we'
sys.exit(0)
def getCommitIds(name, first, second):
commit1 = None
commit2 = None
try:
first_index = int(first) - 1
second_index = int(second) - 1
if int(first) < 0 or int(second) < 0:
print "Cannot handle negative values: "
sys.exit(0)
logs = subprocess.check_output(['git', '-C', name, 'log', '--oneline', '--reverse']).split('\n')
if first_index >= 0:
commit1 = logs[first_index].split(' ')[0]
if second_index >= 0:
commit2 = logs[second_index].split(' ')[0]
except ValueError:
if first != '0':
commit1 = first
if second != '0':
commit2 = second
return commit1, commit2
def validateCommitIds(name, commit1, commit2):
if commit1 == None and commit2 == None:
print "Nothing to do, exit!"
return False
try:
if commit1 != None:
subprocess.check_output(['git', '-C', name, 'cat-file', '-t', commit1]).strip()
if commit2 != None:
subprocess.check_output(['git', '-C', name, 'cat-file', '-t', commit2]).strip()
except subprocess.CalledProcessError:
return False
return True
def cleanup(commit1, commit2):
subprocess.check_output(['rm', '-rf', '/tmp/'+(commit1 if commit1 != None else '0'), '/tmp/'+(commit2 if commit2 != None else '0')])
def checkoutCommit(name, commit):
if commit != None:
subprocess.check_output(['git', 'clone', name, '/tmp/'+commit])
subprocess.check_output(['git', '-C', '/tmp/'+commit, 'checkout', commit])
else:
subprocess.check_output(['mkdir', '/tmp/0'])
def compare(tool, commit1, commit2):
subprocess.check_output([tool, '/tmp/'+(commit1 if commit1 != None else '0'), '/tmp/'+(commit2 if commit2 != None else '0')])
if __name__=='__main__':
tool = getTool()
if tool == None:
print "No GUI diff tools"
sys.exit(0)
if len(sys.argv) != 4:
printUsageAndExit()
name, first, second = None, 0, 0
try:
name, first, second = sys.argv[1], sys.argv[2], sys.argv[3]
except IndexError:
printUsageAndExit()
commit1, commit2 = getCommitIds(name, first, second)
if not validateCommitIds(name, commit1, commit2):
sys.exit(0)
cleanup(commit1, commit2)
checkoutCommit(name, commit1)
checkoutCommit(name, commit2)
try:
compare(tool, commit1, commit2)
except KeyboardInterrupt:
pass
finally:
cleanup(commit1, commit2)
sys.exit(0)