Git: jak "cofnąć" połączenie

Sytuacja: Zaczynając od Master w {[2] } rozgałęziłem i wprowadziłem kilka zmian w B, a następnie połączyłem tę gałąź z powrotem w (C). Po wprowadzeniu kilku zmian byłem na D, ale okazało się, że muszę wdrożyć kod bez zmian, które zaszły w gałęzi. Gdybym go nie połączył, byłoby dobrze.

A_______C___D
 \     /
  \_B_/

Po Pierwsze chciałbym wiedzieć, co powinienem zrobić stąd, aby wdrożyć kod tak, jakby połączenie nigdy nie miało miejsca. Uwaga: żaden z tych samych plików, które były redagowane w oddziale były redagowane w magistracie.

Po Drugie...

Nie miałem czasu na wypracowanie najlepszej metody radzenia sobie z tym, więc usunąłem pliki dodane przez gałąź i ręcznie przywróciłem kilka zmian wprowadzonych w gałęzi, a następnie przekazałem wynik do wdrożenia (F)

A_______C___D___F
 \     /
  \_B_/

Chcę być w stanie nadal rozwijać gałąź i łączyć wszelkie zmiany z master do niej, aby być na bieżąco, ale jeśli to zrobię, rzeczy, które zrobiłem, aby utworzyć F będą scalone i powodują usunięcie plików i przywrócenie zmian. Jak najlepiej sobie z tym poradzić?

Author: Jake, 2010-12-14

2 answers

Możesz użyć rebase, aby to zrobić w jednym kroku:

git rebase --onto A C D

Właśnie to przetestowałem, z odpowiednimi wynikami:

$ 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

Stąd masz sytuację, którą opisałeś. Następnie:

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

Rebases commits from C (excluded) to master, on A. Musiałem naprawić pewne konflikty, ponieważ zmodyfikowałem je w tych samych miejscach w B I D, ale myślę, że tego nie zrobisz.]}

   _D'
  /
 /
A_______C___D
 \     /
  \_B_/

Doc o git rebase --onto, który jest mniej więcej Twoim sytuacja: http://git-scm.com/docs/git-rebase


Gdybyś miał:

A_______C___D___F
 \     /
  \_B_/

, to masz teraz:

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

Stąd łączenie zmian w master do gałęzi jest łatwe. Odrzuć commit F' całkowicie.

$ 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'>

Po powyższych poleceniach masz:

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

Aby połączyć aktualizacje master do the_branch:

$ git checkout the_branch
$ git merge master

... i naprawić konflikty.

 16
Author: Gauthier,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-12-14 12:57:29

Oczywistym rozwiązaniem jest zresetowanie do A, ponowne zainstalowanie wszystkich łatek ręcznie i rozwiązywanie konfliktów (których nie będziesz mieć).

Alternatywnie możesz po prostu git revert patch B , ale to utworzy nowy commit.

Chociaż odpowiedź Gauthiera jest lepsza.
 6
Author: terminus,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-05-22 02:09:01