Как увидеть изменения между двумя коммитами без взаимных договоренностей?

Как вы делаете git diff показывает только разницу между двумя коммитами, исключая другие коммиты между ними?

Ответ 1

вы можете просто передать 2 фиксации на git diff like:

-> git diff 0da94be  59ff30c > my.patch
-> git apply my.patch

Ответ 2

Задание разницы между/двумя коммитами без включения коммитов между ними мало смысла. Записи - это всего лишь моментальные снимки содержимого репозитория; прося разницу между двумя обязательно включает их. Итак, вопрос в том, что вы действительно ищете?

Как предположил Уильям, выбор вишни может дать вам дельта одного фиксации, переделанного поверх другого. То есть:

$ git checkout 012345
$ git cherry-pick -n abcdef
$ git diff --cached

Это принимает commit 'abcdef', сравнивает его с его непосредственным предком, затем применяет эту разницу поверх '012345'. Эта новая разница показывается - единственное изменение заключается в том, что контекст происходит от "012345", а не "непосредственного предка abcdef". Конечно, вы можете получить конфликты и т.д., Поэтому в большинстве случаев это не очень полезный процесс.

Если вас просто интересует сам abcdef, вы можете сделать:

$ git log -u -1 abcdef

Это сравнивает abcdef с его непосредственным предком, в одиночку, и обычно это то, что вы хотите.

И, конечно,

$ git diff 012345..abcdef

дает вам все различия между этими двумя коммитами.

Это поможет лучше понять, чего вы пытаетесь достичь - как я уже говорил, прося разницу между двумя коммитами без того, что между ними на самом деле не имеет смысла.

Ответ 3

Для сравнения двух git совершает 12345 и abcdef как патчи, можно использовать команду diff как

diff <(git show 123456) <(git show abcdef)

Ответ 4

git diff <a-commit> <another-commit> path

Пример:

git diff commit1 commit2 config/routes.rb

Показывает разницу в этом файле между этими коммитами.

Ответ 5

Скажем, у вас есть это

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

Ответ 6

Для проверки полных изменений:

  git diff <commit_Id_1> <commit_Id_2>

Для проверки только измененных/добавленных/удаленных файлов:

  git diff <commit_Id_1> <commit_Id_2> --name-only

ПРИМЕЧАНИЕ. Для проверки diff без фиксации между ними вам не нужно указывать идентификаторы коммитов.

Ответ 7

Предположим, вы хотите увидеть разницу между коммитами 012345 и abcdef. Следующее должно делать то, что вы хотите:

$ git checkout 012345
$ git cherry-pick -n abcdef
$ git diff --cached

Ответ 8

Как насчет этого:

git diff abcdef 123456 | less

Удобно просто перевести его на меньшее, если вы хотите сравнить множество разных различий на лету.

Ответ 9

Мои настройки 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 recent tow commits

Английский не мой родной язык, прошу прощения за ошибки при печати

Ответ 10

Начиная с Git 2.19, вы можете просто использовать:

git range-diff rev1...rev2 - сравнить два дерева коммитов, начиная с их общего предка

или git range-diff rev1~..rev1 rev2~..rev2 - сравнить изменения, внесенные двумя данными коммитами

Ответ 11

Я написал скрипт, который отображает 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)

Ответ 12

Мои настройки alias в файле ~/.zshrc для git diff:

alias gdf='git diff HEAD{'^',}' # diff between your recent tow commits

Спасибо @Jinmiao Luo

Ответ 13

На самом деле я не нашел действительно хорошее решение для этого, чтобы сделать это автоматически, но это хакерское решение, которое дает вам именно то, что вы хотите;

  • сделайте копию исходного каталога (скопируйте dir A в dir A-copy),
  • используйте git для проверки (с параметром силы) этого старого коммита, с которого вы хотите начать,
  • скопируйте эти резервные копии файлов в оригиналы (скопируйте копию A-копий на dir A, за исключением скрытых файлов .git).
  • diff to commit теперь будет включать в себя все ваши изменения, суммированные по всем коммиттам между ними.