Je me demandais s'il existe une bonne solution "d'exportation git" qui crée une copie d'un arbre sans le répertoire de référentiel _.git
_. Je connais au moins trois méthodes:
git clone
_ suivi de la suppression du répertoire de référentiel _.git
_.git checkout-index
fait allusion à cette fonctionnalité mais commence par "Il suffit de lire l'arbre souhaité dans l'index ...", ce que je ne sais pas trop comment faire.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. 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, en supposant que je puisse comprendre ce que signifie lire un arbre dans l'index.
Le moyen le plus simple d'y parvenir est probablement git archive
. 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, 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
_
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 d’autres fichiers cachés spécifiques à git, tels que .gitignore, .gitattributes, etc. Si vous ne les voulez pas dans l’archive, assurez-vous utilisez l'attribut export-ignore dans un fichier .gitattributes et validez-le avant de créer votre archive. Lire plus ...
Remarque: Si vous souhaitez exporter l'index, la commande est
_git checkout-index -a -f --prefix=/destination/path/
_
(Voir réponse de Greg pour plus de détails)
J'ai découvert ce que l'option 2 signifie. 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'.
Comme 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'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 genre d '"exportation géniale" que je cherchais.
git archive
fonctionne également avec un 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
Il suffit d'utiliser svn export
.
Autant que je sache, Github n'autorise pas archive --remote
. Bien que GitHub soit svn compatible et qu'ils aient tous les dépôts Git svn
accessibles, vous pouvez 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 master
(ou quelle que soit la la branche du projet HEAD est définie sur ):
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
La branche HEAD
ou la branche principale sera disponible à l'aide de trunk
:
svn ls https://github.com/jquery/jquery/trunk
Les branches non -HEAD
seront accessibles sous /branches/
:
svn ls https://github.com/jquery/jquery/branches/2.1-stable
Toutes les balises sous /tags/
de la même manière:
svn ls https://github.com/jquery/jquery/tags/2.1.3
De la Manuel Git :
Utiliser git-checkout-index pour "exporter un arbre entier"
La capacité prefix rend fondamentalement trivial 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 ajouter -f
ou --force
.
L'installation est simple. déposez simplement le script quelque part dans votre PATH
et assurez-vous qu'il est exécutable.
Il semble que ce soit moins un problème 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. Donc, "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
dans un dépôt 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 de fichiers avec .gitattributes
export-ignore
, essayez alors 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 sur les entrées non fusionnées; au lieu de cela, les entrées non fusionnées sont ignorées.
et
-q
Évitez les commentaires
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 /path/to/checkout/
doit être vide, Git ne supprimera aucun fichier, mais écrasera les fichiers portant le même nom sans aucun avertissement.
UPDATE: pour éviter le problème décapité ou pour laisser intact le référentiel de travail lors de l'utilisation de la commande 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 et, dans ce cas également, indique à git checkout
de ne pas modifier le HEAD
.
Exemples:
Cette commande obtiendra uniquement le répertoire libs et également le fichier readme.txt
de ce dernier exactement
git --git-dir=/path/to/repo/.git --work-tree=/path/to/checkout/ checkout fef2e1f2de5f3d4f5e87df7d8 -f -q -- ./libs ./docs/readme.txt
Cela créera (écrasera) 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 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 lorsque je cherchais 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é:
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 --branch stable
ou --branch release/0.9
.
Cela 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 éléments .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 && rm -rf path_to_export/.git
Oui, this est une commande propre et ordonnée pour archiver votre code sans aucune inclusion de git dans l'archive et il est bon de le faire circuler sans se soucier de l'historique de ses validations.
git archive --format Zip --output /full/path/to/zipfile.Zip master
Je veux juste souligner que dans le cas où vous êtes
Ensuite, vous pouvez simplement utiliser cp foo [destination]
à la place du git-archive master foo | -x -C [destination]
mentionné.
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
facilite les choses:
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 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 --strip 1
Vous pouvez archiver un dépôt distant à n'importe quel commit sous forme de fichier Zip.
git archive --format=Zip --output=archive.Zip --remote=USERNAME@HOSTNAME:PROJECTNAME.git HASHOFGITCOMMIT
Si vous voulez quelque chose qui fonctionne avec des sous-modules, cela peut valoir le coup.
Remarque:
Hypothèses:
cd MASTER_DIR && tar -zcvf ../DEST_DIR/export.tar.gz --exclude = '. git *'. && cd ../DEST_DIR/ && tar xvfz export.tar.gz && rm export.tar.gz
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'index de check-out: ... terminé.
Réinitialisation de HEAD et index: ... done.
Purging Git-Specific composant (s): ...
'/tmp/rel-1.0.0/{.buildpath}' fichiers ... réalisés. '
'/tmp/rel-1.0.0/{.project}' fichiers ... réalisés. '
'/tmp/rel-1.0.0/{.gitignore}' fichiers ... réalisés. '
'/tmp/rel-1.0.0/{.git}' fichiers ... terminé. '
'/tmp/rel-1.0.0/{.gitattributes}' fichiers ... réalisés. '
'/tmp/rel-1.0.0/{*.mno}' fichiers ... réalisés. '
'/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 ... terminé. '
'/tmp/rel-1.0.0/{*.swo}' fichiers ... terminé. '
'/tmp/rel-1.0.0/{.DS_Store}' fichiers ... réalisés. '
'/tmp/rel-1.0.0/{.settings}' fichiers ... réalisés. '
'/tmp/rel-1.0.0/{.empty}' fichiers ... réalisés. '
terminé.
Archivage du (des) composant (s) extrait (s): ... terminé.
-rw-r - r-- 1 roue admin 25445901 3 nov. 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;
}
Ma préférence serait en fait 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 pour vous automatiquement. 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 basculer les systèmes de contrôle du code source, et la présence de cette cible ant signifie une migration de moins en cas de problème.
Cela 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.
--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 gamme 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 $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
Si je comprends bien la question, il s’agit plus 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 être fait comme ça:
git clone -b someBranch --depth 1 --single-branch git://somewhere.com/repo.git \
&& rm -rf repo/.git/
--single-branch
est disponible depuis Git 1.7.10 (avril 2012).--depth
est (était?) apparemment défectueux, mais dans le cas d'une exportation, les problèmes mentionnés ne devraient pas avoir d'importance.Pour le faire facilement, il s’agit d’une fonction pour .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 saute TOUJOURS au répertoire de base précédemment comme indiqué 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' -
Je pense que le message de @ Aredridel était le plus proche, mais il y a un peu plus que cela - je vais donc l'ajouter ici; la chose est, dans svn
, si vous êtes dans un sous-dossier d'un dépôt, et vous faites:
/media/disk/repo_svn/subdir$ svn export . /media/disk2/repo_svn_B/subdir
alors svn
exportera tous les fichiers sous 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 en faire partie .svn
sous-dossiers ici, mais des éléments visibles tels que .o
fichiers), 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é ; 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
:
- Exporte une arborescence de répertoire vierge de la copie de travail spécifiée par PATH1, à la révision REV si elle est fournie, sinon à WORKING, dans PATH2. ... Si REV n'est pas spécifié, toutes les modifications locales seront préservées. Les fichiers non sous contrôle de version ne seront pas copiés.
Pour réaliser que git
ne conservera pas les horodatages, comparez le résultat de ces commandes (dans un sous-dossier d'un repo 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 dans tous les cas, je remarque que git archive
fait en sorte que tous les horodatages du fichier archivé soient identiques! git help archive
dit:
git archive se comporte différemment lorsqu'un identifiant d'arbre est attribué à un identifiant de validation ou un identifiant de balise. Dans le premier cas, l'heure actuelle est utilisée comme heure de modification de chaque fichier de l'archive. Dans ce dernier cas, l'heure de validation telle qu'elle est enregistrée dans l'objet de validation référencé est utilisée à la place.
... mais apparemment les deux cas définissent "l'heure de modification de chaque fichier "; Ainsi pas en préservant les 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", bien qu'un peu compliqué - il est affiché en 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 le répertoire "courant" (ci-dessus, /media/disk/git_svn/subdir
) - et que la destination dans laquelle vous exportez est placée de manière peu commode, mais dans l'environnement DEST
variable. Notez cela avec ce script; vous devez créer vous-même le répertoire DEST
manuellement 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 ça aide quelqu'un,
À votre santé!
De loin le moyen le plus simple que j'ai vu de le faire (et fonctionne aussi sur Windows) est git bundle
:
git bundle create /some/bundle/path.bundle --all
Voir cette réponse pour plus de détails: Comment puis-je 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 avez une copie locale du référentiel sur la machine sur laquelle vous souhaitez créer l'exportation. Dans ce cas, déplacez-vous vers ce répertoire de référentiel et entrez la commande suivante:
GIT_WORK_TREE=outputdirectory 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 propre 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 vers une archive Zip tout en ajoutant un préfixe (par exemple, un nom de répertoire):
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
}
L'option 1 ne semble pas trop efficace. Que se passe-t-il s'il n'y a pas d'espace dans le client pour faire un clone et , puis supprimer le dossier .git
?
Aujourd'hui, je me suis retrouvé à essayer de le faire, le client étant un Raspberry Pi avec presque aucun espace. De plus, je souhaite également exclure certains dossiers lourds du référentiel.
L'option 2 et les autres réponses apportées ici n'aident en rien ce scénario. Ni git archive
(car il est nécessaire de valider un fichier .gitattributes
et je ne souhaite pas enregistrer cette exclusion dans le référentiel).
Ici, je partage ma solution, similaire à l'option 3, mais sans la nécessité de git clone
:
tmp=`mktemp`
git ls-tree --name-only -r HEAD > $tmp
rsync -avz --files-from=$tmp --exclude='fonts/*' . raspberry:
Changer la ligne rsync
pour une ligne équivalente à compresser fonctionnera également comme un git archive
mais avec une sorte d’option d’exclusion (comme demandé ici ).