172 votes

rsync exclure selon .gitignore & .hgignore & svn:ignore comme --filter=:C

Rsync comprend une option très pratique. --cvs-exclude pour "ignorer les fichiers de la même manière que CVS", mais CVS est obsolète depuis des années. Existe-t-il un moyen de faire en sorte qu'il exclue également les fichiers qui seraient ignorés par les systèmes de contrôle de version modernes (Git, Mercurial, Subversion) ?

Par exemple, j'ai beaucoup de projets Maven extraits de GitHub. En général, ils comprennent un .gitignore en énumérant au moins target le répertoire de construction Maven par défaut (qui peut être présent au niveau supérieur ou dans les sous-modules). Étant donné que le contenu de ces répertoires est entièrement jetable et qu'il peut être beaucoup plus important que le code source, je voudrais les exclure lorsque j'utilise rsync pour les sauvegardes.

Bien sûr, je peux explicitement --exclude=target/ mais cela supprimera accidentellement des répertoires non liés qui s'appellent simplement target et ne sont pas censés être ignorés.

Et je pourrais fournir une liste complète des chemins absolus pour tous les noms de fichiers et les modèles mentionnés dans n'importe quel fichier de la liste. .gitignore , .hgignore ou svn:ignore sur mon disque, mais ce serait une liste énorme qui devrait être produite par une sorte de script.

Puisque rsync n'a pas de support intégré pour les extractions VCS autres que CVS, y a-t-il une bonne astuce pour lui fournir leurs modèles d'ignorance ? Ou une sorte de système de rappel par lequel on peut demander à un utilisateur script si un fichier/répertoire donné doit être inclus ou non ?

Mise à jour : --filter=':- .gitignore' comme suggéré par LordJavac semble fonctionner aussi bien pour Git que --filter=:C le fait pour CVS, du moins sur les exemples que j'ai trouvés, bien qu'il ne soit pas clair si la syntaxe est une correspondance exacte. --filter=':- .hgignore' ne fonctionne pas très bien pour Mercurial ; par exemple, un fichier de type .hgignore contenant une ligne comme ^target$ (l'équivalent Mercurial de Git /target/ ) n'est pas reconnu par rsync comme une expression régulière. Et rien ne semble fonctionner pour Subversion, pour lequel vous devriez analyser .svn/dir-prop-base pour une copie de travail 1.6 ou antérieure, et levez les mains en signe de consternation pour une copie de travail 1.7 ou ultérieure.

1voto

Doug Harris Points 716

Par le rsync en plus de la liste standard des modèles de fichiers :

Les fichiers listés dans un fichier $HOME/.cvsignore sont ajoutés à la liste et tous les fichiers listés dans la variable d'environnement CVSIGNORE

Ainsi, mon fichier $HOME/.cvsignore ressemble à ceci :

.git/
.sass-cache/

pour exclure .git et les fichiers générés par Sass .

0voto

Adrian Points 466

Réponse courte

rsync -r --info=progress2 --filter=':- .gitignore' SOURCE DEST/

La signification des paramètres :

-r : récursif

--info=... : montrer les progrès

--filter=... : exclure par les règles listées dans le fichier .gitignore

0voto

Au lieu de créer des filtres d'exclusion, vous pouvez utiliser les éléments suivants git ls-files pour sélectionner chaque fichier à rsynchroniser :

#!/usr/bin/env bash

if [[ ! $# -eq 2 ]] ; then
    echo "Usage: $(basename $0) <local source> <rsync destination>"
    exit 1
fi

cd $1
versioned=$(git ls-files --exclude-standard)
rsync --verbose --links --times --relative --protect-args ${versioned} $2

Cela fonctionne même si git ls-files renvoie les chemins séparés par une nouvelle ligne. Cela ne fonctionnera probablement pas si vous avez des fichiers versionnés avec des espaces dans les noms de fichiers.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X