From aaf962df4a807886abb21c1a95ba6652a64943eb Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Mon, 11 Dec 2023 12:40:09 -0800 Subject: Reintegrate: cope with delete-modify conflicts A more proper solution is probably to teach "rerere" to remember what modification (probably indexed via a patch ID for flexibility, but either the pre- or post-image blob ID without such flexibility is probably good enough) was deemed "uninteresting" to resolve in favor of deletion and reapply it when we see another delete-modify conflict with the same modification, but for now, treat all delete-modify conflict to be with uninteresting modification. The way the Reintegrate machinery is used makes it somewhat safer than it looks---the initial attempt to merge (and come up with a merge-fix if needed) will always be done using "git merge" and the resulting commit is manually examined (if only to see if there is a need for a further merge-fix) before redo-foo script is written out of the resulting history. We'll need to deal with a case where a modifying side need to be kept over the deleting side if/when it arises, but so far I haven't seen such a case in real life. --- Reintegrate | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/Reintegrate b/Reintegrate index ddff2664bc..db914c6987 100755 --- a/Reintegrate +++ b/Reintegrate @@ -123,6 +123,27 @@ cocci_mark="treewide: apply cocci patch" case "$generate" in no) accept_rerere () { + git ls-files -u -z | + perl -0 -e ' + my %path_stage = (); + my @to_remove = (); + while (<>) { + my ($mode, $sha1, $stage, $path) = + /^([0-7]+) ([0-9a-f]+) ([0-3]) (.*)$/; + $path_stage{$path} ||= 0; + $path_stage{$path} |= (1 << ($stage - 1)); + } + + while (my ($path, $bits) = each %path_stage) { + if ($bits == 3 || $bits == 5) { + push @to_remove, $path; + } + } + if (@to_remove) { + system(qw(git rm -f), @to_remove); + } + ' + if ! git write-tree 2>/dev/null >/dev/null then git rerere remaining -- cgit v1.2.3