Faire un “git export” (comme “svn export”)?

Je me demandais s’il existe une bonne solution “git export” qui crée une copie d’une arborescence sans le .git référentiel .git . Il y a au moins trois méthodes que je connais:

  1. git clone suivi par la suppression du .git référentiel .git .
  2. git checkout-index fait allusion à cette fonctionnalité mais commence par “Il suffit de lire l’arbre souhaité dans l’index …”, ce que je ne suis pas tout à fait sûr de savoir faire.
  3. git-export est un script tiers qui effectue essentiellement un git clone dans un emplacement temporaire suivi de rsync --exclude='.git' dans la destination finale.

Aucune de ces solutions ne me semble vraiment satisfaisante. La plus proche de svn export pourrait être l’option 1, car les deux requièrent que le répertoire cible soit vide en premier. Mais l’option 2 semble encore meilleure, en supposant que je puisse comprendre ce que signifie lire un arbre dans l’index.

Le moyen le plus simple d’y parvenir est sans doute d’ git archive . Si vous avez vraiment besoin de l’arborescence développée, vous pouvez faire quelque chose comme ça.

 git archive master | tar -x -C /somewhere/else 

La plupart du temps, j’ai besoin d’exporter quelque chose à partir de git, je veux en tout cas une archive compressée, donc je fais quelque chose comme ça.

 git archive master | bzip2 >source-tree.tar.bz2 

Archive ZIP:

 git archive --format zip --output /full/path/to/zipfile.zip master 

git help archive pour plus de détails, c’est assez flexible.


Sachez que même si l’archive ne contient pas le répertoire .git, elle contiendra cependant d’autres fichiers cachés spécifiques à git, tels que .gitignore, .gitatsortingbutes, etc. Si vous ne les voulez pas dans l’archive, assurez-vous Utilisez l’atsortingbut export-ignore dans un fichier .gitatsortingbutes et validez-le avant de faire votre archive. Lire la suite…


Remarque: Si vous souhaitez exporter l’index, la commande est

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

(Voir la réponse de Greg pour plus de détails)

J’ai découvert quelle option 2 signifie. Depuis un référentiel, vous pouvez faire:

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

La barre oblique à la fin du chemin est importante, sinon les fichiers seront dans / destination avec un préfixe de «chemin».

Dans une situation normale, l’index contient le contenu du référentiel, il n’y a rien de spécial à faire pour “lire l’arbre désiré dans l’index”. C’est déjà là.

L’indicateur -a est nécessaire pour extraire tous les fichiers de l’index (je ne suis pas sûr de savoir ce que cela signifie d’omettre cet indicateur dans cette situation, car il ne fait pas ce que je veux). L’indicateur -f force l’écrasement des fichiers existants dans la sortie, ce que ne fait normalement pas cette commande.

Cela semble être le genre de “git export” que je cherchais.

git archive fonctionne également avec le référentiel distant.

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

Pour exporter un chemin particulier dans le repository, ajoutez autant de chemins que vous souhaitez pour le dernier argument de git, par exemple:

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

entrer la description de l'image ici

Un cas particulier répond si le référentiel est hébergé sur GitHub.

Utilisez simplement svn export .

A ma connaissance, Github n’autorise pas l’ archive --remote . Bien que GitHub soit compatible avec svn et que tous les git repos svn soient accessibles, vous pouvez simplement utiliser svn export comme vous le feriez normalement avec quelques ajustements de votre URL GitHub.

Par exemple, pour exporter un référentiel complet, notez comment le trunk dans l’URL remplace le master (ou quelle que soit la twig HEAD du projet ):

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

Et vous pouvez exporter un seul fichier ou même un certain chemin ou dossier:

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

Exemple avec jQuery JavaScript Library

La twig HEAD ou twig principale sera disponible en utilisant le trunk :

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

Les twigs non HEAD seront accessibles sous /twigs/ :

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

Tous les tags sous /tags/ de la même manière:

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

Du manuel Git :

Utilisation de git-checkout-index pour “exporter un arbre entier”

La capacité de préfixe rend fondamentalement sortingvial l’utilisation de git-checkout-index en tant que fonction “export as tree”. Il suffit de lire l’arbre souhaité dans l’index et de faire:

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

J’ai écrit un simple wrapper autour de git-checkout-index que vous pouvez utiliser comme ceci:

 git export ~/the/destination/dir 

Si le répertoire de destination existe déjà, vous devrez append -f ou --force .

L’installation est simple Il suffit de déposer le script quelque part dans votre PATH et de vous assurer qu’il est exécutable.

Le repository github pour git-export

