Rsync inclut une option astucieuse --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 d'exclure é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 incluent .gitignore
au moins une liste target
, le répertoire de construction par défaut de Maven (qui peut être présent au niveau supérieur ou dans des sous-modules). Étant donné que le contenu de ces répertoires est entièrement jetable et qu'ils peuvent être beaucoup plus volumineux que le code source, je voudrais les exclure lors de l'utilisation de rsync pour les sauvegardes.
Bien sûr, je peux explicitement, --exclude=target/
mais cela supprimera accidentellement les répertoires non liés qui se trouvent juste être nommés 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 de motifs mentionnés dans tout .gitignore
, .hgignore
ou svn:ignore
bien sur mon disque, mais ce serait une énorme liste qui devrait être produit 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 donner leurs modèles d'ignorance? Ou une sorte de système de rappel par lequel un script utilisateur peut être demandé 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
pour CVS, du moins sur les exemples que j'ai trouvés, bien que l'on ne sache pas si la syntaxe correspond exactement. --filter=':- .hgignore'
ne fonctionne pas très bien pour Mercurial; par exemple, un .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 auriez à analyser .svn/dir-prop-base
une copie de travail 1.6 ou antérieure, et à lever les mains avec consternation pour une copie de travail 1.7 ou ultérieure.
:-
signifie exactement? Que signifie le côlon? Qu'est-ce que le tableau de bord?check-ignore
sous-commande qui peut gérer le dur travail d'analyse des divers fichiers "ignorer", si vous voulez utiliser l'option "générer une liste de tous les fichiers non ignorés". Ma réponse ici donne des détails sur la façon de procéder.Réponses:
Comme mentionné par luksan, vous pouvez le faire avec le
--filter
passage àrsync
. J'ai réalisé cela avec--filter=':- .gitignore'
(il y a un espace avant ".gitignore") qui ditrsync
de faire une fusion de répertoire avec les.gitignore
fichiers et de les exclure par les règles de git. Vous pouvez également ajouter votre fichier ignorer global, si vous en avez un. Pour faciliter son utilisation, j'ai créé un aliasrsync
auquel le filtre était inclus.la source
--exclude='/.git' --filter="dir-merge,- .gitignore"
rsync -rvv --exclude='.git*' --exclude='/rsync-to-dev.sh' --filter='dir-merge,-n /.gitignore' $DIR/ development.foobar.com:~/test/
.. mais bien qu'il dise[sender] hiding file .gitignore because of pattern .git*
, le fichier est toujours envoyé à la desintation--delete
option, voici la ligne de commande de travail:rsync --delete-after --filter=":e- .gitignore" --filter "- .git/" -v -a ...
. Cela m'a pris du temps ...e
en filtre et--delete-after
sont tous les deux importants. Je suggère de lire le chapitre "RÈGLES PAR RÉPERTOIRE ET SUPPRIMER" de larsync
page de manuel.--delete-after
à la version de la commande de @ VasiliNovikov. (Cela semble équivalent à la version de la commande de @ dboliton, sauf que @db utilise: e qui, à mon avis, exclut les fichiers .gitignore de la copie, ce qui n'est pas ce que je voulais.)Vous pouvez utiliser
git ls-files
pour créer la liste des fichiers exclus par les.gitignore
fichiers du référentiel . https://git-scm.com/docs/git-ls-filesOptions:
--exclude-standard
Considérez tous les.gitignore
fichiers.-o
N'ignorez pas les changements non organisés.-i
Afficher uniquement les fichiers ignorés.--directory
Affiche le chemin du répertoire uniquement si le répertoire entier est ignoré.La seule chose qu'il me restait à ignorer était
.git
.la source
rsync -azP --exclude-from="$(git -C SRC ls-files --exclude-standard -oi --directory > /tmp/excludes; echo /tmp/excludes)" SRC DEST
.gitignore
(c'est-à-dire des lignes commençant par!
). Il synchronise également les fichiers que vous avez--force
ajoutés à votre dépôt, ce qui est généralement une bonne chose.et pourquoi
rsync --exclude-from='path/.gitignore' --exclude-from='path/myignore.txt' source destination
?Cela a fonctionné pour moi.
Je pense que vous pouvez aussi avoir plus de
--exclude-from
paramètres.la source
.gitignore
fichiers utilisent une syntaxe compatible avecrsync
.Solution 2018 confirmée
Détails:
--exclude-from
est obligatoire au lieu de --exclude car le cas probable qui exclut la liste ne serait pas analysé comme un argument. Exclure de nécessite un fichier et ne peut pas fonctionner avec des tuyaux.La solution actuelle enregistre le fichier d'exclusion dans le dossier .git afin de garantir qu'il n'affectera pas
git status
tout en le gardant autonome. Si vous le souhaitez, vous pouvez utiliser / tmp.la source
SRC
ici - mais pas pour le problème d'origine que j'ai déclaré, qui est un répertoire tentaculaire avec des milliers de référentiels Git comme sous-répertoires à différentes profondeurs, dont beaucoup ont idiosyncratique.gitignore
s.--exclude-from=<(git -C SRC ls-files --exclude-standard -oi --directory)
Pour mercurial, vous pourriez utiliser
pour collecter la liste des fichiers qui ne sont PAS sous contrôle mercurial en raison des restrictions .hgignore , puis exécutez
pour rsync tous les fichiers sauf ceux ignorés. Remarquez l' indicateur -m dans rsync qui exclura les répertoires vides de la synchronisation car hg status -i ne listerait que les fichiers exclus, pas les répertoires
la source
Essaye ça:
rsync -azP --delete --filter=":- .gitignore" <SRC> <DEST>
Il peut copier tous les fichiers dans le répertoire distant à l'exception des fichiers dans '.gitignore' et supprimer les fichiers qui ne se trouvent pas dans votre répertoire actuel.
la source
Selon la
rsync
page de manuel, en plus de la liste standard des modèles de fichiers:Donc, mon fichier $ HOME / .cvsignore ressemble à ceci:
pour exclure .git et les fichiers générés par Sass .
la source
.git/
répertoires, peut-être même plus fortement que la copie de travail. Ce que je veux exclure, ce sont les produits de construction.rsync
page de manuel citée dans cette réponse décrit l'--cvs-exclude
option, vous devez donc l'utiliser explicitement. 2 / Vous pouvez créer des.cvsignore
fichiers dans n'importe quel répertoire pour avoir des ignorés spécifiques au projet, ceux-ci sont également lus. 3 /.git
est déjà ignoré lorsque vous utilisez--cvs-exclude
, selon le manuel, donc l'avoir en$HOME/.cvsignore
semble redondant.J'avais un certain nombre de
.gitignore
fichiers très volumineux et aucune des solutions «rsync pure» ne fonctionnait pour moi. J'ai écrit ce script wrapper rsync , il respecte totalement les.gitignore
règles (incluez les!
exceptions de style -style et les.gitignore
fichiers dans les sous-répertoires) et a fonctionné comme un charme pour moi.la source
locate -0e .gitignore | (while read -d '' x; do process_git_ignore "$x"; done)
, mais a beaucoup de problèmes. Les fichiers dans le même répertoire.gitignore
ne sont pas correctement séparés du nom du répertoire avec/
. Lignes vides et commentaires mal interprétés. Étouffe les.gitignore
fichiers dans les chemins avec des espaces (sans parler/opt/vagrant/embedded/gems/gems/rb-fsevent-0.9.4/spec/fixtures/custom 'path/.gitignore
du diabolique duvagrant
paquet pour Ubuntu). Peut-être mieux fait en tant que script Perl.rsync
, pour la raison spécifique que la gestion des guillemets / espaces blancs est une telle douleur. Si vous avez un exemple degsync
ligne de commande qui échoue et les.gitignore
fichiers qui y sont associés, je serais heureux de l'examiner de plus près.rsync
un système de fichiers entier, avec divers dépôts Git dispersés autour de lui. Peut-être que votre script fonctionne correctement dans le cas de la synchronisation d'un seul référentiel.Consultez la section RÈGLES DE FILTRE DE FUSION-FILES dans rsync (1).
Il semble qu'il soit possible de créer une règle rsync --filter qui inclura les fichiers .gitignore au fur et à mesure que la structure des répertoires sera parcourue.
la source
Au lieu de créer des filtres d'exclusion, vous pouvez utiliser
git ls-files
pour sélectionner chaque fichier à rsync:Cela fonctionne même si
git ls-files
renvoie des chemins séparés par une nouvelle ligne. Ne fonctionnera probablement pas si vous avez des fichiers versionnés avec des espaces dans les noms de fichiers.la source
Alternatives:
git ls-files -zi --exclude-standard |rsync -0 --exclude-from=- ...
git ls-files -zi --exclude-per-directory=".gitignore" |...
(rsync ne comprend que partiellement .gitignore)
la source
Réponse courte
Paramètres signifiant:
-r
: récursif--info=...
: afficher la progression--filter=...
: exclure selon les règles répertoriées dans le fichier .gitignorela source