Как вы можете показать git diff
только разницу между двумя коммитами, исключая другие коммиты между ними?
Как вы можете показать git diff
только разницу между двумя коммитами, исключая другие коммиты между ними?
Ответы:
вы можете просто передать 2 коммита в git diff:
-> 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'. Затем показывается это новое отличие - единственное изменение заключается в том, что контекст происходит от «012345», а не от «непосредственного предка» abcdef. Конечно, вы можете столкнуться с конфликтами и т. Д., Поэтому в большинстве случаев это не очень полезный процесс.
Если вы просто заинтересованы в самом abcdef, вы можете сделать:
$ git log -u -1 abcdef
Это сравнивает abcdef с его непосредственным предком, в одиночку, и обычно это то, что вы хотите.
И конечно
$ git diff 012345..abcdef
дает вам все различия между этими двумя коммитами.
Это помогло бы получить лучшее представление о том, чего вы пытаетесь достичь - как я уже говорил, просить разницу между двумя коммитами без того, что между ними, на самом деле не имеет смысла.
origin/featurebranch#HEAD
с local/featurebranch#HEAD
может помочь вам убедиться, что вы ничего не испортили во время разрешения конфликта.
Для сравнения двух коммитов git 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
s. Это включает в себя чтение и сравнение двух входных потоков. 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 без фиксации между ними вам не нужно указывать идентификаторы коммитов.
Допустим, у вас есть это
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
Это удобно, если вы хотите сравнить множество различных различий на лету.
Начиная с Git 2.19, вы можете просто использовать:
git range-diff rev1...rev2
- сравнить два дерева коммитов, начиная с их общего предка
или
git range-diff rev1~..rev1 rev2~..rev2
- сравнить изменения, внесенные двумя данными коммитами
Мои 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
Я написал скрипт, который отображает diff между двумя коммитами, хорошо работает на 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)