Как переместить HEAD обратно в предыдущее место? (Отдельная головка)

В git я пытался выполнить squash commit путем слияния в другой ветке и затем сброса HEAD в предыдущее место с помощью:

git reset origin/master

Но мне нужно выйти из этого. Как переместить HEAD обратно в предыдущее место?

У меня есть SHA1 frag (23b6772) коммита, который мне нужно переместить.
Как я могу вернуться к этой фиксации?

90
задан 30 дек. '16 в 0:53
источник поделиться
5 ответов

Прежде чем ответить, давайте добавим некоторый фон, объясняя, что это за HEAD.

First of all what is HEAD?

HEAD - это просто ссылка на текущий коммит (последний) в текущей ветке.
В любой момент времени может быть только одна HEAD. (исключая git worktree)

Содержимое HEAD хранится в .git/HEAD и содержит 40 байтов SHA-1 текущего коммита.


detached HEAD

Если вы не используете последний коммит - это означает, что HEAD указывает на предыдущий коммит в истории, он называется detached HEAD.

enter image description here

В командной строке он будет выглядеть как this- SHA-1 вместо имени ветки, так как HEAD не указывает на конец текущей ветки

enter image description here


Несколько вариантов того, как восстановить систему с отключенной HEAD:


git checkout

git checkout <commit_id>
git checkout -b <new branch> <commit_id>
git checkout HEAD~X // x is the number of commits t go back

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

# Checkout a given commit. 
# Doing so will result in a 'detached HEAD' which mean that the 'HEAD'
# is not pointing to the latest so you will need to checkout branch
# in order to be able to update the code.
git checkout <commit-id>

# create a new branch forked to the given commit
git checkout -b <branch name>

git reflog

Вы всегда можете также использовать reflog.
git reflog отобразит все изменения, которые обновили HEAD а проверка нужной записи reflog вернет HEAD к этому коммиту.

Каждый раз, когда reflog в reflog будет новая запись

git reflog
git checkout HEAD@{...}

Это вернет вас к желаемой фиксации

enter image description here


git reset --hard <commit_id>

"Переместите" ГОЛОВУ назад к желаемому коммиту.

# This will destroy any local modifications.
# Don't do it if you have uncommitted work you want to keep.
git reset --hard 0d1d7fc32

# Alternatively, if there work to keep:
git stash
git reset --hard 0d1d7fc32
git stash pop
# This saves the modifications, then reapplies that patch after resetting.
# You could get merge conflicts, if you've modified things which were
# changed since the commit you reset to.
  • Примечание: (начиная с Git 2.7)
    Вы также можете использовать git rebase --no-autostash.


git revert <sha-1>

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

# add new commit with the undo of the original one.
# the <sha-1> can be any commit(s) or commit range
git revert <sha-1>

Эта схема иллюстрирует, какая команда что делает.
Как вы видите, reset && checkout изменяет HEAD.

enter image description here

228
ответ дан 30 дек. '16 в 0:56
источник

Здесь подход, который может быть очень простым и запоминающимся. Проверьте 2 условия и выполните команду 1. Затем вы снова на ходу.

Если

вы находитесь в "отдельной голове"
(т.е. тип git status, вы видите HEAD detached at <commit_id>)

и

существующая ветка соответствует вашим потребностям
(т.е. тип git branch -v, вы видите имя ветки с связанными сообщениями фиксации, представляющими работу, которую вы хотите продолжить)

Тогда

просто проверьте, что ветвь (т.е. тип git checkout <branch_name>, вы видите Switched to branch <branch_name>).

Результаты

Теперь вы можете продолжать добавлять и выполнять свою работу по-прежнему; изменения будут отслеживаться на <branch_name>.

Обратите внимание, что если вы сохранили работу, когда HEAD был отсоединен, в большинстве случаев эта работа будет автоматически объединена в описанном выше процессе. Если вы видите сообщение о конфликте слиянием, не паникуйте. Существует несколько замечательных руководств с простыми шагами для устранения конфликта и завершения слияния.

9
ответ дан 09 авг. '16 в 17:10
источник

Вопрос может быть прочитан как:

Я был в состоянии отсоединения с HEAD в 23b6772 и набрал git reset origin/master (потому что я хотел сквош). Теперь я передумал, как вернуться к HEAD в 23b6772?

Прямой ответ: git reset 23b6772

Но я столкнулся с этим вопросом, потому что мне стало больно печатать (копировать и вставлять) хэши фиксации или его аббревиатуру каждый раз, когда я хотел ссылаться на предыдущий HEAD, и был Googling, чтобы увидеть, есть ли какая-либо стенография.

Оказывается, есть!

git reset - (или в моем случае git cherry-pick -)

Что, кстати, было таким же, как cd -, чтобы вернуться в предыдущий текущий каталог в * nix! Так ура, изучил две вещи одним камнем.

3
ответ дан 22 июля '17 в 7:46
источник

Делать

git reset 23b6772

Чтобы увидеть, если вы находитесь в правильном положении:

git status

Вы увидите что-то

На ветке master Ваша ветвь отстает от 'origin/master' на 17 коммитов и может быть быстро перенесена.

Затем исправьте HEAD к текущему коммиту:

git push --force
3
ответ дан 10 окт. '18 в 16:14
источник

Когда вы запустите команду git checkout commit_id тогда HEAD отсоединится от 13ca5593d(say commit-id) и ветвь будет доступна дольше.

Вернитесь к предыдущему месту и выполните шаг команды wise- a) git pull origin_name_name (скажем master) b) git checkout branch_name c) git pull origin_name_plant_name

Вы вернетесь в предыдущее место с обновленным коммитом из удаленного репозитория.

0
ответ дан 18 янв. '19 в 12:15
источник

Другие вопросы по меткам или Задайте вопрос