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
123
git
demandé sur altocumulus 2011-04-09 17:36:48

7 réponses

Essayez la commande suivante, que j'AI testée:

$ cp -pv --parents `git diff --name-only` DESTINATION-DIRECTORY
100
répondu York 2015-08-16 04:39:42

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 à avec git 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éfaut xargs voudrais ajouter les paramètres à la fin de la rsync commande. Au lieu de cela, cela dit de les mettre où le plus tard REPLACE 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.)

13
répondu Mark Longair 2017-04-13 12:13:48

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 -@
10
répondu kolypto 2012-02-22 00:56:58
zip update.zip $(git diff --name-only commit commit)
5
répondu Mark 2013-02-01 06:47:05
#!/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

2
répondu Surjit Sidhu 2017-05-23 11:55:07

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
2
répondu knight2016 2017-01-13 10:44:53

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
1
répondu hexten 2017-06-16 10:50:58