Git Clone: ​​Tylko pliki, proszę?

141

Chcę sklonować repozytorium GIT i NIE kończyć się .gitkatalogiem. Innymi słowy, chcę tylko pliki. Czy jest na to sposób?

git clone --no-checkoutzrobiłem dokładnie odwrotnie niż chciałem (dał mi tylko .gitkatalog).

Próbuję to zrobić dla zdalnego repozytorium, a nie lokalnego, co oznacza, że nie jest to duplikatJak zrobić„ eksport git ”(np.„ Eksport svn ”) ” (nawet jeśli rozwiązaniem może być podobnie).

Dan Rosenstark
źródło
@Greg Hewgill Próbuję to zrobić ze zdalnego repozytorium. Nie jestem jednak pewien, czy to czyni to pytanie wyjątkowym.
Dan Rosenstark
1
Chociaż jest to nowsze pytanie, ale myślę, że warto je sprawdzić: stackoverflow.com/questions/11497457/ ...
eonil
1
Zobacz moją odpowiedź dotyczącą aktualizacji : git archivejest teraz (IV kwartał 2017 r.) Bardziej precyzyjna i nie będzie zawierać pustych folderów.
VonC,
1
Zapraszamy. Najwyraźniej Twój komentarz został oznaczony i usunięty ... chat.stackoverflow.com/transcript/134259?m=39402889#39402889
VonC

Odpowiedzi:

75

Polecenie git, które byłoby najbliższe temu, czego szukasz, byłoby przez git archive.
Zobacz tworzenie kopii zapasowej projektu korzystającego z git : w archiwum umieści wszystkie pliki (w tym moduły podrzędne, jeśli używasz git-archive-allskryptu)

Następnie możesz użyć tego archiwum w dowolnym miejscu, zwracając tylko pliki, bez .gitkatalogu.

git archive --remote=<repository URL> | tar -t

Jeśli potrzebujesz folderów i plików tylko z pierwszego poziomu:

git archive --remote=<repository URL> | tar -t --exclude="*/*"

Aby wyświetlić tylko foldery pierwszego poziomu zdalnego repozytorium:

git archive --remote=<repository URL> | tar -t --exclude="*/*" | grep "/"

Uwaga: to nie działa dla GitHub (nie jest obsługiwane)

Musiałbyś więc sklonować (płytko, aby przyspieszyć krok klonowania), a następnie zarchiwizować lokalnie :

git clone --depth=1 [email protected]:xxx/yyy.git
cd yyy
git archive --format=tar aTag -o aTag.tar

Inną opcją byłoby wykonanie płytkiego klonu (jak wspomniano poniżej), ale zlokalizowanie folderu .git w innym miejscu.

git --git-dir=/path/to/another/folder.git clone --depth=1 /url/to/repo

Folder repo zawierałby tylko plik, bez .git.

Uwaga: git --git-dir jest opcją poleceniagit , nie git clone.


Aktualizacja za pomocą Git 2.14.X / 2.15 (Q4 2017): pozwoli to uniknąć dodawania pustych folderów .

" git archive", szczególnie gdy jest używany z pathspec, zapisał pusty katalog w swoim wyjściu, mimo że sam Git nigdy tego nie robi.
Zostało to naprawione.

Zobacz zatwierdzenie 4318094 (12 września 2017) autorstwa René Scharfe (``) .
Sugerowane przez: Jeff King ( peff) .
(Scalone przez Junio ​​C Hamano - gitster- w zatwierdzeniu 62b1cb7 , 25 września 2017 r.)

archive: nie dodawaj pustych katalogów do archiwów

Chociaż git nie śledzi pustych katalogów, git archivemożna go oszukać, aby umieścić niektóre z nich w archiwach.
Chociaż jest to obsługiwane przez obiektową bazę danych, nie może być reprezentowane w indeksie i dlatego jest mało prawdopodobne, aby wystąpiło w środowisku naturalnym.

Ponieważ puste katalogi nie są obsługiwane przez git, nie powinny być również zapisywane w archiwach.
Jeśli naprawdę potrzebny jest pusty katalog, można go śledzić i archiwizować, umieszczając w nim pusty .gitignoreplik.

VonC
źródło
4
To zadziałało dla mnie. Dodałbym jeszcze jedną rzecz. Jeśli w ogóle nie obchodzi cię folder .git, git --git-dir=/dev/null clone --depth=1 /url/to/repo
użyłbym
Nie usuwa to folderu .git
aliasav
@VonC Próbowałem: git --git-dir = / dev / null clone --depth = 1 / url / to / repo
aliasav
1
Uruchomiony git archive --remote=https://github.com/pornel/dssim.git @ | tar -totrzymuję tar: This does not look like a tar archive. Czy to nie działa z GitHubem? Co to @oznacza?
André Werlang
2
@ AndréWerlang 7 lat później ... Nie jestem pewien @: usunąłem go. Również GitHub nie obsługuje pilota git archive: zredagowałem odpowiedź, aby zaproponować alternatywę.
VonC,
59
git archive --format=tar --remote=<repository URL> HEAD | tar xf -

zaczerpnięte stąd

