Отменить слияние Git, которое еще не было нажато

в моей главной ветви я сделал git merge some-other-branch локально, но никогда не нажимал изменения в origin master. Я не хотел сливаться, поэтому я хотел бы отменить это. При выполнении git status после моего слияния я получал это сообщение:

# On branch master
# Your branch is ahead of 'origin/master' by 4 commits.

на основе некоторых инструкции я не нашел, я пробовал использовать

git revert HEAD -m 1

но теперь я получаю это сообщение с git status:

# On branch master
# Your branch is ahead of 'origin/master' by 5 commits.

Я не хочу, чтобы моя ветка была впереди на любое количество коммитов. Как мне получить вернуться к тому моменту?

26 ответов


С git reflog проверьте, какая фиксация является одной до слияния (git reflog будет лучшим вариантом, чем git log ). Затем вы можете сбросить его, используя:

git reset --hard commit_sha

есть и другой способ

git reset --hard HEAD~1

вернет вам 1 фиксацию.

имейте в виду, что любые измененные и незафиксированные/unstashed файлы будут сброшены в их неизмененное состояние. Чтобы сохранить их либо stash изменения прочь или увидеть ниже.


Как @Velmont предложил ниже в своем ответе, в этом прямом случае используя:

git reset --hard ORIG_HEAD

может дать лучшие результаты, так как он должен сохранить ваши изменения. ORIG_HEAD будет указывать на фиксацию непосредственно перед слиянием, поэтому вам не нужно охотиться за ней самостоятельно.


еще один совет-использовать --merge переключатель вместо --hard поскольку он не сбрасывает ненужные файлы:

--merge

сбрасывает индекс и обновляет файлы в рабочее дерево, которое отличается между и HEAD, но сохраняет те, которые отличаются между индексом и рабочим деревом (т. е. имеют изменения, которые не были добавлены).


предполагая, что ваш местный мастер не опередил origin / master, вы должны быть в состоянии сделать

git reset --hard origin/master

ваш местный master ветка должна выглядеть идентично origin/master.


посмотреть Глава 4 в книге Git и оригинальный пост Лайнуса Торвальдса.

отменить слияние это уже было нажато:

git revert -m 1 commit_hash

обязательно верните возврат, если вы снова фиксируете ветку, как сказал Лайнус.


странно, что не хватало самой простой команды. Большинство ответов работают, но отменяя слияние, которое вы только что сделали,Это простой и безопасный способ:

git reset --merge ORIG_HEAD

ref ORIG_HEAD будет указывать на исходную фиксацию до слияния.

(том --merge опция не имеет ничего общего с слиянием. Это так же, как git reset --hard ORIG_HEAD, но безопаснее, так как он не касается незафиксированных изменений.)


С более новыми версиями Git, если вы еще не совершили слияние и у вас есть конфликт слияния, вы можете просто сделать:

git merge --abort

С man git merge:

[This] можно запустить только после того, как слияние привело к конфликтам. git merge --abort прервет процесс слияния и попытается восстановить состояние, предшествующее слиянию.


вы должны сбросить предыдущую фиксацию. Это должно сработать:

git reset --hard HEAD^

или даже HEAD^^ для возврата этой фиксации возврата. Вы всегда можете дать полную ссылку SHA, если вы не уверены, сколько шагов назад вы должны предпринять.

в случае, если у вас есть проблемы, и ваша главная ветвь не имела никаких локальных изменений, вы можете сбросить до origin/master.


в последнее время я использую git reflog, чтобы помочь с этим. Это в основном работает, только если слияние просто произошло, и это было на вашем компьютере.

git reflog может вернуть что-то вроде:

fbb0c0f HEAD@{0}: commit (merge): Merge branch 'master' into my-branch
43b6032 HEAD@{1}: checkout: moving from master to my-branch
e3753a7 HEAD@{2}: rebase finished: returning to refs/heads/master
e3753a7 HEAD@{3}: pull --rebase: checkout e3753a71d92b032034dcb299d2df2edc09b5830e
b41ea52 HEAD@{4}: reset: moving to HEAD^
8400a0f HEAD@{5}: rebase: aborting

первая строка указывает, что произошло слияние. Вторая строка-это время до моего слияния. Я просто git reset --hard 43b6032 чтобы заставить эту ветку отслеживать до слияния и продолжить.


С современным Git, вы можете:

git merge --abort

старый синтаксис:

git reset --merge

старой школы:

git reset --hard

но на самом деле, стоит заметить, что git merge --abort только эквивалентно git reset --merge учитывая, что MERGE_HEAD присутствует. Это можно прочитать в команде git help for merge.

git merge --abort is equivalent to git reset --merge when MERGE_HEAD is present.

после неудачного слияния, когда нет MERGE_HEAD, неудачное слияние можно отменить с помощью git reset --merge, но не обязательно git merge --abort, так они не только старый и новый синтаксис для одного и того же.

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


хорошо, ответы, которые дали мне другие люди, были близки, но это не сработало. Вот что я сделал.

