Отмените слияние 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.
Я не хочу, чтобы моя ветка была впереди по количеству попыток. Как мне вернуться к этой точке?
Ответы
Ответ 1
С помощью 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, но сохраняет те, которые отличаются между индексом и рабочим деревом (т.е. С изменениями, которые не были добавлены).
Ответ 2
Предполагая, что ваш локальный мастер не опережал начало/мастер, вы должны иметь возможность делать
git reset --hard origin/master
Затем ваша локальная ветвь master
должна выглядеть идентично origin/master
.
Ответ 3
Смотрите глава 4 в книге Git и исходный пост Линусом Торвальдсом.
Чтобы отменить слияние , которое уже было нажато:
git revert -m 1 commit_hash
Обязательно верните возврат, если вы снова завершаете ветку, как сказал Линус.
Ответ 4
Странно, что простейшая команда отсутствовала. Большинство ответов работают, но отменив слияние, которое вы только что сделали, это простой и безопасный способ:
git reset --merge ORIG_HEAD
Ссылка ref ORIG_HEAD
будет указывать на первоначальную фиксацию до слияния.
(Параметр --merge
не имеет ничего общего с слиянием. Это просто как git reset --hard ORIG_HEAD
, но безопаснее, так как он не касается незафиксированных изменений.)
Ответ 5
С более новыми версиями Git, если вы еще не завершили слияние, и у вас есть конфликт слияния, вы можете просто сделать:
git merge --abort
От man git merge
:
[Это] можно запустить только после того, как слияние привело к конфликтам. git merge --abort
прервет процесс слияния и попытается восстановить состояние предварительного слияния.
Ответ 6
Вы должны reset выполнить предыдущую фиксацию. Это должно работать:
git reset --hard HEAD^
Или даже HEAD^^
, чтобы вернуться, чтобы вернуть фиксацию. Вы всегда можете дать полную ссылку на SHA, если не уверены, сколько шагов вы должны предпринять.
Если у вас возникли проблемы, и ваша главная ветвь не имела локальных изменений, вы можете reset до origin/master
.
Ответ 7
В последнее время я использовал git reflog
, чтобы помочь с этим. Это в основном работает только в том случае, если слияние произошло просто, и оно было на вашем компьютере.
git reflog
может возвращать что-то вроде:
fbb0c0f [email protected]{0}: commit (merge): Merge branch 'master' into my-branch
43b6032 [email protected]{1}: checkout: moving from master to my-branch
e3753a7 [email protected]{2}: rebase finished: returning to refs/heads/master
e3753a7 [email protected]{3}: pull --rebase: checkout e3753a71d92b032034dcb299d2df2edc09b5830e
b41ea52 [email protected]{4}: reset: moving to HEAD^
8400a0f [email protected]{5}: rebase: aborting
Первая строка указывает, что произошло слияние. Вторая строка - это время до моего слияния. Я просто git reset --hard 43b6032
, чтобы заставить эту ветвь отслеживать до слияния и переноса.
Ответ 8
С помощью современных 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
гораздо более мощным и полезным в повседневной работе, так что тот, который я всегда использую.
Ответ 9
Хорошо, ответы, которые дали мне другие люди, были близки, но это не сработало. Вот что я сделал.
Выполнение этого...
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
Ответ 10
Вы можете использовать git reflog
, чтобы найти предыдущую проверку. Иногда это хорошее состояние, на которое вы хотите вернуться.
В частности,
$ git reflog
$ git reset --hard [email protected]{0}
Ответ 11
Если вы находитесь в процессе слияния, вы всегда можете прервать его git merge --abort
Ответ 12
Если вы еще не сделали этого, вы можете использовать
$ git checkout -f
Отменит слияние (и все, что вы сделали).
Ответ 13
Получил этот вопрос, также обратившись к тому, чтобы вернуться к совпадению с началом (т.е. НЕТ берет начало до начала). Изучая далее, нашел там команду reset
для этого:
git reset --hard @{u}
Примечание: @{u}
является сокращением для origin/master
. (И, конечно же, вам нужен этот удаленный репозиторий для этого.)
Ответ 14
Я смог решить эту проблему с помощью одной команды, которая не включает поиск идентификатора фиксации.
git reset --hard remotes/origin/HEAD
Принятый ответ не работал для меня, но эта команда достигла результатов, которые я искал.
Ответ 15
Просто для дополнительной опции, чтобы посмотреть, я в основном следовал описанной здесь модели ветвления: http://nvie.com/posts/a-successful-git-branching-model/ и, как таковые, слияние с --no-ff
(без быстрой перемотки вперед) обычно.
Я просто прочитал эту страницу, поскольку случайно случайно объединил ветку тестирования вместо моей ветки релиза с мастером для развертывания (веб-сайт, мастер - это то, что является живым). У тестирующей ветки есть две другие ветки, объединенные с ней и насчитывающие около шести коммитов.
Итак, чтобы вернуть всю транзакцию, мне просто понадобился один git reset --hard HEAD^
, и он вернул все слияние. Поскольку слияния не были быстро перенаправлены, слияние было блоком и одним шагом назад является "ветвь не объединена".
Ответ 16
Вы можете использовать только две команды для возврата слияния или перезапуска с помощью определенной фиксации:
-
git reset --hard commitHash
(вы должны использовать фиксацию, которую хотите перезапустить, например, 44a587491e32eafa1638aca7738)
-
git push origin HEAD --force
(Отправка новой локальной ведущей ветки в начало/мастер)
Удачи и вперед!
Ответ 17
Самый простой ответ - тот, который дается odinho - Velmont
Сначала сделайте git reset --merge ORIG_HEAD
Для тех, кто смотрит на reset после того, как изменения нажаты, сделайте это
(Потому что это первое сообщение, которое было обнаружено для любых вопросов о слиянии git reset)
git push origin HEAD --force
Это будет reset таким образом, что вы не получите объединенные изменения обратно после нажатия.
Ответ 18
Если ваш слияние и соответствующие коммиты еще не были нажаты, вы всегда можете переключиться на другую ветку, удалить исходную и повторно создать ее.
Например, я случайно объединил ветку разработки в мастер и хотел ее отменить. Используя следующие шаги:
git checkout develop
git branch -D master
git branch -t master origin/master
Voila! Мастер находится на той же стадии, что и происхождение, и ваше неправильно объединенное состояние стирается.
Ответ 19
Если вам требуется решение из командной строки, я предлагаю просто пойти с ответом MBO.
Если вы новичок, вам может понравиться графический подход:
- Отключить
gitk
(из командной строки или щелкнуть правой кнопкой мыши в браузере файлов, если у вас есть)
- Вы можете легко определить фиксацию слияния - первый node сверху с двумя родителями
- Следуйте ссылке на первый/левый родитель (тот, который находится в вашей текущей ветке до слияния, обычно красный для меня)
- В выбранном коммите щелкните правой кнопкой мыши раздел "Reset", выберите жесткий reset там
Ответ 20
Стратегия: Создайте новую ветку, откуда все было хорошо.
Обоснование: Возвращение слияния сложно. Слишком много решений, в зависимости от многих факторов, таких как то, что вы совершили или нажали ваше слияние, или были новые коммиты с момента вашего слияния. Также вам необходимо иметь относительно глубокое понимание 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
Ответ 21
Вы должны изменить свою ГОЛОВУ, Не свою, конечно, но мерзавца ГОЛОВУ....
Поэтому, прежде чем ответить, давайте добавим некоторую предысторию, объясняющую, что это HEAD
.
First of all what is HEAD?
HEAD
- это просто ссылка на текущий коммит (последний) в текущей ветке.
В любой момент времени может быть только один HEAD
. (исключая git worktree
)
Содержимое HEAD
хранится внутри .git/HEAD
и содержит 40 байтов SHA-1 текущего коммита.
detached HEAD
Если вы не используете последний коммит - это означает, что HEAD
указывает на предыдущий коммит в истории, он называется detached HEAD
.
В командной строке он будет выглядеть как this- SHA-1 вместо имени ветки, поскольку HEAD
не указывает на конец текущей ветки
Несколько вариантов восстановления после отсоединения HEAD:
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>
Вы также всегда можете использовать reflog
.
git reflog
отобразит любое изменение, которое обновило HEAD
, а проверка нужной записи журнала повторного вызова вернет HEAD
к этой фиксации.
Каждый раз, когда заголовок изменяется, в reflog
будет добавляться новая запись
git reflog
git checkout [email protected]{...}
Это вернет вас к желаемой фиксации
"Переместите" ГОЛОВУ назад к желаемому коммиту.
# 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
.
"Отменить" указанный диапазон фиксации или фиксации.
Команда сброса "отменит" любые изменения, сделанные в данном коммите.
Новый коммит с патчем отмены будет зафиксирован, в то время как оригинальный коммит также останется в истории.
# 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
.
Ответ 22
Я знаю, что это не прямой ответ на этот вопрос, но имея в виду, насколько сложна эта проблема для истории репозитория, я хотел поделиться своим опытом и дать всем понять, что создание новой ветки от последнего коммита до слияние может быть хорошей альтернативой, в основном, когда слияние уже было нажато.
Ответ 23
Это можно сделать несколькими способами.
1) Прервать слияние
Если вы находитесь в промежутке между неудачным слиянием (ошибочно сделанным с неправильной ветвью) и хотите избежать слияния, вернитесь к последней ветке, как показано ниже:
git merge --abort
2) Сбросить HEAD в удаленную ветку
Если вы работаете с удаленной веткой разработки, вы можете сбросить HEAD до последнего коммита в удаленной ветке, как показано ниже:
git reset --hard origin/develop
3) Удалить текущую ветку и снова оформить заказ из удаленного репозитория
Учитывая, что вы работаете над веткой разработки в локальном репозитории, которая синхронизируется с удаленной веткой/веткой разработки, вы можете сделать следующее:
git checkout master
##to delete one branch, you need to be on another branch, otherwise you will fall with the branch :)
git branch -D develop
git checkout -b develop origin/develop
Ответ 24
Я думаю, что вы можете сделать git rebase -i [hash] [branch_name]
, где [hash]
- это идентификационный хеш, если вы еще хотите перемотать назад, плюс один (или сколько бы то ни было коммитов, которые вы хотите отправить), а затем удалите строки для коммитов в редактор, который вам больше не нужен. Сохраните файл. Выход. Молиться. И он должен быть перемотан. Возможно, вам придется сделать git reset --hard
, но в этот момент это должно быть хорошо. Вы также можете использовать это, чтобы вытащить определенные коммиты из стека, если вы не хотите сохранять их в своей истории, но это может оставить ваш репозиторий в состоянии, которое вам, вероятно, не нужно.
Ответ 25
-
Во-первых, убедитесь, что вы все сделали.
-
Затем 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
где это диапазон правильных коммитов, которые вы совершили (за исключением ошибочно зафиксированного слияния).
Ответ 26
Если вы совершили слияние:
git reset HEAD~1
# Make sure what you are reverting is in fact the merge files
git add .
git reset --hard
Ответ 27
Если вы заметили, что вам нужно вернуться сразу после слияния, и после попытки слияния вы ничего не сделали, вы можете просто выполнить эту команду:
git reset --hard [email protected]{1}
.
По существу, ваше слияние sha
будет указывать на [email protected]{0}
, если после слияния ничего не было зафиксировано, и поэтому [email protected]{1}
будет предыдущей точкой перед слиянием.
Ответ 28
Самый простой из простейших шансов, гораздо проще, чем что-либо, сказанное здесь:
Удалите локальную ветвь (локальную, а не удаленную) и потяните ее снова. Таким образом, вы отмените изменения в своей основной ветке, и на кого-либо повлияет изменение, которое вы не хотите нажимать. Запустите его.
Ответ 29
В этом случае вы захотите сбросить свою ветку с помощью 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 в других сценариях.
Ответ 30
git stash
git branch -d the_local_branch
git checkout -t <name of remote>
git stash apply
Это сработало для меня.. !!