2012-03-18 10 views
28

Mam dwa git oddziałów, „A” i „B”, i zobowiązuje ponumerowane 1 thru 8. Moja historia wygląda takgit: ruchome głowy oddział

1 -> 2 -> 3 -> 4[A] -> 5 -> 6 -> 7 -> 8[B] 

chcę zmienić go tak, Moja historia wygląda tak:

1 -> 2 -> 3 -> 4 -> 5 -> 6[A] -> 7 -> 8[B] 

Oznacza to, że chcę, aby przesunąć głowę gałęzi z popełnić 4 popełnić 6.

Co polecenia mogę używać, aby to zrobić?

Odpowiedz

41

można uruchomić:

git branch -f A 6 
+1

To działa w tej sytuacji, ponieważ A faktycznie nie zawiera niczego; po prostu wskazuje punkt rozgałęzienia, więc przesuniemy wskaźnik w inne miejsce, nie tracąc nic. Przypuśćmy, że A miał jakieś zobowiązania? Następnie musisz wykonać 'git rebase', aby przenieść zatwierdzenia. Jest to bardziej ogólne i powinno również zajmować się tym banalnym przypadkiem "pustej gałęzi". – Kaz

+4

@Kaz, git ma lekkie gałęzie, więc nigdy nie "zawierają" niczego. Są tylko ruchomymi notatkami dołączonymi do zatwierdzenia. Moja odpowiedź dotyczy tego scenariusza, historii liniowej gałęzi.Gdyby nie był liniowy, sprawdziłbym, co właściwie chciał OP i zaproponował rozwiązanie. –

+0

Można powiedzieć, że również o CVS. Oddział nie zawiera niczego. Jest to tylko znacznik gałęzi ("notatka") oznaczający numer oddziału, taki jak 1.2.0.2. Czy CVS ma lekkie rozgałęzienia? :) – Kaz

13
git checkout A 
git reset --hard 6 
+6

To działa, ale jest "hard way". Powodem, dla którego działa, jest to, że jeśli jesteś "w oddziale" (w git), 'git reset --hard ' przesuwa gałąź dla ciebie. Ale 'git branch -f ' ponownie wskazuje gałąź w jednym kroku. Jest jedno ograniczenie: 'git branch -f' nie pozwoli ci przenieść twojej obecnej gałęzi. Więc jeśli już jesteś "na gałęzi A" (jak pokazano przez wyjście 'git branch') musisz użyć tej metody' git reset --hard'. (Albo zejdź z oddziału A, ale to staje się głupie. :-)) – torek

7

Jest to szczególny przypadek rebase, po prostu, że oddział jest pusty:

git checkout A 
git rebase B 

rebase jest bardziej ogólne; obsługuje tę sprawę także:

Przed:

    A1 -> A2 -> [A] 
       /
1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8[B] 

Po:

         A1' -> A2' -> [A] 
            /
1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8[B] 

A1' i A2' są łączone w celu uwzględnienia delty między 4 i 8 na oddziale macierzystym.

Git rebase obsługuje ten trywialny przypadek bez kłopotów. Stworzyłem repo z dwoma zatwierdzeniami na master i odgałęzieniem br wskazującym na pierwsze zatwierdzenie.

$ git checkout br 
Switched to branch 'br' 
$ git rebase master 
First, rewinding head to replay your work on top of it... 
Fast-forwarded br to master. 

Puf, gotowe. Dziennik pokazuje teraz gałąź wskazującą na drugie zatwierdzenie.

Możemy również osiągnąć ten cel „po”: [Dzięki M. Flaschen za wskazanie tego brakowało]:

      A1'' -> A2'' -> [A] 
         /
1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8[B] 

Zamiast podścielanie do oddziału B, chcielibyśmy nazwać specyficzny commit 6, na przykład

git checkout A 
git rebase 6 # rather than rebase B 

Kiedy nie ma A1 i A2 popełnia ten redukuje do pierwotnego pytania: przesuwając [A] wskaźnik od 4 do 6.

+0

Wcześniejszy przypadek nie pasuje do pytania. W pytaniu brak zobowiązań dotyczy tylko A. –

+0

Wcześniejszy przypadek jest uogólnieniem pytania. A1 i A2 nie istnieją. Pusta lista to lista. – Kaz

+1

Twój przypadek również się nie zgadza. [A] wskazuje na 8, a nie 6. Ponadto, nie jestem pewien, czy to uogólnienie pomaga w odpowiedzi na oryginalne pytanie. –