Il semble que ce soit moins un problème avec Git que SVN. Git ne place qu’un dossier .git dans la racine du référentiel, alors que SVN place un dossier .svn dans chaque sous-répertoire. Donc, “svn export” évite la magie récursive de la ligne de commande, alors qu’avec Git, la récursivité n’est pas nécessaire.

L’équivalent de

 svn export . otherpath 

à l’intérieur d’un repo existant est

 git archive branchname | (cd otherpath; tar x) 

L’équivalent de

 svn export url otherpath 

est

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

J’utilise beaucoup les sous-modules git. Celui-ci travaille pour moi:

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

Si vous n’excluez pas les fichiers avec .gitatsortingbutes export-ignore puis essayez git checkout

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

-F
Lors de la vérification des chemins de l’index, ne pas échouer sur les entrées non fusionnées; à la place, les entrées non fusionnées sont ignorées.

et

-q
Éviter les verbeux

De plus, vous pouvez obtenir une twig, un tag ou une révision de validation spécifique comme dans SVN en ajoutant simplement le SHA1 (SHA1 dans Git est l’équivalent du numéro de révision dans SVN)

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

Le fichier /path/to/checkout/ doit être vide, Git ne supprimera aucun fichier, mais écrasera les fichiers portant le même nom sans aucun avertissement

MISE À JOUR: Pour éviter le problème décapité ou pour laisser intact le référentiel de travail lorsque vous utilisez l’extraction pour l’exportation avec des balises, des twigs ou SHA1, vous devez append -- ./ à la fin

Le double tiret -- indique à git que tout ce qui suit les tirets sont des chemins ou des fichiers, et dans ce cas, indique à git checkout de ne pas modifier le HEAD

Exemples:

Cette commande obtiendra juste le répertoire libs ainsi que le fichier readme.txt de celui

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

Cela va créer (écraser) my_file_2_behind_HEAD.txt deux commits derrière la tête 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 

Pour exporter l’exportation d’une autre twig

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

Notez que ./ est relatif à la racine du référentiel

Ceci copiera tous les contenus, moins les fichiers .dot. Je l’utilise pour exporter des projets git clonés dans le repository git de mon application web sans les trucs .git.

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

Plain Old Bash fonctionne tout simplement génial 🙂

J’ai fréquemment consulté cette page lorsque je cherchais un moyen d’exporter un repository git. Ma réponse à cette question considère trois propriétés que svn export a de par sa conception par rapport à git, puisque svn suit une approche de référentiel centralisé:

  • Il minimise le trafic vers un emplacement de référentiel distant en n’exportant pas toutes les révisions
  • Il n’inclut pas les méta-informations dans le répertoire d’exportation
  • L’exportation d’une certaine twig en utilisant svn est accomplie en spécifiant le chemin approprié

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

Lors de la construction d’une certaine version, il est utile de cloner une twig stable, par exemple --branch stable ou --branch release/0.9 .

Aussi simple que cloner, supprimez le dossier .git:

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

Je veux juste souligner que dans le cas où vous êtes

  1. exporter un sous-dossier du référentiel (c’est comme ça que j’utilisais la fonctionnalité d’exportation SVN)
  2. OK pour copier tout depuis ce dossier vers la destination de déploiement
  3. et puisque vous avez déjà une copie du référentiel complet en place.

Ensuite, vous pouvez simplement utiliser cp foo [destination] place du git-archive master foo | -x -C [destination] mentionné git-archive master foo | -x -C [destination] git-archive master foo | -x -C [destination] .

Vous pouvez archiver un repo distant à n’importe quel commit en tant que fichier zip.

 git archive --format=zip --output=archive.zip --remote=USERNAME@HOSTNAME:PROJECTNAME.git HASHOFGITCOMMIT 

Pour les utilisateurs de GitHub, la méthode git archive --remote ne fonctionnera pas directement, car l’URL d’exportation est éphémère . Vous devez demander l’URL à GitHub, puis télécharger cette URL. curl rend cela facile:

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

Cela vous donnera le code exporté dans un répertoire local. Exemple:

 $ 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 

modifier
Si vous voulez que le code soit placé dans un répertoire spécifique existant (plutôt que dans le répertoire aléatoire de github):

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

Oui, il s’agit d’une commande propre et ordonnée pour archiver votre code sans aucune inclusion git dans l’archive et il est bon de la faire circuler sans vous soucier de l’historique de commit git.

 git archive --format zip --output /full/path/to/zipfile.zip master 

Bash-implémentation de git-export.

