Ответ 1
Попробуйте выполнить следующую команду:
$ cp -pv --parents `git diff --name-only` DESTINATION-DIRECTORY
Я просто хочу получить список измененных файлов между двумя версиями, что просто:
git diff -–name-only commit1 commit2 > /path/to/my/file
Но что мне написать, если я хочу скопировать все перечисленные файлы в другое место? И мне нужна полностью идентичная структура каталогов для скопированных файлов.
Например, у меня есть модифицированные и добавленные файлы:
/protected/texts/file1.txt
/protected/scripts/index.php
/public/pics/pic1.png
Я хочу иметь в /home/changes/
все эти измененные и добавленные файлы:
/home/changes/protected/texts/file1.txt
/home/changes/protected/scripts/index.php
/home/changes/public/pics/pic1.png
Попробуйте выполнить следующую команду:
$ cp -pv --parents `git diff --name-only` DESTINATION-DIRECTORY
Следующее должно работать нормально:
git diff -z --name-only commit1 commit2 | xargs -0 -IREPLACE rsync -aR REPLACE /home/changes/protected/
Далее пояснить:
-z
to с git diff --name-only
означает вывести список файлов, разделенных NUL байтами вместо строк новой строки, на всякий случай, если ваши имена файлов имеют в них необычные символы.
-0
to xargs
говорит интерпретировать стандартный ввод как список параметров, разделенных нулями.
Требуется -IREPLACE
, поскольку по умолчанию xargs
будет добавлять параметры в конец команды rsync
. Вместо этого говорится, что они помещают их туда, где находится REPLACE
. (Это хороший отзыв от этого ответа на ошибку сервера.)
Параметр -a
на rsync
означает сохранение разрешений, прав собственности и т.д., если это возможно. -R
означает использование полного относительного пути при создании файлов в месте назначения.
Обновление: если у вас есть старая версия xargs
, вам нужно использовать опцию -i
вместо -i
. (Первая версия устарела в более поздних версиях findutils
.)
Здесь однострочный:
Перечислите измененные файлы и установите их как *.zip:
git diff --name-only | zip patched.zip [email protected]
Перечислить последние зафиксированные измененные файлы и упаковать их как *.zip:
git diff --name-only HEAD~ HEAD | zip patched.zip [email protected]
zip update.zip $(git diff --name-only commit commit)
#!/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
Он отлично работает.
git diff 1526043 82a4f7d --name-only | xargs zip update.zip
git diff 1526043 82a4f7d --name-only |xargs -n 10 zip update.zip
Никто не упомянул cpio
, который легко набрать, создает жесткие ссылки и обрабатывает пробелы в именах файлов:
git diff --name-only $from..$to | cpio -pld outdir