Показать историю одного файла во всех ветках

Как я могу показать полную историю одного файла в Git? Когда я использую git log <filename> или же gitk <filename>Я получаю только слияния. Я хочу видеть коммиты из объединенных веток, которые влияют на файл. я пробовал --follow и другие флаги и не могут найти способ.

2 ответа

Это покажет все версии файла (объединяет или нет):

gitk --all <filename>

TL;DR резюме: --all

Во-первых, позвольте мне рассмотреть один общий элемент, который применяется ко многим командам git.

git log смотрит на ревизию (ы), вы указываете, используя git rev-list справиться с ними. Причина, по которой вы обычно видите много коммитов, заключается в том, что git rev-list "история прогулок", если не сказано:

$ git rev-list --no-walk HEAD
d1574b852963482d4b482992ad6343691082412f
$ git rev-list HEAD
d1574b852963482d4b482992ad6343691082412f
b9491ea160d12ddfd69a9ddc79ebd264cda20679
676699a0e0cdfd97521f3524c763222f1c30a094
[snip]

Тем не менее, ревизии, которые посетили git rev-list начать с заданных вами точек (по умолчанию = HEAD). Поэтому любые ревизии, которые еще не являются частью указанной точки или ее истории, опущены:

        C - D           <-- branchA
      /
A - B - E - F - G       <-- branchB
      \
        H - I - J - M   <-- HEAD=branchC
          \       /
            K - L

На этой диаграмме я поместил три названия веток и показал, что HEAD является branchC, Каждая буква представляет коммит (SHA-1). Родители любого коммита - это те, кто слева от него, либо прямо слева, либо движется вверх или вниз по ссылкам родительского коммита, которые идут между коммитами.

С этой точки зрения, git log покажет вам коммиты M, L, K, J, I, H, B, а также A, так как git log (а также git rev-list) начнется с HEAD и идти назад. (Точный порядок этих коммитов зависит от дополнительных аргументов.)

С другой стороны, git log branchB покажет вам коммиты G, F, E, B, а также Aпотому что, начиная с коммита G и ход назад выбирает те коммиты (и никаких других). Так же, git log branchA начинается с D и идет назад к A,

Если вы спросите git rev-list смотреть на --all, он будет начинаться со всех ссылок (все ветви, все теги, все удаленные ветви и все другие ссылки в refs/ пространство имен) и идти в обратном направлении. В этом случае всех ветвей достаточно для выбора каждого коммита. В репозиториях с тегами --branches может получить меньше, чем --all, поскольку могут быть некоторые строки, которые помечены, но не отмечены ветвью. Видеть (довольно подавляющим) git rev-list документацию, чтобы увидеть все доступные варианты здесь.


Добавление имени файла в git log позволяет пропустить печать некоторых (многих или большинства) коммитов, которые он посещает, через то, что описано в документации как "Упрощение истории". То есть, git log сначала выбирает все коммиты, выбранные вашим git rev-list аргументы, но тогда это показывает только меньшее число.

Добавление --follow марки git log попытаться заметить случаи, когда файл переименовывается через определенный коммит, и в этих случаях переключать выбранные ревизии на версии с прежним именем, когда он переходит через такие коммиты в своей истории. Другими словами, он пытается настроить упрощение истории, чтобы исправить изменения имени. Это обнаружение переименования выполняется динамически (повторно проверяется для каждой пары коммитов). Это работает только при шаге назад - кода просто нет для обработки других коммитов.

Когда используешь git diffу вас больше контроля над тем, что называется переименованием; с git log"s --followВы застряли со скомпилированным значением по умолчанию 50% -ого совпадения.

Другие вопросы по тегам