это делаешь...

git reset --hard HEAD^
git status

...дал мне следующий статус.

# On branch master
# Your branch and 'origin/master' have diverged,
# and have 3 and 3 different commit(s) each, respectively.

мне тогда пришлось ввести то же самое git reset команду еще несколько раз. Каждый раз, когда я это делал, сообщение менялось на одно, как вы можете видеть ниже.

> git reset --hard HEAD^
HEAD is now at [...truncated...]
> git status
# On branch master
# Your branch and 'origin/master' have diverged,
# and have 3 and 3 different commit(s) each, respectively.
> git reset --hard HEAD^
HEAD is now at [...truncated...]
> git status
# On branch master
# Your branch and 'origin/master' have diverged,
# and have 2 and 3 different commit(s) each, respectively.
> git reset --hard HEAD^
HEAD is now at [...truncated...]
> git status
# On branch master
# Your branch and 'origin/master' have diverged,
# and have 1 and 3 different commit(s) each, respectively.
> git reset --hard HEAD^
HEAD is now at [...truncated...]
> git status
# On branch master
# Your branch is behind 'origin/master' by 3 commits, and can be fast-forwarded.

в этот момент я увидел, что сообщение о состоянии изменилось, поэтому я попытался сделать git pull, и это, казалось, работа:

> git pull
Updating 2df6af4..12bbd2f
Fast forward
 app/views/truncated |    9 ++++++---
 app/views/truncated |   13 +++++++++++++
 app/views/truncated |    2 +-
 3 files changed, 20 insertions(+), 4 deletions(-)
> git status
# On branch master

короче говоря, мои команды сводились к следующему:

git reset --hard HEAD^
git reset --hard HEAD^
git reset --hard HEAD^
git reset --hard HEAD^
git pull

можно использовать git reflog найти предыдущий заказ. Иногда это хорошее состояние, в которое хочется вернуться.

конкретно

$ git reflog
$ git reset --hard HEAD@{0}

Если вы еще не зафиксировали его, вы можете использовать только

$ git checkout -f

он отменит слияние (и все, что вы сделали).


просто для дополнительной опции, чтобы посмотреть, я в основном следовал модели ветвления, описанной здесь:http://nvie.com/posts/a-successful-git-branching-model/ и как таковые сливались с --no-ff (нет быстрой перемотки вперед) обычно.

Я просто прочитал эту страницу, поскольку я случайно объединил ветку тестирования вместо моей ветви выпуска с master для развертывания (веб-сайт, master-это то, что живет). Ветвь тестирования имеет две другие ветви, объединенные с ней и итоговые около шести коммитов.

поэтому, чтобы вернуть всю фиксацию, мне просто нужен был один git reset --hard HEAD^ и он вернул все слияние. Поскольку слияния не были быстро перенаправлены, слияние было блоком, а один шаг назад - "ветвь не объединена".


вы можете использовать только две команды для возврата слияния или перезапуска с помощью определенной фиксации:

  1. git reset --hard commitHash (вы должны использовать фиксацию, которую хотите перезапустить, например. 44a587491e32eafa1638aca7738)
  2. git push origin HEAD --force (отправка новой локальной главной ветви в origin / master)

удачи и вперед!


добрался до этого вопроса, также желая вернуться к совпадению origin (т. е. никаких коммитов впереди origin). Исследуя дальше, обнаружил, что есть reset команда именно для этого:

git reset --hard @{u}

Примечание: @{u} сокращенно от origin/master. (И, конечно же, вам нужно, чтобы этот удаленный репозиторий работал.)


самый простой ответ к odinho - Вельмонт

сначала git reset --merge ORIG_HEAD

для тех, кто хочет сбросить после нажатия изменений, сделайте это (Потому что это первый пост, увиденный для любых вопросов слияния сброса git)

git push origin HEAD --force

это будет сброшено таким образом, что вы не получите объединенные изменения снова после вытягивания.


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

например, я случайно объединил ветку разработки в master и хотел отменить это. Используя следующие шаги:

git checkout develop
git branch -D master
git branch -t master origin/master

вуаля! Мастер находится на той же стадии, что и origin, и Ваше неправильно объединенное состояние стирается.


Если вы хотите решение командной строки, я предлагаю просто пойти с ответом MBO.

Если вы новичок, вам может понадобиться графический подход:

  1. старт gitk (из командной строки или щелкните правой кнопкой мыши в обозревателе файлов, если у вас есть что)
  2. вы можете легко определить фиксацию здесь - первый узел сверху с двумя родителями
  3. перейдите по ссылке на первый / левый родитель (тот, который находится в вашей текущей ветви перед слиянием, обычно красный для меня)
  4. на выбранной фиксации щелкните правой кнопкой мыши "сбросить ветку сюда", выберите жесткий сброс там

стратегия: создайте новую ветку, из которой все было хорошо.

