Подтвердить что ты не робот

Как "w20> винить" удаляемую строку?

git blame отлично подходит для модифицированных и добавленных строк, но как я могу найти, когда строка, которая существовала в конкретной предыдущей фиксации, была в конечном итоге удалена. Я думаю bisect, но я надеялся на что-то более удобное.

[прежде чем вы спросите: в случае, я просто сделал git log -p и выполнил поиск для строки кода, и (а) какой-то идиот просто удалил жизненно важную строку в предыдущем фиксации и (б) я был тем идиотом ]

4b9b3361

Ответ 1

Если вы знаете содержимое строки, это идеальный вариант использования для:

git log -S <string> path/to/file

который показывает вам фиксации, которые вводят или удаляют экземпляр этой строки. Там также -G<regex>, который делает то же самое с регулярными выражениями! См. man git-log и найдите параметры -G и -S, или кирку (дружественное имя для этих функций) для получения дополнительной информации.

Опция -S на самом деле упоминается в заголовке git-blame manpage, в разделе описания, где приведен пример с использованием git log -S....

Ответ 2

Я думаю, что вы действительно хотите,

git blame --reverse START..END filename

Из справочной страницы:

Пройдите историю вперед, а не назад. Вместо того, чтобы показывать ревизию, в которой появилась строка, она показывает последнюю ревизию, в которой существовала строка. Для этого требуется ряд изменений, таких как START..END, где путь к обвинению существует в START.

С помощью git blame reverse вы можете найти последний коммит, в котором появилась строка. Вам все еще нужно получить коммит, который последует за ним.

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

git log --reverse --ancestry-path COMMIT^..master

Ответ 3

Просто чтобы завершить ответ Каскабель

git log --full-history -S <string> path/to/file

У меня была та же проблема, что и здесь, но оказалось, что строка отсутствовала, потому что коммит слияния из ветки был возвращен, а затем снова слит в него, эффективно удаляя рассматриваемую строку. Флаг --full-history предотвращает пропуск этих коммитов.

Ответ 4

мерзавец --reverse может приблизить вас к тому месту, где удалена строка. Но это на самом деле не указывает на ревизию, где строка удаляется. Это указывает на последнюю ревизию, где линия присутствовала. Тогда, если следующая ревизия является простым коммитом, вам повезло, и вы получили ревизию удаления. OTOH, если следующая ревизия является коммитом слияния, то все может стать немного диким. В рамках усилий по созданию difflame я решил именно эту проблему, поэтому, если у вас уже есть Python, установленный на вашем компьютере, и вы хотите попробовать его, не ждите больше и дайте мне знать, как он работает.

https://github.com/eantoranz/difflame

Ответ 5

Для изменений, скрытых в коммитах слияния

Коммиты слияния автоматически скрывают свои изменения из вывода git-log. Как кирка, так и обратная вина не нашли изменений. Итак, нужная мне строка была добавлена, а затем удалена, и я хотел найти слияние, которое ее удалило. История файла git log -p -- path/file только показала, что он был добавлен. Вот лучший способ найти его:

git log -p -U9999 -- path/file

Ищите изменения, затем ищите в обратном направлении "^ 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 не включал, когда изменения фактически были объединены с основной линией.)

Показать дерево мерзавцев с этими 2 коммитами (и удалена большая часть сложной истории мерзавцев):

git log --graph --oneline A B ^$(git merge-base A B) (A - первый коммит выше, B - второй коммит выше)

Показать историю A и историю B минус история как A, так и B.

Альтернативная версия: (кажется, что путь более линейный, нежели обычное дерево git-history - однако я предпочитаю обычное дерево git-history):

git log --graph --oneline A...B

3 не 2 точки - 3 точки означают "r1 r2 --not $ (git merge-base --all r1 r2). Это набор коммитов, которые доступны либо с одного из r1 (левая сторона) или r2 (правая сторона) ) но не от обоих. - источник: "Человек Гитревенс"