it-swarm.com.de

Mache einen "Git Export" (wie "Svn Export")?

Ich habe mich gefragt, ob es eine gute "Git-Export" -Lösung gibt, die eine Kopie eines Baums ohne das Repository-Verzeichnis _.git_ erstellt. Ich kenne mindestens drei Methoden:

  1. _git clone_ gefolgt vom Entfernen des Repository-Verzeichnisses _.git_.
  2. git checkout-index spielt auf diese Funktionalität an, beginnt aber mit "Einfach den gewünschten Baum in den Index einlesen ...", was ich nicht ganz genau weiß.
  3. git-export ist ein Skript eines Drittanbieters, das im Wesentlichen ein _git clone_ an einem temporären Ort ausführt, gefolgt von _rsync --exclude='.git'_ am endgültigen Ziel.

Keine dieser Lösungen scheint mir wirklich zufriedenstellend zu sein. Der _svn export_ am nächsten liegende ist möglicherweise Option 1, da bei beiden das Zielverzeichnis zuerst leer sein muss. Aber Option 2 scheint noch besser zu sein, vorausgesetzt, ich kann herausfinden, was es bedeutet, einen Baum in den Index einzulesen.

2281
Greg Hewgill

Der wahrscheinlich einfachste Weg, dies zu erreichen, ist mit git archive . Wenn Sie wirklich nur den erweiterten Baum benötigen, können Sie so etwas tun.

_git archive master | tar -x -C /somewhere/else
_

Die meiste Zeit, in der ich etwas aus git 'exportieren' muss, möchte ich auf jeden Fall ein komprimiertes Archiv, also mache ich so etwas.

_git archive master | bzip2 >source-tree.tar.bz2
_

Zip-Archiv:

_git archive --format Zip --output /full/path/to/zipfile.Zip master 
_

git help archive Für weitere Details ist es ziemlich flexibel.


Beachten Sie, dass das Archiv zwar nicht das Verzeichnis .git enthält, jedoch andere verborgene git-spezifische Dateien wie .gitignore, .gitattributes usw. enthält. Wenn Sie sie nicht im Archiv haben möchten, müssen Sie dies sicherstellen Verwenden Sie das export-ignore-Attribut in einer .gitattributes-Datei und schreiben Sie dies fest, bevor Sie Ihr Archiv erstellen. Weiterlesen ...


Hinweis: Wenn Sie den Index exportieren möchten, lautet der Befehl

_git checkout-index -a -f --prefix=/destination/path/
_

(Siehe Gregs Antwort für weitere Details)

2326
CB Bailey

Ich habe herausgefunden, was Option 2 bedeutet. Aus einem Repository können Sie Folgendes ausführen:

git checkout-index -a -f --prefix=/destination/path/

Der Schrägstrich am Ende des Pfades ist wichtig, da sonst die Dateien in/destination mit dem Präfix 'path' abgelegt werden.

Da der Index im Normalfall den Inhalt des Repositorys enthält, ist nichts Besonderes zu tun, um "den gewünschten Baum in den Index einzulesen". Es ist schon da.

Das -a -Flag ist erforderlich, um alle Dateien im Index auszuchecken (ich bin nicht sicher, was es bedeutet, dieses Flag in dieser Situation wegzulassen, da es nicht das tut, was ich will). Das -f -Flag erzwingt das Überschreiben vorhandener Dateien in der Ausgabe, was dieser Befehl normalerweise nicht ausführt.

Dies scheint die Art von "Git-Export" zu sein, nach der ich gesucht habe.

314
Greg Hewgill

git archive funktioniert auch mit Remote-Repository.

git archive --format=tar \
--remote=ssh://remote_server/remote_repository master | tar -xf -

Um einen bestimmten Pfad innerhalb des Repos zu exportieren, fügen Sie so viele Pfade hinzu, wie Sie möchten, als letztes Argument für git, z.

git archive --format=tar \
--remote=ssh://remote_server/remote_repository master path1/ path2/ | tar -xv
252
Aleksandr Somov

enter image description here

Eine Sonderfallantwort, wenn das Repository auf GitHub gehostet wird.

Verwenden Sie einfach svn export.

Soweit ich weiß, erlaubt Github archive --remote nicht. Obwohl GitHub svn-kompatibel ist und alle Git-Repos svn verfügbar sind, können Sie svn export wie gewohnt mit ein paar Anpassungen an Ihrer GitHub-URL verwenden.

