Ändern Sie die Repository-Verzeichnisstruktur mit Sparse Checkout

Lesezeit: 6 Minuten

Benutzeravatar von davr
davr

Mit dem Neuen spärliche Checkout-Funktion Ist es in Git 1.7.0 möglich, einfach den Inhalt eines Unterverzeichnisses abzurufen, wie Sie es in SVN können? ich fand dieses Beispiel, behält aber die vollständige Verzeichnisstruktur bei. Stellen Sie sich vor, ich wollte nur den Inhalt des Verzeichnisses „perl“ ohne ein tatsächliches Verzeichnis namens „perl“.

— BEARBEITEN —

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 in der Lage zu sein, dieses Layout aus dem obigen Repository zu erstellen:

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

Mit der aktuellen Sparse-Checkout-Funktion scheint es jedoch nur möglich zu sein, zu bekommen

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

was ich NICHT will.

  • sie haben es endlich umgesetzt! Kalt!

    – Mauricio Scheffer

    25. Februar 2010 um 18:42 Uhr

  • Wieso den? Was ist das Problem? Und warum möchten Sie eine andere Verzeichnisstruktur im Repository und eine andere lokal haben? Macht auf den ersten Blick nicht viel Sinn.

    – Jiri Klouda

    9. März 2010 um 9:02 Uhr

  • @Jiri: Ich habe eine Webanwendung mit Actionscript-Code (clientseitig) und PHP-Code (serverseitig). Die Dateien sind eng miteinander verwandt, daher möchte ich sie in einem einzigen Repo/Zweig ablegen. Ich möchte jedoch nicht die Actionscript-Quelldateien auf dem Server, sondern nur die PHP-Dateien.

    – davr

    9. März 2010 um 21:02 Uhr

  • @davr das ist kein so seltener umstand, ich wollte genau das. Schade, dass ich es noch nicht bekomme.

    – Preinheimer

    7. Oktober 2011 um 5:00 Uhr

  • @preinheimer, das versuche ich auch zu bekommen. Es würde das Entwickeln und Testen eines Themas, das ich mache, viel einfacher machen.

    – Apokaliptis

    4. November 2014 um 23:04 Uhr

Benutzeravatar von richq
richq

Sie müssen immer noch das gesamte Repository klonen, das alle Dateien enthalten wird. Du könntest die verwenden --depth Flag, um nur eine begrenzte Menge an Historie 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 befinden .git/info/sparse-checkout Datei.

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

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

Wenn Sie dieses Skript speichern als git-sparse.sh in den durch Aufruf gemeldeten Pfad git --exec-pathdann kannst du laufen git sparse foo/ bar/ nur die Verzeichnisse foo und bar “auszuchecken”, oder git sparse '*' alles wieder zurück zu bekommen.

  • Danke für die Hilfe, aber das scheint meine Frage nicht zu beantworten. Siehe meine aktualisierte Frage zur Klärung.

    – davr

    26. Februar 2010 um 22:59 Uhr

  • Ja, Sparse ist nur eine Möglichkeit, den eigentlichen Baum zu filtern, es können keine Dateien verschoben werden. Du kannst also nicht machen was du willst…

    – richq

    27. Februar 2010 um 11:07 Uhr

Die kurze Antwort ist nein. Git betrachtet 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üssen, können Sie ein Repo erstellen, das aus besteht Submodule.

Ohne ins Detail zu gehen, warum Sie dies tun möchten, kann Ihr Problem (wahrscheinlich) einfach durch einen Symlink/Shortcut gelöst werden.

Um die Frage zu beantworten – nein, und mit einem sinnvollen Grund. Die gesamte Historie des Repos wird auch bei einem „sparse checkout“ heruntergeladen. Um zu verdeutlichen, warum dies notwendig ist – andernfalls wäre das Verfolgen umbenannter Dateien eine Nervensäge. Stellen Sie sich vor, Sie verschieben die Datei /repo_root/asd/file1.cpp zu /repo_root/fgh/file1.cpp – jetzt, wenn Sie nur heruntergeladen hätten /repo_root/fgh Deltas, wissen Sie nichts über file1.cpp. Das bedeutet also, dass Sie alle Deltas herunterladen müssen. Aber dann haben Sie ein vollständiges Repository; nicht nur einen Ordnerschnitt davon, also einfach den /rero_root/fgh Der Ordner ist selbst kein Repo. Dies mag beim Auschecken nicht wichtig klingen, aber wenn Sie es festschreiben, weiß Git möglicherweise nicht genug, um richtig zu funktionieren.

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

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

Hier ist das erste Argument der Zweig zum Auschecken, 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 Ort, an den es kopiert werden soll.

Warnung: Meine Shell-Fähigkeiten sind fast nicht vorhanden, also verwenden Sie dies nach dem Testen. Es sollte nicht schwer sein, die Umkehrung dieses Skripts neu zu erstellen, das Material zurückkopiert, damit es in das Repo übertragen werden kann.

  • Den gesamten Verlauf des Repos zu haben, ist kein Problem, es ist kein großes Repo, und wir haben viel Speicherplatz. Ich denke, unser spezieller Anwendungsfall ist nicht so häufig, also haben Git-Entwickler nie daran gedacht, ihn hinzuzufügen. Es ist eines der wenigen Dinge, die SVN für uns besser funktioniert hat (Git macht 99 andere Dinge besser, weshalb wir gewechselt haben, aber immer noch)

    – davr

    7. August 2011 um 6:01 Uhr

  • Symlinks auf Windows sind ein Albtraum – das ist nicht zu handhaben.

    – Alex Braun

    20. März 2013 um 17:50 Uhr

richqs Antwort war knapp, aber es ging ein Schritt daneben. Sie müssen Sparse Checkout explizit aktivieren:

git config core.sparsecheckout wahr

In diesem Blogbeitrag sind alle Schritte klar umrissen:

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

Sie können es mit Braid versuchen – es verfolgt Fernbedienungen, während es sie einem Pfad zuordnet.
https://github.com/evilchelu/braid/wiki

Benutzeravatar der Community
Gemeinschaft

git filter-branch --subdirectory-filter was Sie brauchen, finden Sie unter Unterverzeichnis trennen (verschieben) in separates Git-Repository.

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

Dadurch wird zuerst eine Arbeitskopie des ursprünglichen Repos erstellt und dann der Zweig mithilfe des Unterverzeichnisfilters gefiltert, um das zu erhalten, was Sie möchten.

#!/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.

Benutzeravatar von Daemeon
Dämon

Es scheint, dass Sie versuchen, den Verzeichnisbaum so umzubenennen, dass Ihre Dateien an einem anderen Ort landen. Es scheint mir, dass Sie nach einer Anti-Vorlage für das Code-/Projektmanagement in zweierlei Hinsicht fragen: Kategorisierung von Modulen (Java-Bits unter Java-Knoten, Perl unter Perl-Knoten) und ein Projekt mit Dateien an verschiedenen Orten von wo aus der Entwickler sie visualisiert. Da git Hashes von Verzeichnisinhalten verwaltet, um zu sehen, was sich geändert hat, bricht dies auch git als solches.

Dämon Reiydelle

1429830cookie-checkÄndern Sie die Repository-Verzeichnisstruktur mit Sparse Checkout

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy