Подтвердить что ты не робот

Отменить изменения, сделанные слиянием

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

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

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

4b9b3361

Ответ 1

мерзавец вернуться --mainline

Обычно:

git revert --mainline 1 dd8cbe3e4

Куда:

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

Источник:

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

Ответ 2

Короче говоря, ПРЕДУПРЕЖДЕНИЕ: нет реального безопасного способа свернуть объединение, за исключением того, что на самом деле reset ветвь должна быть зафиксирована до слияния.

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

Цитата связанного ответа от Как вы отменили ошибку git commit merge commit

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

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

Вот пробой

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

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

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

      git reflog
      
    • reset ветвь

      git reset [email protected]{n} # substitute reflog entry index
      
    • необязательно rebase/cherry-pick коммиты, сделанные после слияния

      git cherry-pick [email protected]{1} # just an example. interactive tools will make this easier
      

Ответ 3

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

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

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

Ответ 4

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

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

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

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