Wenn Sie beispielsweise ein gesamtes Repository exportieren möchten, beachten Sie, dass trunk in der URL master ersetzt (oder auf was auch immer der Zweig des Projekts HEAD festgelegt ist ):

svn export https://github.com/username/repo-name/trunk/

Und Sie können eine einzelne Datei oder sogar einen bestimmten Pfad oder Ordner exportieren:

svn export https://github.com/username/repo-name/trunk/src/lib/folder

Beispiel mit jQuery JavaScript Library

Der Zweig HEAD oder Master ist über trunk verfügbar:

svn ls https://github.com/jquery/jquery/trunk

Die nicht-HEAD Zweige sind unter /branches/ zugänglich:

svn ls https://github.com/jquery/jquery/branches/2.1-stable

Alle Tags unter /tags/ auf dieselbe Weise:

svn ls https://github.com/jquery/jquery/tags/2.1.3
54

Aus dem Git Manual :

Git-checkout-index verwenden, um "einen ganzen Baum zu exportieren"

Die Präfix-Fähigkeit macht es im Grunde trivial, git-checkout-index als "Export als Baum" -Funktion zu verwenden. Lies einfach den gewünschten Baum in den Index und mache:

$ git checkout-index --prefix=git-export-dir/ -a

40
jperras

Ich habe einen einfachen Wrapper um git-checkout-index geschrieben, den Sie folgendermaßen verwenden können:

git export ~/the/destination/dir

Wenn das Zielverzeichnis bereits vorhanden ist, müssen Sie -f oder --force hinzufügen.

Die Installation ist einfach; Legen Sie das Skript einfach irgendwo in Ihrem PATH ab und vergewissern Sie sich, dass es ausführbar ist.

Das Github-Repository für git-export

38

Es scheint, dass dies bei Git weniger ein Problem ist als bei SVN. Git legt nur einen .git-Ordner im Repository-Stammverzeichnis ab, während SVN einen .svn-Ordner in jedem Unterverzeichnis ablegt. "Svn export" vermeidet also rekursive Befehlszeilenmagie, während bei Git keine Rekursion erforderlich ist.

36
kostmo

Das Äquivalent von

svn export . otherpath

in einem vorhandenen Repo ist

git archive branchname | (cd otherpath; tar x)

Das Äquivalent von

svn export url otherpath

ist

git archive --remote=url branchname | (cd otherpath; tar x)
27
aredridel

Wenn Sie Dateien mit .gitattributesexport-ignore nicht ausschließen, versuchen Sie git checkout

mkdir /path/to/checkout/
git --git-dir=/path/to/repo/.git --work-tree=/path/to/checkout/ checkout -f -q

-f
Wenn Sie Pfade aus dem Index auschecken, schlagen Sie bei nicht zusammengeführten Einträgen nicht fehl. Stattdessen werden nicht zusammengeführte Einträge ignoriert.

und

-q
Vermeiden Sie ausführlich

Zusätzlich können Sie einen Zweig, ein Tag oder eine bestimmte Commit-Revision wie in SVN erhalten, indem Sie einfach den SHA1 hinzufügen (SHA1 in Git entspricht der Revisionsnummer in SVN).

mkdir /path/to/checkout/
git --git-dir=/path/to/repo/.git --work-tree=/path/to/checkout/ checkout 2ef2e1f2de5f3d4f5e87df7d8 -f -q -- ./

Der /path/to/checkout/ muss leer sein, Git löscht keine Datei, überschreibt jedoch Dateien mit demselben Namen ohne Vorwarnung

UPDATE: Um das enthauptete Problem zu vermeiden oder das funktionierende Repository bei Verwendung von Checkout für den Export mit Tags, Zweigen oder SHA1 intakt zu lassen, müssen Sie am Ende -- ./ hinzufügen

Der doppelte Bindestrich -- sagt git, dass alles nach den Bindestrichen Pfade oder Dateien sind, und auch in diesem Fall sagt git checkout, dass das HEAD nicht geändert werden soll.

Beispiele:

Dieser Befehl ruft genau das libs-Verzeichnis und auch die readme.txt -Datei von diesem Commit ab

