Сброс моего последнего коммита, отменяющий множество коммитов

#git

#git

Вопрос:

В моей локальной ветке есть два коммита. Один из них — небольшой коммит, в котором был изменен один файл. Другой — слияние, в котором изменилось много файлов. Я хотел бы отменить оба коммита, в результате чего третий коммит вернется в историю моих ветвей.

Это то, что я пробовал:

 git reset --hard HEAD^
  

Это возвращает 1 коммит. Когда я запускаю его снова, ожидаемое поведение — вернуться еще на один коммит. Однако при выполнении этой команды, когда последний коммит был слиянием, похоже, что он также отменяет последние ~ 10 коммитов. Почему это? Есть ли способ отменить коммит слияния, не касаясь каких-либо дополнительных коммитов?

Комментарии:

1. Когда HEAD указывает на коммит слияния, вы должны указать, к какому из двух родительских элементов вы хотите вернуться.

2. git reset --hard HEAD^ является первым родителем, git reset --hard HEAD^2 является вторым родителем, что, вероятно, и есть то, что вы хотите.

3. Попробуйте включить информацию журнала git, иначе мы просто стреляем в темноте.

4. Документация ( git help rev-parse ) определяет значение <rev>^ .

Ответ №1:

Если вы запустите:

 git log --graph --oneline -n 14
  

Выглядит ли ваш журнал так:

 * xxxxx The top commit
* xxxxx merge commit
|
| * aaaaa
| * bbbbb
| * ccccc
| * ddddd
| * eeeee
| * fffff
| * 11111
| * 22222
| * 33333
| * 44444
|/
* yyyyyy The commit where you ended up after the 2nd `reset`
  

Если это так, если я правильно понял, вы хотите, чтобы ваша ветка заканчивалась на aaaaaa , это так?

Если это так, вы можете сделать:

 git reset --hard aaaaa
  

и в вашей ветке будет 10 коммитов

Комментарии:

1. git reset --hard HEAD^2 также работает 🙂 Но я признаю, что я тоже, как и вы здесь, обычно работаю с хэшами коммитов.

Ответ №2:

 git revert SHA
  

Позволяет сбросить коммиты. SHA указывает коммит, который вы хотите отменить.

Ответ №3:

Чтобы вернуться к фиксации и отменить ваши изменения, удалите --hard . git reset <sha_of_parent>
Чтобы вернуть свои изменения, посмотрите предыдущие коммиты git reflog .

Комментарии:

1. git reset HEAD^ отменяет все недавние коммиты, возвращаясь к ~ 10 коммит, аналогично проблеме, описанной в предыдущем сообщении.

2. Попробуйте использовать sha, на котором вы хотите закончить. git reset <sha>

Ответ №4:

В итоге я сделал следующее:

 git reset --hard abcdef 
  

Где abcdef хэш коммита до слияния.

Комментарии:

1. Для тех, кто, возможно, читает, вы можете запустить git log --pretty=oneline , чтобы просмотреть хэши коммитов.

Ответ №5:

<someCommit>^ означает «для someCommit первого родителя» git , что для «обычного» (т. Е. Не связанного со слиянием) коммита означает родительский коммит.

Но когда HEAD указывает на коммит слияния, вы должны указать, к какому из двух родителей вы хотите «вернуться».

 A     B
    /
   /
   C <<< HEAD (merge commit)
  
  • HEAD относится к C
  • HEAD^ и HEAD^1 обратитесь к
  • HEAD^2 относится к B

Документация (git help rev-parse) определяет значение <rev>^ и многое другое.