Как перечислить историю изменений дерева каталогов в git
Git не отслеживает каталоги как таковые. Он отслеживает только файлы, которые живут в каком-то каталоге.
(См. Как добавить пустой каталог в репозиторий Git?)
Однако, если у меня есть определенная история коммитов, я неявно также имею историю изменений в дереве каталогов.
Итак, как мне ответить на такие вопросы, как:
- когда был создан каталог foo/bar (в Git терминология: когда был первый файл, созданный в этом каталоге). Если foo/bar уже был
удалил некоторое время в истории и воссоздал позже.
- при удалении каталога foo/bar (в терминологии Git: когда последний файл был удален из этого каталога). Как и выше, может быть более одного квалифицирующего коммита.
- каковы подкаталоги foo/bar, существовавшие в любой момент времени в истории
Ближайший я могу найти в псевдокоде:
loop over all commits (git rev-list --all)
start from repo root directory
do recursively on the directory tree rebuilt so far
call git ls-tree and grep the tree lines
rebuild next level of directory tree
end
end
Очевидно, это может быть написано на вашем любимом языке сценариев.
Затем у меня есть все деревья каталогов, и мне по-прежнему нужно искать их разумным способом, чтобы отвечать на вопросы типа 1 - 3. Опять же, выполнимо, но, вероятно, не через пару минут.
Вопросы:
- Есть ли более простой способ?
- Если нет: подходят ли скрипты уже в сети? (мой поисковик не выявил, но я тоже не нашел идеальные слова поиска)
Ответы
Ответ 1
Для вопросов 1 и 2 это довольно просто:
Однако, третья часть немного сложна, и я не могу полностью ответить на нее.
Две приведенные выше команды дают вам $FIRST_REV
(созданный) и $LAST_REV
(удалены).
Следующий фрагмент дает вам все коммиты, где было изменено дерево:
for rev in $(git rev-list FIRST_REV..LAST_REV)
do
git ls-tree -r -t $rev | grep tree | cut -f 2
done
Затем у вас есть список каталогов, которые присутствовали. Но есть еще дубликаты. Передайте этот список в sort -u
, и вы закончите:
#!/bin/sh
for r in $(git rev-list FIRST_REV..LAST_REV)
do
git ls-tree -r -t $r | grep tree | cut -f 2
done | sort -u
Однако вы теряете информацию о коммитах, в которых были затронуты эти каталоги. Это недостаток.
И это предполагает, что foo/bar
был создан только один раз и больше не присутствует.
Ответ 2
gitk foo/bar
предоставляет пользовательский интерфейс для просмотра истории git, ограниченной фиксацией, которая коснулась foo/bar
.