git diff
사이의 다른 커밋을 제외하고 두 커밋의 차이점 만 어떻게 표시합니까?
git diff
사이의 다른 커밋을 제외하고 두 커밋의 차이점 만 어떻게 표시합니까?
답변:
다음과 같이 git diff에 2 개의 커밋을 전달할 수 있습니다.
-> git diff 0da94be 59ff30c > my.patch
-> git apply my.patch
my.patch
은 다른 지점에 어떻게 신청할 수 있습니까?
사이에 커밋을 포함시키지 않고 두 커밋 사이의 차이를 묻는 것은 의미가 없습니다. 커밋은 저장소 내용의 스냅 샷일뿐입니다. 둘 사이의 차이를 요구하는 것은 반드시 그것들을 포함합니다. 그렇다면 문제는 무엇을 찾고 있습니까?
윌리엄이 제안했듯이 체리 피킹은 다른 커밋을 기반으로 단일 커밋의 델타를 제공 할 수 있습니다. 그건:
$ git checkout 012345
$ git cherry-pick -n abcdef
$ git diff --cached
커밋 'abcdef'를 가져 와서 직계 조상과 비교 한 다음 그 차이 를 적용 합니다 '012345'위에 . 이 새로운 차이점은 다음과 같습니다. 유일한 변화는 컨텍스트가 'abcdef'의 직계 조상이 아닌 '012345'에서 비롯된 것입니다. 물론 충돌 등이 발생할 수 있으므로 대부분의 경우 유용한 프로세스가 아닙니다.
abcdef 자체에 관심이 있다면 다음을 수행하십시오.
$ git log -u -1 abcdef
이것은 abcdef를 바로 직계 조상과 비교하며 일반적으로 원하는 것입니다.
그리고 물론
$ git diff 012345..abcdef
두 커밋 사이의 모든 차이점을 알려줍니다.
앞서 언급했듯이 두 커밋 사이의 차이점을 묻는 것이 실제로 의미가있는 것은 아닙니다.
origin/featurebranch#HEAD
하면 local/featurebranch#HEAD
충돌 해결 중에 아무것도 뭉치지 않도록 할 수 있습니다.
두 개의 git commit 12345와 abcdef를 패치로 비교하려면 diff 명령을 다음과 같이 사용할 수 있습니다.
diff <(git show 123456) <(git show abcdef)
git diff <(git show 123456) <(git show abcdef)
이 작동하지 않습니다. diff <(...) <(...)
그렇습니다. (방금 시도했습니다).
git diff 123456 abcdef
.
diff
를 출력 diff
합니다. 여기에는 두 개의 입력 스트림을 읽고 비교하는 작업이 포함됩니다. diff
(GNU 또는 Unix diff
)는 그렇게 git diff
할 수 있지만 할 수는 없습니다. 어떤 사람들은 왜 그렇게하고 싶어하는지 궁금 할 것입니다. 나는 지금 그 일을하는 중입니다. 나쁜 병합을 정리하십시오.
전체 변경 사항을 확인하려면 다음을 수행하십시오.
git diff <commit_Id_1> <commit_Id_2>
변경 / 추가 / 삭제 된 파일 만 확인하려면 :
git diff <commit_Id_1> <commit_Id_2> --name-only
참고 : 사이에 커밋없이 diff를 확인하기 위해 커밋 ID를 넣을 필요는 없습니다.
당신이 이것을 가지고 있다고 가정 해 봅시다
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-캐시
두 커밋 사이의 차이점을 표시하고 우분투에서 잘 작동하는 스크립트를 작성했습니다.
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)