git blame
отлично подходит для измененных и добавленных строк, но как я могу найти, когда строка, которая существовала в конкретном предыдущем коммите, была в конечном итоге удалена. Я думаю bisect
, но я надеялся на что-то более удобное.
(Прежде чем вы спросите: в этом случае я просто сделал a git log -p
и перебрал строку кода, и (а) какой-то идиот только что удалил жизненно важную строку в предыдущем коммите, и (б) я был этим идиотом.)
git log -S<string> /path/to/file
хочет , чтобы-c
или-cc
во время слияния (конфликты) также отображались удаления-c
и--cc
. @Steen: Правильно, спасибо за указание! Глупый недосмотр. Хотел бы я отредактировать комментарий. Добавление нового, затем удаление моего, а затем удаление вашего слишком громоздко, я думаю :)git blame
бы иметь возможность показывать удаленные строки (возможно с зачеркиванием или красным текстом) с ревизией, в которой они были удалены.Ответы:
Если вы знаете содержимое строки, это идеальный вариант использования для:
который показывает вам коммиты, которые вводят или удаляют экземпляр этой строки. Также есть то,
-G<regex>
что делает то же самое с регулярными выражениями! Смотритеman git-log
и поиск-G
и-S
варианты, или кирка (понятное имя для этих функций) для получения дополнительной информации.Эта
-S
опция также упоминается в заголовкеgit-blame
man-страницы, в разделе описания, где приводится пример использованияgit log -S...
.источник
git blame --reverse
Метод нашел его, хотя.)-c
опцию дополнительно.Я думаю, что вы действительно хотите,
Из справочной страницы :
С помощью
git blame reverse
вы можете найти последний коммит, в котором появилась строка. Вам все еще нужно получить коммит, который следует после.Вы можете использовать следующую команду, чтобы показать обратный журнал git. Первый показанный коммит будет в последний раз, когда появляется эта строка, а следующий коммит будет, когда он будет изменен или удален.
источник
git blame --reverse
будет показана ревизия до слияния, которая была хронологически наконец, не ревизия перед первоначальным слиянием, где было принято решение не принимать строку. Есть ли способ найти самую раннюю ревизию, в которой линия перестала существовать, а не самую последнюю?Просто чтобы завершить ответ Каскабель :
У меня была та же проблема, что и здесь, но оказалось, что строка отсутствует, потому что коммит слияния из ветви был возвращен, а затем снова слит в него, эффективно удаляя рассматриваемую строку. В
--full-history
флаг предотвращает пропуск этих фиксаций.источник
git blame --reverse может приблизить вас к месту удаления строки. Но это на самом деле не указывает на ревизию, где строка удаляется. Это указывает на последнюю ревизию, где линия присутствовала . Тогда, если следующая ревизия является простым коммитом, вам повезло, и вы получили ревизию удаления. OTOH, если следующая ревизия является коммитом слияния , то все может стать немного диким.
В рамках усилий по созданию difflame я решил эту проблему, поэтому, если у вас уже есть Python, установленный на вашем компьютере, и вы хотите попробовать его, то не ждите больше и дайте мне знать, как он работает.
https://github.com/eantoranz/difflame
источник
Для изменений, скрытых в коммитах слияния
Коммиты слияния автоматически скрывают свои изменения из вывода журнала Git. Как кирка, так и обратная вина не нашли изменений. Итак, нужная мне строка была добавлена, а затем удалена, и я хотел найти слияние, которое ее удалило. История файла
git log -p -- path/file
только показала, что он был добавлен. Вот лучший способ найти его:git log -p -U9999 -- path/file
Ищите изменения, затем ищите в обратном направлении «^ commit» - первый «^ commit» - это коммит, в котором файл последний раз содержал эту строку. Второй «^ commit» после того, как он исчез. Второй коммит может быть тем, который удалил его.
-U9999
Призван показать все содержимое файла (после каждый раз , когда файл был изменен), предполагая , что ваши файлы все не более 9999 строк.Находит любые связанные слияния с помощью грубой силы (различие каждого возможного коммита слияния с его первым родителем, работает с тоннами коммитов)
git log --merges --pretty=format:"git diff %h^...%h | grep target_text" HEAD ^$(git merge-base A B) | sh -v 2>&1 | less
(Я пытался ограничить фильтр ревизий больше, но столкнулся с проблемами и не рекомендую это. Изменения добавления / удаления, которые я искал, были в разных ветках, которые были объединены в разное время, и A ... B не включал когда изменения фактически были объединены с основной линией.)
Покажите дерево Git с этими двумя коммитами (и удалена большая часть сложной истории Git):
git log --graph --oneline A B ^$(git merge-base A B)
(A - первый коммит выше, B - второй коммит выше)Показать историю A и историю B минус история как A, так и B.
Альтернативная версия (кажется, показывает путь более линейно, чем обычное дерево истории Git - однако я предпочитаю обычное дерево истории git):
Три, а не две точки - три точки означают «r1 r2 - not $ (git merge-base --all r1 r2). Это набор коммитов, которые доступны либо с одного из r1 (слева) или r2 (справа) сторона), но не от обоих. - источник: "Человек Гитревенс"
источник