Question

Je me suis demandé s'il existait un bon "export git". solution qui crée une copie d’une arborescence sans le répertoire de référentiel .git . Je connais au moins trois méthodes:

  1. git clone suivi de la suppression du répertoire de référentiel .git .
  2. git checkout-index fait allusion à cette fonctionnalité mais commence par " Il suffit de lire l’arborescence souhaitée dans l’index ... " ce que je ne sais pas trop comment faire.
  3. git-export est un script tiers. cela fait 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. Le plus proche de svn export pourrait être l'option 1, car les deux exigent que le répertoire cible soit vide en premier. Mais l'option 2 semble encore meilleure, si je peux comprendre ce que signifie lire un arbre dans l'index.

Était-ce utile?

La solution

Le moyen le plus simple d'y parvenir est d'utiliser la archive git . Si vous avez vraiment besoin de l’arbre développé, vous pouvez faire quelque chose comme ceci.

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

La plupart du temps que j'ai besoin d'exporter quelque chose de git, je veux de toute façon une archive compressée, alors 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 

archive d'aide git 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 d’autres fichiers cachés spécifiques à git, tels que .gitignore, .gitattributes, etc. Si vous ne les voulez pas dans l’archive, assurez-vous d'utiliser l'attribut export-ignore dans un fichier .gitattributes et validez-le avant de créer votre archive. En savoir plus ...

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.)

Autres conseils

J'ai découvert la signification de l'option 2. A partir d'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 se trouveraient dans / destination avec un préfixe 'chemin'.

Étant donné que l'index contient normalement le contenu du référentiel, il n'y a rien de spécial à faire pour "lire l'arborescence souhaitée dans l'index". C'est déjà là.

L'indicateur -a est requis pour extraire tous les fichiers de l'index (je ne sais pas ce que signifie omettre cet indicateur dans cette situation, car il ne fait pas ce que je veux. ). L'indicateur -f force le remplacement des fichiers existants dans la sortie, ce que cette commande ne fait normalement pas.

Cela semble être le type de " exportation git " Je cherchais.

L'archive git 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 référentiel, ajoutez autant de chemins que vous le souhaitez comme 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

Réponse à un cas particulier si le référentiel est hébergé sur GitHub.

Utilisez simplement svn export .

Autant que je sache, Github n'autorise pas archive --remote . Bien que GitHub soit svn compatible et qu'ils disposent de tous les git repos svn accessible afin que vous puissiez simplement utiliser svn export comme vous le feriez normalement avec quelques ajustements à votre URL GitHub.

Par exemple, pour exporter un référentiel entier, notez comment trunk dans l'URL remplace maître (ou quel que soit le la branche HEAD du projet est définie sur ):

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

Et vous pouvez exporter un seul fichier, voire un certain chemin ou dossier:

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

Exemple avec la bibliothèque JavaScript jQuery

La branche HEAD ou maître sera disponible à l'aide de trunk :

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

Le non HEAD branches sera accessible sous / branches / :

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

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

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

Extrait du Manuel Git :

Utilisation de git-checkout-index pour "exporter un arbre entier"

La capacité de préfixe rend fondamentalement trivial l’utilisation de git-checkout-index comme "exportation sous forme d’arbre". une fonction. Il suffit de lire l’arbre souhaité dans l’index et de faire:

$ git checkout-index --prefix = rép_export-git / -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 devez ajouter -f ou - force .

L'installation est simple. déposez simplement le script quelque part dans votre CHEMIN et assurez-vous qu'il est exécutable.

référentiel github pour git-export

Il semble que cela pose moins de problèmes avec Git que SVN. Git ne place qu'un dossier .git à la racine du référentiel, alors que SVN place un dossier .svn dans chaque sous-répertoire. So " svn export " évite la magie récursive en 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 référentiel 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)

Si vous n'excluez pas les fichiers avec .gitattributes export-ignore , essayez git checkout

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

-f
  Lorsque vous extrayez des chemins de l'index, n'échouez pas lors de la suppression de la fusion.   les entrées; à la place, les entrées non fusionnées sont ignorées.

et

  

-q
  Évitez les commentaires verbeux

De plus, vous pouvez obtenir n'importe quelle branche ou balise ou une révision de validation spécifique, comme dans SVN, en ajoutant simplement 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 / chemin / à / checkout / doit être vide, Git ne supprimera aucun fichier, mais écrasera les fichiers du même nom sans aucun avertissement

UPDATE: Pour éviter le problème de décapitation ou pour laisser intact le référentiel de travail lors de l'utilisation de la validation pour l'exportation avec des balises, des branches ou SHA1, vous devez ajouter - ./ à la fin

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

Exemples:

Cette commande obtiendra uniquement le répertoire libs ainsi que le fichier readme.txt de ce commit exact

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

