shithub: git9

Download patch

ref: 84ee79f00473db926883945991233dfe084d1823
parent: 8bd0182f46c5159341714af16cca43f7c579e199
author: Ori Bernstein <ori@eigenstate.org>
date: Tue Feb 9 00:52:32 EST 2021

git/merge, git/branch: share merge code, delete better

There were some edge cases when merges deleted files:
With diff3 redirected to an output, the output always
exists. This lead to trash files being added to repos,
and branch switches not cleaning up properly.

In addition, this speeds up git/merge by not walking
the whole tree, just the files changed by the commits
that are getting merged.

--- a/branch
+++ b/branch
@@ -93,34 +93,13 @@
 		walk -eq $m > .git/index9/tracked/$m
 	}
 }
-for(f in $dirtypaths){
-	ours=$f
+
+for(ours in $dirtypaths){
 	common=/mnt/git/object/$orig/tree/$ours
 	theirs=/mnt/git/object/$base/tree/$ours
-	n=$pid
-	tmp=$ours.tmp
-	while(test -f $tmp){
-		tmp=$tmp.$n
-		n=`{echo $n + 1 | hoc}
-	}
-	if(! test -f $ours)
-		ours=/dev/null
-	if(! test -f $theirs)
-		theirs=/dev/null
-	if(! test -f $common)
-		common=/dev/null
-	echo merging $f...
-	if(! ape/diff3 -3 -m $ours $common $theirs > $tmp)
-		echo '	'merge needed: $ours
-	if(test -f $f){
-		git/add $ours
-		mv $tmp $ours
-	}
-	if not {
-		git/rm $ours
-		rm $tmp
-	}
+	merge1 $ours $ours $commmon $theirs
 }
+
 if(! ~ $#deleted 0){
 	rm -f $deleted
 	rm -f .git/index9/tracked/$deleted
--- a/common.rc
+++ b/common.rc
@@ -30,6 +30,47 @@
 	}' $*
 }
 
+fn present {
+	if(~ $1 /dev/null && cmp $2 $3>/dev/null)
+		status=gone
+	if not if (~ $3 /dev/null && cmp $1 $2>/dev/null)
+		status=gone
+	if not
+		status=()
+}
+
+# merge1 out theirs base ours
+fn merge1 {
+	n=$pid
+	out=$1
+	theirs=$2
+	base=$3
+	ours=$4
+	tmp=$out.tmp
+	while(test -f $tmp){
+		tmp=$tmp.$n
+		n=`{echo $n + 1 | hoc}
+	}
+
+	if(! test -f $ours)
+		ours=/dev/null
+	if(! test -f $base)
+		base=/dev/null
+	if(! test -f $theirs)
+		theirs=/dev/null
+	if(! ape/diff3 -3 -m $ours $base $theirs > $tmp)
+		echo merge needed: $out
+
+	if(present $ours $base $theirs){
+		mv $tmp $out
+		git/add $out
+	}
+	if not {
+		rm -f $tmp $out
+		git/rm $out
+	}
+}
+
 fn gitup{
 	gitroot=`{git/conf -r >[2]/dev/null}
 	if(~ $#gitroot 0)
--- a/merge
+++ b/merge
@@ -3,29 +3,17 @@
 . /sys/lib/git/common.rc
 
 fn merge{
-	ourbr=$1/tree
-	basebr=$2/tree
-	theirbr=$3/tree
+	ourbr=/mnt/git/object/$1/tree
+	basebr=/mnt/git/object/$2/tree
+	theirbr=/mnt/git/object/$3/tree
 
-	all=`$nl{walk -f $ourbr $basebr $theirbr | \
+	all=`$nl{{git/query -c $1 $2; git/query -c $2 $3} | sed 's/^..//' | \
 		subst -g '^('$ourbr'|'$basebr'|'$theirbr')/*' | sort | uniq}
 	for(f in $all){
 		ours=$ourbr/$f
 		base=$basebr/$f
 		theirs=$theirbr/$f
-		if(! test -f $ourbr/$f)
-			ours=/dev/null
-		if(! test -f $basebr/$f)
-			base=/dev/null
-		if(! test -f $theirbr/$f)
-			theirs=/dev/null
-		if(! ape/diff3 -3 -m $ours $base $theirs > $f)
-			echo merge needed: $f
-
-		if(test -f $f)
-			git/add $f
-		if not
-			git/rm $f
+		merge1 $f $theirs $base $ours
 	}
 }
 
@@ -54,6 +42,6 @@
 echo $ours >> .git/index9/merge-parents
 echo $theirs >> .git/index9/merge-parents
 
-merge /mnt/git/object/$ours /mnt/git/object/$base /mnt/git/object/$theirs
+merge $ours $base $theirs
 >[1=2] echo 'merge complete: remember to commit'
 exit ''