Как найти фиксацию, когда строка была удалена/удалена?

У меня есть удаленная строка в файле в моем репозитории Git. Я знал часть отсутствующего текста и файл, в котором он находился, поэтому использовал git log -S'missingtext' /path/to/file.

Однако единственное, что вернулось, — это коммит, в котором я добавил строку, содержащую отсутствующий текст. Текста не было в HEAD, а коммит, добавивший его, присутствовал в моей ветке, поэтому я знал, что один из коммитов в истории моей ветки, должно быть, удалил его, но он не отображался.

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

  1. Это причина, по которой кирка не смогла найти фиксацию, которая удалила строку?
  2. Как я мог найти, где был удален недостающий текст, не копаясь в истории вручную?

Любое понимание № 1 было бы здорово (я предполагал, что git log -S даст мне мой ответ), но мой настоящий вопрос — № 2, так как я хотел бы иметь возможность избежать этого в будущем.


person matthewwithanm    schedule 25.09.2012    source источник
comment
git log -p и /missingtext в то время как в less это быстрый и грязный способ сделать это.   -  person nneonneo    schedule 26.09.2012
comment
Возможный дубликат Как обвинить удаленную строку   -  person hypehuman    schedule 11.02.2016


Ответы (3)


git log -c -S'missingtext' /path/to/file

git log по умолчанию не показывает разницу для коммитов слияния. Попробуйте флаги -c или --cc.

Дополнительные обсуждения/объяснения:
https://git-scm.com/docs/git-log
nabble.com

Из документов git-log:

-c С этой опцией выходные данные различий для коммита слияния показывают различия от каждого из родителей к результату слияния одновременно, вместо того, чтобы показывать попарные различия между родителем и результатом по одному за раз. Кроме того, в нем перечислены только файлы, которые были изменены от всех родителей.

--cc Этот флаг подразумевает опцию -c и дополнительно сжимает выходные данные исправления, опуская неинтересные фрагменты, содержимое которых в родительских элементах имеет только два варианта, а результат слияния выбирает один из них без изменений.

person lettertwo    schedule 25.09.2012
comment
Если вы хотите узнать, когда была удалена строка из удаленного файла, вы можете использовать git log -c -S'missingtext' -- /path/to/file. - person Jonathan; 19.08.2016
comment
если вы не знаете, в каком файле отсутствует текст, вы можете опустить /path/to/file и просто запустить git log -c -S'missingtext' - person Aryeh Beitz; 01.06.2017
comment
В Windows мне пришлось сделать git log -c -Smissingtext/path/to/file — обратите внимание на двойные кавычки - person SpeedOfSpin; 29.01.2020

У Super User есть отличный ответ на этот вопрос: Git: как узнать, какая фиксация удалила строку?

git blame --reverse START.. file.ext

Это покажет для каждой строки последнюю фиксацию, в которой присутствовала строка — скажем, хеш 0123456789. Следующей фиксацией будет та, которая удалила ее. Используйте git log и найдите хэш 0123456789, а затем зафиксируйте его преемник.

person James    schedule 18.04.2017
comment
Следующим последующим коммитом будет тот, который удалил его. -Это не всегда верно. blame --reverse покажет последнюю фиксацию - по метке времени - содержащую строку, но она могла быть удалена более ранней фиксацией из другой ветки. - person Superole; 07.12.2020

Быстрый и грязный способ №2 — использовать цикл for.

for commit in $(git log --pretty='%H'); do
    git diff -U0 --ignore-space-change "$commit^" "$commit" | grep '^-.*missingtext' > /dev/null && echo "$commit"
done

Это будет включать все изменения слияния, поскольку оно явно указывает базовую фиксацию для diff. Я придумал это, потому что git log -c -S... давал мне кучу ложных срабатываний. Кроме того, когда я указал путь к файлу в начальной команде git log, она пропустила коммит, который я искал.

Поскольку это может выполняться какое-то время, вы можете указать -n в команде git log или поставить && break в конце цикла, если вам нужен только 1 результат.

person wolverdude    schedule 07.04.2015