Ceci créera (écrasera) mon_fichier_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 obtenir l'exportation d'une autre branche

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

J'utilise beaucoup les sous-modules git. Celui-ci fonctionne pour moi:

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

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

  • Cela minimise le trafic vers un emplacement de référentiel distant en n'exportant pas toutes les révisions
  • Cela n'inclut pas les méta-informations dans le répertoire d'exportation
  • L’exportation d’une branche donnée à l’aide de svn est réalisée 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 création d’une version donnée, il est utile de cloner une branche stable, comme par exemple - branche stable ou - branche version / 0.9 .

Ceci va copier tout le contenu, moins les fichiers .dot. J'utilise cela pour exporter des projets clonés git dans le dépôt git de mon application Web sans les fichiers .git.

  

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

Plain old bash fonctionne tout simplement génial:)

Aussi simple que clone, supprimez le dossier .git:

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

Oui, ceci est une commande propre et soignée permettant d'archiver votre code sans aucune inclusion de git dans l'archive. se déplacer sans se soucier de l’historique des commits git.

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

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

  1. exportation d'un sous-dossier du référentiel (c'est ainsi que j'avais l'habitude d'utiliser la fonctionnalité d'exportation SVN)
  2. accepte de tout copier de ce dossier vers la destination de déploiement
  3. et puisque vous avez déjà une copie de tout le référentiel en place.

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

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 vous facilite la tâche:

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 souhaitez que le code soit placé dans un répertoire existant spécifique (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 --strip 1

Vous pouvez archiver un référentiel distant à n’importe quel commit en tant que fichier zip.

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

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 'git-archive' (sera publié ultérieurement).

J'ai également ajouté le fichier '.gitattributes' au processus afin de supprimer les fichiers inutiles du dossier d'exportation cible. Inclusion de verbosité dans le processus tout en rendant la fonction 'git-export' plus efficace.

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

Sortie:

     

$ git-export /tmp/rel-1.0.0

     

Ajout de fichiers '.empty' dans un ou plusieurs dossiers vides: ... terminé.

     

Composant (s) d’extraction de sortie: ... terminé.

     

Réinitialisation de HEAD et de l'Index: ... done.

     

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

     

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

     

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

     

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

     

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

     

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

     

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

     

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

     

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

     

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

     

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

     

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

     

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

     

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

     

terminé.

     

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

     

-rw-r - r-- 1 molette d'administration 25445901 le 3 novembre 12:57 /tmp/rel-1.0.0.tgz

     

J'ai maintenant intégré la fonctionnalité "git archive" dans un processus unique utilisant 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
# 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;
  }

Si vous voulez quelque chose qui fonctionne avec les sous-modules, cela vaut peut-être la peine d'essayer.

Remarque:

  • MASTER_DIR = une commande avec vos sous-modules empruntés également
  • DEST_DIR = où cette exportation aboutira
  • Si vous avez rsync, je pense que vous seriez capable de faire la même chose avec encore moins de douleur au ballon.

Hypothèses:

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

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

Ma préférence serait plutôt d'avoir une cible dist dans votre Makefile (ou un autre système de construction) qui exporte une archive distribuable de votre code (.tar.bz2, .zip, .jar ou ce qui est approprié). Si vous utilisez GNU autotools ou les systèmes MakeMaker de Perl, je pense que cela existe automatiquement pour vous. Sinon, je recommande fortement de l'ajouter.

ETA (2012-09-06): Ouah, critiques négatives. Je crois toujours qu'il est préférable de construire vos distributions avec vos outils de construction plutôt qu'avec 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 sommes en train de changer de système de contrôle de code source et la présence de cette cible ant signifie une migration de moins en cas de problème.

Ceci copiera les fichiers dans une plage de commits (C à G) dans un fichier tar. Remarque: seuls les fichiers validés seront récupérés. Pas le référentiel entier. Légèrement modifié à partir de ici

Exemple d'historique de validation

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

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 - > recurse en 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.

- nom uniquement - > Afficher uniquement les noms des fichiers modifiés.

