У git есть "относительное" дерево? - PullRequest
2 голосов
/ 21 февраля 2012

Я пытаюсь проверить каждый коммит в последовательности, переходя от первого к текущему совету. Это на самом деле не git bisect, я не ожидаю никаких проблем, и совет работает. Но я хочу убедиться, что каждый коммит является самодостаточным и правильным.

Я могу использовать ГОЛОВУ ^, чтобы вернуться к одному из кончика, но есть ли «один вперед, откуда я»? То есть, если у меня есть

o aaabbbccc (tip)
|
o abcdefabc
|
o fedcbafed
|
o abcdabcde
|
o deadbeefe (root)

Я хочу сделать:

git checkout deadbeefe
build and test
git checkout current+1
<up two, return>
<up two, return>

Но я не могу понять, что означает «текущий + 1».

1 Ответ

4 голосов
/ 29 февраля 2012

Git не хранит ссылки от родителей на детей;только ссылки от детей к родителям.Чтобы найти потомков коммитов, вы должны начать с самых дочерних коммитов в своем репозитории (подсказки веток, теги, HEAD и т. Д.) И пройтись по цепочке родителей, пока не достигнете корневого узла или не найдете нужный коммит.

Если DAG вашего коммита линейный и tip является ссылкой на самый дочерний коммит, вы можете сделать что-то вроде следующего, чтобы найти дочерний коммит ревизии deadbeefe:

git rev-list deadbeefe..tip | tail -n 1

Это приводит к тому, что Git начинает ходить с tip до достижения deadbeefe или корня и распечатывает все коммиты, с которыми он сталкивается.Затем выходные данные передаются по каналу tail, чтобы выбрать последний посещенный коммит, который будет дочерним по отношению к deadbeefe, если история коммитов является линейной.

HEAD относится к текущему извлеченному коммиту, поэтому, если вам нужен дочерний элемент текущего коммита вместо deadbeefe, используйте HEAD.Команды, для которых требуется фиксация по умолчанию HEAD, если она не указана, поэтому вы можете сделать следующее:

git rev-list ..tip | tail -n 1

Опять же, это работает, только если группа доступности баз данных является линейной.Если история коммитов не является линейной, вы можете использовать аргумент --ancestry-path для rev-list.

. Каждый раз, когда вы хотите перейти к следующему коммиту, вы должны выполнить O (n ^ 2), ноGit настолько быстр, что на практике это обычно не имеет значения.Если вам нужно, чтобы это было O (n), я бы сделал следующее:

git rev-list --reverse tip | while IFS= read -r rev; do
    git checkout "${rev}" || handle_checkout_error_here
    # build and test here
done

И @knittl правильный - термин, который вы хотите здесь - это commit, а не treeish.Некоторая терминология:

  • Treeish - это нечто, что может действовать как дерево файловой системы (например, индекс, ваш рабочий каталог, подкаталог в вашем рабочем каталоге, коммит, подкаталог внутриcommit и т. д.).
  • «Редакция» менее четко определена, чем фиксация, но обычно она означает вещи, которые идентифицируют коммит (сами коммиты, аннотированные теги, которые указывают на коммит, и ссылки, которые ссылаются наcommit).
  • Ссылка - это указатель на объект Git или другую ссылку (в этом случае это называется символической ссылкой).Ссылка обычно указывает на коммит или аннотированный объект тега, но может указывать на что угодно.Люди обычно говорят «ссылка», когда они хотят ссылаться на HEAD, теги и / или ветви.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...