Jon Penn
źródło
2
--format=tarjest niepotrzebne. „tar” jest domyślnym wyjściem, nie trzeba go określać.
VasiliNovikov
1
Rurociąg do tar xwystarcza
Jens Bannmann
42

możesz utworzyć płytki klon, aby uzyskać tylko kilka ostatnich wersji:

 git clone --depth 1 git://url

następnie po prostu usuń katalog .git lub użyj go git archivedo wyeksportowania drzewa.

knittl
źródło
Jak zapobiec temu błędowi, gdy aktualizuję go, powtarzając klon: „fatal: ścieżka docelowa 'XYZ' już istnieje i nie jest pustym katalogiem.”
Sohail Si,
1
@SohailSi: albo sklonuj do nowej lokalizacji, albo usuń stary katalog. Prawdopodobnie lepiej będzie po prostu pobrać nowe wersje, jeśli chcesz zaktualizować swoją lokalną kopię.
knittl
3

Dlaczego nie wykonać klonu, a następnie usunąć plik .git katalog, aby mieć tylko kopię roboczą?

Edycja: A właściwie po co w ogóle używać klonowania? To trochę mylące, gdy mówisz, że chcesz repozytorium git, ale bez .gitkatalogu. Jeśli masz na myśli, że chcesz po prostu skopiować jakiś stan drzewa, to dlaczego nie zrobić cp -Rw powłoce zamiast klonu git, a następnie usunąć .gitpóźniej.

Andrzej
źródło
Dziękuję za to. Pliki znajdują się w repozytorium git. Miałem nadzieję, że uda mi się skierować użytkowników komputerów Mac do uzyskania kopii repozytorium w jednej linii, bez przekształcania się w repozytorium GIT.
Dan Rosenstark
Nie powinieneś mieć ludzi bezpośrednio pobierających kod z repozytorium, jeśli nie mogą go używać (tj. Nie mają repozytorium Git).
alternatywny
@Amoss Wydajesz archiwum tar, żeby ludzie nie pobierali ciągle najnowszego kodu?
alternatywny
1
@mathepic: i aby wypuścić archiwum, potrzebujesz sposobu na uzyskanie czystej kopii roboczej z repozytorium - i właśnie to zostało postawione pytanie.
Andrew,
1
Przeczytanie odpowiedzi poniżej, a następnie trochę googlowania doprowadziło do kolejnego pytania: stackoverflow.com/questions/160608/… Jeśli spojrzysz na użycie archiwum git --remote, robi dokładnie to, co Ty (i oryginalny plakat ) szuka. Edycja: oto, co Jon odpowiedział niżej.
Andrew,
2

Wygląda na to, że potrzebujesz tylko kopii kodu źródłowego. Jeśli tak, dlaczego po prostu nie skopiować katalogu i wykluczyć z kopii katalogu .git?

JaredPar
źródło
5
Właśnie o to pytam: jak to zrobić z gitem ... Jednak już mogę stwierdzić, że nie ma na to wbudowanego sposobu na podstawie odpowiedzi, które otrzymuję. W każdym razie dzięki!
Dan Rosenstark
2

git checkout -f

Można to zrobić w inny sposób, dzieląc repozytorium z drzewa roboczego.

Ta metoda jest przydatna, jeśli musisz regularnie aktualizować te pliki git bez git. Na przykład używam go, gdy muszę pobrać pliki źródłowe i zbudować artefakt, a następnie skopiować artefakt do innego repozytorium tylko w celu wdrożenia na serwer, a także używam go podczas wypychania kodu źródłowego na serwer, gdy chcę kod źródłowy do pobrania i wbudowania w katalog www.

Zrobimy dwa foldery, jeden dla git, drugi dla plików roboczych:

mkdir workingfiles
mkdir barerepo.git

zainicjuj nagie repozytorium git:

cd barerepo.git
git --bare init 

Następnie utwórz hak po odbiorze:

touch hooks/post-receive
chmod ug+x hooks/post-receive

Edytuj odbiór wiadomości w swoim ulubionym edytorze:

GIT_WORK_TREE=/path/to/workingfiles git checkout -f
# optional stuff:
cd down/to/some/directory
[do some stuff]

Dodaj to jako pilot:

git remote add myserver ssh://user@host:/path/to/barerepo.git

Teraz za każdym razem, gdy pchasz do tego samego repozytorium, pobierze ono drzewo robocze /workingfiles/. Ale /workingfiles/sam nie podlega kontroli wersji; uruchomiony git statusw /workingfiles/dadzą błądfatal: Not a git repository (or any parent up to mount point /data) . To tylko zwykłe pliki.

W przeciwieństwie do innych rozwiązań rm -r .gitpolecenie nie jest potrzebne, więc jeśli /workingfiles/jest jakieś inne repozytorium git, nie musisz się martwić o polecenie użyte do usunięcia plików git innego repozytorium.

Zatrzasnąć
źródło
1
Zgoda. Możliwy jest hak po odbiorze na gołym repozytorium. +1
VonC
dużo pracy, jeśli tylko próbujesz zdobyć pliki
Rainb
To nie jest dużo pracy, jeśli potrzebujesz tylko regularnie plików.
Slam