J’ai segmenté les processus de création et de suppression de fichiers .empty sur leur propre fonction, dans le but de les réutiliser dans l’implémentation de ‘git-archive’ (qui sera publiée ultérieurement).

J’ai également ajouté le fichier ‘.gitatsortingbutes’ au processus afin de supprimer les fichiers indésirables du dossier d’exportation cible. Verbosité incluse dans le processus tout en rendant la fonction «git-export» plus efficace.

EMPTY_FILE = “. Vide”;

 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; } 

Sortie:

$ git-export /tmp/rel-1.0.0

Ajouter des fichiers '.empty' aux dossiers vides: ... done.

Composant (s) d'index de vérification: ... terminé.

Réinitialisation HEAD et Index: ... terminé.

Purge des composants spécifiques à Git: ...

'/tmp/rel-1.0.0/{.buildpath}' fichiers ... terminés. '

'/tmp/rel-1.0.0/{.project}' fichiers ... terminés. '

'/tmp/rel-1.0.0/{.gitignore}' fichiers ... terminés. '

'/tmp/rel-1.0.0/{.git}' fichiers ... faits. '

'/tmp/rel-1.0.0/{.gitatsortingbutes}' fichiers ... terminés. '

'/tmp/rel-1.0.0/{*.mno}' fichiers ... terminés. '

'/tmp/rel-1.0.0/{*~}' fichiers ... terminés. '

'/tmp/rel-1.0.0/{.*~}' fichiers ... faits. '

'/tmp/rel-1.0.0/{*.swp}' fichiers ... terminés. '

'/tmp/rel-1.0.0/{*.swo}' fichiers ... terminés. '

'/tmp/rel-1.0.0/{.DS_Store}' fichiers ... terminés. '

'/tmp/rel-1.0.0/{.settings}' fichiers ... terminés. '

'/tmp/rel-1.0.0/{.empty}' fichiers ... terminés. '

terminé.

Archivage composant (s) extrait (s): ... terminé.

-rw-r - r-- 1 roue d'administration 25445901 3 nov 12:57 /tmp/rel-1.0.0.tgz

J'ai maintenant intégré la fonctionnalité «archive git» dans un processus unique qui utilise la fonction «create_empty» et d'autres fonctionnalités.

 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 # eg: 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; } 

Si vous voulez quelque chose qui fonctionne avec des sous-modules, cela pourrait valoir le coup.

Remarque:

  • MASTER_DIR = un checkout avec vos sous-modules extraits également
  • DEST_DIR = où cette exportation se terminera
  • Si vous avez du rsync, je pense que vous seriez capable de faire la même chose avec encore moins de douleurs au niveau de la balle.

Hypothèses:

  • Vous devez l’exécuter à partir du répertoire parent de MASTER_DIR (c.-à-d. À partir de cd MASTER_DIR ..)
  • DEST_DIR est supposé avoir été créé. C’est assez facile à modifier pour inclure la création d’un DEST_DIR si vous voulez

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

Cela copiera les fichiers dans une plage de commits (C à G) dans un fichier tar. Note: ceci ne fera que commettre les fichiers. Pas l’intégralité du référentiel. Légèrement modifié d’ ici

Exemple Commit History

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

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

Page de manuel de git-diff-tree

-r -> récurer dans les sous-arbres

–no-commit-id -> git diff-tree génère une ligne avec l’ID de validation, le cas échéant. Cet indicateur a supprimé la sortie de l’ID de validation.

–name-only -> Affiche uniquement les noms des fichiers modifiés.

–diff-filter = ACMRT -> Sélectionnez uniquement ces fichiers. Voir ici pour la liste complète des fichiers

C..G -> Fichiers dans cette plage de commits

C ~ -> Inclure les fichiers de Commit C. Pas seulement les fichiers depuis Commit C.

| xargs tar -rf myTarFile -> sorties vers tar

Ma préférence serait en fait d’avoir une cible distante dans votre Makefile (ou autre système de compilation) qui exporte une archive dissortingbuable de votre code (.tar.bz2, .zip, .jar ou tout ce qui est approprié). Si vous utilisez des autotools GNU ou des systèmes MakeMaker de Perl, je pense que cela existe automatiquement pour vous. Sinon, je recommande fortement de l’append.

ETA (2012-09-06): Wow, rudes baisses. Je pense toujours qu’il est préférable de construire vos dissortingbutions avec vos outils de génération plutôt que votre outil de contrôle de code source. Je crois en la construction d’artefacts avec des outils de construction. Dans mon travail actuel, notre produit principal est construit avec une cible de fourmi. Nous sums en train de changer de système de contrôle de code source, et la présence de cette cible ant un problème de migration de moins.

