Показать разницу между коммитами

Я использую Git в Ubuntu 10.04 (Lucid Lynx).

Я дал своему хозяину несколько обязательств.

Однако я хочу понять разницу между этими коммитами. Все они находятся в моей основной ветке.

Например:

commit dj374
made changes

commit y4746
made changes

commit k73ud
made changes

Хочу получить разницу между k73ud и dj374. Однако когда я сделал следующее, я не увидел изменений, внесенных в k73ud.

git diff k73ud..dj374 > master.patch

person ant2009    schedule 30.07.2010    source источник


Ответы (13)


Пытаться

git diff k73ud^..dj374

чтобы убедиться, что вы включили все изменения k73ud в результирующий файл diff.

git diff сравнивает две конечные точки (вместо диапазона фиксации). Поскольку OP хочет видеть изменения, внесенные k73ud, ему / ей необходимо различать первую родительскую фиксацию k73ud: _6 _ (или k73ud^1 или k73ud~).

Таким образом, результаты diff будут включать изменения с k73ud родителя (то есть включая изменения самого k73ud) вместо изменений, внесенных с k73ud (до dj374).

Также вы можете попробовать:

git diff oldCommit..newCommit
git diff k73ud..dj374 

и (1 пробел, не более):

git diff oldCommit newCommit
git diff k73ud dj374

И если вам нужно получить только имена файлов (например, чтобы скопировать исправление вручную):

git diff k73ud dj374 --name-only

И вы можете применить изменения к другой ветке:

git diff k73ud dj374 > my.patch
git apply my.patch
person VonC    schedule 30.07.2010
comment
Уверены ли вы? git diff 275e8922ab4e995f47a753b88b75c3027444a54c..a8d9d944c32e945cbb9f60b3f724ecc580da86ae работает, но git diff 275e8922ab4e995f47a753b88b75c3027444c86d4c9c8bbbb3d3d3d3d1bbbb3d3d3d1bbb3d3d3d4e4c8bb3d3d3db - person demas; 30.07.2010
comment
@demas: работает на моей машине;) вы также можете использовать git diff 275e8^ a8d9d9, так как это то же самое, что и '..'. - person VonC; 30.07.2010
comment
@VonC На моей машине нет необходимости использовать ^ - person xi.lin; 11.08.2014
comment
@ xi.lin какую ОС вы используете? В оболочке Windows (cmd) вам понадобится ^^ - person VonC; 11.08.2014
comment
@VonC Ubuntu 14.04. Только git diff k73ud..dj374 в порядке - person xi.lin; 11.08.2014
comment
@ xi.lin Согласен. Я предполагаю, что топология веток должна быть особым случаем, когда OP должен использовать k73ud^. - person VonC; 11.08.2014
comment
@Eug Вы уверены в своей правке git diff dj374 k73ud? k73ud должен быть старой фиксацией, а не новой. - person VonC; 18.01.2019
comment
@Eug Спасибо за редактирование. Обратите внимание, что он исключает изменения из самого k73ud (старый коммит), что может быть не тем, что хотел OP. - person VonC; 18.01.2019
comment
@demas 275e892 - первая фиксация в вашем репо? Если это так, у него нет родителя, поэтому вы не будете использовать ^ после него или ^^ в командной строке Windows (и использование каретки приведет к этой ошибке). В этом случае это будет эквивалентно diff -r /dev/null /path/to/repo (это просто каждая строка с + перед ней, или, другими словами, бессмысленно). - person Poikilos; 29.06.2019
comment
Если ваш репозиторий находится на Github и вы хотите увидеть разницу в графическом интерфейсе пользователя, см. Это руководство help.github.com/en/github/committing-changes-to-your-project/ - person Brady Dowling; 28.05.2020
comment
@BradyDowling Согласен. И если вы хотите увидеть разницу PR, вы можете сделать это в командной строке с новым gh CLI: stackoverflow.com/a/62031065 / 6309 - person VonC; 28.05.2020

Чтобы увидеть разницу между:

Ваша рабочая копия и промежуточная область:

% git diff

Промежуточная область и последний коммит:

% git diff --staged

