Что является противоположностью `git diff HEAD ^`? - PullRequest
19 голосов
/ 24 августа 2010

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

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

Ответы [ 3 ]

30 голосов
/ 24 августа 2010

Вы не можете сделать именно это.History в 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, найденный следом за всеми последними родителями.

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

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

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

3 голосов
/ 24 августа 2010

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

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

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

2 голосов
/ 24 августа 2010

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

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

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

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

    Support for complex trig/pow.

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

    Fix doc formatting warning.

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

    Merge branch 'master' 

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

    Fix link
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...