Jak wyciągnąć określony katalog za pomocą git

193

Mam projekt z git i chcę po prostu sklonować lub pobrać określony katalog, taki jak myproject / javascript, tak jak robi to subversion.
wprowadź zmiany, zatwierdź i wypchnij ponownie.
To jest możliwe?

bluefoot
źródło
3
rzadka realizacja transakcji może Cię zainteresować (nawet jeśli nadal musisz pobrać wszystko): patrz stackoverflow.com/questions/2416815/…
VonC

Odpowiedzi:

205
  1. na górze kopii repo
  2. git fetch
  3. git checkout HEAD path/to/your/dir/or/file

    • Gdzie „ path/...” w (3) zaczyna się w katalogu tuż poniżej katalogu głównego repozytorium zawierającego „ .../file

    • UWAGA: zamiast „HEAD” można użyć kodu skrótu określonego zatwierdzenia, a następnie otrzymasz wersję (plik) lub wersje (katalog) specyficzne dla tego zatwierdzenia.

vergueishon
źródło
1
Właśnie zdałem sobie sprawę, że źle zrozumiałem pytanie. Moja odpowiedź dotyczy natomiast sposobu pobrania pojedynczego pliku, który można następnie zmodyfikować i zatwierdzić.
vergueishon
Podszedłeś do tytułu pytania, które jest wystarczająco dobre. Właśnie mnie to uratowało, o ile mi wiadomo, to jest poprawna odpowiedź - zwłaszcza, że ​​było to hit Google w tym problemie.
Morgon,
21
Nadal dostaje to całe repo. W przypadku projektu o wielkości 2 GB nie oszczędza to dużo czasu.
Pithikos
5
Dla tych, którzy czytają te komentarze i nie wiedzą, jak to nie odpowiada na pytanie, to rozwiązanie daje kopię tylko jednego folderu, ale nie jest to kopia robocza, co oznacza, że ​​nie można modyfikować i ponownie -popełnić. Tak jak powiedział @Morgon, odnosi się do tytułu pytania (MOŻESZ pobrać tylko jeden katalog), ale nie odpowiada na treść pytania („dokonaj zmian, zatwierdź i odsuń”).
msb
@StanHolodnak --nie jest jednak wymagany. Wymusza to, że bity po nim będą interpretowane jako ścieżka. Tak więc, jeśli masz plik o nazwie --help, którą chcesz pobrać, wymagane będzie poprzedzenie go łącznikami:git checkout HEAD -- --help
Tim Visée
105

W pustym katalogu:

git init
git remote add [REMOTE_NAME] [GIT_URL]
git fetch REMOTE_NAME
git checkout REMOTE_NAME/BRANCH -- path/to/directory
szkocki
źródło
to działa, jeśli tylko chcesz używać pilota wersję pliku do zastąpienia lokalnego pliku, myślę
Jan
to również pociągnij folder, jak nie załadować folderu, ale tylko rzeczy w folderze?
Al Kasih
Nie ma potrzeby fetchani checkoutpoleceń, możemy po prostu wykonać polecenie ściągania za remote addpoleceniem, aby uzyskać całą gałąź master.
Iqra.
2
Jak wskazuje Pithkos w zaakceptowanej odpowiedzi, ta odpowiedź spowoduje również pobranie CAŁEGO zdalnego repozytorium na komputer lokalny. odpowiedź shingary jest najbardziej jasna - nie ma sposobu na zdalne wykonanie części repo. Jednak dla tych, którzy nie przeszkadzają w przepustowości CAŁEGO pobierania i są zainteresowani zrobieniem kopii roboczej części lokalnej pamięci podręcznej, wówczas zaakceptowana odpowiedź pokazuje, jak to zrobić. Chcę tylko wyjaśnić, że całą historię repozytorium (w skompresowanym formacie) należy pobrać na komputer.
Gabe Halsmer
39

Po wielu poszukiwaniach odpowiedzi, nie znajdowaniu, rezygnacji, ponownym próbowaniu itd., W końcu znalazłem rozwiązanie tego problemu w innym wątku SO:

Jak wyciągnąć wszystkie foldery oprócz jednego

Aby skopiować i wkleić to, co tam jest:

git init
git remote add -f origin <url>
git config core.sparsecheckout true
echo <dir1>/ >> .git/info/sparse-checkout
echo <dir2>/ >> .git/info/sparse-checkout
echo <dir3>/ >> .git/info/sparse-checkout
git pull origin master

Aby zrobić to, czego chce OP (pracować tylko z jednym katalogiem), po prostu dodaj ten jeden katalog .git/info/sparse-checkout, wykonując powyższe kroki.

Ogromne podziękowania dla @cforbish!

