Найти, когда строка была удалена

Ранее сегодня я обнаружил, что в моем репозитории git отсутствует код. Я знал некоторый недостающий текст и файл, в котором он был, поэтому я использовал git log -S'missingtext' /path/to/file. Однако единственное, что вернулось, - это фиксация, в которой я добавил строку, содержащую недостающий текст. Текст не присутствовал в HEAD, а фиксация, которая добавила его, присутствовала в моей ветке, поэтому я знал, что один из коммитов в истории моего ветки должен удалить его, но он не отображался.

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

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

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

Ответ 1

git log не показывает diff для объединения, по умолчанию. Флаги -c или --cc должны делать трюк:

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

Больше обсуждений/объяснений здесь.

Ответ 2

Быстрый и грязный способ # 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 результат.