Jaka jest najlepsza praktyka „klonowania gita” w istniejącym folderze?
479
Mam kopię roboczą projektu, bez metadanych kontroli źródła. Teraz chciałbym zrobić odpowiednik git-clone w tym folderze i zachować moje lokalne zmiany.
git-clone nie pozwala mi klonować do istniejącego folderu. Jaka jest tutaj najlepsza praktyka?
@ ripper234 - Tak. Byłem w tej samej sytuacji i po prostu zrobiłem te kroki i żadnych problemów. Wszystko czyste i miłe. Wydaje mi się, że to kwestia preferencji. Najważniejsze jest to, że oba działają, jak twierdzisz. Twoje zdrowie.
MEM
1
Jest to tak szalone, że nie ma czystego sposobu na osiągnięcie tego, tak przydatnego, gdy chcesz sklonować projekt do zamontowanego folderu współdzielonego.
Zauważ, że jest to dokładnie sugestia @ChrisJohnsen pozostawiona w komentarzach. Uznałem, że jest to przydatne i chciałem zrobić z niego prawdziwą odpowiedź. Chris, jeśli w końcu znajdziesz odpowiedź, chętnie ją usunę.
amicitas,
2
Dzięki! Chociaż brakuje w tym kroku „git Checkout -”. ponieważ uważa, że wszystkie pliki zostały usunięte, prawda?
mrooney,
2
Nie, dopóki użyjesz git clonejako pierwszego polecenia, dalsze polecenie pobierania nie jest konieczne. Jeśli zamiast tego użyjesz czegoś takiego jak git clone --no-checkoutw pierwszym kroku, po przeniesieniu katalogu .git konieczne będzie użycie git reset HEADpolecenia poinformowania gita, że pliki nie zostały usunięte.
amicitas
3
Dodałbym to jako trzeci krok: mv temp / .gitignore code / .gitignore
Daniel Aranda
1
@KalpeshSoni, tak git będzie wiedział o zmodyfikowanych plikach i będzie można zobaczyć zmiany za pomocą normalnych poleceń git, takich jak git status.
Następnie możesz zresetować drzewo, aby uzyskać żądane zatwierdzenie:
git reset origin/master # or whatever commit you think is proper...
i jesteś jak sklonowany.
Interesujące pytanie tutaj (i jedno bez odpowiedzi): jak dowiedzieć się, na którym podstawie opierało się twoje nagie drzewo, a zatem na której pozycji zresetować.
Nie jestem fanem tego - według konfiguracji github „Wskazówka: Pomocnik poświadczeń działa tylko po sklonowaniu adresu URL repozytorium HTTPS”. Używałem pomocnika uwierzytelnienia, co posłało mnie do długiej, dość bezowocnej nory królika.
Andrew
5
„git checkout --track origin / master” również działa dobrze zamiast „git checkout -b master --track origin / master”. Reset nie jest potrzebny.
felipecrp
1
Pojawił się błąd „Błąd Git: Następujące nieśledzone działające pliki drzewa zostaną nadpisane przez kasę”, więc dodaję to polecenie: git clean -d -fx "”
shakaran
1
zdecydowanie nie wskazane we wszystkich sytuacjach, ale właśnie tego potrzebowałem.
Chaim Eliyah
1
@AndreasKrey Twoja oryginalna odpowiedź (którą przeszedłem do historii edycji) zawiera dokładnie to, czego potrzebuje pytanie (i ja). Zmienione paski odpowiedzi przy kasie bez użycia opcji -f, która odrzuca lokalne zmiany i jest dokładnie tym, czego nie chcę. Gdybym był tobą, rozważyłbym przywrócenie oryginalnej odpowiedzi.
Ajean
77
Wykonałem następujące czynności, aby dokonać transakcji oddziału master w istniejącym katalogu:
jeśli to zrobisz, upewnij się, że dokładnie sprawdziłeś różnicę przed zatwierdzeniem - jest to absolutnie klasyczny przypadek, w którym możesz przypadkowo przywrócić zmiany wprowadzone w repozytorium źródłowym od czasu otrzymania kopii roboczej - ponieważ nie ma wystarczających informacji w kopii roboczej, aby dowiedzieć się, jakie zmiany wprowadziłeś, a jak to było przed rozpoczęciem wprowadzania zmian, aby połączyć się z innymi zmianami wprowadzonymi w repozytorium. Widziałem to wielokrotnie w tej sytuacji, do tego stopnia, że „mocno zniechęcałem” siebie i ludzi, z którymi współpracowałem, od zrobienia tego.
Ben Clifford
72
git clone wherever tmp && git mv tmp/.git . && rm -rf tmpInnymi słowy, przeniesienie katalogu .gitpoza tymczasowy klon wydaje się prostsze niż wyczyszczenie działającego drzewa klonowania i skopiowanie tam istniejących plików.
Chris Johnsen
1
@ChrisJohnsen: powinieneś był znaleźć odpowiedź, to zdecydowanie najlepszy sposób, aby to zrobić imho
Stefano
2
@ChrisJohnsen git mv tmp/.git .wraca fatal: cannot move directory over file, source=tmp/.git, destination=.gitpo mnie. Czy ktoś wie, na czym polega problem?
Dennis,
6
@Dennis, To literówka: to polecenie powinno być proste mv, a nie git mv; chociaż to nie wyjaśnia, dlaczego masz .gitjuż plik (zawierający gitdir: some/path/to/a/git-dir„gitfile”; gdyby go nie było, zobaczyłbyś fatal: Not a git repository (or any of the parent directories): .gitzamiast tego).
Chris Johnsen,
34
Korzystanie z katalogu tymczasowego jest w porządku, ale zadziała, jeśli chcesz uniknąć tego kroku. Z katalogu głównego katalogu roboczego:
git reset --hard origin/masterusunie wszystkie lokalne pliki.
Mouad Debbar
1
aby dodać do tego, co już wskazano powyżej, różnica między hardi mixedpolega na tym, że mieszane zachowa zmiany lokalne (więc jeśli spróbujesz później go wyciągnąć, pokaże Ci np. Nie można wyciągnąć z rebase: masz zmiany niestabilne. Zatwierdź je lub ukryj ) , podczas gdy twardy odrzuci te lokalne zmiany
Istnieją dwa podejścia do tego. Jeśli to możliwe, zacznę od czystego folderu dla nowego katalogu roboczego git, a następnie skopiuję twoją wersję rzeczy później. Może to wyglądać jak *:
W tym momencie powinieneś mieć całkiem czystą kopię roboczą z poprzednim folderem roboczym jako bieżącym katalogiem roboczym, więc wszelkie zmiany obejmujące usunięcie plików pojawią się na radarze, jeśli uruchomisz git status.
Z drugiej strony, jeśli naprawdę musisz to zrobić na odwrót, możesz uzyskać ten sam wynik z czymś takim:
cd $dir
git clone --no-checkout $url tempdir
mv tempdir/.git .
rmdir tempdir
git reset --mixed HEAD
Tak czy inaczej, pierwszą rzeczą, którą chciałbym zrobić, to uruchomić coś takiego, git stashaby uzyskać kopię wszystkich lokalnych zmian odłożonych na bok, a następnie możesz je ponownie zastosować i przeanalizować, które z nich chcesz popełnić.
* Oba przykłady zakładają, że zaczynasz od powłoki w katalogu nadrzędnym swojego projektu.
--mirrorsprawia, że nowy klon w folderze jako czysto metadanych .gitmusi być
--config core.bare=falsecountermands niejawny bare=truez --mirroropcji, umożliwiając tym samym repozytorium mieć skojarzony katalog roboczy i działać jak normalny klonu
To oczywiście nie zadziała, jeśli .gitkatalog metadanych już istnieje w katalogu, który chcesz przekształcić w kopię roboczą.
Zauważ, że ta technika zaowocuje [core]sekcją konfiguracji lokalnej obejmującą zarówno bare = trueibare = false . Bardziej problematyczne jest to, że będzie miał niepoprawne wartości dla originpilota, wraz z [remote "origin"]sekcją zawierającą mirror = truespecyfikację pobierania, która nie będzie działać poprawnie z kopią roboczą. Po rozwiązaniu tych problemów klonowanie normalnie i przenoszenie nowych kopii roboczych .gitbędzie bardziej wydajne.
Araxia
0
Zwykle najpierw sklonuję pierwsze repozytorium, a następnie przeniosę wszystko z istniejącego folderu do początkowego repozytorium. Działa za każdym razem.
Zaletą tej metody jest to, że nie przegapisz niczego z początkowego repozytorium, w tym README lub .gitignore.
Możesz także użyć poniższego polecenia, aby zakończyć kroki:
Możesz to zrobić, wpisując rekurencyjnie następujące wiersze poleceń:
mkdir temp_dir // Create new temporary dicetory named temp_dir
git clone https://www...........git temp_dir // Clone your git repo inside it
mv temp_dir/* existing_dir // Move the recently cloned repo content from the temp_dir to your existing_dir
rm -rf temp_dir // Remove the created temporary directory
Odpowiedzi:
Można to zrobić poprzez klonowanie do nowego katalogu, a następnie przeniesienie
.git
katalogu do istniejącego katalogu.Jeśli twój istniejący katalog nosi nazwę „kod”.
Można to również zrobić bez robienia kasy podczas polecenia klonowania; więcej informacji można znaleźć tutaj .
źródło
git clone
jako pierwszego polecenia, dalsze polecenie pobierania nie jest konieczne. Jeśli zamiast tego użyjesz czegoś takiego jakgit clone --no-checkout
w pierwszym kroku, po przeniesieniu katalogu .git konieczne będzie użyciegit reset HEAD
polecenia poinformowania gita, że pliki nie zostały usunięte.git status
.Nie klonuj, pobierz zamiast. W repozytorium:
Następnie możesz zresetować drzewo, aby uzyskać żądane zatwierdzenie:
i jesteś jak sklonowany.
Interesujące pytanie tutaj (i jedno bez odpowiedzi): jak dowiedzieć się, na którym podstawie opierało się twoje nagie drzewo, a zatem na której pozycji zresetować.
źródło
Wykonałem następujące czynności, aby dokonać transakcji oddziału master w istniejącym katalogu:
źródło
-t
użyto tu flagi?Przejdę
git clone
do nowego katalogu i skopiuję zawartość istniejącego katalogu do nowego klonu.źródło
git clone wherever tmp && git mv tmp/.git . && rm -rf tmp
Innymi słowy, przeniesienie katalogu.git
poza tymczasowy klon wydaje się prostsze niż wyczyszczenie działającego drzewa klonowania i skopiowanie tam istniejących plików.git mv tmp/.git .
wracafatal: cannot move directory over file, source=tmp/.git, destination=.git
po mnie. Czy ktoś wie, na czym polega problem?mv
, a niegit mv
; chociaż to nie wyjaśnia, dlaczego masz.git
już plik (zawierającygitdir: some/path/to/a/git-dir
„gitfile”; gdyby go nie było, zobaczyłbyśfatal: Not a git repository (or any of the parent directories): .git
zamiast tego).Korzystanie z katalogu tymczasowego jest w porządku, ale zadziała, jeśli chcesz uniknąć tego kroku. Z katalogu głównego katalogu roboczego:
źródło
git reset --hard origin/master
usunie wszystkie lokalne pliki.hard
imixed
polega na tym, że mieszane zachowa zmiany lokalne (więc jeśli spróbujesz później go wyciągnąć, pokaże Ci np. Nie można wyciągnąć z rebase: masz zmiany niestabilne. Zatwierdź je lub ukryj ) , podczas gdy twardy odrzuci te lokalne zmianyźródło
git reset --hard
spowoduje zmianę lokalnych plików, szczególnie NIE o to poprosił ten OP.--mixed
należy zamiast tego użyć.Aby sklonować repozytorium git w pustym istniejącym katalogu, wykonaj następujące czynności:
Zwróć uwagę
.
na koniecgit clone
polecenia. Spowoduje to pobranie repozytorium do bieżącego katalogu roboczego.źródło
fatal: destination path '.' already exists and is not an empty directory.
Wiele odpowiedzi już na to, tak jak chciał PO. Warto jednak zauważyć, że robienie tego w drugą stronę jest znacznie prostsze:
Masz teraz pożądany stan docelowy - świeży klon + lokalne zmiany.
źródło
Istnieją dwa podejścia do tego. Jeśli to możliwe, zacznę od czystego folderu dla nowego katalogu roboczego git, a następnie skopiuję twoją wersję rzeczy później. Może to wyglądać jak *:
W tym momencie powinieneś mieć całkiem czystą kopię roboczą z poprzednim folderem roboczym jako bieżącym katalogiem roboczym, więc wszelkie zmiany obejmujące usunięcie plików pojawią się na radarze, jeśli uruchomisz
git status
.Z drugiej strony, jeśli naprawdę musisz to zrobić na odwrót, możesz uzyskać ten sam wynik z czymś takim:
Tak czy inaczej, pierwszą rzeczą, którą chciałbym zrobić, to uruchomić coś takiego,
git stash
aby uzyskać kopię wszystkich lokalnych zmian odłożonych na bok, a następnie możesz je ponownie zastosować i przeanalizować, które z nich chcesz popełnić.* Oba przykłady zakładają, że zaczynasz od powłoki w katalogu nadrzędnym swojego projektu.
źródło
To najlepsza ze wszystkich metod, jakie spotkałem
Sklonuj tylko folder .git repozytorium (wyłączając pliki, które już są w folderze
existing-dir
) do pustego katalogu tymczasowegogit clone --no-checkout repo-path-to-clone existing-dir/existing-dir.tmp
// może chcieć --no-hardlinks do klonowania lokalnego repozytoriumPrzenieś folder .git do katalogu z plikami. To sprawia, że
existing-dir
repozytorium git.mv existing-dir/existing-dir.tmp/.git existing-dir/
Usuń katalog tymczasowy
rmdir existing-dir/existing-dir.tmp
cd existing-dir
Git uważa, że wszystkie pliki zostały usunięte, co przywraca stan repozytorium do HEAD.
UWAGA: wszelkie lokalne zmiany w plikach zostaną utracone.
git reset --mixed HEAD
źródło
Jeśli używasz co najmniej git 1.7.7 (który nauczył się
clone
tej--config
opcji), aby zmienić bieżący katalog w kopię roboczą:Działa to przez:
.git
folderze--mirror
sprawia, że nowy klon w folderze jako czysto metadanych.git
musi być--config core.bare=false
countermands niejawnybare=true
z--mirror
opcji, umożliwiając tym samym repozytorium mieć skojarzony katalog roboczy i działać jak normalny klonuTo oczywiście nie zadziała, jeśli
.git
katalog metadanych już istnieje w katalogu, który chcesz przekształcić w kopię roboczą.źródło
[core]
sekcją konfiguracji lokalnej obejmującą zarównobare = true
ibare = false
. Bardziej problematyczne jest to, że będzie miał niepoprawne wartości dlaorigin
pilota, wraz z[remote "origin"]
sekcją zawierającąmirror = true
specyfikację pobierania, która nie będzie działać poprawnie z kopią roboczą. Po rozwiązaniu tych problemów klonowanie normalnie i przenoszenie nowych kopii roboczych.git
będzie bardziej wydajne.Zwykle najpierw sklonuję pierwsze repozytorium, a następnie przeniosę wszystko z istniejącego folderu do początkowego repozytorium. Działa za każdym razem.
Zaletą tej metody jest to, że nie przegapisz niczego z początkowego repozytorium, w tym README lub .gitignore.
Możesz także użyć poniższego polecenia, aby zakończyć kroki:
źródło
Możesz to zrobić, wpisując rekurencyjnie następujące wiersze poleceń:
źródło
Po prostu użyj. na końcu
git clone
polecenia (znajdującego się w tym katalogu), jak poniżej:źródło