Ваша рабочая копия и фиксация 4ac0a6733:

% git diff 4ac0a6733

Фиксация 4ac0a6733 и последняя фиксация:

% git diff 4ac0a6733 HEAD

Зафиксировать 4ac0a6733 и зафиксировать 826793951

% git diff 4ac0a6733 826793951

Дополнительные сведения см. В официальной документации.

person Alex Yursha    schedule 31.03.2015
comment
кроме того, если вы действительно хотите увидеть различия в одном файле в этих коммитах, git diff {x} {y} -- filename, где {x} и {y} - это любые из приведенных примеров. См. Также git log -p, поскольку есть некоторые совпадения. - person michael; 25.09.2017

Если вы хотите видеть изменения, вносимые при каждой фиксации, попробуйте «git log -p»

person cxreg    schedule 30.07.2010
comment
MVP! Как я могу сделать это между двумя конкретными хешами? И наоборот (от более старого к более позднему)? git log -p --reverse old_hash..new_hash! - person David 天宇 Wong; 20.06.2021

  1. gitk --all
  2. Выберите первую фиксацию
  3. Щелкните правой кнопкой мыши на другом, затем выберите diff выбрал это
person geekbytes0xff    schedule 11.02.2016
comment
Я начинаю доверять gitk немного меньше, потому что он показывает другого автора коммитера, чем фактический. - person Ciasto piekarz; 09.02.2018

Чтобы увидеть разницу между двумя разными коммитами (назовем их a и b), используйте

git diff a..b
  • Обратите внимание, что разница между a и b противоположна b и a.

Чтобы увидеть разницу между вашей последней фиксацией и еще не зафиксированными изменениями, используйте

git diff

Если вы хотите вернуться к различию позже, вы можете сохранить его в файле.

git diff a..b > ../project.diff
person AldaronLau    schedule 20.09.2015

Я использую gitk, чтобы увидеть разницу:

gitk k73ud..dj374

У него есть режим графического интерфейса, что упрощает просмотр.

person user2647616    schedule 03.08.2013

Самый простой способ проверить изменения в последних двух коммитах после pull:

git diff HEAD~2 
person Flowkap    schedule 14.09.2018
comment
для меня это разница между последней фиксацией и предпоследней (после извлечения): git diff HEAD~1. - person SwissNavy; 19.08.2020

Я написал скрипт, который отображает разницу между двумя коммитами, хорошо работает на Ubuntu.

https://gist.github.com/jacobabrahamb4/a60624d627bd2ece7a

#!/usr/bin/env python
import sys, subprocess, os

TOOLS = ['bcompare', 'meld']

def execute(command):
    return subprocess.check_output(command)