- diff-filter = ACMRT - > Sélectionnez uniquement ces fichiers. Voir ici 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

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 <*> 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 utilisant la méthode la plus simple, c’est une fonction de .bash_profile, elle décompresse directement l’archive sur l’emplacement actuel, configurez d’abord votre [url: chemin] habituel. REMARQUE: Avec cette fonction, vous évitez les opérations de clonage, elles sont directement obtenues du référentiel distant.

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 ??pour .gitconfig, même configuration requise (TAKE CARE exécutant la commande dans les projets .git, il passe TOUJOURS au répertoire de base précédemment comme dit ici , jusqu'à ce que ce soit corrigé, je préfère personnellement la fonction

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

Si je comprends bien la question, il s’agit davantage de télécharger un certain état du serveur, sans historique, et sans les données d’autres branches, plutôt que d’extraire un état d’un référentiel local (comme beaucoup de réponses le font ici).

Cela peut se faire comme ceci:

git clone -b someBranch --depth 1 --single-branch git://somewhere.com/repo.git \
&& rm -rf repo/.git/
  • - une seule branche est disponible depuis Git 1.7.10 (avril 2012).
  • - profondeur est (était?) aurait été défectueux , mais dans le cas d'une exportation, les problèmes mentionnés ne devraient pas avoir d'importance.

Je pense que le message de @Aredridel était le plus proche, mais il y a un peu plus que cela - je vais donc ajouter ceci ici; la chose est, dans svn , si vous êtes dans un sous-dossier d'un référentiel, et vous faites:

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

alors svn exportera tous les fichiers en cours de contrôle de révision (ils pourraient également avoir un statut récemment ajouté; ou modifié) - et si vous avez d'autres "fichiers indésirables". dans ce répertoire (et je ne compte pas les sous-dossiers .svn ici, mais des éléments visibles tels que les fichiers .o ), il ne sera pas exporté ; seuls les fichiers enregistrés par le référentiel SVN seront exportés. Pour moi, une bonne chose est que cette exportation inclut également les fichiers avec des modifications locales qui n'ont pas encore été validées; et une autre bonne chose est que les horodatages des fichiers exportés sont les mêmes que ceux d'origine. Ou, comme le dit svn help export :

  
      
  1. Exporte une arborescence de répertoire vierge à partir de la copie de travail spécifiée par   PATH1, à la révision REV si elle est donnée, sinon à WORKING, dans   PATH2. ... Si REV n'est pas spécifié, tous les locaux   les changements seront préservés. Les fichiers non sous contrôle de version seront   ne pas être copié.
  2.   

Pour réaliser que git ne conservera pas les horodatages, comparez le résultat de ces commandes (dans un sous-dossier d'un référentiel git de votre choix):

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

... et:

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

... et je remarque de toute façon que archive git fait en sorte que tous les horodatages du fichier archivé soient identiques! archive d'aide git dit:

  

L'archive git se comporte différemment lorsqu'un identifiant d'arbre est attribué à un identifiant de validation ou un identifiant de tag. Dans le premier cas, le   l'heure actuelle est utilisée comme heure de modification de chaque fichier de l'archive. Dans ce dernier cas, le temps de validation enregistré   dans l'objet commit référencé est utilisé à la place.

... mais apparemment, les deux cas définissent le "délai de modification de chaque fichier" ;; ce qui ne conserve pas la conservation des horodatages réels de ces fichiers!

Donc, afin de préserver également les horodatages, voici un script bash , qui est en réalité un "one-liner", quoique quelque peu compliqué - il est affiché ci-dessous sur plusieurs lignes:

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

Notez qu'il est supposé que vous exportez le contenu dans " current " répertoire (ci-dessus, / media / disk / git_svn / subdir ) - et la destination dans laquelle vous exportez est placée de manière peu pratique, mais elle se trouve dans la variable d’environnement DEST . Notez cela avec ce script; vous devez créer manuellement le répertoire DEST vous-même, avant d'exécuter le script ci-dessus.

Une fois le script exécuté, vous devriez pouvoir comparer:

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

... et, espérons-le, voir les mêmes horodatages (pour les fichiers sous contrôle de version).

J'espère que cela aide quelqu'un,
À la vôtre!

De loin, le moyen le plus simple que j'ai vu de le faire (et fonctionne aussi sur Windows) est bundle Git :

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

Voir cette réponse pour plus de détails: Comment copier mon référentiel git de ma machine Windows sur une machine Linux via un lecteur USB?

J'ai une autre solution qui fonctionne bien si vous disposez d'une copie locale du référentiel sur la machine sur laquelle vous souhaitez créer l'exportation. Dans ce cas, accédez à ce répertoire de référentiel et entrez la commande suivante:

GIT_WORK_TREE = répertoire de sortie git checkout -f

Ceci est particulièrement utile si vous gérez un site Web avec un référentiel git et souhaitez extraire une version vierge dans / var / www / . Dans ce cas, ajoutez cette commande dans un script .git / hooks / post-receive ( hooks / post-receive sur un référentiel nu, ce qui est plus approprié dans cette situation).

une exportation git dans une archive zip tout en ajoutant un préfixe (nom de répertoire, par exemple):

git archive master --prefix=directoryWithinZip/  --format=zip -o out.zip

Si vous avez également besoin de sous-modules, cela devrait faire l'affaire: https: / /github.com/meitar/git-archive-all.sh/wiki

J'ai la fonction d'utilitaire suivante dans mon fichier .bashrc: il crée une archive de la branche actuelle dans un référentiel git.

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
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top