2010-03-11 7 views
42

Posiadałem jedno repozytorium Git (A), które zawiera rozwinięcie projektu do pewnego momentu. Potem zgubiłem pendrive USB, w którym to repo A było włączone. Na szczęście miałem kopię zapasową ostatniego zatwierdzenia, więc mogłem stworzyć nowe repozytorium (B) później, gdzie zaimportowałem stan najnowszego projektu i kontynuowałem rozwój. Teraz odzyskałem utraconą pamięć USB, więc mam dwa repozytoria Git.Jak zmienić położenie jednego repozytorium Git na inne?

Myślę, że muszę po prostu zmienić repozytorium B na repo A, ale nie mam pojęcia, jak to zrobić, może za pomocą pobierania/ściągania i rebase?

Odpowiedz

57

Jeśli A i B nie są tym samym repozytorium (utworzono B przy użyciu najnowszej kopii roboczej), należy użyć graft, aby udawać, że mają wspólną historię.

Załóżmy, że dodaliśmy jako pilot do B, jak na VonC’s answer i repo wygląda to :

~/B$ git tnylog 
* 6506232 (HEAD, master) Latest work on B 
* 799d6ae Imported backup from USB stick 
~/B$ git tnylog A/master 
* 33b5b16 (A/master) Head of A 
* 6092517 Initial commit 

Tworzenie przeszczep informujący korzeń B, że jego rodzic jest głowa:

echo '799d6aeb41095a8469d0a12167de8b45db02459c 33b5b16dde3af6f5592c2ca6a1a51d2e97357060' \ 
>> .git/info/grafts 

teraz pojawią się dwie historie powyżej jako jedno kiedy zwrócić się do historii dla B. Dokonywanie przeszczep stałe to prosta git filter-branch bez argumentów. Jednak po filtrze nie jesteś w żadnej gałęzi, więc powinieneś git branch -D master; git checkout -b master.


git tnylog = git log --oneline --graph --decorate

+2

+1 za zajęcie się "innym scenariuszem" to A i B różnią się całkowicie w historii commitów. – VonC

+3

To była świetna pomoc; zrobiłem absolutnie to, co chciałem z minimalnym zamieszaniem. Dziękuję Ci! –

+1

Po prostu skorzystałem z podejścia do łączenia podrzędnego, aby połączyć kilka repozytoriów w jeden. Sukcesywnie mi się nie powiodło, gdy próbowałem je ponownie rozstawić. Korzystając z punktów przeszczepu, udało mi się połączyć je na jednej osi czasu rozwoju, dzięki! –

24

Jeśli A i B są takie same repo (pierwszy SHA1 są wspólne), można:

  • zadeklarować jako pilot do B: git remote add A /path/to/A
  • git fetch A do update all remote A branches na repo B
  • (na B, gdzie pracujesz)
  • git rebase A/devBranch powtórne odtwarzanie B (tj. To, co rozwijasz lub tworzysz ponownie z kopii zapasowej) na A/devBranch (utracony program). Trochę jak to SO question.

Ostatni krok umożliwia zsynchronizowanie urządzenia z utraconym.
Ale rzeczywiście, kiedyś trzeba sprowadzić z A, skończysz: B zawiera teraz „wszystkie” Historia (jeden utracony i aktualnej pracy)

+0

Dzięki, wydaje się działać, tylko trzeba rozwiązać konflikty podczas scalania/rebase teraz :) – kroimon

+0

@kroimon: konflikty są nieuniknione, jak sądzę, ponieważ byłaś ponowne opracowanie w B jakiejś części kodu popełnionego w A. – VonC

+0

Skończyło się na odłączeniu HEAD i musiałem odwołać się do tego: https://stackoverflow.com/a/25670296/1807668 –

2

przede wszystkim zacząć od klona roboczą z repozytorium A.

Następnie po prostu wciągnij go z B i połącz. Możesz stworzyć nową gałąź, wciągnąć ją, a następnie połączyć dwie gałęzie. Możesz także potrzebować flagi forsowania; Robiłem takie rzeczy w Mercurial (przeszczepianie dwóch pozornie niepowiązanych repozytoriów razem) i to wymaga "-f".

Powiązane problemy