J’avais besoin de cela pour un script de déploiement et je ne pouvais utiliser aucune des approches mentionnées ci-dessus. Au lieu de cela, j’ai trouvé une solution différente:

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

En toute simplicité, il s’agit d’une fonction pour .bash_profile, qui décompresse directement l’archive sur l’emplacement actuel, configurez d’abord votre [url: path] habituel. REMARQUE: Avec cette fonction, vous évitez l’opération de clonage, elle provient directement du repository à distance.

 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 for .gitconfig, same configuration required (TAKE CARE executing the command inside .git projects, it ALWAYS jumps to the base dir previously as said here , until this is fixed I personally prefer the function

 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' - 

I think @Aredridel ‘s post was closest, but there’s a bit more to that – so I will add this here; the thing is, in svn , if you’re in a subfolder of a repo, and you do:

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

then svn will export all files that are under revision control (they could have also freshly Added; or Modified status) – and if you have other “junk” in that directory (and I’m not counting .svn subfolders here, but visible stuff like .o files), it will not be exported; only those files registered by the SVN repo will be exported. For me, one nice thing is that this export also includes files with local changes that have not been committed yet; and another nice thing is that the timestamps of the exported files are the same as the original ones. Or, as svn help export puts it:

  1. Exports a clean directory tree from the working copy specified by PATH1, at revision REV if it is given, otherwise at WORKING, into PATH2. … If REV is not specified, all local changes will be preserved. Files not under version control will not be copied.

To realize that git will not preserve the timestamps, compare the output of these commands (in a subfolder of a git repo of your choice):

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

… and:

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

… and I, in any case, notice that git archive causes all the timestamps of the archived file to be the same! git help archive says:

git archive behaves differently when given a tree ID versus when given a commit ID or tag ID. In the first case the current time is used as the modification time of each file in the archive. In the latter case the commit time as recorded in the referenced commit object is used instead.

… but apparently both cases set the “modification time of each file”; thereby not preserving the actual timestamps of those files!

So, in order to also preserve the timestamps, here is a bash script, which is actually a “one-liner”, albeit somewhat complicated – so below it is posted in multiple lines:

 /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 \ ) 

Note that it is assumed that you’re exporting the contents in “current” directory (above, /media/disk/git_svn/subdir ) – and the destination you’re exporting into is somewhat inconveniently placed, but it is in DEST environment variable. Note that with this script; you must create the DEST directory manually yourself, before running the above script.

After the script is ran, you should be able to compare:

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

… and hopefully see the same timestamps (for those files that were under version control).

Hope this helps someone,
À votre santé!

By far the easiest way i’ve seen to do it (and works on windows as well) is git bundle :

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

See this answer for more details: How can I copy my git repository from my windows machine to a linux machine via usb drive?

If you need submodules as well, this should do the sortingck: https://github.com/meitar/git-archive-all.sh/wiki

i have the following utility function in my .bashrc file: it creates an archive of the current branch in a git repository.

 function garchive() { if [[ "x$1" == "xh" || "x$1" == "x" ]]; then cat < create zip archive of the current branch into  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 } 

The option 1 sounds not too efficient. What if there is no space in the client to do a clone and then remove the .git folder?

Today I found myself trying to do this, where the client is a Raspberry Pi with almost no space left. Furthermore, I also want to exclude some heavy folder from the repository.

Option 2 and others answers here do not help in this scenario. Neither git archive (because require to commit a .gitatsortingbutes file, and I don’t want to save this exclusion in the repository).

Here I share my solution, similar to option 3, but without the need of git clone :

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

Changing the rsync line for an equivalent line for compress will also work as a git archive but with a sort of exclusion option (as is asked here ).

I have another solution that works fine if you have a local copy of the repository on the machine where you would like to create the export. In this case move to this repository directory, and enter this command:

GIT_WORK_TREE=outputdirectory git checkout -f

This is particularly useful if you manage a website with a git repository and would like to checkout a clean version in /var/www/ . In this case, add thiscommand in a .git/hooks/post-receive script ( hooks/post-receive on a bare repository, which is more suitable in this situation)

As I understand the question, it it more about downloading just certain state from the server, without history, and without data of other twigs, rather than extracting a state from a local repository (as many anwsers here do).

That can be done like this:

 git clone -b someBranch --depth 1 --single-branch git://somewhere.com/repo.git \ && rm -rf repo/.git/ 
  • --single-branch is available since Git 1.7.10 (April 2012).
  • --depth is (was?) reportedly faulty, but for the case of an export, the mentioned issues should not matter.