git --git-dir=/path/to/repo/.git --work-tree=/path/to/checkout/ checkout fef2e1f2de5f3d4f5e87df7d8 -f -q -- ./libs ./docs/readme.txt

Dies erzeugt (überschreibt) my_file_2_behind_HEAD.txt zwei Commits hinter dem Kopf HEAD^2

git --git-dir=/path/to/repo/.git --work-tree=/path/to/checkout/ checkout HEAD^2 -f -q -- ./my_file_2_behind_HEAD.txt

Um den Export einer anderen Filiale zu bekommen

git --git-dir=/path/to/repo/.git --work-tree=/path/to/checkout/ checkout myotherbranch -f -q -- ./

Beachten Sie, dass ./ relativ zum Stammverzeichnis des Repositorys ist

22

Ich benutze Git-Submodule ausgiebig. Dieser arbeitet für mich:

rsync -a ./FROM/ ./TO --exclude='.*'
21
slatvick

Ich habe diese Seite häufig aufgerufen, wenn ich nach einer Möglichkeit gesucht habe, ein Git-Repository zu exportieren. Meine Antwort auf diese Frage bezieht sich auf drei Eigenschaften, die svn export im Vergleich zu git hat, da svn einem zentralisierten Repository-Ansatz folgt:

  • Es minimiert den Datenverkehr zu einem Remote-Repository-Speicherort, indem nicht alle Revisionen exportiert werden
  • Das Exportverzeichnis enthält keine Metainformationen
  • Das Exportieren eines bestimmten Zweigs mit svn erfolgt durch Angabe des entsprechenden Pfads

    git clone --depth 1 --branch master git://git.somewhere destination_path
    rm -rf destination_path/.git
    

Wenn Sie ein bestimmtes Release erstellen, ist es nützlich, einen stabilen Zweig wie beispielsweise --branch stable oder --branch release/0.9 zu klonen.

19

Dadurch wird der gesamte Inhalt ohne die DOT-Dateien kopiert. Ich verwende dies, um git-geklonte Projekte ohne das .git-Zeug in das git-Repo meiner Web-App zu exportieren.

cp -R ./path-to-git-repo/path/to/destination /

Einfache alte Bash funktioniert einfach toll :)

16
Harmon

So einfach wie das Klonen, dann lösche den .git Ordner:

git clone url_of_your_repo path_to_export && rm -rf path_to_export/.git

13
teleme.io

Ja, this ist ein sauberer und ordentlicher Befehl zum Archivieren Ihres Codes, ohne dass ein Git in das Archiv aufgenommen wird.

git archive --format Zip --output /full/path/to/zipfile.Zip master 
11
zeeawan

Ich möchte nur darauf hinweisen, dass in dem Fall, dass Sie sind

  1. exportieren eines Unterordners des Repositorys (so habe ich die SVN-Exportfunktion verwendet)
  2. sie können alles aus diesem Ordner in das Bereitstellungsziel kopieren
  3. und da Sie bereits eine Kopie des gesamten Repositorys haben.

Dann können Sie einfach cp foo [destination] anstelle des erwähnten git-archive master foo | -x -C [destination] verwenden.

10
dkinzer

Für GitHub-Benutzer funktioniert die git archive --remote -Methode nicht direkt, da die Export-URL ist kurzlebig . Sie müssen GitHub nach der URL fragen und diese dann herunterladen. curl macht das einfach:

curl -L https://api.github.com/repos/VENDOR/PROJECT/tarball | tar xzf -

Dadurch erhalten Sie den exportierten Code in einem lokalen Verzeichnis. Beispiel:

$ curl -L https://api.github.com/repos/jpic/bashworks/tarball | tar xzf -
$ ls jpic-bashworks-34f4441/
break  conf  docs  hack  LICENSE  mlog  module  mpd  mtests  os  README.rst  remote  todo  vcs  vps  wepcrack

Bearbeiten
Wenn Sie den Code in ein bestimmtes existierendes Verzeichnis schreiben möchten (anstelle des zufälligen von github):

curl -L https://api.github.com/repos/VENDOR/PROJECT/tarball | \
tar xzC /path/you/want --strip 1
10
bishop

Sie können ein Remote-Repo bei jedem Commit als Zip-Datei archivieren.

git archive --format=Zip --output=archive.Zip [email protected]:PROJECTNAME.git HASHOFGITCOMMIT
9
orkoden

