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

Что противоположно `git diff HEAD ^`?

В git я могу указать предыдущую версию, сказав HEAD^ или HEAD~1. А как насчет другого пути? Предположим, что я нахожусь в редакции X, и я делаю git checkout X^. Как мне вернуться?

Что-то вроде git checkout X+?

4b9b3361

Ответ 1

Вы не можете сделать именно это. История в git является ориентированным ациклическим графом - каждая фиксация содержит ссылки на своих родителей, но у родителей нет ссылок на их детей.

Проблема здесь должна стать очевидной, когда вы думаете о фиксации, с которой вы создали несколько ветвей. Какой "следующий бой" вы имеете в виду? С родителями вы можете пропустить (у обычного слияния есть первый и второй родитель), но как вы это делаете с детьми? Даже если вы знаете, к какой ветке вы пытаетесь подключиться (например, вы проверили master~4 и теперь хотите посмотреть master~3), она не определена - вы можете быть в такой ситуации:

- X (HEAD) - o - o - o - Y (master)
   \                    /
    o - o - o ----------

Тем не менее, в простых случаях вы можете сделать что-то вроде этого:

git checkout $(git rev-list HEAD..master | tail -n 1)

Ясно, что это будет отлично работать с линейной историей. Слияния... rev-list работает от настоящего к прошлому в истории, следуя за ним назад. Я считаю, что сначала он следует за первым родителем, поэтому напечатанная последняя вещь будет фиксацией после HEAD найденной, следуя за всеми последними родителями.

Изменить: это предполагает, что вы знаете, к какой ветке вы хотите двигаться вперед. Если вы этого не сделаете... ну, вы сильно застряли, глядя на все refs для коммитов, которые имеют текущий HEAD как родительский - возможно, grepping вывод git rev-parse:

git rev-list --all --children | grep ^$(git rev-parse HEAD)

Затем возьмите другой SHA1 из строки (используйте awk, что угодно). Вам придется вручную проверить или сделать произвольный выбор, если есть несколько результатов, хотя...

Ответ 2

Я не думаю, что это возможно, так как Git commit сохраняет только родительский коммит, но не его дочерние элементы.

Представьте, что фиксация будет хранить его дочерние элементы. Что произойдет, если вы создадите несколько ветвей с этой фиксацией, так что несколько коммитов имеют эту фиксацию как родитель? Что будет тогда "ГОЛОВНОЙ +"? Это неоднозначно и неправильно.

Говоря в том, что я знаю из структур данных: Git хранит историю как односвязный список, тогда как для работы вам понадобится дважды связанный список.

Ответ 3

Насколько я могу судить, нет никакого символического способа ссылаться на детей фиксации.

Лучшее, что я могу вам сейчас дать, это --children вариант git rev-list. Здесь я прошу, чтобы четыре последних коммитов были довольно печатными, а также информация о своих детях. Обратите внимание, что в строке "commit" каждой записи (кроме последних) есть дополнительный номер фиксации, который определяет дочерний элемент этого node. Вы можете захватить это вручную или через некоторые сценарии оболочки, чтобы добраться до ребенка.

$ git rev-list --children --pretty HEAD~3...

commit 20dba296ad1d48ec90f9319e2c13b245e849f698
Author: Somebody <[email protected]____.net>
Date:   Thu May 6 19:10:38 2010 -0400

    Support for complex trig/pow.

commit 9d42b5bac1721a847a39c25672e577c7101c8ff0 20dba296ad1d48ec90f9319e2c13b245e849f698
Author: Somebody <[email protected]____.net>
Date:   Wed May 5 21:55:07 2010 -0400

    Fix doc formatting warning.

commit 72bed3baa9df71cb224dfa8388b5969d50f5567c 9d42b5bac1721a847a39c25672e577c7101c8ff0
Merge: b8244cb61491c9cdb83d36e57f8eb49773e44f6b 899c3dd3f9f419f200b84ca0abe59d7ac3d5bb53
Author: Somebody <[email protected]____.net>
Date:   Wed May 5 21:54:59 2010 -0400

    Merge branch 'master' 

commit 899c3dd3f9f419f200b84ca0abe59d7ac3d5bb53 72bed3baa9df71cb224dfa8388b5969d50f5567c
Author: Somebody <[email protected]____.net>
Date:   Wed May 5 21:19:11 2010 -0400

    Fix link