Я думаю, что вы работаете под неправильным представлением здесь.В частности, вы не хотите, чтобы использовал 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
.На втором шаге текущий извлеченный коммит не изменился, но текущая ветвь изменилась.