Last active
September 1, 2015 05:02
-
-
Save fumikito/2f644fb9b47c6438c872 to your computer and use it in GitHub Desktop.
Archive files between 2 commits on Git repository
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env php | |
<?php | |
if( isset( $argv[1] ) && preg_match('/(-{1,2})?help$/', $argv[1] ) ) { | |
echo <<<'TXT' | |
/** | |
* Archive git diff file between specified commit | |
* | |
* git_diff ./archive 29879823c HEAD | |
* | |
* Enter above, diff between HEAD and 29879823c will be arvhived to `./archive`. | |
* | |
* [How to install] | |
* | |
* | |
* @param string $path Output folder's path. | |
* @param string $hash Target commit's hash. | |
* @param string $from_hash Origin commit's hash. HEAD if not specified. | |
*/ | |
TXT; | |
exit; | |
} | |
/** | |
* Echo | |
* | |
* @param string $string | |
* @param int $lf Number of line feed | |
*/ | |
function e($string, $lf = 1){ | |
echo $string.implode('', array_map(function($var){ | |
return PHP_EOL; | |
}, range(0, max(1, $lf) - 1))); | |
} | |
/** | |
* Die | |
* | |
* @param $string | |
*/ | |
function d($sring){ | |
echo $sring.PHP_EOL; | |
exit; | |
} | |
// | |
// Start processing | |
// | |
// | |
echo <<<TXT | |
< This is an Git diff tool! > | |
--------------------------- | |
\ ^__^ | |
\ (oo)\_______ | |
(__)\ )\/\ | |
||----w | | |
|| || | |
TXT; | |
foreach( [ | |
1 => 'Target path is not specified.', | |
2 => 'Target commit is not specified.', | |
] as $index => $msg){ | |
if( !isset($argv[$index]) ){ | |
d('[ERROR] '.$msg); | |
} | |
} | |
$from = isset($argv[3]) ? $argv[3] : 'HEAD'; | |
$to = $argv[2]; | |
$out = $argv[1]; | |
$cur_dir = getcwd(); | |
$summary = <<<'TXT' | |
======================= | |
From : %s | |
To : %s | |
Target Directory : %s | |
Current DIrectory: %s | |
======================= | |
TXT; | |
e(sprintf($summary, $from, $to, $out, $cur_dir), 2); | |
$cmd = escapeshellcmd(sprintf('git diff --name-only %s %s', escapeshellarg($from), escapeshellarg($to))); | |
$result = exec($cmd, $output); | |
// 確認 | |
$deleted = []; | |
$updated = []; | |
array_map(function($line) use ($cur_dir, &$updated, &$deleted){ | |
$path = $cur_dir.DIRECTORY_SEPARATOR.trim($line); | |
if( file_exists($path) ){ | |
$updated[] = $line; | |
}else{ | |
$deleted[] = $line; | |
} | |
}, $output); | |
$summary = <<<'TXT' | |
[Updated] | |
%s | |
============== | |
[Deleted] | |
%s | |
============== | |
TXT; | |
e(sprintf($summary, implode(PHP_EOL, $updated), implode(PHP_EOL, $deleted))); | |
echo 'Are you sure to archive these files? [y/n]'; | |
while($f = fgets(STDIN)){ | |
if( false !== array_search(strtolower(trim($f)), ['y', 'yes']) ){ | |
e('Now archiving...'); | |
break; | |
}else{ | |
d('Abort!'); | |
} | |
} | |
// Create directory | |
if( !is_dir($out) ){ | |
if( !mkdir($out, 0755, true) ){ | |
d(sprintf('[ERROR] Failed to create %s!', $out)); | |
} | |
}elseif( !is_writable($out) ){ | |
d(sprintf('[ERROR] %s is not writable!', $out)); | |
} | |
foreach( $updated as $file ){ | |
$path = $cur_dir.DIRECTORY_SEPARATOR.$file; | |
if( file_exists($path) ){ | |
$target = rtrim($out, DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR.$file; | |
$dir = dirname($target); | |
if( !is_dir($dir) ){ | |
mkdir($dir, 0755, true); | |
} | |
copy($path, $target); | |
echo '.'; | |
} | |
} | |
echo PHP_EOL; | |
e(sprintf('[SUCCCESS] Archived on %s!', $out)); | |
exit; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment