Git Clone: ​​Nur die Dateien, bitte?

141

Ich möchte ein GIT-Repo klonen und NICHT mit einem .gitVerzeichnis enden . Mit anderen Worten, ich möchte nur die Dateien. Gibt es eine Möglichkeit, dies zu tun?

git clone --no-checkouttat genau das Gegenteil von dem, was ich will (gab mir nur das .gitVerzeichnis).

Ich versuche dies für ein Remote- Repo zu tun , nicht für ein lokales, was bedeutet, dass dies kein Duplikat ist von " Wie man einen" Git-Export "(wie" SVN-Export ") macht " ist (obwohl die Lösung möglicherweise die ist gleich).

Dan Rosenstark
quelle
5
mögliches Duplikat von Wie man einen "Git-Export" macht (wie "SVN-Export")
Greg Hewgill
@ Greg Hewgill Ich versuche dies von einem Remote-Repo aus zu tun. Ich bin mir jedoch nicht sicher, ob dies diese Frage einzigartig macht.
Dan Rosenstark
1
Dies ist zwar eine neuere Frage, aber ich denke, dies ist einen Blick
eonil
1
Siehe meine Update-Antwort : git archiveIst jetzt (4. Quartal 2017) genauer und enthält keine leeren Ordner.
VonC
1
Bitte schön. Anscheinend wurde Ihr Kommentar markiert und entfernt ... chat.stackoverflow.com/transcript/134259?m=39402889#39402889
VonC

Antworten:

75

Der git-Befehl, der dem, was Sie suchen, am nächsten kommt, würde von git archive.
Siehe Sichern eines Projekts, das git verwendet : Es enthält alle Dateien in einem Archiv (einschließlich Submodule, wenn Sie das git-archive-allSkript verwenden).

Sie können dieses Archiv dann überall verwenden und nur Dateien und kein .gitVerzeichnis zurückgeben.

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

Wenn Sie Ordner und Dateien nur von der ersten Ebene benötigen:

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

So listen Sie nur Ordner der ersten Ebene eines Remote-Repos auf:

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

Hinweis: Das funktioniert nicht für GitHub (nicht unterstützt)

Sie müssten also klonen (flach, um den Klonschritt zu beschleunigen) und dann lokal archivieren :

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

Eine andere Möglichkeit wäre, einen flachen Klon (wie unten erwähnt) zu erstellen, aber den .git-Ordner an einer anderen Stelle zu suchen.

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

Der Repo-Ordner würde nur die Datei enthalten, ohne .git.

Hinweis: git --git-dir ist eine Option des Befehlsgit , nicht git clone.


Update mit Git 2.14.X / 2.15 (Q4 2017): Es wird sichergestellt, dass keine leeren Ordner hinzugefügt werden .

" git archive", insbesondere bei Verwendung mit pathspec, hat ein leeres Verzeichnis in seiner Ausgabe gespeichert, obwohl Git selbst dies niemals tut.
Dies wurde behoben.

Siehe Commit 4318094 (12. September 2017) von René Scharfe (``) .
Vorgeschlagen von: Jeff King ( peff) .
(Zusammengeführt von Junio ​​C Hamano - gitster- in Commit 62b1cb7 , 25. September 2017)

archive: Fügen Sie keine leeren Verzeichnisse zu Archiven hinzu

Während git keine leeren Verzeichnisse verfolgt, git archivekann es dazu gebracht werden, einige in Archive zu stellen.
Dies wird zwar von der Objektdatenbank unterstützt, kann jedoch nicht im Index dargestellt werden und ist daher in freier Wildbahn unwahrscheinlich.

Da leere Verzeichnisse von git nicht unterstützt werden, sollten sie auch nicht in Archive geschrieben werden.
Wenn ein leeres Verzeichnis wirklich benötigt wird, kann es verfolgt und archiviert werden, indem eine leere .gitignoreDatei darin abgelegt wird.

VonC
quelle
4
Das hat bei mir funktioniert. Ich würde noch etwas hinzufügen. Wenn Sie sich überhaupt nicht für den Ordner git --git-dir=/dev/null clone --depth=1 /url/to/repo
.git interessieren
Dies entfernt nicht den Ordner
.git
@VonC Ich habe versucht: git --git-dir = / dev / null Klon --depth = 1 / url / to / repo
aliasav
1
Laufen git archive --remote=https://github.com/pornel/dssim.git @ | tar -tbekomme ich tar: This does not look like a tar archive. Funktioniert es nicht mit GitHub? Was bedeutet das @auch?
André Werlang
2
@ AndréWerlang 7 Jahre später ... Ich bin mir nicht sicher @: Ich habe es entfernt. Auch GitHub unterstützt keine Fernbedienung git archive: Ich habe die Antwort bearbeitet, um eine Alternative vorzuschlagen.
VonC
59
git archive --format=tar --remote=<repository URL> HEAD | tar xf -

von hier genommen

Jon Penn
quelle
2
--format=tarist unnötig. "tar" ist die Standardausgabe, die nicht angegeben werden muss.
VasiliNovikov
1
Piping in tar xist ausreichend
Jens Bannmann
42

Sie können einen flachen Klon erstellen, um nur die letzten Revisionen zu erhalten:

 git clone --depth 1 git://url

Löschen Sie dann entweder einfach das .git-Verzeichnis oder git archiveexportieren Sie Ihren Baum.

stricken
quelle
So verhindern Sie diesen Fehler, wenn ich ihn aktualisiere, indem Sie den Klon wiederholen: "Schwerwiegend: Der Zielpfad 'XYZ' ist bereits vorhanden und kein leeres Verzeichnis."
Sohail Si
1
@SohailSi: entweder an einen neuen Speicherort klonen oder das alte Verzeichnis entfernen. Sie sollten wahrscheinlich nur die neuen Revisionen abrufen, wenn Sie Ihre lokale Kopie aktualisieren möchten.
Knittl
3

