it-swarm.com.de

Sparse Checkout in Git 1.7.0?

Ist es mit dem neuen sparse Checkout-Feature in Git 1.7.0 möglich, den Inhalt eines Unterverzeichnisses wie in SVN zu erhalten? Ich habe dieses Beispiel gefunden, die vollständige Verzeichnisstruktur bleibt jedoch erhalten. Stellen Sie sich vor, ich wollte nur den Inhalt des 'Perl'-Verzeichnisses, ohne ein tatsächliches Verzeichnis namens' Perl '.

- EDIT -

Beispiel:

Mein Git-Repository enthält die folgenden Pfade

repo/.git/
repo/Perl/
repo/Perl/script1.pl
repo/Perl/script2.pl
repo/images/
repo/images/image1.jpg
repo/images/image2.jpg
repo/doc/
repo/doc/readme.txt
repo/doc/help.txt

Was ich möchte, ist, aus dem oben genannten Repository dieses Layout erstellen zu können:

repo/.git/
repo/script1.pl
repo/script2.pl

Mit der aktuellen spärlichen Checkout-Funktion scheint es jedoch nur möglich zu sein

repo/.git/
repo/Perl/script1.pl
repo/Perl/script2.pl

das ist nicht was ich will.

67
davr

Sie müssen immer noch das gesamte Repository klonen, in dem sich alle Dateien befinden. Sie können das Flag --depth verwenden, um nur eine begrenzte Menge des Verlaufs abzurufen.

Sobald das Repository geklont ist, beschränkt der Read-Tree-Trick Ihre "Ansicht" des Repositorys auf nur die Dateien oder Verzeichnisse, die sich in der .git/info/sparse-checkout-Datei befinden.

Ich habe ein kurzes Skript geschrieben, um die Spärlichkeit zu bewältigen, da es momentan etwas unfreundlich ist:

#!/bin/sh
echo > .git/info/sparse-checkout
for i in "[email protected]"
do
    echo "$i" >> .git/info/sparse-checkout
done
git read-tree -m -u HEAD

Wenn Sie dieses Skript als git-sparse.sh im Pfad speichern, der durch Aufruf von git --exec-path gemeldet wird, können Sie git sparse foo/ bar/ ausführen, um nur die Verzeichnisse foo und bar zu "checkout", oder git sparse '*', um alles wieder herzustellen.

26
richq

Die kurze Antwort lautet nein. Git sieht alle Dateien als eine Einheit.

Was ich empfehle, ist, dass Sie Ihre Repositories in logische Blöcke aufteilen. Eine separate für Perl, Bilder und Dokumente. Wenn Sie auch den Uber-Repo-Stil beibehalten möchten, können Sie ein Repo erstellen, das aus Submodules besteht.

16
John K

richqs Antwort war knapp, aber einen Schritt verfehlt. Sie müssen die spärliche Kasse explizit aktivieren:

git config core.sparsecheckout wahr

In diesem Blogpost sind alle Schritte klar umrissen:

http://blog.quilitz.de/2010/03/checkout-sub-directories-in-git-sparse-checkouts/comment-page-1/#comment-3146

7
PhilYoussef

Nun, ohne ins Detail zu gehen, warum Sie dies tun möchten, kann Ihr Problem (wahrscheinlich) leicht durch einen Symlink/eine Verknüpfung gelöst werden.

Um die Frage zu beantworten - nein und mit einem sinnvollen Grund. Die gesamte Historie des Repos wird auch mit einer spärlichen Kasse heruntergeladen. Um zu klären, warum dies notwendig ist - andernfalls wäre das Nachverfolgen umbenannter Dateien ein Ärgernis. Stellen Sie sich vor, Sie verschieben die Datei /repo_root/asd/file1.cpp nach /repo_root/fgh/file1.cpp. Wenn Sie jetzt nur /repo_root/fgh-Deltas heruntergeladen hätten, wissen Sie nichts über file1.cpp. Das bedeutet also, dass Sie alle Deltas herunterladen müssen. Aber dann haben Sie ein vollständiges Repository. es ist nicht nur ein Ordnerausschnitt, daher ist der /rero_root/fgh-Ordner selbst kein Repo. Das hört sich vielleicht nicht wichtig an, wenn Sie zur Kasse gehen, aber wenn Sie einen Commit ausführen, weiß git möglicherweise nicht genug, um gut zu funktionieren.

Workaround : Wenn Sie wirklich wollen, können Sie ein Skript erstellen, das git-checkout so aufruft (für die sh-Shell sollte Batch für Windows nicht schwer zu produzieren sein):

!/bin/sh
curDir=`pwd`
cd $2
git-checkout $1
cp -R $3/* $4
cd $curDir

Hier ist das erste Argument der Zweig, der ausgecheckt werden soll, das zweite - der Ordner, in dem sich das Repo derzeit befindet, das dritte - das Unterverzeichnis, das Sie wirklich verwenden möchten, und das vierte - der Speicherort, an den das Repo kopiert werden soll.

Warnung: Meine Shell-Fähigkeiten sind fast nicht vorhanden. Verwenden Sie diese Funktion also nach dem Testen. Es sollte nicht schwer sein, die Umkehrung dieses Skripts wiederherzustellen, mit dem zurückgeschriebenes Material kopiert wird, damit es an das Repo übergeben werden kann.

5
Ger4ish

git filter-branch --subdirectory-filter ist das, was Sie brauchen, siehe Unterverzeichnis trennen (verschieben) in separates Git-Repository .

Hier ist ein kleines Bash-Skript, um das zu tun.

Dadurch wird zunächst eine Arbeitskopie des Original-Repos erstellt, dann wird der Zweig mithilfe des Unterverzeichnisfilters gefiltert, um das gewünschte Ergebnis zu erhalten.

#!/bin/bash
#
# git-subdir.sh
#
git clone --no-hardlinks $1 $2

cd $2

git filter-branch --subdirectory-filter $2 --Prune-empty --tag-name-filter cat HEAD -- --all

git reset --hard

git remote rm Origin

refbak=$(git for-each-ref --format="%(refname)" refs/original/)

if [ -n "$refbak" ];then
    echo -n $refbak | xargs -n 1 git update-ref -d
fi

git reflog expire --expire=now --all

git repack -ad

git gc --aggressive --Prune=now

Verwenden Sie für das Beispiel in der Frage, git-subdir.sh repo Perl würde funktionieren.

3
weynhamz

Sie können Flechten ausprobieren - es verfolgt Fernbedienungen, während sie einem Pfad zugeordnet werden . https://github.com/evilchelu/braid/wiki

2
Antoine Toulme

Es scheint, als würden Sie versuchen, die Verzeichnisstruktur umzubenennen, sodass Ihre Dateien an einem anderen Ort landen. Mir scheint, dass Sie ein Anti-Template für das Code-/Projektmanagement aus zwei Gründen benötigen: Kategorisierung von Modulen (Java-Bits unter Java-Knoten, Perl unter Perl-Knoten) und Projekt mit Dateien an verschiedenen Speicherorten von wo aus der Entwickler sie visualisiert. Da git Hashes des Verzeichnisinhalts verwaltet, um zu sehen, was geändert wird, bricht dies auch git als solches. 

Daemeon Reiydelle

0
Daemeon