обоснование: возврат слияния трудно. Существует слишком много решений, в зависимости от многих факторов, таких как ли вы совершили или толкнули слияние или если были новые коммиты с момента слияния. Кроме того, вам все равно нужно иметь относительно глубокое понимание git, чтобы адаптировать эти решения к вашему случаю. Если вы слепо следуете некоторым инструкциям, вы можете получить " пустой слияние", где ничего не будет объединено, и дальнейшие попытки слияния заставят Git сказать вам "уже в курсе".

устранение:

предположим, вы хотите объединить dev на feature-1.

  1. найдите редакцию, которую вы хотите получить слияние:

    git log --oneline feature-1
    a1b2c3d4 Merge branch 'dev' into 'feature-1' <-- the merge you want to undo
    e5f6g7h8 Fix NPE in the Zero Point Module <-- the one before the merge, you probably want this one
    
  2. зацени (вернуться в прошлое):

    git checkout e5f6g7h8
    
  3. создать новую ветку и проверить его out:

    git checkout -b feature-1
    

теперь вы можете перезапустить слияние:

  1. слияние: git merge dev

  2. исправьте конфликты слияния.

  3. Commit:git commit

  4. когда вы будете удовлетворены результатами, удалите старую ветку:git branch --delete feature-1


я смог решить эту проблему с помощью одной команды, которая не требует поиска идентификатора фиксации.

git reset --hard remotes/origin/HEAD

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


Я думаю, вы можете сделать git rebase -i [hash] [branch_name] здесь [hash] - это идентифицирующий хэш для того, как далеко вы хотите перемотать назад плюс один (или сколько коммитов вы хотите вернуться), а затем удалить строки для коммитов в Редакторе, которые вы больше не хотите. Сохранить файл. Выход. Молиться. И его нужно перемотать. Возможно, вам придется сделать git reset --hard, но это должно быть хорошо на данный момент. Вы также можете использовать это для извлечения определенных коммитов из стека, если вы не хотите хранить их в своей истории, но это может оставить ваш репозиторий в состоянии, которое вы, вероятно, не хотите.


  1. во-первых, убедитесь, что вы совершили все.

  2. затем сбросьте репозиторий в предыдущее рабочее состояние:

    $ git reset f836e4c1fa51524658b9f026eb5efa24afaf3a36
    

    или через --hard (это удалит все локальные, не зафиксированные изменения!):

    $ git reset f836e4c1fa51524658b9f026eb5efa24afaf3a36 --hard
    

    используйте хэш, который был там до вашего неправильно объединенного коммита.

  3. проверьте, какие коммиты вы хотели бы повторно совершить поверх предыдущего правильного версия:

    $ git log 4c3e23f529b581c3cbe95350e84e66e3cb05704f
    
    commit 4c3e23f529b581c3cbe95350e84e66e3cb05704f
    
    ...
    
    commit 16b373a96b0a353f7454b141f7aa6f548c979d0a
    
    ...
    
  4. примените свои правые коммиты в верхней части правой версии вашего репозитория по:

    • С помощью cherry-pick (изменения, внесенные некоторыми существующими коммитами)

          git cherry-pick ec59ab844cf504e462f011c8cc7e5667ebb2e9c7
      
    • или cherry-picking диапазон коммитов по:

      • сначала проверьте правильные изменения перед их объединением:

        git diff 5216b24822ea1c48069f648449997879bb49c070..4c3e23f529b581c3cbe95350e84e66e3cb05704f
        
      • первая проверка правые изменения перед их объединением:

        git cherry-pick 5216b24822ea1c48069f648449997879bb49c070..4c3e23f529b581c3cbe95350e84e66e3cb05704f
        

        где это диапазон правильных коммитов, которые вы совершили (исключая ошибочно Совершенное слияние).


если вы заметили, что вам нужно вернуться сразу после слияния, и вы ничего не сделали после попытки слияния, вы можете просто выполнить эту команду: git reset --hard HEAD@{1}.

по сути, слияние sha будет указывать на HEAD@{0} Если после слияния ничего не было зафиксировано и так HEAD@{1} будет предыдущей точкой перед слиянием.


самый простой из самых простых шансов, гораздо проще, чем все, что здесь сказано:

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


Если вы совершили слияние:

git reset HEAD~1
# Make sure what you are reverting is in fact the merge files
git add .
git reset --hard

в этом случае вы захотите сбросить свою ветку с git reset --hard <branch_name>. Если вы хотите сохранить изменения перед их сбросом, обязательно создайте новую ветку и git checkout <branch_name>.

вы можете сбросить состояние до определенной фиксации с помощью git reset --hard <commit_id> Как хорошо.

если изменения были нажаты, вы можете использовать . Не забудьте проверить, как использовать git revert и git checkout в других случаях, а также.


вы можете использовать команду git-reset.

git-reset-сброс текущей головки на

указанное состояние. git reset [--mixed/

--soft / --hard / --merge] [- q] [] сброс git [- q] []

[--] ... git reset --patch

[] [--] [...]

git-Reset