特定のコミットで変更および追加されたファイルのリストを取得して、それらをエクスポートし、ファイル構造を持つパッケージを生成できるようにしたいと思います。
アイデアは、パッケージを取得してサーバーに抽出することです。多くの理由で、リポジトリを自動的にプルするフックを作成できません。サーバーを最新の状態に保つための最も簡単な方法は、このパッケージを生成することです。
回答:
git diff-tree -r --no-commit-id --name-only --diff-filter=ACMRT $commit_id
git diff-tree -r $commit_id
:
その親(トップディレクトリだけでなく、すべてのサブディレクトリを含む)への指定されたコミットの差分を取ります。
--no-commit-id --name-only
:
コミットSHA1を出力しません。完全な差分ではなく、影響を受けるファイルの名前のみを出力します。
--diff-filter=ACMRT
:
このコミットでは、追加、コピー、変更、名前変更されたファイル、またはタイプが変更されたファイル(ファイル→シンボリックリンクなど)のみを表示します。これにより、削除されたファイルが除外されます。
コメントからの更新:質問のコンテキストと以下のコメントに基づいて、次のコマンドをACMRT
使用して、.tar
ファイルをフォルダー構造を持つファイルとして取得できます。
git diff-tree -r --no-commit-id --name-only --diff-filter=ACMRT $commit_id | tar -czf file.tgz -T -
git diff-tree -r --no-commit-id --name-only --diff-filter=ACMRT $commit_id | tar -czf file.tgz -T -
git diff-tree -r --no-commit-id --name-only --diff-filter=ACMRT $commit_id | xargs tar -rf mytarfile.tar
これを締めくくるために、ここにtarにパイプされたコマンドがあります。これにより、ファイルがtarアーカイブにエクスポートされます。
これは、Windows7で機能する1行のコマンドです。リポジトリの最上位フォルダーから実行します。
for / f "usebackq tokens = *"%A in( `git diff-tree -r --no-commit-id --name-only --diff-filter = ACMRT HEAD〜1 HEAD`)do echo FA | xcopy "%〜fA" "C:\ git_changed_files \%A"
コミットハッシュがたとえばa9359f9の場合、次のコマンド:
git archive -o patch.zip a9359f9 $(git diff --name-only a9359f9^..a9359f9)
コミットで変更されたファイルを抽出し、プロジェクトのディレクトリ構造をそのままにして、patch.zipに配置します。
少し冗長で、コミットハッシュは3回言及されていますが、私にとってはうまくいくようです。
ここで入手:http://tosbourn.com/2011/05/git/using-git-to-create-an-archive-of-changed-files/
function
して、コマンドを関数名だけに減らし、コミットハッシュを1回だけ渡すことができると思います。* nixでは、おそらくシェルスクリプトを使用して同じ効果を達成できます。$args
git archive -o patch.zip HEAD /**or a commit**/ $(git diff --name-only commit1 commit2)
。archive
コマンドに渡されるコミットは任意のコミット(ほとんどの場合、HEADまたはそれ以降のコミット)であり、ファイルはそのコミット段階でチェックアウトされているかのようにプルされます。commit1とcommit2はに渡されたdiff
だけプルへのファイルのリストを生成するために使用されている-彼らは引っ張られたファイルのバージョンには影響を与えません。
diff
セミコロンでコマンドを:git archive -o patch.zip HEAD /**or a commit**/ $(git diff --name-only commit1A commit1B; git diff --name-only commit2A commit2B; git diff --name-only commit3A commit3B)
git diff -z --name-only commit1 commit2 | xargs -0 git archive -o patch.zip HEAD
TortoiseGitを使用してdiffをMSWindowsにエクスポートできます。
右クリックしてTortoiseGit > [ログの表示]を選択すると、ログメッセージが開きます。
2つのリビジョンを選択し、比較します。違いはオープンになります。
ファイルを選択し、選択内容を...フォルダにエクスポートします。
テストサーバーを更新し、バージョン2.1以降に変更されたファイルを追加する必要がありました。
私にとっては、James Ehlyが投稿したのと同様のソリューションを使用しましたが、私の場合は、2つの古いタグ(tag_ver_2.1とtag_ver_2.2だけではない)の違いをアーカイブパッケージにエクスポートしたいと思いました。
例:
tag_ver_2.1 = 1f72b38ad
tag_ver_2.2 = c1a546782
変更された例は次のとおりです。
git diff-tree -r --no-commit-id --name-only c1a546782 1f72b38ad | xargs tar -rf test.tar
以下のコマンドは私のために働いた。
最後のコミットで変更されたファイルの違いが必要な場合:
git archive -o update.zip HEAD $(git diff --name-only HEAD HEAD^)
または、2つの特定のコミットの違いが必要な場合:
git archive -o update.zip sha1 $(git diff --name-only sha1 sha2)
または、コミットされていないファイルがある場合、gitの方法はすべてをコミットすることであり、ブランチは安価であることを忘れないでください。
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 HEAD^)
変更したファイルをWindowsにエクスポートするためのphpスクリプトを作成しました。PHPが設定されたローカルホスト開発サーバーがある場合は、簡単に実行できます。最後のリポジトリを記憶し、常に同じフォルダにエクスポートします。エクスポートフォルダは、エクスポートする前に常に空になります。また、削除されたファイルは赤で表示されるため、サーバーで何を削除するかがわかります。
これらは2つのファイルなので、ここに投稿します。リポジトリが独自のフォルダのc:/ wwwの下にあり、http:// localhostもc:/ wwwを指し、php対応であると仮定します。これらの2つのファイルをc:/ www / git-exportに入れましょう-
index.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-export.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コマンドがPATHに含まれている場合に機能します。これは、WindowsGitインストーラーを実行するときに構成できます。
日付で始まる変更されたファイルをエクスポートするには:
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 @{$1} --diff-filter=ACRMRT --name-only | xargs tar -cf $2; \
}; f"
これは私が書いた小さなbash(Unix)スクリプトで、フォルダー構造を持つ特定のコミットハッシュのファイルをコピーします。
ARRAY=($(git diff-tree -r --no-commit-id --name-only --diff-filter=ACMRT $1))
PWD=$(pwd)
if [ -d "$2" ]; then
for i in "${ARRAY[@]}"
do
:
cp --parents "$PWD/$i" $2
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 log --reverse commit_HashX^..commit_HashY --pretty=format:'%h'
上記のコマンドは、commit_HashXからcommit_HashYへのCommit Hash(Revision)を逆の順序で表示します。
456d517 (second_hash)
9362d03
5362d03
226x47a
478bf6b (six_hash)
次に、上記のコマンドを使用するメインのシェルスクリプト。
commitHashList=$(git log --reverse $1^..$2 --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ローカルディレクトリパスを設定します。 それが役に立てば幸い..!
これは、UnixとWindowsの両方で機能します。
git diff-tree -r --no-commit-id --name-only --diff-filter=ACMRT __1__.. | xargs cp --parents -t __2__
コマンドには2つのプレースホルダーがあります。あなたはあなたの目的のためにそれらを交換する必要があります:
__1__:エクスポートするすべてのコミットの直前にコミットのコミットIDに置き換えます(例:997cc7b6-コミットIDの後にその二重ドットを保持することを忘れないでください-これは「このコミットよりも新しいすべてのコミットを含む」ことを意味します)
__2__:ファイルをエクスポートする既存のパスに置き換えます(例:../ export_path /)
その結果、誰かがsvnリポジトリでtortoise svn exportsを使用することに慣れている可能性があるため、ファイルはフォルダ構造(zip / tarはありません...)になります。
これは、たとえば、最後のコミットがほとんどない追加/変更されたファイルの手動デプロイを実行する場合に非常に便利です。したがって、ftpクライアントを介してこれらのファイルをコピーするだけです。