Muszę połączyć dwa repozytoria Git z nowym, trzecim repozytorium. Znalazłem wiele opisów tego, jak to zrobić za pomocą scalania poddrzewa (na przykład odpowiedź Jakuba Narębskiego na temat Jak scalić dwa repozytoria Git? ) I przestrzeganie tych instrukcji w większości działa, z tym wyjątkiem, że kiedy zatwierdzam poddrzewo, scalam wszystkie pliki ze starych repozytoriów są zapisywane jako nowo dodane pliki. Widzę historię zatwierdzeń ze starych repozytoriów, kiedy to robię git log
, ale jeśli to zrobię git log <file>
, pokazuje tylko jedno zatwierdzenie dla tego pliku - scalanie poddrzewa. Sądząc po komentarzach do powyższej odpowiedzi, nie jestem sam widząc ten problem, ale nie znalazłem opublikowanych rozwiązań tego problemu.
Czy istnieje sposób scalenia repozytoriów i pozostawienia nienaruszonej historii poszczególnych plików?
źródło
Odpowiedzi:
Okazuje się, że odpowiedź jest znacznie prostsza, jeśli po prostu próbujesz skleić dwa repozytoria razem i sprawić, by wyglądało to tak od samego początku, zamiast zarządzać zewnętrzną zależnością. Musisz po prostu dodać piloty do swoich starych repozytoriów, połączyć je z nowym masterem, przenieść pliki i foldery do podkatalogu, zatwierdzić przeniesienie i powtórzyć dla wszystkich dodatkowych repozytoriów. Podmoduły, scalanie poddrzewa i fantazyjne rebazy mają na celu rozwiązanie nieco innego problemu i nie są odpowiednie do tego, co próbowałem zrobić.
Oto przykładowy skrypt Powershell do sklejenia dwóch repozytoriów:
Oczywiście możesz zamiast tego połączyć old_b w old_a (który staje się nowym połączonym repozytorium), jeśli wolisz to zrobić - zmodyfikuj skrypt, aby pasował.
Jeśli chcesz również przenieść gałęzie funkcji w toku, użyj tego:
To jedyna nieoczywista część procesu - nie jest to scalanie poddrzewa, ale raczej argument na rzecz normalnego scalania rekurencyjnego, które mówi Gitowi, że zmieniliśmy nazwę celu i pomaga Gitowi poprawnie wszystko wyrównać.
Tutaj napisałem nieco bardziej szczegółowe wyjaśnienie .
źródło
git mv
nie działa tak dobrze. kiedy później użyjeszgit log
jednego z przeniesionych plików, otrzymasz tylko zatwierdzenie z przeniesienia. cała poprzednia historia została utracona. to dlatego, żegit mv
tak naprawdę jestgit rm; git add
tylko jeden krok .git log --follow
, lub wszystkie narzędzia GUI robią to automatycznie. O ile wiem, dzięki scaleniu poddrzewa nie można uzyskać historii poszczególnych plików, więc ta metoda jest lepsza.1
(numer jeden)ls
i wielkie „oko”xargs
. Dziękuję za tę wskazówkę!Oto sposób, który nie przepisuje żadnej historii, więc wszystkie identyfikatory zatwierdzeń pozostaną ważne. W rezultacie pliki drugiego repozytorium znajdą się w podkatalogu.
Dodaj drugie repozytorium jako zdalne:
Upewnij się, że pobrałeś wszystkie zatwierdzenia Secondrepo:
Utwórz oddział lokalny z drugiego oddziału repozytorium:
Przenieś wszystkie swoje pliki do podkatalogu:
Scal drugą gałąź z gałęzią główną pierwszego repozytorium:
Twoje repozytorium będzie miało więcej niż jedno zatwierdzenie główne, ale to nie powinno stanowić problemu.
źródło
git remote show secondrepo
)--allow-unrelated-histories
. Zobacz historię tego posta z odpowiedzią.Minęło kilka lat i są dobrze oparte na dobrze ocenianych rozwiązaniach, ale chcę udostępnić moje, ponieważ było trochę inaczej, ponieważ chciałem połączyć 2 zdalne repozytoria w nowe bez usuwania historii z poprzednich repozytoriów.
Utwórz nowe repozytorium w Github.
Pobierz nowo utworzone repozytorium i dodaj stare zdalne repozytorium.
Pobierz wszystkie pliki ze starego repozytorium, aby utworzyć nowy oddział.
W gałęzi master wykonaj scalenie, aby połączyć stare repozytorium z nowo utworzonym.
Utwórz nowy folder do przechowywania całej nowo utworzonej zawartości, która została dodana z OldRepo i przenieś swoje pliki do tego nowego folderu.
Na koniec możesz przesłać pliki z połączonych repozytoriów i bezpiecznie usunąć OldRepo z GitHub.
Mam nadzieję, że może to być przydatne dla każdego, kto zajmuje się łączeniem zdalnych repozytoriów.
źródło
git remote rm OldRepo
.proszę spojrzeć na korzystanie
połączyć dwie historie na wczesnym etapie życia.
Jeśli masz ścieżki, które się pokrywają, napraw je
podczas korzystania z dziennika upewnij się, że „trudniej znaleźć kopie”
w ten sposób znajdziesz wszelkie ruchy plików na ścieżce.
źródło
I okazało się, że rozwiązanie z @Flimm to do
git alias
tak (Dodane do moich~/.gitconfig
):źródło
$GIT_PREFIX
?Ta funkcja sklonuje zdalne repozytorium do lokalnego katalogu repo:
Jak używać:
Ogłoszenie. Ten skrypt może przepisać zatwierdzenia, ale zapisze wszystkich autorów i daty, oznacza to, że nowe zatwierdzenia będą miały kolejne skróty, a jeśli spróbujesz wypchnąć zmiany na zdalny serwer, będzie mógł to zrobić tylko za pomocą klucza wymuszenia, a także przepisać zatwierdzenia na serwerze. Zrób więc kopie zapasowe przed uruchomieniem.
Zysk!
źródło
git filter-branch --index-filter
do pracy. Zazwyczaj pojawia się komunikat o błędzie, że plik indeksu .new nie istnieje. Czy to dzwoni?git-add-repo.sh
z funkcją powyżej, na końcu pliku wstaw tę linięgit-add-repo "$@"
. Następnie możesz go używać z Zsh jakcd current/git/package
ibash path/to/git-add-repo.sh https://github.com/example/example dir/to/save
mv "$GIT_INDEX_FILE.new" "$GIT_INDEX_FILE"
czasami się nie udaje, więc musisz dodaćif test
.Postępuj zgodnie z instrukcjami, aby osadzić jedno repo w innym repo, mając jedną historię git, łącząc obie historie git.
my/new/subdir
(3 wystąpienia) na strukturę katalogów, w której chcesz mieć repozytorium potomne.Jeśli sprawdzisz teraz dziennik git w repozytorium nadrzędnym, powinien on zostać scalony. Możesz także zobaczyć znacznik wskazujący ze źródła zatwierdzenia.
Poniższy artykuł pomógł mi Osadzić jedno repo w innym repo, mając jedną historię git, łącząc obie historie git.
http://ericlathrop.com/2014/01/combining-git-repositories/
Mam nadzieję że to pomoże. Happy Coding!
źródło
git filter-branch --prune-empty --tree-filter ' if [ ! -e my/new/subdir ]; then mkdir -p my/new/subdir; git ls-tree --name-only $GIT_COMMIT | xargs -I files mv files my/new/subdir; fi'
Powiedzmy, że chcesz scalić repozytorium
a
dob
(jestem zakładając się znajdują obok siebie):Jeśli chcesz umieścić
a
w podkatalogu, wykonaj następujące czynności przed powyższymi poleceniami:Do tego trzeba
git-filter-repo
zainstalować (filter-branch
jest odradzane ).Przykład połączenia 2 dużych repozytoriów i umieszczenia jednego z nich w podkatalogu: https://gist.github.com/x-yuri/9890ab1079cf4357d6f269d073fd9731
Więcej na ten temat tutaj .
źródło