Wenn Sie etwas wollen, das mit Submodulen funktioniert, ist dies möglicherweise einen Versuch wert.

Hinweis:

  • MASTER_DIR = ein Checkout, bei dem auch Ihre Submodule ausgecheckt sind
  • DEST_DIR = wo dieser Export enden wird
  • Wenn Sie rsync haben, können Sie das Gleiche mit noch weniger Ballschmerzen tun.

Annahmen:

  • Sie müssen dies aus dem übergeordneten Verzeichnis von MASTER_DIR ausführen (d. H. Von MASTER_DIR cd ..)
  • Es wird angenommen, dass DEST_DIR erstellt wurde. Dies ist ziemlich einfach zu ändern, um die Erstellung eines DEST_DIR einzuschließen, wenn Sie wollten

cd MASTER_DIR && tar -zcvf ../DEST_DIR/export.tar.gz --exclude = '. git *'. && cd ../DEST_DIR/ && tar xvfz export.tar.gz && rm export.tar.gz

8
Rob Jensen

Bash-Implementierung von Git-Export.

Ich habe die Erstellungs- und Entfernungsprozesse für .empty-Dateien nach ihrer eigenen Funktion unterteilt, um sie in der Implementierung von 'git-archive' wiederzuverwenden (wird später veröffentlicht).

Ich habe dem Prozess auch die Datei ".gitattributes" hinzugefügt, um unerwünschte Dateien aus dem Zielexportordner zu entfernen. Fügte dem Prozess Ausführlichkeit bei, während die Funktion 'Git-Export' effizienter wurde.

EMPTY_FILE = ". Empty";

function create_empty () {
## Processing path (target-dir):
    TRG_PATH="${1}";
## Component(s):
    EXCLUDE_DIR=".git";
echo -en "\nAdding '${EMPTY_FILE}' files to empty folder(s): ...";
    find ${TRG_PATH} -not -path "*/${EXCLUDE_DIR}/*" -type d -empty -exec touch {}/${EMPTY_FILE} \;
#echo "done.";
## Purging SRC/TRG_DIRs variable(s):
    unset TRG_PATH EMPTY_FILE EXCLUDE_DIR;
    return 0;
  }

declare -a GIT_EXCLUDE;
function load_exclude () {
    SRC_PATH="${1}";
    ITEMS=0; while read LINE; do
#      echo -e "Line [${ITEMS}]: '${LINE%%\ *}'";
      GIT_EXCLUDE[((ITEMS++))]=${LINE%%\ *};
    done < ${SRC_PATH}/.gitattributes;
    GIT_EXCLUDE[${ITEMS}]="${EMPTY_FILE}";
## Purging variable(s):
    unset SRC_PATH ITEMS;
    return 0;
  }

function purge_empty () {
## Processing path (Source/Target-dir):
    SRC_PATH="${1}";
    TRG_PATH="${2}";
echo -e "\nPurging Git-Specific component(s): ... ";
    find ${SRC_PATH} -type f -name ${EMPTY_FILE} -exec /bin/rm '{}' \;
    for xRULE in ${GIT_EXCLUDE[@]}; do
echo -en "    '${TRG_PATH}/{${xRULE}}' files ... ";
      find ${TRG_PATH} -type f -name "${xRULE}" -exec /bin/rm -rf '{}' \;
echo "done.'";
    done;
echo -e "done.\n"
## Purging SRC/TRG_PATHs variable(s):
    unset SRC_PATH; unset TRG_PATH;
    return 0;
  }

