Bagaimana Anda membuat git diff
hanya menunjukkan perbedaan antara dua komit, tidak termasuk komit lainnya di-antara?
Bagaimana Anda membuat git diff
hanya menunjukkan perbedaan antara dua komit, tidak termasuk komit lainnya di-antara?
Jawaban:
Anda cukup memberikan 2 commit ke git diff seperti:
-> git diff 0da94be 59ff30c > my.patch
-> git apply my.patch
my.patch
ke cabang lain?
Meminta perbedaan / antara / dua komit tanpa menyertakan komit di antaranya tidak masuk akal. Komit hanyalah snapshot dari isi repositori; meminta perbedaan antara keduanya harus mencakup mereka. Jadi pertanyaannya adalah, apa yang sebenarnya Anda cari?
Seperti yang disarankan William, memetik ceri dapat memberi Anda delta dari satu komit yang direbus di atas yang lain. Itu adalah:
$ git checkout 012345
$ git cherry-pick -n abcdef
$ git diff --cached
Ini membutuhkan komit 'abcdef', membandingkannya dengan leluhur langsungnya, kemudian menerapkan perbedaan itu di atas '012345'. Perbedaan baru ini kemudian ditampilkan - satu-satunya perubahan adalah konteksnya berasal dari '012345' daripada 'leluhur langsung abcdef. Tentu saja, Anda mungkin mendapatkan konflik dan lain-lain, jadi itu bukan proses yang sangat berguna dalam kebanyakan kasus.
Jika Anda hanya tertarik dengan abcdef itu sendiri, Anda dapat melakukannya:
$ git log -u -1 abcdef
Ini membandingkan abcdef dengan leluhur langsungnya, sendirian, dan biasanya itulah yang Anda inginkan.
Dan tentu saja
$ git diff 012345..abcdef
memberi Anda semua perbedaan antara kedua komitmen tersebut.
Ini akan membantu untuk mendapatkan ide yang lebih baik tentang apa yang ingin Anda capai - seperti yang saya sebutkan, meminta perbedaan antara dua komitmen tanpa apa yang ada di antaranya sebenarnya tidak masuk akal.
origin/featurebranch#HEAD
dengan local/featurebranch#HEAD
dapat membantu Anda memastikan Anda tidak membuang apa pun selama resolusi konflik.
Untuk membandingkan dua git melakukan 12345 dan abcdef sebagai tambalan kita dapat menggunakan perintah diff sebagai
diff <(git show 123456) <(git show abcdef)
git diff <(git show 123456) <(git show abcdef)
tidak berfungsi; diff <(...) <(...)
tidak. (Saya baru mencobanya).
git diff 123456 abcdef
.
diff
menghasilkan output dari dua diff
s. Ini melibatkan membaca dan membandingkan dua aliran input. diff
(GNU, atau Unix, diff
) dapat melakukan itu, sementara git diff
tidak bisa. Beberapa orang mungkin bertanya-tanya mengapa seseorang ingin melakukan itu. Saya sedang melakukan itu sekarang, membersihkan gabungan yang menjadi buruk.
Untuk memeriksa perubahan lengkap:
git diff <commit_Id_1> <commit_Id_2>
Untuk memeriksa hanya file yang diubah / ditambahkan / dihapus:
git diff <commit_Id_1> <commit_Id_2> --name-only
CATATAN : Untuk memeriksa perbedaan tanpa komit di antaranya, Anda tidak perlu meletakkan id komit.
Katakanlah Anda punya ini
A
|
B A0
| |
C D
\ /
|
...
Dan Anda ingin memastikan bahwa A
itu sama dengan A0
.
Ini akan melakukan trik:
$ git diff B A > B-A.diff
$ git diff D A0 > D-A0.diff
$ diff B-A.diff D-A0.diff
Misalkan Anda ingin melihat perbedaan antara komit 012345 dan abcdef. Berikut ini harus melakukan apa yang Anda inginkan:
checkout $ git 012345 $ git cherry-pick -n abcdef $ git diff --cached
Bagaimana dengan ini:
git diff abcdef 123456 | less
Berguna hanya untuk mengurangi menjadi pipa jika Anda ingin membandingkan banyak perbedaan yang berbeda dengan cepat.
Sejak Git 2.19, Anda cukup menggunakan:
git range-diff rev1...rev2
- membandingkan dua pohon komit, dimulai oleh nenek moyang mereka bersama
atau
git range-diff rev1~..rev1 rev2~..rev2
- bandingkan perubahan yang dilakukan oleh 2 commit yang diberikan
alias
Pengaturan saya di ~/.bashrc
file untuk 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
Saya menulis sebuah skrip yang menampilkan perbedaan antara dua commit, berfungsi dengan baik di 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)