Как переместить ГОЛОВУ назад в предыдущее место? (Отдельная голова) & Отменить фиксацию

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

git reset origin/master

Но мне нужно выйти из этого. Как я могу переместить ГОЛОВУ назад в предыдущее место?

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

Ответ 1

Прежде чем ответить, давайте добавим некоторую предысторию, объясняющую, что это за 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

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 [email protected]{...}

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

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

Ответ 2

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

Если

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

и

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

Тогда

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

Результаты

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

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

Ответ 3

Делать

git reset 23b6772

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

git status

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

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

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

git push --force

Ответ 4

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

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

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

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

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

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

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

Ответ 5

Когда вы запустите команду 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

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

Ответ 6

Сегодня я по ошибке извлекаю коммит и начинаю работать над ним, делая некоторые коммиты при отключенном состоянии HEAD. Затем то, что я сделал, я отправил в удаленную ветку, используя следующую команду

git push origin HEAD: <My-remote-branch>

затем

git checkout <My-remote-branch>

затем

git pull 

Я наконец получаю все изменения в моей ветке, которые я сделал в detach HEAD