From e21df820e6112ab5f6a818f2b2bb342b942c0598 Mon Sep 17 00:00:00 2001 From: MaPePeR Date: Tue, 18 Nov 2025 10:08:00 +0100 Subject: [PATCH 1/2] Move argument parsing to the top of the file --- bin/composer-git-merge-driver | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/bin/composer-git-merge-driver b/bin/composer-git-merge-driver index 17b8c44..3edfbf4 100755 --- a/bin/composer-git-merge-driver +++ b/bin/composer-git-merge-driver @@ -5,22 +5,37 @@ define('CONFLICT_PLACEHOLDER', '=c=o=n=f=(\d+)=l=i=c=t='); // options for json encode define('JSON_ENCODE_OPTIONS', JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); + +// Read arguments in order of %O %A %B %L %P +reset($argv); +// next skips first argv element +next($argv); +$arg_ancestor = current($argv); +$arg_ours = next($argv); +$arg_theirs = next($argv); +$arg_markersize = next($argv); +$arg_pathname = next($argv); + // file states -$states = ['ancestor', 'ours', 'theirs']; +$states = [ + 'ancestor' => $arg_ancestor, + 'ours' => $arg_ours, + 'theirs' => $arg_theirs, +]; // unique object that represents a void $void = (object) []; // conflicts we have identified $conflicts = []; // length for conflict marker (<<<) -$markerLen = $argv[4]; +$markerLen = $arg_markersize; // are we working with the lock file? -$isLock = basename(strtolower($argv[5])) === 'composer.lock'; +$isLock = basename(strtolower($arg_pathname)) === 'composer.lock'; // indentation type to use $indentation = $defaultIndentation = ' '; // grab the contents of each file state -foreach ($states as $i => $state) { - $contents = file_get_contents($argv[$i + 1]); +foreach ($states as $state => $statepath) { + $contents = file_get_contents($statepath); // use our file to base the indentation off of; // we ignore the possibility of indentation style changes @@ -59,7 +74,7 @@ function merge($ancestor, $ours, $theirs) { // reconcile each key foreach ($keys as $key) { // get the value of this key from each state - foreach ($states as $state) { + foreach ($states as $state => $_) { ${rtrim($state, 's') . 'Value'} = is_array($$state) && array_key_exists($key, $$state) ? ${$state}[$key] : $void; } @@ -144,7 +159,7 @@ if ($isLock) { // @todo handle alias property as well $packageKeys = ['packages', 'packages-dev']; - foreach ($states as $state) { + foreach ($states as $state => $_) { // ensure we don't get a conflict on the content hash ${$state}['content-hash'] = null; @@ -236,7 +251,7 @@ if (count($conflicts)) { } // update the file -file_put_contents($argv[2], $merged . "\n"); +file_put_contents($arg_ours, $merged . "\n"); // determine exit status based on whether there were conflicts exit(count($conflicts) ? 1 : 0); From 715ad43aa478a558e993787e8b17a26ade496701 Mon Sep 17 00:00:00 2001 From: MaPePeR Date: Tue, 18 Nov 2025 10:21:10 +0100 Subject: [PATCH 2/2] Add option to always report a conflict when the tool merged a file automatically. This gives an opportunity to review the automatic changes and run `composer update --lock` to update the `content-hash`. --- bin/composer-git-merge-driver | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/bin/composer-git-merge-driver b/bin/composer-git-merge-driver index 3edfbf4..507ce45 100755 --- a/bin/composer-git-merge-driver +++ b/bin/composer-git-merge-driver @@ -10,6 +10,12 @@ define('JSON_ENCODE_OPTIONS', JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT | JSON_ reset($argv); // next skips first argv element next($argv); +if (current($argv) == '--always-conflict-on-merge') { + $always_conflict_on_merge = true; + next($argv); +} else { + $always_conflict_on_merge = false; +} $arg_ancestor = current($argv); $arg_ours = next($argv); $arg_theirs = next($argv); @@ -254,4 +260,4 @@ if (count($conflicts)) { file_put_contents($arg_ours, $merged . "\n"); // determine exit status based on whether there were conflicts -exit(count($conflicts) ? 1 : 0); +exit($always_conflict_on_merge || count($conflicts) ? 1 : 0);