function git-export () {
    TRG_DIR="${1}"; SRC_DIR="${2}";
    if [ -z "${SRC_DIR}" ]; then SRC_DIR="${PWD}"; fi
    load_exclude "${SRC_DIR}";
## Dynamically added '.empty' files to the Git-Structure:
    create_empty "${SRC_DIR}";
    GIT_COMMIT="Including '${EMPTY_FILE}' files into Git-Index container."; #echo -e "\n${GIT_COMMIT}";
    git add .; git commit --quiet --all --verbose --message "${GIT_COMMIT}";
    if [ "${?}" -eq 0 ]; then echo " done."; fi
    /bin/rm -rf ${TRG_DIR} && mkdir -p "${TRG_DIR}";
echo -en "\nChecking-Out Index component(s): ... ";
    git checkout-index --prefix=${TRG_DIR}/ -q -f -a
## Reset: --mixed = reset HEAD and index:
    if [ "${?}" -eq 0 ]; then
echo "done."; echo -en "Resetting HEAD and Index: ... ";
        git reset --soft HEAD^;
        if [ "${?}" -eq 0 ]; then
echo "done.";
## Purging Git-specific components and '.empty' files from Target-Dir:
            purge_empty "${SRC_DIR}" "${TRG_DIR}"
          else echo "failed.";
        fi
## Archiving exported-content:
echo -en "Archiving Checked-Out component(s): ... ";
        if [ -f "${TRG_DIR}.tgz" ]; then /bin/rm ${TRG_DIR}.tgz; fi
        cd ${TRG_DIR} && tar -czf ${TRG_DIR}.tgz ./; cd ${SRC_DIR}
echo "done.";
## Listing *.tgz file attributes:
## Warning: Un-TAR this file to a specific directory:
        ls -al ${TRG_DIR}.tgz
      else echo "failed.";
    fi
## Purgin all references to Un-Staged File(s):
   git reset HEAD;
## Purging SRC/TRG_DIRs variable(s):
    unset SRC_DIR; unset TRG_DIR;
    echo "";
    return 0;
  }

Ausgabe:

$ git-export /tmp/rel-1.0.0

Hinzufügen von '.empty'-Dateien zu leeren Ordnern: ... fertig.

Check-Out-Index-Komponente (n): ... erledigt.

Zurücksetzen von HEAD und Index: ... erfolgt.

Git-spezifische Komponente (n) löschen: ...

'/tmp/rel-1.0.0/{.buildpath}' files ... done. '

'/tmp/rel-1.0.0/{.project}' files ... done. '

'/tmp/rel-1.0.0/{.gitignore}' files ... done. '

'/tmp/rel-1.0.0/{.git}' files ... done. '

'/tmp/rel-1.0.0/{.gitattributes}' files ... done. '

'/tmp/rel-1.0.0/{*.mno}' files ... done. '

'/tmp/rel-1.0.0/{*~}' files ... done. '

'/tmp/rel-1.0.0/{.*~}' files ... done. '

'/tmp/rel-1.0.0/{*.swp}' files ... done. '

'/tmp/rel-1.0.0/{*.swo}' files ... done. '

'/tmp/rel-1.0.0/{.DS_Store}' files ... done. '

'/tmp/rel-1.0.0/{.settings}' files ... done. '

'/tmp/rel-1.0.0/{.empty}' files ... done. '

getan.

Archivierung ausgecheckter Komponenten: ... erledigt.

-rw-r - r-- 1 Administrator-Rad 25445901 3 Nov 12:57 /tmp/rel-1.0.0.tgz

Ich habe jetzt die "Git-Archiv" -Funktionalität in einen einzelnen Prozess integriert, der die "create_empty" -Funktion und andere Funktionen nutzt.

function git-archive () {
    PREFIX="${1}"; ## Sudo mkdir -p ${PREFIX}
    REPO_PATH="`echo "${2}"|awk -F: '{print $1}'`";
    RELEASE="`echo "${2}"|awk -F: '{print $2}'`";
    USER_PATH="${PWD}";
echo "$PREFIX $REPO_PATH $RELEASE $USER_PATH";
## Dynamically added '.empty' files to the Git-Structure:
    cd "${REPO_PATH}"; populate_empty .; echo -en "\n";
#    git archive --prefix=git-1.4.0/ -o git-1.4.0.tar.gz v1.4.0
# e.g.: git-archive /var/www/htdocs /repos/domain.name/website:rel-1.0.0 --explode
    OUTPUT_FILE="${USER_PATH}/${RELEASE}.tar.gz";
    git archive --verbose --prefix=${PREFIX}/ -o ${OUTPUT_FILE} ${RELEASE}
    cd "${USER_PATH}";
    if [[ "${3}" =~ [--explode] ]]; then
      if [ -d "./${RELEASE}" ]; then /bin/rm -rf "./${RELEASE}"; fi
      mkdir -p ./${RELEASE}; tar -xzf "${OUTPUT_FILE}" -C ./${RELEASE}
    fi
## Purging SRC/TRG_DIRs variable(s):
    unset PREFIX REPO_PATH RELEASE USER_PATH OUTPUT_FILE;
    return 0;
  }
