Экспорт только измененных и добавленных файлов со структурой папок в Git
Я хотел бы получить список измененных и добавленных файлов в определенный коммит, так что я могу экспортировать их и создать пакет с файловой структурой.
идея в том, чтобы получить пакет и распаковать его на сервере. По многим причинам я не могу создать крюк, чтобы автоматически вытащить РЕПО, и самый простой способ, которым я должен обновить сервер, - это создать этот пакет.
11 ответов:
git diff-tree -r --no-commit-id --name-only --diff-filter=ACMRT $commit_id
git diff-tree -r $commit_id:возьмите diff данной фиксации к ее родителю(ам) (включая все подкаталоги, а не только верхний каталог).
--no-commit-id --name-only:не выводите коммит SHA1. Выводить только имена файлов, а не полный дифференциал.
--diff-filter=ACMRT:показывать только файлы, добавленные, скопированные, измененные, переименованные или изменившие свой тип (например. файл → символическая ссылка) в этом совершают. Это оставляет удаленные файлы.
git diff-tree -r --no-commit-id --name-only --diff-filter=ACMRT $commit_id | xargs tar -rf mytarfile.tarпросто чтобы завершить это, вот команда, переданная в tar. Это экспортирует файлы в архив tar.
вот однострочная команда, которая работает на Windows 7. Запустите его из папки верхнего уровня вашего репозитория.
для /F "usebackq жетонов=*" %a в (`ГИТ дифф-дерево -р-нет фиксации-идентификатор-имя-только-дифф-фильтр=ACMRT Глава~1 глава`) сделать эхо Альфа|команды xcopy "%~альфа" "C:\git_changed_files\%A"
- Эхо отвечает на неизбежный вопрос xcopy о том, копируете ли вы файл или каталог (файл), и возможный вопрос о перезапись файла (перезаписать все)
- usebackq позволяет нам использовать выходные данные нашей команды git в качестве входных данных для нашего предложения do
- ГЛАВА~1 ГОЛОВКА получает все различия между предыдущей фиксацией и текущей головкой
- %~fA преобразует вывод git в полные пути (необходимые для изменения косых черт на обратные)
- C:\git_changed_files\ где вы найдете все файлы, которые отличаются
если ваш хэш фиксации, например, a9359f9, эта команда:
git archive -o patch.zip a9359f9 $(git diff --name-only a9359f9^..a9359f9)извлекает файлы, измененные в фиксации, и помещает их в патч.zip при сохранении структуры каталогов проекта нетронутыми.
немного многословно, хэш фиксации упоминается три раза, но это, кажется, работает для меня.
получил его здесь : http://tosbourn.com/2011/05/git/using-git-to-create-an-archive-of-changed-files/
вы можете экспортировать diff с помощью Черепаха ГИТ для MS Windows:
Я щелкните правой кнопкой мыши и выберите TortoiseGit>Показать Журнал и Сообщения Журнала будет открыт.
выберите две ревизии и сравните их. разницу между будет открыт.
Выберите файлы и выбор экспорт ... в папку!
мне нужно обновить мой тестовый сервер и добавить файлы, которые изменились начиная с версии 2.1.
Для меня работало аналогичное решение, как написал Джеймс Эли, но в моем случае я хотел экспортировать в архив пакет разницы между двумя старыми тегами - tag_ver_2.1 и tag_ver_2.2 не только один коммит.например:
tag_ver_2.1 = 1f72b38adtag_ver_2.2 = c1a546782
Вот модифицированный пример:git diff-tree -r --no-commit-id --name-only c1a546782 1f72b38ad | xargs tar -rf test.tar
Я сделал php скрипт для экспорта измененных файлов в Windows. Если у вас есть сервер разработки localhost с установленным php, вы можете легко запустить его. Он будет помнить ваш последний репозиторий и экспортировать всегда в ту же папку. Папка экспорта всегда очищается перед экспортом. Вы также увидите удаленные файлы в красном, так что вы знаете, что удалить на сервере.
это всего лишь два файла, поэтому я опубликую их здесь. Давайте предположим, что ваши репозитории находятся под c:/www в свои папки и то http://localhost также указывает на c:/www и php-включен. Давайте положим эти 2 файла в c:/www/git-export -
.php:<?php /* create directory if doesn't exist */ function createDir($dirName, $perm = 0777) { $dirs = explode('/', $dirName); $dir=''; foreach ($dirs as $part) { $dir.=$part.'/'; if (!is_dir($dir) && strlen($dir)>0) { mkdir($dir, $perm); } } } /* deletes dir recursevely, be careful! */ function deleteDirRecursive($f) { if (strpos($f, "c:/www/export" . "/") !== 0) { exit("deleteDirRecursive() protection disabled deleting of tree: $f - please edit the path check in source php file!"); } if (is_dir($f)) { foreach(scandir($f) as $item) { if ($item == '.' || $item == '..') { continue; } deleteDirRecursive($f . "/" . $item); } rmdir($f); } elseif (is_file($f)) { unlink($f); } } $lastRepoDirFile = "last_repo_dir.txt"; $repo = isset($_POST['repo']) ? $_POST['repo'] : null; if (!$repo && is_file($lastRepoDirFile)) { $repo = file_get_contents($lastRepoDirFile); } $range = isset($_POST['range']) ? $_POST['range'] : "HEAD~1 HEAD"; $ini = parse_ini_file("git-export.ini"); $exportDir = $ini['export_dir']; ?> <html> <head> <title>Git export changed files</title> </head> <body> <form action="." method="post"> repository: <?=$ini['base_repo_dir'] ?>/<input type="text" name="repo" value="<?=htmlspecialchars($repo) ?>" size="25"><br/><br/> range: <input type="text" name="range" value="<?=htmlspecialchars($range) ?>" size="100"><br/><br/> target: <strong><?=$exportDir ?></strong><br/><br/> <input type="submit" value="EXPORT!"> </form> <br/> <?php if (!empty($_POST)) { /* ************************************************************** */ file_put_contents($lastRepoDirFile, $repo); $repoDir = $ini['base_repo_dir'] ."/$repo"; $repoDir = rtrim($repoDir, '/\'); echo "<hr/>source repository: <strong>$repoDir</strong><br/>"; echo "exporting to: <strong>$exportDir</strong><br/><br/>\n"; createDir($exportDir); // empty export dir foreach (scandir($exportDir) as $file) { if ($file != '..' && $file != '.') { deleteDirRecursive("$exportDir/$file"); } } // execute git diff $cmd = "git --git-dir=$repoDir/.git diff $range --name-only"; exec("$cmd 2>&1", $output, $err); if ($err) { echo "Command error: <br/>"; echo implode("<br/>", array_map('htmlspecialchars', $output)); exit; } // $output contains a list of filenames with paths of changed files foreach ($output as $file) { $source = "$repoDir/$file"; if (is_file($source)) { if (strpos($file, '/')) { createDir("$exportDir/" .dirname($file)); } copy($source, "$exportDir/$file"); echo "$file<br/>\n"; } else { // deleted file echo "<span style='color: red'>$file</span><br/>\n"; } } } ?> </body> </html>git-экспорт.ini:
; path to all your git repositories for convenience - less typing base_repo_dir = c:/www ; if you change it you have to also change it in the php script ; in deleteDirRecursive() function - this is for security export_dir = c:/www/exportа теперь загрузите localhost/ git-export / в браузере. Скрипт настроен на экспорт всегда в c:/www/export -измените все пути в соответствии с вашей средой или измените сценарий в соответствии с вашими потребностями.
это будет работать, если у Вас установлен Git так что команда git находится в вашем пути - это можно настроить при запуске установщика windows Git.
для экспорта измененных файлов, начиная с даты:
diff --stat @{2016-11-01} --diff-filter=ACRMRT --name-only | xargs tar -cf 11.tarярлык (использовать псевдоним)
git exportmdf 2016-11-01 11.tarпсевдоним .gitconfig
[alias] exportmdf = "!f() { \ git diff --stat @{} --diff-filter=ACRMRT --name-only | xargs tar -cf ; \ }; f"
вот небольшой скрипт bash (Unix), который я написал, который будет копировать файлы для данного хэша фиксации со структурой папок:
ARRAY=($(git diff-tree -r --no-commit-id --name-only --diff-filter=ACMRT )) PWD=$(pwd) if [ -d "" ]; then for i in "${ARRAY[@]}" do : cp --parents "$PWD/$i" done else echo "Chosen destination folder does not exist." fiсоздать файл с именем ' ~/Scripts/copy-commit.sh-тогда дайте ему право на исполнение:
chmod a+x ~/Scripts/copy-commit.shзатем из корня репозитория git:
~/Scripts/copy-commit.sh COMMIT_KEY ~/Existing/Destination/Folder/
ниже команды работали для меня.
Если вы хотите разницу файлов, измененных последней фиксацией:
git archive -o update.zip HEAD $(git diff --name-only HEAD^)или если вы хотите разницу между двумя конкретными фиксациями:
git archive -o update.zip 4d50f1ee78bf3ab4dd8e66a1e230a64b62c49d42 $(git diff --name-only 07a698fa9e5af8d730a8c33e5b5e8eada5e0f400)или если у вас есть незафиксированные файлы, помните, что Git way должен фиксировать все, ветви дешевы:
git stash git checkout -b feature/new-feature git stash apply git add --all git commit -m 'commit message here' git archive -o update.zip HEAD $(git diff --name-only HEAD^)
Я также сталкивался с подобной проблемой раньше. Я написал простой сценарий оболочки.
$git log --reverse commit_HashX^..commit_HashY --pretty=format:'%h'приведенная выше команда отобразит хэш фиксации (ревизию) от commit_HashX до commit_HashY в обратном порядке.
456d517 (second_hash) 9362d03 5362d03 226x47a 478bf6b (six_hash)Теперь основной сценарий оболочки с помощью команды выше.
commitHashList=$(git log --reverse ^.. --pretty=format:'%h') for hash in $commitHashList do echo "$hash" git archive -o \Path_Where_you_want_store\ChangesMade.zip $hash doneдобавить этот код export_changes.sh теперь передайте файл и зафиксируйте хэши в скрипте.
убедитесь, что начальный commit_hash должен быть первым аргументом, а затем последним commit_hash, до которого вы хотите экспортировать изменения.
пример:
$sh export_changes.sh hashX hashY
поместите этот скрипт в локальный каталог git или установите путь к локальному каталогу git в скрипте. надеюсь, что это помогает..!

Comments