Jak mogę cofnąć podmoduł git (przywrócić cały kod z powrotem do rdzenia)?
Jak w „jak” powinienem, tak jak w „Najlepszej procedurze” ...
git
git-submodules
Quickredfox
źródło
źródło
git submodule deinit
, patrz moja odpowiedź poniżejgit submodule deinit asubmodule ; git rm asubmodule
wystarczy prosty , jak pokazano w mojej odpowiedzi poniżejOdpowiedzi:
Jeśli wszystko, czego chcesz, to umieścić kod submodułu w głównym repozytorium, wystarczy usunąć submoduł i ponownie dodać pliki do głównego repozytorium:
Jeśli chcesz również zachować historię podmodułu, możesz zrobić małą sztuczkę: „scal” podmoduł z głównym repozytorium, aby wynik był taki sam jak wcześniej, z tym że pliki podmodułów znajdują się teraz w główne repozytorium.
W głównym module musisz wykonać następujące czynności:
Powstałe repozytorium będzie wyglądać nieco dziwnie: będzie więcej niż jedno wstępne zatwierdzenie. Ale to nie spowoduje żadnych problemów dla git.
W tym drugim rozwiązaniu będziesz miał dużą zaletę, że nadal możesz uruchamiać git blame lub git log na plikach, które pierwotnie były w submodułach. W rzeczywistości zmieniłeś nazwę wielu plików w jednym repozytorium i git powinien to automatycznie wykryć. Jeśli nadal masz problemy z git logiem, wypróbuj kilka opcji (--follow, -M, -C), które lepiej wykrywają zmianę nazwy / kopiowanie.
źródło
git merge
zapewnia, że dla każdego pliku będzie „poprzednie zatwierdzenie” (po jednej z dwóch „stron” scalenia).mkdir foo && git mv !(foo) foo && git commit
.--allow-unrelated-histories
aby wymusić scalanie podczas fałszywego scalania, gdy się dostawałemfatal: refusing to merge unrelated histories
, więcej tutaj: github.com/git/git/blob/master/Documentation/RelNotes/…Od wersji git 1.8.5 (listopad 2013 ) ( bez przechowywania historii submodułu ):
To będzie:
deinit
stądmv
pierwszy ),.gitmodules
dla ciebie (rm
),rm
).Po zakończeniu usuwania submodułu (
deinit
igit rm
) możesz zmienić nazwę folderu z powrotem na jego pierwotną nazwę i dodać go do repozytorium git jako zwykłego folderu.Uwaga: jeśli modułem został stworzony przez starego Git (<1,8), może być konieczne, aby usunąć zagnieżdżony
.git
folder, w samym modułem, jak skomentował przez Simona WschodzieJeśli trzeba zachować historię modułem, patrz jsears „s odpowiedź , który korzysta
git filter-branch
.źródło
deinit
sam wyczyściłeś działające drzewo ze swojego podmodułu?Stworzyłem skrypt, który przetłumaczy submoduł do prostego katalogu, zachowując całą historię plików. Nie ma
git log --follow <file>
problemów z innymi rozwiązaniami. Jest to również bardzo łatwe wywołanie jednowierszowe, które wykonuje całą pracę za Ciebie. Chodź.Opiera się na doskonałej pracy Lucasa Jenßa, opisanej w jego blogu „ Integracja submodułu w repozytorium nadrzędnym ”, ale automatyzuje cały proces i oczyszcza kilka innych przypadków narożnych.
Najnowszy kod będzie utrzymywany z poprawkami błędów w github na https://github.com/jeremysears/scripts/blob/master/bin/git-submodule-rewrite , ale ze względu na odpowiedni protokół odpowiedzi stackoverflow, zawarłem rozwiązanie w całości poniżej.
Stosowanie:
git-submodule-rewrite:
źródło
curl https://raw.githubusercontent.com/jeremysears/scripts/master/bin/git-submodule-rewrite > git-submodule-rewrite.sh
i./git-submodule-rewrite.sh <submodule-name>
git rm --cached the_submodule_path
.gitmodules
pliku lub, jeśli jest to jedyny submoduł, usuń plik.git add the_submodule_path
Nie znalazłem jeszcze łatwiejszego sposobu. Możesz skompresować 3-5 w jeden krok
git commit -a
- kwestia smaku.źródło
.gitmodules
zamiast.submodules
?.gitmodules
nie.submodules
.git
katalog submodułu, zanim zacznęgit add
pracować z folderem submodułuWiele odpowiedzi tutaj, ale wszystkie wydają się zbyt skomplikowane i prawdopodobnie nie robią tego, co chcesz. Jestem pewien, że większość ludzi chce zachować swoją historię.
W tym przykładzie będzie to repozytorium główne
[email protected]:main/main.git
i repozytorium submodułu[email protected]:main/child.git
. Zakłada się, że podmoduł znajduje się w katalogu głównym repozytorium nadrzędnego. Dostosuj instrukcje w razie potrzeby.Zacznij od klonowania repozytorium nadrzędnego i usunięcia starego podmodułu.
Teraz dodamy repozytorium potomne w górę do repozytorium głównego.
W następnym kroku założono, że chcesz przenieść pliki z gałęzi scalania do tej samej lokalizacji, co podmoduł powyżej, chociaż możesz łatwo zmienić lokalizację, zmieniając ścieżkę pliku.
przenieś wszystkie foldery i pliki oprócz folderu .git do folderu podrzędnego.
Teraz możesz po prostu scalić swoje pliki z powrotem w gałęzi master.
Rozejrzyj się i upewnij się, że wszystko wygląda dobrze przed uruchomieniem
git push
Jedyną rzeczą, którą musisz teraz zapamiętać, jest to, że git log domyślnie nie śledzi przeniesionych plików, jednak po uruchomieniu
git log --follow filename
możesz zobaczyć pełną historię swoich plików.źródło
git merge merge-prep
i otrzymałem błądfatal: refusing to merge unrelated histories
. Obejście to:git merge --allow-unrelated-histories merge-prep
.child
katalogu, więc nie musisz ich przenosić później? Mam takie same nazwy plików w podmodule i głównym repozytorium ... więc dostaję konflikt scalania, ponieważ próbuje połączyć dwa pliki razem.Zdarzyło się nam, że stworzyliśmy 2 repozytoria dla 2 projektów, które były tak połączone, że rozdzielenie ich nie miało sensu, więc połączyliśmy je.
Pokażę, jak połączyć główne gałęzie w każdej z nich, a następnie wyjaśnię, jak możesz to rozszerzyć na każdą otrzymaną gałąź, mam nadzieję, że to ci pomoże.
Jeśli podmoduł działa i chcesz przekonwertować go na katalog w miejscu, możesz:
Tutaj robimy czysty klon do pracy. W tym procesie nie musisz inicjować ani aktualizować submodułów, więc po prostu go pomiń.
Edytuj za
.gitmodules
pomocą swojego ulubionego edytora (lub Vima), aby usunąć submoduł, który planujesz zastąpić. Linie, które musisz usunąć, powinny wyglądać mniej więcej tak:Po zapisaniu pliku
Tutaj całkowicie usuwamy relację podmodułu, abyśmy mogli stworzyć drugą repozytorium w projekcie.
Tutaj pobieramy repozytorium submodułu do scalenia.
Tutaj rozpoczynamy operację scalania 2 repozytoriów, ale zatrzymujemy się przed zatwierdzeniem.
Tutaj wysyłamy zawartość wzorca w podmodule do katalogu, w którym była przed prefiksem nazwy katalogu
Tutaj kończymy procedurę zatwierdzając zmiany w scalaniu.
Po zakończeniu możesz pchać i zaczynać od innej gałęzi w celu scalenia, po prostu sprawdź gałąź w swoim repozytorium, która otrzyma zmiany i zmieni gałąź, którą wprowadzasz w operacjach scalania i odczytu.
źródło
directory_of_submodule
git log original_path_of_file_in_submodule
np. ścieżkę zarejestrowaną w repozytorium git dla pliku (który już nie istnieje w systemie plików), mimo że plik submodułu teraz mieszka wsubmodule_path/new_path_of_file
Najlepsza odpowiedź na to, którą znalazłem, jest tutaj:
http://x3ro.de/2013/09/01/Integrating-a-submodule-into-the-parent-repository.html
W tym artykule bardzo dobrze wyjaśniono tę procedurę.
źródło
Oto nieco ulepszona wersja (IMHO) odpowiedzi @ gyim. Dokonuje wielu niebezpiecznych zmian w głównej kopii roboczej, gdzie myślę, że o wiele łatwiej jest operować na oddzielnych klonach, a następnie scalić je na końcu.
W osobnym katalogu (aby ułatwić usuwanie błędów i spróbuj ponownie), sprawdź zarówno najlepsze repozytorium, jak i subrepo.
Najpierw edytuj subrepo, aby przenieść wszystkie pliki do żądanego podkatalogu
Zanotuj HEAD
Teraz usuń subrepo z głównego repozytorium
I w końcu po prostu je połącz
I zrobione! Bezpiecznie i bez magii.
źródło
subrepo
z zawartością ?git merge $SUBREPO_HEAD fatal: refusing to merge unrelated histories
Czy powinienem użyćgit merge $SUBREPO_HEAD --allow-unrelated-histories
w tym przypadku? A może powinien działać bez i popełniłem błąd?Do kiedy
zwroty
Kontekst: Zrobiłem to
rm -r .git*
w folderach submodułów, zanim zdałem sobie sprawę, że trzeba je zdekodulodować w głównym projekcie, do którego właśnie je dodałem. Wystąpił powyższy błąd podczas usuwania niektórych modeli, ale nie wszystkich. W każdym razie naprawiłem je, uruchamiając (po, oczywiścierm -r .git*
)Pamiętaj, że to nie zachowuje historii.
źródło
Na podstawie odpowiedzi VonC stworzyłem prosty skrypt bash, który to robi. Na
add
końcu należy użyć symboli wieloznacznych, w przeciwnym razie cofnie poprzednierm
dla samego podmodułu. Ważne jest, aby dodać zawartość katalogu submodułu, a nie nazywać samego katalogu wadd
poleceniu.W pliku o nazwie
git-integrate-submodule
:źródło
Uważam, że wygodniej jest (również?) Pobierać dane lokalnego zatwierdzenia z podmodułu, ponieważ w przeciwnym razie straciłbym je. (Nie można ich wypchnąć, ponieważ nie mam dostępu do tego pilota). Więc dodałem submodule / .git jako remote_origin2, ściągnąłem commits i połączyłem z tej gałęzi. Nie jestem pewien, czy nadal potrzebuję zdalnego modułu podrzędnego jako źródła, ponieważ nie znam jeszcze git.
źródło
Oto, co uważam za najlepsze i najprostsze.
W repozytorium submodułowym HEAD chcesz scalić w repozytorium główne:
git checkout -b "mergeMe"
mkdir "foo/bar/myLib/"
(identyczna ścieżka jak w przypadku plików na głównym repozytorium)git mv * "foo/bar/myLib/"
(przenieś wszystko na ścieżkę)git commit -m "ready to merge into main"
Powrót do głównego repozytorium po usunięciu podmodułu i wyczyszczeniu ścieżki „foo / bar / myLib”:
git merge --allow-unrelated-histories SubmoduleOriginRemote/mergeMe
boom zrobiony
historie zachowane
bez obaw
Zauważ, że prawie identyczne z niektórymi innymi odpowiedziami. Ale zakłada to, że posiadasz repozytorium submodułu. Ułatwia to także uzyskanie przyszłych zmian dla podmodułu.
źródło