8
tocororo

Eigentlich würde ich es vorziehen, ein dist - Ziel in Ihrem Makefile (oder einem anderen Build-System) zu haben, das ein verteilbares Archiv Ihres Codes (.tar.bz2, .Zip, .jar oder was auch immer angebracht ist) exportiert ). Wenn Sie zufällig GNU Autotools oder Perls MakeMaker-Systeme verwenden, gibt es diese meiner Meinung nach automatisch für Sie. Wenn nicht, empfehle ich das Hinzufügen.

ETA (2012-09-06): Wow, harte Ablehnungen. Ich glaube immer noch, dass es besser ist, Ihre Distributionen mit Ihren Build-Tools zu erstellen, als mit Ihrem Quellcode-Kontroll-Tool. Ich glaube daran, Artefakte mit Build-Tools zu erstellen. In meiner jetzigen Arbeit wird unser Hauptprodukt mit einem Ameisenziel gebaut. Wir sind mitten in der Umstellung der Quellcode-Kontrollsysteme, und das Vorhandensein dieses Ameisenziels bedeutet einen geringeren Aufwand bei der Migration.

6
skiphoppy

Dadurch werden die Dateien in einer Reihe von Commits (C bis G) in eine tar-Datei kopiert. Hinweis: Dadurch werden nur die Dateien festgeschrieben. Nicht das gesamte Repository. Leicht modifiziert von hier

Beispiel Commit-Verlauf

A -> B -> C -> D -> E -> F -> G -> H -> ich

git diff-tree -r --no-commit-id --name-only --diff-filter=ACMRT C~..G | xargs tar -rf myTarFile.tar

git-diff-tree Manual Page

-r -> Rekursion in Unterbäume

--no-commit-id -> git diff-tree gibt gegebenenfalls eine Zeile mit der Festschreibungs-ID aus. Dieses Flag unterdrückte die Ausgabe der Festschreibungs-ID.

--name-only -> Nur Namen geänderter Dateien anzeigen.

--diff-filter = ACMRT -> Nur diese Dateien auswählen. Eine vollständige Liste der Dateien finden Sie hier

C..G -> Dateien in diesem Bereich von Commits

C ~ -> Dateien aus Commit C einschließen. Nicht nur Dateien seit Commit C.

| xargs tar -rf myTarFile -> gibt tar aus

6
Fuyu Persimmon

Ich brauchte dies für ein Bereitstellungsskript und konnte keinen der oben genannten Ansätze verwenden. Stattdessen habe ich eine andere Lösung gefunden:

