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

В моей главной ветке я сделал git merge some-other-branch локально, но никогда не подталкивал изменения в исходный мастер. Я не собирался сливаться, поэтому я бы хотел его отменить. Когда я делал 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.

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

3252
05 марта '10 в 22:24
источник поделиться
28 ответов

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

git reset --hard commit_sha

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

git reset --hard HEAD~1

Это вернет вам 1 коммит.

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


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

git reset --hard ORIG_HEAD

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


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

git reset --merge ORIG_HEAD

--merge

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

3585
05 марта '10 в 22:34
источник

Предполагая, что ваш локальный мастер не опережал начало/мастер, вы должны иметь возможность делать

git reset --hard origin/master

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

1321
17 марта '11 в 21:06
источник

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

Чтобы отменить слияние , которое уже было нажато:

git revert -m 1 commit_hash

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

1102
02 июня '11 в 19:31
источник

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

git reset --merge ORIG_HEAD

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

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

882
29 янв. '13 в 18:46
источник

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

git merge --abort

От man git merge:

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

330
12 февр. '13 в 5:13
источник

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

git reset --hard HEAD^

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

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

113
05 марта '10 в 22:31
источник

В последнее время я использовал 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, чтобы заставить эту ветвь отслеживать до слияния и переноса.

80
19 дек. '14 в 20:51
источник

С помощью современных Git вы можете:

git merge --abort

Более старый синтаксис:

git reset --merge

Старая школа:

git reset --hard

Но на самом деле стоит заметить, что git merge --abort эквивалентен только git reset --merge, если присутствует MERGE_HEAD. Это можно прочитать в справке Git для команды 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 гораздо более мощным и полезным в повседневной работе, так что тот, который я всегда использую.

47
08 мая '15 в 22:13
источник

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

Выполнение этого...

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
36
05 марта '10 в 22:54
источник

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

В частности,

$ git reflog
$ git reset --hard HEAD@{0}
21
18 янв. '14 в 1:36
источник

Если вы еще не сделали этого, вы можете использовать

$ git checkout -f

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

13
18 янв. '13 в 18:25
источник

Получил этот вопрос, также обратившись к тому, чтобы вернуться к совпадению с началом (т.е. НЕТ берет начало до начала). Изучая далее, нашел там команду reset для этого:

git reset --hard @{u}

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

11
17 февр. '17 в 0:54
источник

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

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

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

10
13 дек. '14 в 2:16
источник

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

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

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

10
09 июня '11 в 3:54
источник

Самый простой ответ - тот, который дается odinho - Velmont

Сначала сделайте git reset --merge ORIG_HEAD

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

git push origin HEAD --force

Это будет reset таким образом, что вы не получите объединенные изменения обратно после нажатия.

7
03 нояб. '17 в 2:22
источник

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

git reset --hard remotes/origin/HEAD

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

6
25 июля '18 в 12:55
источник

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

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

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

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

5
26 июня '12 в 14:15
источник

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

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

  • Отключить gitk (из командной строки или щелкнуть правой кнопкой мыши в браузере файлов, если у вас есть)
  • Вы можете легко определить фиксацию слияния - первый node сверху с двумя родителями
  • Следуйте ссылке на первый/левый родитель (тот, который находится в вашей текущей ветке до слияния, обычно красный для меня)
  • В выбранном коммите щелкните правой кнопкой мыши раздел "Reset", выберите жесткий reset там
4
21 марта '13 в 17:38
источник

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

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

Решение:

Предположим, вы хотите объединить dev в feature-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
    
  • Проверьте это (вернитесь назад):

    git checkout e5f6g7h8
    
  • Создайте новую ветку и проверьте ее:

    git checkout -b feature-1
    

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

  • Объединить: git merge dev

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

  • Commit: git commit

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

4
11 июня '15 в 18:42
источник

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

2
19 июля '12 в 19:04
источник
  • Во-первых, убедитесь, что вы все сделали.

  • Затем reset ваш репозиторий в предыдущее рабочее состояние:

    $ git reset f836e4c1fa51524658b9f026eb5efa24afaf3a36
    

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

    $ git reset f836e4c1fa51524658b9f026eb5efa24afaf3a36 --hard
    

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

  • Проверьте, какие коммиты вы хотите перехватить в верхней части предыдущей правильной версии:

    $ git log 4c3e23f529b581c3cbe95350e84e66e3cb05704f
    
    commit 4c3e23f529b581c3cbe95350e84e66e3cb05704f
    
    ...
    
    commit 16b373a96b0a353f7454b141f7aa6f548c979d0a
    
    ...
    
  • Примените свои права на верхнюю часть нужной версии вашего репозитория:

    • Используя вишневый выбор (изменения, внесенные некоторыми существующими коммитами)

          git cherry-pick ec59ab844cf504e462f011c8cc7e5667ebb2e9c7
      
    • Или путем выбора вишней диапазона значений:

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

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

        git cherry-pick 5216b24822ea1c48069f648449997879bb49c070..4c3e23f529b581c3cbe95350e84e66e3cb05704f
        

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

1
29 янв. '13 в 18:09
источник

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

1
08 марта '10 в 5:55
источник

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

git reset HEAD~1
# Make sure what you are reverting is in fact the merge files
git add .
git reset --hard
1
10 нояб. '16 в 18:57
источник

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

Вы можете сбросить состояние до определенного коммита с помощью git reset --hard <commit_id>.

Если изменения были git revert <branch_name> вы можете использовать git revert <branch_name> вместо git revert <branch_name>. Обязательно ознакомьтесь с тем, как использовать git revert и git checkout в других сценариях.

0
29 мая '18 в 13:21
источник

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

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

0
26 апр. '16 в 21:52
источник

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

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

0
15 июля '16 в 17:16
источник

Если вы находитесь в процессе слияния, вы всегда можете прервать его git merge --abort

0
13 дек. '18 в 17:05
источник

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

git - reset - Reset текущий HEAD для

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

- мягкий | --hard | --merge] [-q] [] git Reset [-q] []

[-]... git Reset --patch

[] [-] [...]

GIT-Reset

-13
05 марта '10 в 22:28
источник

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