diff --git a/src/IDF/Scm.php b/src/IDF/Scm.php index e34c989..708b02a 100644 --- a/src/IDF/Scm.php +++ b/src/IDF/Scm.php @@ -340,7 +340,8 @@ class IDF_Scm * stdClass object { * 'additions' => array('path/to/file', 'path/to/directory', ...), * 'deletions' => array('path/to/file', 'path/to/directory', ...), - * 'renames' => array('old/path/to/file' => 'new/path/to/file', ...) + * 'renames' => array('old/path/to/file' => 'new/path/to/file', ...), + * 'copies' => array('path/to/source' => 'path/to/target', ...), * 'patches' => array('path/to/file', ...), * 'properties' => array('path/to/file' => array( * 'propname' => 'propvalue', 'deletedprop' => null, ...) diff --git a/src/IDF/Scm/Git.php b/src/IDF/Scm/Git.php index 9f3e03d..f02f018 100644 --- a/src/IDF/Scm/Git.php +++ b/src/IDF/Scm/Git.php @@ -67,6 +67,7 @@ class IDF_Scm_Git extends IDF_Scm 'additions' => array(), 'deletions' => array(), 'renames' => array(), + 'copies' => array(), 'patches' => array(), 'properties' => array(), ); diff --git a/src/IDF/Scm/Mercurial.php b/src/IDF/Scm/Mercurial.php index 8c0b34d..95ddada 100644 --- a/src/IDF/Scm/Mercurial.php +++ b/src/IDF/Scm/Mercurial.php @@ -59,7 +59,7 @@ class IDF_Scm_Mercurial_LogStyle . "\n" . 'file_del = "{file_del}\0"' . "\n" - . 'file_copy = "{name}\0{source}\0"' + . 'file_copy = "{source}\0{name}\0"' . "\n"; } else { throw new IDF_Scm_Exception('invalid type ' . $type); @@ -457,24 +457,32 @@ class IDF_Scm_Mercurial extends IDF_Scm 'patches' => preg_split('/\0/', $log->file_mods, -1, PREG_SPLIT_NO_EMPTY), // hg has no support for built-in attributes, so this keeps empty 'properties' => array(), - // this is filled below + // these two are filled below + 'copies' => array(), 'renames' => array(), ); $file_copies = preg_split('/\0/', $log->file_copies, -1, PREG_SPLIT_NO_EMPTY); - // FIXME: copies are only treated as renames if they have an add _and_ - // an drop, otherwise they're just treated as adds + // copies are treated as renames if they have an add _and_ a drop; + // only if they only have an add, but no drop, they're treated as copies for ($i=0; $iadditions); - $oldidx = array_search($old, $return->deletions); - if ($newidx !== false && $oldidx !== false) { - $return->renames[$old] = $new; - unset($return->additions[$newidx]); - unset($return->deletions[$oldidx]); + $src = $file_copies[$i]; + $trg = $file_copies[$i+1]; + $srcidx = array_search($src, $return->deletions); + $trgidx = array_search($trg, $return->additions); + if ($srcidx !== false && $trgidx !== false) { + $return->renames[$src] = $trg; + unset($return->deletions[$srcidx]); + unset($return->additions[$trgidx]); + continue; + } + if ($srcidx === false && $trgidx !== false) { + $return->copies[$src] = $trg; + unset($return->additions[$trgidx]); + continue; } + // file sutures (counter-operation to copy) not supported } return $return; diff --git a/src/IDF/Scm/Monotone.php b/src/IDF/Scm/Monotone.php index d04c53b..63f40e3 100644 --- a/src/IDF/Scm/Monotone.php +++ b/src/IDF/Scm/Monotone.php @@ -609,6 +609,7 @@ class IDF_Scm_Monotone extends IDF_Scm 'additions' => array(), 'deletions' => array(), 'renames' => array(), + 'copies' => array(), 'patches' => array(), 'properties' => array(), ); diff --git a/src/IDF/templates/idf/source/commit.html b/src/IDF/templates/idf/source/commit.html index 7cc2bf7..6b88158 100644 --- a/src/IDF/templates/idf/source/commit.html +++ b/src/IDF/templates/idf/source/commit.html @@ -34,6 +34,9 @@ {foreach $changes.renames as $oldname => $newname} R{$oldname} → {$newname} {/foreach} +{foreach $changes.copies as $srcname => $destname} +C{$srcname} → {$destname} +{/foreach} {foreach $changes.additions as $filename} A{$filename}{if !empty($diff.files[$filename])} ({trans 'full'}){/if} {/foreach} diff --git a/www/media/idf/css/style.css b/www/media/idf/css/style.css index 3f80fdd..3480828 100644 --- a/www/media/idf/css/style.css +++ b/www/media/idf/css/style.css @@ -1058,6 +1058,10 @@ span.scm-action.renamed { background-color: purple; } +span.scm-action.copied { + background-color: orchid; +} + span.scm-action.property-changed { background-color: blue; }