Отменить изменения, сделанные слиянием - PullRequest
22 голосов
/ 30 ноября 2011

Разработчик вносил небольшие изменения в два файла. Но во время этого коммита у него был конфликт слияния, который удалил много вещей (вероятно, не было последней версии) Затем он был перенесен в общий репозиторий, и некоторые другие разработчики сделали некоторые другие коммиты.

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

Я пытался git revert commitsha, но это не вернуло изменения. Нужно ли вернуть обратно mergesha? Как я могу это определить?

Ответы [ 4 ]

28 голосов
/ 19 августа 2015

git revert --mainline

Обычно:

git revert --mainline 1 dd8cbe3e4

Где:

  • dd8cbe3e4 - это плохое слияние, которое вы хотите отменить, и
  • --mainline сообщает вам, какой из нескольких предыдущих коммитов будет восстановлен (помните, что коммит слияния имеет несколько родительских коммитов, и вы можете оставить только один из них).
    • Я не могу найти хорошее объяснение того, что означает 1, но я предполагаю, что 1,2,3... соответствует списку сопоставлений с коммитами непосредственно перед dd8cbe3e4, отсортированными по по возрастанию хронологический порядок (сначала самый старый - обычно это то, к чему вы хотите вернуться).

Источник:

http://thezencoder.com/2013/09/05/how-to-correctly-revert-a-bad-merge-in-git/

8 голосов
/ 30 ноября 2011

Короче говоря, ПРЕДУПРЕЖДЕНИЕ : нет реального безопасного способа отменить слияние, кроме на самом деле сброса перехода кcommit до слияния.

Позвольте мне объяснить и просмотреть существующую ссылку на данный момент.

Цитировать связанный ответ из Как отменитьошибочный коммит git merge

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

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

Вот разбивка

  • git merge <someref> на слияние (необязательно, фиксация после разрешения конфликтов)
  • Если вы сразу обнаружите , на который хотите сбросить ветку до слияния:

    git reset HEAD@{1} 
         # optionally pass --hard to reset the working tree too
    
  • , если вы узнали только позже,

    • для каждого использования reflog, чтобы найти точку перед слиянием.(HEAD@{1} является коротким для предыдущего значения текущей ссылки на заголовок, но журнал изменений отслеживает ограниченную историю значений для ссылки на заголовок)

      git reflog
      
    • сбросить ветвь

      git reset HEAD@{n} # substitute reflog entry index
      
    • опционально перебазировать / выбрать те коммиты, которые были сделаны после слияния

      git cherry-pick HEAD@{1} # just an example. interactive tools will make this easier
      
6 голосов
/ 30 ноября 2011

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

Это всегда работает, не требует каких-либо нечетных опций командной строки и не вмешивается в вещи, которые вы должны оставить в покое: -)

Например, в Eclipse есть хорошие инструменты, чтобы выбрать каждую индивидуальную разницу и скопировать ее в любую версию. Просто используйте меню «Сравнить», чтобы открыть обе версии рядом.

0 голосов
/ 30 ноября 2011

Короче, вы можете сделать git reset --soft <commit> где commit может быть HEAD^ (предыдущий), HEAD~2 (current-2), SHA и т. д.

С --soft все изменения будут готовы к фиксации, так что вы можете изменить фиксацию. С --hard все изменения будут потеряны.

После того, как вы изменили коммит, вы должны принудительно протолкнуть изменения в общий репозиторий с помощью git push --force.

Обратите внимание, что вам нужно будет сообщить другим разработчикам, что им следует переназначить свои репо на общий репо. (используйте git pull --rebase). Они могут получить некоторые конфликты слияния, хотя ... Пожалуйста, имейте это в виду.

...