Làm thế nào để bạn thực hiện git diff
chỉ hiển thị sự khác biệt giữa hai cam kết, ngoại trừ các cam kết khác ở giữa?
Làm thế nào để bạn thực hiện git diff
chỉ hiển thị sự khác biệt giữa hai cam kết, ngoại trừ các cam kết khác ở giữa?
Câu trả lời:
bạn chỉ có thể chuyển 2 cam kết sang git diff như:
-> git diff 0da94be 59ff30c > my.patch
-> git apply my.patch
my.patch
cho chi nhánh khác?
Yêu cầu sự khác biệt / giữa / hai cam kết mà không bao gồm các cam kết ở giữa có ý nghĩa rất nhỏ. Cam kết chỉ là ảnh chụp nhanh nội dung của kho lưu trữ; yêu cầu sự khác biệt giữa hai nhất thiết bao gồm chúng. Vì vậy, câu hỏi sau đó là, bạn thực sự đang tìm kiếm cái gì?
Như William đề xuất, việc hái anh đào có thể mang lại cho bạn đồng bằng của một cam kết duy nhất nổi loạn trên đầu người khác. Đó là:
$ git checkout 012345
$ git cherry-pick -n abcdef
$ git diff --cached
Điều này có cam kết 'abcdef', so sánh nó với tổ tiên trực tiếp của nó, sau đó áp dụng sự khác biệt đó trên đầu trang '012345'. Sự khác biệt mới này sau đó được hiển thị - thay đổi duy nhất là bối cảnh đến từ '012345' thay vì 'tổ tiên ngay lập tức' abcdef '. Tất nhiên, bạn có thể bị xung đột và vân vân, vì vậy đó không phải là một quá trình rất hữu ích trong hầu hết các trường hợp.
Nếu bạn chỉ quan tâm đến abcdef, bạn có thể làm:
$ git log -u -1 abcdef
Điều này so sánh abcdef với tổ tiên trực tiếp của nó, một mình, và thường là những gì bạn muốn.
Và dĩ nhiên
$ git diff 012345..abcdef
cung cấp cho bạn tất cả sự khác biệt giữa hai cam kết.
Nó sẽ giúp có được một ý tưởng tốt hơn về những gì bạn đang cố gắng đạt được - như tôi đã đề cập, yêu cầu sự khác biệt giữa hai cam kết mà không có gì ở giữa không thực sự có ý nghĩa.
origin/featurebranch#HEAD
với local/featurebranch#HEAD
có thể giúp bạn đảm bảo rằng bạn đã không làm hỏng bất cứ điều gì trong khi giải quyết xung đột.
Để so sánh hai git cam kết 12345 và abcdef dưới dạng các bản vá, người ta có thể sử dụng lệnh diff như
diff <(git show 123456) <(git show abcdef)
git diff <(git show 123456) <(git show abcdef)
không hoạt động; diff <(...) <(...)
làm. (Tôi vừa thử nó).
git diff 123456 abcdef
.
diff
lấy đầu ra từ hai diff
s. Điều này liên quan đến việc đọc và so sánh hai luồng đầu vào. diff
(GNU, hoặc Unix, diff
) có thể làm điều đó, trong khi git diff
không thể. Một số có thể tự hỏi tại sao một người muốn làm điều đó. Tôi đang ở giữa để làm điều đó ngay bây giờ, làm sạch một sự hợp nhất đã trở nên tồi tệ.
Để kiểm tra thay đổi hoàn toàn:
git diff <commit_Id_1> <commit_Id_2>
Để chỉ kiểm tra các tệp đã thay đổi / thêm / xóa:
git diff <commit_Id_1> <commit_Id_2> --name-only
LƯU Ý : Để kiểm tra khác biệt mà không có cam kết ở giữa, bạn không cần đặt id cam kết.
Hãy nói rằng bạn có cái này
A
|
B A0
| |
C D
\ /
|
...
Và bạn muốn chắc chắn rằng A
nó giống như A0
.
Điều này sẽ thực hiện các mẹo:
$ git diff B A > B-A.diff
$ git diff D A0 > D-A0.diff
$ diff B-A.diff D-A0.diff
Giả sử bạn muốn thấy sự khác biệt giữa các lần xác nhận 012345 và abcdef. Sau đây nên làm những gì bạn muốn:
$ git thanh toán 012345 $ git cherry-pick -n abcdef $ git diff - đã đóng gói
Cái này thì sao:
git diff abcdef 123456 | less
Thật tiện lợi khi chỉ đưa nó xuống ít hơn nếu bạn muốn so sánh nhiều khác biệt khác nhau khi đang bay.
Kể từ Git 2.19, bạn chỉ cần sử dụng:
git range-diff rev1...rev2
- so sánh hai cây cam kết, bắt đầu bởi tổ tiên chung của chúng
hoặc
git range-diff rev1~..rev1 rev2~..rev2
- so sánh các thay đổi được giới thiệu bởi 2 cam kết đã cho
alias
Cài đặt của tôi trong ~/.bashrc
tệp cho 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
Tôi đã viết một tập lệnh hiển thị khác nhau giữa hai lần xác nhận, hoạt động tốt trên 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)