msb
źródło
2
Publikuję go tutaj głównie dlatego, że za każdym razem, gdy próbuję google, jak to zrobić, jest to najlepszy wynik, a ten wątek nie jest nawet bliski wyświetlenia. :( Czuję się źle wklejanie i kopiowanie, ale uważam, że to TAK najlepsze praktyki?
msb
1
To jedyne czyste rozwiązanie. Próbowałem odpowiedzi powyżej. Po sprawdzeniu mojej gałęzi z innymi odpowiedziami nie mogłem pobrać i miałem kilka nowych plików, które wymagały zatwierdzenia. Dzięki temu rozwiązaniu wszystko wygląda poprawnie. Ale UWAGA: Bez względu na gałąź, która została sprawdzona, git pomyśli, że jesteś master. Tylko upewnij się, że robisz git branch --set-upstream-to=origin/<branch>to poprawnie
seebiscuit
12

To nie jest możliwe. Musisz wyciągnąć całe repozytorium lub nic.

shingara
źródło
1
Nawet jeśli musisz pobrać wszystko, czy w tym przypadku interesujące byłoby przyciągnięcie rzadkiego drzewa roboczego kasy? Zobacz stackoverflow.com/questions/2416815/…
VonC
10
Wystarczy dodać, że powodem, dla którego nie można wyciągnąć tylko katalogu, jest to, że git korzysta ze śledzenia semantycznego danych, a nie ze śledzenia semantycznego pliku, dzięki czemu można bezproblemowo przenosić kod (lub inne dane) do i z plików bez konieczności podawania źródła system śledzenia (dopóki oczywiście nie zaktualizujesz). Z tego powodu kod może płynnie wchodzić i wychodzić z katalogów, więc pobieranie tylko jednego katalogu nie ma większego sensu. Mam nadzieję że to pomoże.
OmnipotentEntity
12
@OmnipotentEntity Przepraszamy, ale IMHO ma sens. Implementacja nie powinna ograniczać użycia. Git wie, jakie są katalogi (przynajmniej podczas tworzenia lokalnej kopii roboczej), więc nie ma powodu, aby nie mógł wykonać podobnej operacji na serwerze i po prostu wysłać odpowiednie dane wyjściowe. To prawda, że ​​nie jest to obecnie zaimplementowane, ale wynika to z braku funkcji, a nie fundamentalnej niemożliwości. Osobiście uważam, że jest to dość ważna funkcja, ale hej, to jeden z powodów, dla których unikam gita, gdy jest to możliwe.
Podstawowy
10

Może to polecenie może być pomocne:

git archive --remote=MyRemoteGitRepo --format=tar BranchName_or_commit  path/to/your/dir/or/file > files.tar

"Zrobione"

fabrice belle
źródło
2
Spowoduje to pobranie określonego katalogu pliku do celów archiwizacji, a nie pobranie kopii, którą można zmodyfikować i odepchnąć.
leetNightshade
Bardzo fajny. Prawdopodobnie nie do zaakceptowania jako rozwiązanie OP, ale tak naprawdę chciałem, ponieważ muszę po prostu przeszukać zawartość dużego folderu w jeszcze większym repozytorium, którego zdecydowanie nie chcę pobierać i nie muszę modyfikować / Pchać.
Oliver
7

Jeśli chcesz uzyskać najnowsze zmiany w katalogu bez wprowadzania go, możesz:

$ git -C <Path to directory> pull
feralamillo
źródło
4

git clone --filter z Git 2.19

Ta opcja faktycznie pomija pobieranie niepotrzebnych obiektów z serwera.

Napisałem szczegółową odpowiedź wyjaśniającą aktualny status wsparcia na: Jak sklonować podkatalog tylko repozytorium Git?

Jest bardzo prawdopodobne, że wszystko, co zostanie wdrożone git clonew tym obszarze, będzie miało git pullanalogi.

Ciro Santilli
źródło
1

Wypróbowałem i przetestowałem to działa!

mkdir <directory name> ;  //Same directory name as the one you want to pull
cd <directory name>;
git remote add origin <GIT_URL>;
git checkout -b '<branch name>';
git config core.sparsecheckout true;
echo <directory name>/ >> .git/info/sparse-checkout;
git pull origin <pull branch name>

Mam nadzieję, że to było pomocne!

Nnaik
źródło
0

Czasami chcesz po prostu spojrzeć na poprzednie kopie plików bez rygoru przechodzenia przez diffs.

W takim przypadku równie łatwo jest utworzyć klon repozytorium i sprawdzić konkretne zatwierdzenie, które Cię interesuje i zajrzeć do podkatalogu w tym sklonowanym repozytorium. Ponieważ wszystko jest lokalne, możesz po prostu usunąć ten klon po zakończeniu.

Abizern
źródło
-1

Dla wszystkich tych zmagań z teoretycznymi ścieżkami plików i przykładami, tak jak ja, oto przykład ze świata rzeczywistego: Microsoft oferuje swoje dokumenty i przykłady w git hub, niestety zbierają wszystkie swoje przykładowe pliki dla dużej liczby tematów w tym repozytorium:

https://github.com/microsoftarchive/msdn-code-gallery-community-s-z

Byłem zainteresowany tylko plikami Microsoft Dynamics js na ścieżce

msdn-code-gallery-community-s-z/Sdk.Soap.js/

więc zrobiłem następujące

Stwórz

msdn-code-gallery-community-s-zSdkSoapjs\.git\info\sparse-checkout

plik w folderze moich repozytoriów na dysku

git sparse-checkout init

w tym katalogu za pomocą polecenia cmd w systemie Windows

Zawartość pliku

msdn-code-gallery-community-s-zSdkSoapjs\.git\info\sparse-checkout

jest

Sdk.Soap.js/*

w końcu zrobić

git pull origin master
DM
źródło