Warum nicht einen Klon durchführen und dann den löschen? .git Verzeichnis sodass Sie nur eine bloße Arbeitskopie haben?

Bearbeiten: Oder warum überhaupt Klon verwenden? Es ist etwas verwirrend, wenn Sie sagen, dass Sie ein Git-Repo wollen, aber ohne .gitVerzeichnis. Wenn Sie meinen, dass Sie nur eine Kopie eines bestimmten Status des Baums möchten, können Sie dies cp -Rin der Shell anstelle des Git-Klons tun und anschließend löschen .git.

Andrew
quelle
Dank dafür. Die Dateien befinden sich in einem Git-Repo. Ich hatte gehofft, Mac-Benutzer anweisen zu können, eine Kopie des Repos in einer Zeile zu erhalten, ohne dass es zu einem GIT-Repo wird.
Dan Rosenstark
Sie sollten keine Leute haben, die direkt Code aus dem Repo erhalten, wenn sie ihn nicht verwenden können (dh kein Git-Repository haben).
Alternative
@Amoss Einen Tarball veröffentlichen, damit die Leute nicht ständig nach dem neuesten Code greifen?
Alternative
1
@mathepic: und um einen Tarball freizugeben, benötigen Sie eine Möglichkeit, eine saubere Arbeitskopie aus dem Repository zu holen - genau diese Frage wurde gestellt.
Andrew
1
Das Lesen der Antwort unten und das anschließende Googeln führten zu einer weiteren Frage: stackoverflow.com/questions/160608/… Wenn Sie sich die Verwendung des Git-Archivs --remote ansehen, dann macht es genau das, was Sie (und das Originalposter) tun ) sind auf der Suche nach. Bearbeiten: Das ist, was Jon weiter unten antwortete.
Andrew
2

Es hört sich so an, als wollten Sie nur eine Kopie des Quellcodes. Wenn ja, warum nicht einfach das Verzeichnis kopieren und das .git-Verzeichnis von der Kopie ausschließen?

JaredPar
quelle
5
Das ist es, was ich frage: Wie mache ich das mit Git? Ich kann bereits anhand der Antworten, die ich bekomme, erkennen, dass es keinen eingebauten Weg gibt, dies zu tun. Danke trotzdem!
Dan Rosenstark
2

Git Checkout -f

Es gibt eine andere Möglichkeit, dies zu tun, indem Sie das Repo vom Arbeitsbaum trennen.

Diese Methode ist nützlich, wenn Sie diese Git-Dateien ohne Git regelmäßig aktualisieren müssen. Zum Beispiel verwende ich es, wenn ich Quelldateien auschecken und ein Artefakt erstellen muss, dann kopiere ich das Artefakt in ein anderes Repo, nur um es auf einem Server bereitzustellen, und ich verwende es auch, wenn ich Quellcode auf einen Server schiebe, wenn ich das möchte Quellcode zum Auschecken und Einbauen in das WWW-Verzeichnis.

Wir werden zwei Ordner erstellen, einen für den Git und einen für die Arbeitsdateien:

mkdir workingfiles
mkdir barerepo.git

Initialisiere ein nacktes Git-Repo:

cd barerepo.git
git --bare init 

Erstellen Sie dann einen Post-Receive-Hook:

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

Bearbeiten Sie Post-Receive in Ihrem Lieblingseditor:

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

Fügen Sie dies als Fernbedienung hinzu:

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

Jedes Mal, wenn Sie auf dieses nackte Repo klicken, wird der Arbeitsbaum ausgecheckt /workingfiles/. Aber /workingfiles/selbst ist nicht unter Versionskontrolle; läuft git statusin /workingfiles/dem Fehler geben fatal: Not a git repository (or any parent up to mount point /data). Es sind nur einfache Dateien.

Im Gegensatz zu anderen Lösungen wird der rm -r .gitBefehl nicht benötigt. Wenn /workingfiles/es sich also um ein anderes Git-Repo handelt, müssen Sie sich keine Gedanken über den Befehl machen, mit dem die Git-Dateien des anderen Repos entfernt werden.

Zuschlagen
quelle
1
Einverstanden. Hier ist ein Post-Receive-Hook für ein Bare-Repo möglich. +1
VonC
viel Arbeit, wenn Sie nur versuchen, die Dateien zu bekommen
Rainb
Es ist nicht viel Arbeit, wenn Sie regelmäßig nur die Dateien möchten.
Slam
-2

Sehr einfach IMHO:

  1. Genau git clone REPO_URLdann
  2. Entfernen Sie einfach das .gitVerzeichnis mit rm -rf ./REPO_NAME/.gitaus dem Repo.

Wenn der Name meines Repositorys beispielsweise lautet MyRepo, um dieses Repo ohne Metadaten zu erhalten, könnte ich entweder Folgendes ausführen:

git clone https://github.com/MyUser/MyRepo.git && rm -rf ./MyRepo/.git

Oder ich könnte es in ein bestimmtes Verzeichnis bringen (sagen wir in einem Verzeichnis namens MyDir):

git clone https://github.com/MyUser/MyRepo.git MyDir && rm -rf ./MyDir/.git

Hoffentlich hilft das.

Edamer
quelle
2
Danke, das wäre hilfreich, aber es ist eine Wiederholung der Frage. Wir haben Tausende von Möglichkeiten, das .gitVerzeichnis zu entfernen .
Dan Rosenstark