def getTool():
    for tool in TOOLS:
        try:
            out = execute(['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 = execute(['git', '-C', name, 'log', '--oneline', '--reverse']).splitlines()
        if first_index >= 0:
            commit1 = logs[first_index].split(' ')[0]
        if second_index >= 0:
            commit2 = logs[second_index].split(' ')[0]
    except ValueError:
        if first is not '0':
            commit1 = first
        if second is not '0':
            commit2 = second
    return commit1, commit2

def validateCommitIds(name, commit1, commit2):
    if not commit1 and not commit2:
        print "Nothing to do, exit!"
        return False
    try:
        if commit1:
            execute(['git', '-C', name, 'cat-file', '-t', commit1])
        if commit2:
            execute(['git', '-C', name, 'cat-file', '-t', commit2])
    except subprocess.CalledProcessError:
        return False
    return True

def cleanup(commit1, commit2):
        execute(['rm', '-rf', '/tmp/'+(commit1 if commit1 else '0'), '/tmp/'+(commit2 if commit2 else '0')])

def checkoutCommit(name, commit):
    if commit:
        execute(['git', 'clone', name, '/tmp/'+commit])
        execute(['git', '-C', '/tmp/'+commit, 'checkout', commit])
    else:
        execute(['mkdir', '/tmp/0'])

def compare(tool, commit1, commit2):
        execute([tool, '/tmp/'+(commit1 if commit1 else '0'), '/tmp/'+(commit2 if commit2 else '0')])

if __name__=='__main__':
    tool = getTool()
    if not tool:
        print "No GUI diff tools, install bcompare or meld"
        sys.exit(0)
    if len(sys.argv) is not 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 validateCommitIds(name, commit1, commit2) is False:
        sys.exit(0)

    cleanup(commit1, commit2)

    try:
        checkoutCommit(name, commit1)
        checkoutCommit(name, commit2)
        compare(tool, commit1, commit2)
    except KeyboardInterrupt:
        pass
    finally:
        cleanup(commit1, commit2)
    sys.exit(0)
person Jacob Abraham    schedule 02.07.2018
comment
Интересный сценарий. +1 - person VonC; 02.07.2018

Мне всегда нравится использовать командную строку, и у меня под рукой есть удобные инструменты (с графическим интерфейсом). Лучшее из обоих миров. Вот как я это делаю, чтобы сравнить два коммита в Git.

Вы можете показать разницу между двумя коммитами следующим образом.

Отредактируйте файл конфигурации git в РЕДАКТОРЕ ТЕКСТА:

git config --global -e 

Настройте подходящий инструмент сравнения (удобный для пользователя), такой как Meld, например, в Windows в файле конфигурации Git:

[difftool "meld"]
cmd = "C:/Program Files (x86)/Meld/Meld.exe" "LOCAL\" \"REMOTE" --label "DIFF (ORIGINAL MY)"
prompt = false
path = C:\Program Files (x86)\Meld\Meld.exe

Meld можно установить с помощью Chocolatey следующим образом из КОМАНДНОЙ СТРОКИ:

choco install meld

Давайте определим функцию оболочки, которая поможет нам сравнить два sha-s (коммитов) под [псевдонимом] в РЕДАКТОРЕ ТЕКСТА:

[alias]
showchangesbetween = "!w() { git difftool \"$1\" \"$2\" --dir-diff --ignore-all-space; }; w"

Чтобы сравнить коммиты с помощью Meld (или другого вашего любимого инструмента сравнения, просто введите в КОМАНДНОЙ СТРОКЕ:

git showchangesbetween somesha123 somesha456

Ша-ы фиксации легко видны при вводе

 git log 

Например.

person Tore Aurstad    schedule 09.12.2020
comment
Интересный псевдоним. Проголосовали. - person VonC; 10.12.2020

Принятый ответ хорош.

Просто поместите это снова здесь, чтобы его было легко понять и попробовать в будущем

git diff c1...c2 > mypatch_1.patch  
git diff c1..c2  > mypatch_2.patch  
git diff c1^..c2 > mypatch_3.patch  

У меня одинаковые различия для всех вышеперечисленных команд.

Вышеупомянутое помогает в
1. увидеть разницу между фиксацией c1 и другой фиксацией c2
2. Также создание файла патча, который показывает разницу и может использоваться для применения изменений к другой ветке

Если он не показывает разницу правильно
тогда c1 и c2 могут быть приняты неправильно
поэтому отрегулируйте их до фиксации, например c1 до c0, или до одного после, например, c2 до c3

Используйте gitk, чтобы увидеть SHA коммитов, первых 8 символов достаточно, чтобы использовать их как c0, c1, c2 или c3. Вы также можете увидеть идентификаторы коммитов в Gitlab> Repository> Commits и т. Д.

Надеюсь, это поможет.

person Manohar Reddy Poreddy    schedule 03.05.2020

Приведенная ниже команда отлично работает для меня в Ubuntu 20.04 и git v2.25.1:

git diff <base-commit-id> <target-commit-id>
person Muhammed Bera Koç    schedule 03.03.2021

Допустим, у вас есть еще одна фиксация внизу (самая старая), тогда это становится довольно просто:

commit dj374
made changes

commit y4746
made changes

commit k73ud
made changes

commit oldestCommit
made changes

Теперь, используя нижеприведенное, вы легко сможете определить цель.

git diff k73ud oldestCommit
person bit_cracker007    schedule 29.01.2019

Используйте эту команду, чтобы узнать разницу между фиксацией и неустановленным:

git difftool --dir-diff
person Annadurai    schedule 06.06.2017