Git: Как "отменить" слияние - PullRequest
       16

Git: Как "отменить" слияние

16 голосов
/ 14 декабря 2010

Ситуация: Начав с Мастера в A, я разветвился и внес некоторые изменения в B, затем слил эту ветку обратно в (C). После внесения некоторых изменений я оказался на D, но обнаружил, что мне нужно развернуть код без изменений, которые произошли в ветви. Если бы я не слил его, это было бы хорошо.

A_______C___D
 \     /
  \_B_/

Во-первых, я хотел бы знать, что я должен был сделать отсюда, чтобы развернуть код, как если бы слияние никогда не происходило. Примечание: ни один из тех же файлов, которые были отредактированы в ветке, не был отредактирован в мастере.

Во-вторых ...

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

A_______C___D___F
 \     /
  \_B_/

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

Ответы [ 2 ]

16 голосов
/ 14 декабря 2010

Вы можете использовать rebase, чтобы сделать это за один шаг:

git rebase --onto A C D

Я только что проверил это с соответствующими результатами:

$ edit test.txt
$ git add .
$ git commit -mA
$ git checkout -b the_branch
$ edit test.txt
$ git commit -a -mB
$ git checkout master
$ git merge master the_branch --no-ff
$ edit test.txt
$ git commit -a -mD

Здесь у вас есть ситуация, которую вы описали.Затем:

$ git rebase --onto <SHA1-for-A> <SHA1-for-C> master

rebases фиксирует коммиты из C (исключая) в master, в A. Мне нужно было исправить некоторые конфликты, так как я модифицировал в тех же местах в B и D, но я думаю, что вы этого не сделаете.

   _D'
  /
 /
A_______C___D
 \     /
  \_B_/

Документ о git rebase --onto, который более или менее соответствует вашей ситуации: http://git -scm.com / docs / git-rebase


Если у вас было:

A_______C___D___F
 \     /
  \_B_/

, то теперь у вас есть:

   _D'___F'_(master)
  /
 /
A_______C___D___F
 \     /
  \_B_/(the_branch)

Отсюда легко объединить изменения мастера в ветку.Откажитесь от коммита F' в целом.

$ git checkout master # if you were not here already
$ git branch old_fix  # if you want to be able to return to F' later
$ git reset --hard <SHA1-to-D'>

После того, как вышеприведенные команды у вас есть:

     (master)
    /
   _D'___F'_(old_fix)
  /
 /
A_______C___D___F
 \     /
  \_B_/(the_branch)

Чтобы объединить обновления мастера в ветку:

$ git checkout the_branch
$ git merge master

... и исправить конфликты.

6 голосов
/ 14 декабря 2010

Очевидное решение - сбросить на A, повторно применить все патчи вручную и разрешить конфликты (которых у вас не будет).

В качестве альтернативы вы можете просто git revert патч B, но это будетсоздать новый коммит.

Хотя ответ Готье лучше.

...