Git diff --name-only et copiez cette liste
Je veux juste obtenir une liste de fichiers modifiés entre deux révisions, ce qui est simple:
git diff -–name-only commit1 commit2 > /path/to/my/file
Mais, Que dois-je écrire, si je veux copier tous les fichiers listés à un autre endroit? Et j'ai besoin d'une structure de répertoire complètement identique pour les fichiers copiés.
Par exemple, j'ai modifié et ajouté des fichiers:
/protected/texts/file1.txt
/protected/scripts/index.php
/public/pics/pic1.png
Je veux avoir dans /home/changes/
tous ces fichiers modifiés et ajoutés:
/home/changes/protected/texts/file1.txt
/home/changes/protected/scripts/index.php
/home/changes/public/pics/pic1.png
7 réponses
Essayez la commande suivante, que j'AI testée:
$ cp -pv --parents `git diff --name-only` DESTINATION-DIRECTORY
Ce qui suit devrait fonctionner correctement:
git diff -z --name-only commit1 commit2 | xargs -0 -IREPLACE rsync -aR REPLACE /home/changes/protected/
Pour expliquer plus loin:
Le
-z
à avecgit diff --name-only
signifie afficher la liste des fichiers séparés par des octets nuls au lieu de sauts de ligne, juste au cas où vos noms de fichiers auraient des caractères inhabituels.Le
-0
àxargs
indique d'interpréter l'entrée standard comme une liste de paramètres séparée en NUL.Le
-IREPLACE
est nécessaire, car par défautxargs
voudrais ajouter les paramètres à la fin de larsync
commande. Au lieu de cela, cela dit de les mettre où le plus tardREPLACE
est. (C'est une bonne astuce de cette réponse D'erreur de serveur.)Le paramètre
-a
àrsync
signifie conserver les autorisations,la propriété, etc. si cela est possible. Le-R
signifie utiliser le chemin relatif complet lors de la création des fichiers dans la destination.
mise à Jour: si vous avez une ancienne version de xargs
, vous aurez besoin d'utiliser le -i
au lieu de -I
. (L'ancien est obsolète dans les versions ultérieures de findutils
.)
Voici un one-liner:
Liste les fichiers modifiés et les emballer comme *.code postal:
git diff --name-only | zip patched.zip -@
Liste les derniers fichiers modifiés validés et les emballer comme *.code postal:
git diff --name-only HEAD~ HEAD | zip patched.zip -@
#!/bin/bash
# Target directory
TARGET=/target/directory/here
for i in $(git diff --name-only)
do
# First create the target directory, if it doesn't exist.
mkdir -p "$TARGET/$(dirname $i)"
# Then copy over the file.
cp -rf "$i" "$TARGET/$i"
done
Https://stackoverflow.com/users/79061/sebastian-paaske-t%c3%b8rholm
Cela fonctionne parfaitement.
git diff 1526043 82a4f7d --name-only | xargs zip update.zip
git diff 1526043 82a4f7d --name-only |xargs -n 10 zip update.zip
Personne n'a mentionné {[1] } qui est facile à taper, crée des liens durs et gère les espaces dans les noms de fichiers:
git diff --name-only $from..$to | cpio -pld outdir