Показать последний будущий коммит с git rev-parse HEAD? - PullRequest
0 голосов
/ 05 марта 2019

git rev-parse HEAD показать текущий коммит (коммит ветка "сброшена" до). Но как мне получить последний будущий коммит независимо от «перезагрузки» коммита?

* * 1003 Изменить: git log --all -1 --pretty=format:"%H", кажется, работает, но мне действительно нужно использовать другую команду для этой простой задачи?

Edit2: нет, это не работает. Он отображает 03317b1d158cd8a79ff4083884eaf3a2eee3b136, фиксацию между последним и текущим ...

Контекст: В TortoiseGit я выбираю какую-то старую ревизию и выбираю Reset "master" to this this = 051741bc532257903f3563d7d89c69cfdddaaf17 Последний коммит = 19747382e3680bd90689e998834b492aa66c0730 После этого git rev-parse HEAD отобразит 051741bc532257903f3563d7d89c69cfdddaaf17. Как я могу заставить его отображать 19747382e3680bd90689e998834b492aa66c0730?

1 Ответ

1 голос
/ 06 марта 2019

Я думаю, что вы работаете под неправильным представлением здесь.В частности, вы не хотите, чтобы использовал git reset.Сделав это, вам может понадобиться использовать его снова, чтобы исправить проблему.

Обратите внимание, что git rev-parse master превращает имя master в идентификатор хеша коммита.Это достигается путем выполнения шестиэтапного процесса, описанного в документации gitrevisions .Это обнаруживает, что master является сокращением от refs/heads/master и что refs/heads/master идентифицирует одну конкретную фиксацию, поэтому после всей этой работы именно этот хэш-идентификатор фиксации создает git rev-parse.

Специальное имя HEAD - это всегда текущий коммит.Но он может быть текущим коммитом одним из двух способов:

  • Специальное имя содержит (полное) имя ветви, например, cat .git/HEAD производитref: refs/heads/master.Затем имя refs/heads/master фактически содержит идентификатор текущего коммита, и git rev-parse HEAD сначала читает .git/HEAD, чтобы найти этот факт, а затем переводит refs/heads/master в хэш-идентификатор.

    Этот коммит является текущим коммитом.

  • Или специальное имя HEAD содержит необработанный хэш-идентификатор фиксации.То есть cat .git/HEAD выдает большой уродливый идентификатор хеша.Вы находитесь в том, что Git вызывает в режиме detached HEAD , и git rev-parse HEAD выдает тот же самый хэш-идентификатор.

    Этот коммит является текущим коммитом.*

Обратите внимание, что это означает, что есть два способа спросить Git о HEAD.Один из способов - спросить: Какое имя ветви имеет HEAD? Этот вопрос имеет ответ, только если HEAD не отсоединен.Второй способ - спросить: Какой хэш-идентификатор коммита означает HEAD? На этот вопрос почти всегда есть ответ. 1

В любом случае каждый коммитхранит хэш-идентификатор своего непосредственного предшественника или parent commit (или фиксирует, если у него более одного непосредственного предшественника).Большинство коммитов имеют только одного родителя.Таким образом, учитывая идентификатор хеша коммита, вы можете легко перейти назад .Но вы не можете идти вперед , потому что коммит замораживается навсегда, как только он будет сделан.Идентификатор любого коммита, сделанного после , когда этот коммит недоступен в этом коммите.

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

Я думаю, что картинка делает этонамного понятнее:

                I <-J   <-- br1
               /
... <-F <-G <-H   <-- HEAD
               \
                K <-L   <-- br2

Здесь мы находимся в режиме отсоединенного HEAD, где HEAD содержит некоторый хэш-идентификатор H.Таким образом, текущий коммит - это просто HНо есть два возможных следующих коммитов.Начиная с br1, мы перейдем к коммиту J, который говорит, что нужно вернуться к I, который говорит, чтобы вернуться к H.Или, начиная с br2, мы находимся на L, который говорит, что нужно вернуться к K, который говорит, чтобы вернуться к H.Таким образом, следующий коммит вперед после H равен или K или L, и невозможно сказать, какой, если вы не выберете конечную точку.

Чтобы выбрать конечную точку, лучше оставить как br1, так и br2 в покое, чтобы они продолжали указывать на J и L соответственно.Если мы уберем ярлык br1 с J и укажем на H, мы больше не будем знать, как найти I и J.

..В TortoiseGit я выбираю какую-то старую ревизию и выбираю Reset "master" to this

Вы изначально не упоминали TortoiseGit (ни в ваших тегах), и я никогда не использовал его, но эта веб-страница подразумевает, что этот сброс вызывает git reset.

Что git reset делает - ну, одна из многих вещей, которые он может сделать, и что он делает для этого конкретного случая - это изменение идентификатора хеша, хранящегося в имени ветви .Таким образом, если имя ветви master, полное имя которого refs/heads/master, содержало 19747382e3680bd90689e998834b492aa66c0730 ранее, но тогда у вас есть Git, перезаписав его на 051741bc532257903f3563d7d89c69cfdddaaf17, у вас больше не будет master, содержащего число 19747382e3680bd90689e998834b492aa66c0730.Если никакое другое имя не содержит этого числа, единственный способ, которым вы должны запомнить это число, это, ну, записать его куда-нибудь.

С помощью командной строки GitЗатем вы можете запустить git reset master 19747382e3680bd90689e998834b492aa66c0730, чтобы записать это число обратно в master, поскольку оно записано.Это работает, но не является хорошим планом в целом - вместо этого вы должны были использовать или, по крайней мере, начать с режима отключенного HEAD, чтобы получить доступ и работать с коммитом, настоящее имя которого 051741bc532257903f3563d7d89c69cfdddaaf17.(Как вы могли бы сделать это в TortoiseGit, я понятия не имею.)

Если у вас есть командная строка Git, вы можете сделать это сейчас - возможно, вам следует сначала полностью отключить TortoiseGit, чтобы он не пыталсяотменить его.

Обратите внимание, что Git командной строки автоматически «записывает» последние несколько (или много) значений, которые он сохранил под именем каждой ветви, в том, что Git называет reflog дляэта ветка.Из командной строки вы можете запустить:

git reflog master

, чтобы просмотреть содержимое этого журнала.Если вы нигде не сохранили номер 19747382e3680bd90689e998834b492aa66c0730, это может быть способ восстановить его.Но, опять же, вероятно, лучше использовать режим отсоединенного HEAD для проверки старых коммитов.

Обратите внимание, что после использования режима отсоединенного HEAD для получения и проверки некоторых существующих исторических фиксаций вы можете создать new имя ветки на , которое фиксирует, чтобы начать новую разработку, начиная с этой точки.Для этого используйте git branch или git checkout -b из командной строки.Разница между ними заключается в том, что git checkout -b сначала создает новую ветвь, а затем переключает на , так что HEAD содержит имя новой ветви, а не ID хеша.Другими словами:

git checkout -b newbranch

эквивалентно:

git branch newbranch
git checkout newbranch

На первом шаге создается ветвь с сохранением в ней хеш-идентификатора, который получит git rev-parse HEAD.Второй шаг сохраняет имя этой ветви в HEAD, так что HEAD содержит ref: refs/heads/newbranch.На втором шаге текущий извлеченный коммит не изменился, но текущая ветвь изменилась.

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