В моей главной ветке я сделал 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.
Я не хочу, чтобы моя ветка была впереди по количеству попыток. Как мне вернуться к этой точке?
С помощью 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, но сохраняет те, которые отличаются между индексом и рабочим деревом (т.е. С изменениями, которые не были добавлены).
git log
выбирает для показа по умолчанию - возможно, есть другой вывод git log
или для этого можно использовать git reflog
)
Предполагая, что ваш локальный мастер не опережал начало/мастер, вы должны иметь возможность делать
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 reset --merge ORIG_HEAD
сохраняет эти изменения.
С более новыми версиями Git, если вы еще не завершили слияние, и у вас есть конфликт слияния, вы можете просто сделать:
git merge --abort
От man git merge
:
[Это] можно запустить только после того, как слияние привело к конфликтам.
git merge --abort
прервет процесс слияния и попытается восстановить состояние предварительного слияния.
Вы должны reset выполнить предыдущую фиксацию. Это должно работать:
git reset --hard HEAD^
Или даже HEAD^^
, чтобы вернуться, чтобы вернуть фиксацию. Вы всегда можете дать полную ссылку на SHA, если не уверены, сколько шагов вы должны предпринять.
Если у вас возникли проблемы, и ваша главная ветвь не имела локальных изменений, вы можете reset до origin/master
.
ORIG_HEAD
для вас, почему бы не использовать его?
В последнее время я использовал 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
, чтобы заставить эту ветвь отслеживать до слияния и переноса.
reflog
чтобы получить SHA и передать его в git reset
.
С помощью современных 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
гораздо более мощным и полезным в повседневной работе, так что тот, который я всегда использую.
Хорошо, ответы, которые дали мне другие люди, были близки, но это не сработало. Вот что я сделал.
Выполнение этого...
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
HEAD^^^^
origin/master
;)
Вы можете использовать git reflog
, чтобы найти предыдущую проверку. Иногда это хорошее состояние, на которое вы хотите вернуться.
В частности,
$ git reflog
$ git reset --hard HEAD@{0}
Если вы еще не сделали этого, вы можете использовать
$ git checkout -f
Отменит слияние (и все, что вы сделали).
Получил этот вопрос, также обратившись к тому, чтобы вернуться к совпадению с началом (т.е. НЕТ берет начало до начала). Изучая далее, нашел там команду reset
для этого:
git reset --hard @{u}
Примечание: @{u}
является сокращением для origin/master
. (И, конечно же, вам нужен этот удаленный репозиторий для этого.)
Вы можете использовать только две команды для возврата слияния или перезапуска с помощью определенной фиксации:
git reset --hard commitHash
(вы должны использовать фиксацию, которую хотите перезапустить, например, 44a587491e32eafa1638aca7738)git push origin HEAD --force
(Отправка новой локальной ведущей ветки в начало/мастер)Удачи и вперед!
Просто для дополнительной опции, чтобы посмотреть, я в основном следовал описанной здесь модели ветвления: http://nvie.com/posts/a-successful-git-branching-model/ и, как таковые, слияние с --no-ff
(без быстрой перемотки вперед) обычно.
Я просто прочитал эту страницу, поскольку случайно случайно объединил ветку тестирования вместо моей ветки релиза с мастером для развертывания (веб-сайт, мастер - это то, что является живым). У тестирующей ветки есть две другие ветки, объединенные с ней и насчитывающие около шести коммитов.
Итак, чтобы вернуть всю транзакцию, мне просто понадобился один git reset --hard HEAD^
, и он вернул все слияние. Поскольку слияния не были быстро перенаправлены, слияние было блоком и одним шагом назад является "ветвь не объединена".
Самый простой ответ - тот, который дается odinho - Velmont
Сначала сделайте git reset --merge ORIG_HEAD
Для тех, кто смотрит на reset после того, как изменения нажаты, сделайте это (Потому что это первое сообщение, которое было обнаружено для любых вопросов о слиянии git reset)
git push origin HEAD --force
Это будет reset таким образом, что вы не получите объединенные изменения обратно после нажатия.
Я смог решить эту проблему с помощью одной команды, которая не включает поиск идентификатора фиксации.
git reset --hard remotes/origin/HEAD
Принятый ответ не работал для меня, но эта команда достигла результатов, которые я искал.
Если ваш слияние и соответствующие коммиты еще не были нажаты, вы всегда можете переключиться на другую ветку, удалить исходную и повторно создать ее.
Например, я случайно объединил ветку разработки в мастер и хотел ее отменить. Используя следующие шаги:
git checkout develop
git branch -D master
git branch -t master origin/master
Voila! Мастер находится на той же стадии, что и происхождение, и ваше неправильно объединенное состояние стирается.
Стратегия: Создайте новую ветку, откуда все было хорошо.
Обоснование: Возвращение слияния сложно. Слишком много решений, в зависимости от многих факторов, таких как то, что вы совершили или нажали ваше слияние, или были новые коммиты с момента вашего слияния. Также вам необходимо иметь относительно глубокое понимание 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
Если вам требуется решение из командной строки, я предлагаю просто пойти с ответом MBO.
Если вы новичок, вам может понравиться графический подход:
gitk
(из командной строки или щелкнуть правой кнопкой мыши в браузере файлов, если у вас есть)Я знаю, что это не прямой ответ на этот вопрос, но имея в виду, насколько сложна эта проблема для истории репозитория, я хотел поделиться своим опытом и дать всем понять, что создание новой ветки от последнего коммита до слияние может быть хорошей альтернативой, в основном, когда слияние уже было нажато.
Если вы совершили слияние:
git reset HEAD~1
# Make sure what you are reverting is in fact the merge files
git add .
git reset --hard
Во-первых, убедитесь, что вы все сделали.
Затем 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
где это диапазон правильных коммитов, которые вы совершили (за исключением ошибочно зафиксированного слияния).
Я думаю, что вы можете сделать git rebase -i [hash] [branch_name]
, где [hash]
- это идентификационный хеш, если вы еще хотите перемотать назад, плюс один (или сколько бы то ни было коммитов, которые вы хотите отправить), а затем удалите строки для коммитов в редактор, который вам больше не нужен. Сохраните файл. Выход. Молиться. И он должен быть перемотан. Возможно, вам придется сделать git reset --hard
, но в этот момент это должно быть хорошо. Вы также можете использовать это, чтобы вытащить определенные коммиты из стека, если вы не хотите сохранять их в своей истории, но это может оставить ваш репозиторий в состоянии, которое вам, вероятно, не нужно.
Если вы находитесь в процессе слияния, вы всегда можете прервать его git merge --abort
В этом случае вы захотите сбросить свою ветку с помощью 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 в других сценариях.
Самый простой из простейших шансов, гораздо проще, чем что-либо, сказанное здесь:
Удалите локальную ветвь (локальную, а не удаленную) и потяните ее снова. Таким образом, вы отмените изменения в своей основной ветке, и на кого-либо повлияет изменение, которое вы не хотите нажимать. Запустите его.
Если вы заметили, что вам нужно вернуться сразу после слияния, и после попытки слияния вы ничего не сделали, вы можете просто выполнить эту команду:
git reset --hard HEAD@{1}
.
По существу, ваше слияние sha
будет указывать на HEAD@{0}
, если после слияния ничего не было зафиксировано, и поэтому HEAD@{1}
будет предыдущей точкой перед слиянием.
Вы можете использовать команду git - reset.
git - reset - Reset текущий HEAD для
указанное состояние. git Reset [--mixed |
- мягкий | --hard | --merge] [-q] [] git Reset [-q] []
[-]... git Reset --patch
[] [-] [...]
git reset
git reset --merge
и git reset --hard
, но все равно получаю то же сообщение о том, что 5 коммитов впереди origin / master.