Используя git, чтобы сравнить один файл с двух коммитов

У меня есть файл, который сломался где-то по линии, и я нашел последний пункт, в котором он все еще был исправлен.

Я хотел бы знать, как, используя git, я могу сравнить один файл с двух коммитов, или, действительно, если это лучший способ воспроизвести это!

Ответ 1

Чтобы ответить на ваш вопрос, предположите, что вы хотите сравнить файл src/toaster.c между вашим текущим master и старым commit f4l4f3l, вы можете просто сделать:

git diff master f4l4f3l -- src/toaster.c

В качестве альтернативы вы можете просто просмотреть все изменения в этом файле с помощью

git log -p -- src/toaster.c

В общем случае, если вы пытаетесь найти коммит, где была введена определенная ошибка, git имеет замечательный инструмент для этого, называемый git bisect. Если вы сообщите этому инструменту о работе и неработающем фиксации, он даст вам ряд компромиссов для проверки между ними, используя стратегию бинарного поиска.

Вы начали бы делить пополам команду:

git bisect start

Затем, если ваша текущая фиксация имеет ошибку, вы просто выполните:

git bisect bad

Затем вам нужно найти более старую фиксацию, которая определенно не имела ошибки. У этого может быть определенный тег, или, возможно, вы просто выберете фиксацию, которая была несколько месяцев назад. Предположим, что он называется a12b3d, тогда вы будете делать:

git checkout a12b3d
git bisect good

В этот момент git выработает следующий коммит, который вам нужно будет протестировать, и сделайте git checkout, чтобы перенести вас на эту фиксацию. (Эти проверки будут все с "отсоединенным HEAD", поэтому ваш исходный указатель ветки не изменяется.) Затем вы проверяете это commit и запускаете git bisect good или git bisect bad в зависимости от того, есть ли у него ошибка или нет. Этот бинарный поиск между ревизиями будет быстро сужаться до первого плохого коммита и сообщать, какой он есть. Затем, чтобы вернуться к тому, что вы делали, вы можете сделать:

git bisect reset

Ответ 2

$ git diff $start_commit..$end_commit -- path/to/file

Например, вы видите разницу для файла "file.c" между двумя моментами и обратно:

$ git diff HEAD^^..HEAD -- file.c

Я надеюсь, что это поможет вам.