#!/bin/sh
[ $# -eq 2 ] || echo "USAGE $0 REPOSITORY DESTINATION" && exit 1
REPOSITORY=$1
DESTINATION=$2
TMPNAME="/tmp/$(basename $REPOSITORY).$$"
git clone $REPOSITORY $TMPNAME
rm -rf $TMPNAME/.git
mkdir -p $DESTINATION
cp -r $TMPNAME/* $DESTINATION
rm -rf $TMPNAME
4
troelskn

Wie ich die Frage verstehe, geht es eher darum, nur einen bestimmten Status vom Server herunterzuladen, ohne Historie und ohne Daten anderer Zweige, anstatt einen Status aus einem lokalen Repository zu extrahieren (wie es viele Antworten hier tun).

Das geht so:

git clone -b someBranch --depth 1 --single-branch git://somewhere.com/repo.git \
&& rm -rf repo/.git/
  • --single-branch ist verfügbar seit Git 1.7.10 (April 2012).
  • --depth ist (war?) Berichten zufolge fehlerhaft, aber für den Fall eines Exports sollten die genannten Probleme keine Rolle spielen.
4
Ondra Žižka

Auf einfache Weise ist dies eine Funktion für .bash_profile, die das Archiv direkt am aktuellen Speicherort entpackt. Konfigurieren Sie zunächst Ihren üblichen [url: path]. HINWEIS: Mit dieser Funktion vermeiden Sie den Klonvorgang, er wird direkt vom Remote-Repo abgerufen.

gitss() {
    URL=[url:path]

    TMPFILE="`/bin/tempfile`"
    if [ "$1" = "" ]; then
        echo -e "Use: gitss repo [tree/commit]\n"
        return
    fi
    if [ "$2" = "" ]; then
        TREEISH="HEAD"
    else
        TREEISH="$2"
    fi
    echo "Getting $1/$TREEISH..."
    git archive --format=Zip --remote=$URL/$1 $TREEISH > $TMPFILE && unzip $TMPFILE && echo -e "\nDone\n"
    rm $TMPFILE
}

Alias ​​für .gitconfig, gleiche Konfiguration erforderlich (TAKE CARE beim Ausführen des Befehls in .git-Projekten, es springt IMMER zum Basisverzeichnis vorher wie hier gesagt , bis dies behoben ist, bevorzuge ich persönlich die Funktion

ss = !env GIT_TMPFILE="`/bin/tempfile`" sh -c 'git archive --format=Zip --remote=[url:path]/$1 $2 \ > $GIT_TMPFILE && unzip $GIT_TMPFILE && rm $GIT_TMPFILE' -
4
RkG

Ich denke, @ Aredridel s Beitrag war am nächsten, aber dazu gehört noch ein bisschen mehr - also werde ich das hier hinzufügen. Die Sache ist, in svn, wenn Sie in einem Unterordner eines Repos sind und Sie tun:

/media/disk/repo_svn/subdir$ svn export . /media/disk2/repo_svn_B/subdir

dann exportiert svn alle Dateien, die sich unter Versionskontrolle befinden (sie könnten auch frisch hinzugekommen sein oder den Status "Geändert" haben) - und wenn Sie andere "Junk" in diesem Verzeichnis haben (und ich zähle nicht .svn Unterordner hier, aber sichtbare Dinge wie .o Dateien), es wird nicht exportiert; Es werden nur die vom SVN-Repo registrierten Dateien exportiert. Für mich ist eine nette Sache, dass dieser Export auch Dateien mit lokalen Änderungen enthält, die noch nicht festgeschrieben wurden; und eine andere nette sache ist, dass die zeitstempel der exportierten dateien die gleichen sind wie die originalen. Oder, wie es svn help export ausdrückt:

  1. Exportiert einen sauberen Verzeichnisbaum aus der in PATH1 angegebenen Arbeitskopie mit der Revision REV, sofern dieser angegeben ist, andernfalls mit WORKING in PATH2. ... Wenn REV nicht angegeben wird, bleiben alle lokalen Änderungen erhalten. Dateien, die nicht der Versionskontrolle unterliegen, werden nicht kopiert.

Um zu erkennen, dass git die Zeitstempel nicht beibehält, vergleichen Sie die Ausgabe dieser Befehle (in einem Unterordner eines git -Repos Ihrer Wahl):

/media/disk/git_svn/subdir$ ls -la .

... und:

/media/disk/git_svn/subdir$ git archive --format=tar --prefix=junk/ HEAD | (tar -t -v --full-time -f -)

... und ich bemerke auf jeden Fall, dass git archive bewirkt, dass alle Zeitstempel der archivierten Datei gleich sind! git help archive sagt:

git archive verhält sich bei einer Baum-ID anders als bei einer Commit-ID oder Tag-ID. Im ersten Fall wird die aktuelle Zeit als Änderungszeit für jede Datei im Archiv verwendet. Im letzteren Fall wird stattdessen die im referenzierten Festschreibungsobjekt aufgezeichnete Festschreibungszeit verwendet.

... aber anscheinend setzen beide Fälle die "Änderungszeit für jede Datei"; Dadurch werden die tatsächlichen Zeitstempel dieser Dateien nicht beibehalten!

Um auch die Zeitstempel beizubehalten, ist hier ein bash Skript, das eigentlich ein "Einzeiler" ist, wenn auch etwas kompliziert.

/media/disk/git_svn/subdir$ git archive --format=tar master | (tar tf -) | (\
  DEST="/media/diskC/tmp/subdirB"; \
  CWD="$PWD"; \
  while read line; do \
    DN=$(dirname "$line"); BN=$(basename "$line"); \
    SRD="$CWD"; TGD="$DEST"; \
    if [ "$DN" != "." ]; then \
      SRD="$SRD/$DN" ; TGD="$TGD/$DN" ; \
      if [ ! -d "$TGD" ] ; then \
        CMD="mkdir \"$TGD\"; touch -r \"$SRD\" \"$TGD\""; \
        echo "$CMD"; \
        eval "$CMD"; \
      fi; \
    fi; \
    CMD="cp -a \"$SRD/$BN\" \"$TGD/\""; \
    echo "$CMD"; \
    eval "$CMD"; \
    done \
)

Beachten Sie, dass davon ausgegangen wird, dass Sie den Inhalt in das "aktuelle" Verzeichnis exportieren (oben, /media/disk/git_svn/subdir) - und das Ziel, in das Sie exportieren, etwas ungünstig platziert ist, sich jedoch in der Umgebung DEST befindet Variable. Beachten Sie, dass mit diesem Skript; Sie müssen das Verzeichnis DEST manuell erstellen, bevor Sie das obige Skript ausführen.

Nach dem Ausführen des Skripts sollten Sie Folgendes vergleichen können:

ls -la /media/disk/git_svn/subdir
ls -la /media/diskC/tmp/subdirB   # DEST

... und sehen hoffentlich die gleichen Zeitstempel (für diejenigen Dateien, die unter Versionskontrolle standen).

Hoffe das hilft jemandem,
Prost!

3
sdaau

Mit Abstand der einfachste Weg, den ich je gesehen habe (und der auch unter Windows funktioniert), ist git bundle:

git bundle create /some/bundle/path.bundle --all

Weitere Informationen finden Sie in dieser Antwort: Wie kann ich mein Git-Repository über das USB-Laufwerk von meinem Windows-Computer auf einen Linux-Computer kopieren?

3
B T

Ich habe eine andere Lösung, die gut funktioniert, wenn Sie eine lokale Kopie des Repositorys auf dem Computer haben, auf dem Sie den Export erstellen möchten. Verschieben Sie in diesem Fall in dieses Repository-Verzeichnis und geben Sie den folgenden Befehl ein:

GIT_WORK_TREE=outputdirectory git checkout -f

Dies ist besonders nützlich, wenn Sie eine Website mit einem Git-Repository verwalten und eine saubere Version in /var/www/ auschecken möchten. In diesem Fall fügen Sie diesen Befehl in einem .git/hooks/post-receive -Skript hinzu (hooks/post-receive in einem leeren Repository, das in dieser Situation besser geeignet ist).

3
Tom

ein Git-Export in ein Zip-Archiv, während ein Präfix (z. B. ein Verzeichnisname) hinzugefügt wird:

git archive master --prefix=directoryWithinZip/  --format=Zip -o out.Zip
3
DomTomCat

Wenn Sie auch Submodule benötigen, sollte dies der Trick sein: https://github.com/meitar/git-archive-all.sh/wiki

2
Brandon

ich habe die folgende Utility-Funktion in meiner .bashrc-Datei: Es erstellt ein Archiv des aktuellen Zweigs in einem Git-Repository.

function garchive()
{
  if [[ "x$1" == "x-h" || "x$1" == "x" ]]; then
    cat <<EOF
Usage: garchive <archive-name>
create Zip archive of the current branch into <archive-name>
EOF
  else
    local oname=$1
    set -x
    local bname=$(git branch | grep -F "*" | sed -e 's#^*##')
    git archive --format Zip --output ${oname} ${bname}
    set +x
  fi
}
1
MichaelMoser

Die Option 1 klingt nicht zu effizient. Was ist, wenn auf dem Client kein Platz zum Klonen vorhanden ist und dann den Ordner .git entfernt?

Heute habe ich versucht, dies zu tun, wobei der Client ein Raspberry Pi ist, der fast keinen Platz mehr hat. Darüber hinaus möchte ich auch einige schwere Ordner aus dem Repository ausschließen.

Option 2 und andere Antworten hier helfen in diesem Szenario nicht. Weder git archive (da eine .gitattributes -Datei festgeschrieben werden muss und ich diesen Ausschluss nicht im Repository speichern möchte).

Hier teile ich meine Lösung, ähnlich wie Option 3, aber ohne die Notwendigkeit von git clone:

tmp=`mktemp`
git ls-tree --name-only -r HEAD > $tmp
rsync -avz --files-from=$tmp --exclude='fonts/*' . raspberry:

Das Ändern der rsync -Zeile durch eine entsprechende Zeile für die Komprimierung funktioniert auch als git archive, jedoch mit einer Art Ausschlussoption (wie angefordert hier ).

1
alexis