К сожалению, git log
сам строго работает в обратном направлении , как Git всегда делает.Git буквально не может работать вперед, потому что то, что Git сохранил , равно назад: каждый коммит запоминает хэш-идентификатор своего родительского коммита, но, поскольку все коммиты замораживаются во времени, когда они создаются, они не могут запомнить хеш-идентификаторыих детей, которые были созданы позже.
Что git log
(и что-то вроде команды старшей сестры / рабочей лошадки git rev-list
) может сделать это один раз сделать обратный обход, вычисляяиз того, какие коммиты идут раньше других, затем выведите в обратном порядке.Команда git log --reverse
делает это.Но, увы, обнаружение переименования происходит только во время обратного (который Git является вперед) обхода и не может быть втиснуто в более позднюю распечатку вперед (который Git является назад).
Это не встроено в Git, но выможно использовать git rev-list
, чтобы выполнить сторнирование, сохранить результат, а затем выполнить собственную прогулку вперед, выполняя git diff --name-status
для каждой пары коммитов в поисках операций переименования.Обратите внимание, что это все еще немного сложно, так как теперь ветви действительно разветвляются, а слияния действительно объединяются - во внутреннем обратном обходе Git происходит слияние ветвей, а слияния ветвятся.:-) Предположим, у нас есть:
tag:abc
|
v
...--o--o--*--o--o--o <-- tip1
\
o--*--o----o <-- tip2
Вы хотите начать с тега abc
, который находится слева, и "работать вперед".Git хочет начать с tip1
, фиксация вправо вдоль верхней строки или с tip2
, фиксация вправо в нижней строке.
коммиты, отмеченные *
переименовывают ваш файлA
на какое-то новое имя.В том, что вверху, новое имя B
, а в том, что внизу, новое имя C
.
. Если вы начинаете Git с tip2
, вы должны искать C
,Git замечает переименование в *
и с тех пор налево ищет A
.Если вы запускаете Git с tip1
, вы должны искать B
, таким же образом.
Если вы создали листинг «вперед», переходя назад от tip1
к некоторой точке перед тегомabc
, все будет в порядке: в этом списке нет ответвлений, поскольку ни один из коммитов, ведущих к tip2
, не включен.Но затем предположим, что кто-то добавляет слияние к tip1
и еще один коммит:
tag:abc
|
v
...--o--o--*--o--o--o--M--o <-- tip1
\ /
o--*--o----o <-- tip2
Теперь путь от abc
до tip1
включает оба переименовывает.Если вы начинаете с tip1
, вы должны дать git log --follow
имя, которое тот, кто слил, решил сохранить, будь то B
или C
.Поскольку git log -- B
или git log -- C
(в зависимости от того, какое имя подходит) делает упрощение истории , Git собирается пройти только одну из двух ног позади M
- либо верхнююили в нижнем ряду, в зависимости от того, какой файл имеет соответствующий файл - и когда вы работаете вперед с abc
, вам придется выбрать одну из двух ветвей для совместной работы или сделать что-то необычное, чтобы вызнать, чтобы проверить на A
-получает- B
вдоль вершины , а также проверить на A
-попад- C
вдоль дна .(Git ничего необычного не делает.)