Re: cg-update with local uncommitted changes

From: Dan Holmsand <holmsand@gmail.com>
Date: 2005-05-31 08:31:28
Marcel Holtmann wrote:
> I also think that it would be great if we cancel the merge if the local
> changes conflict with the files in the merge. This is how Bitkeeper does
> it and I think it is the only safe way, because if something fails or
> rejects we may destroy the local changes.

I definitely agree (been bitten by patching gone wild a couple of times...).

This patch would make cg-merge and cg-admin-uncommit refuse to do 
anything if there are conflicting uncommitted changes. Note: this only 
applies to fast-forward merging, as cg-merge otherwise bails out if 
there are *any* uncommitted changes (which is perhaps going to far).

/dan

[PATCH] Make tree_timewarp safe, by refusing to handle conflicts.

Signed-off-by: Dan Holmsand <holmsand@gmail.com>


diff --git a/cg-Xlib b/cg-Xlib
--- a/cg-Xlib
+++ b/cg-Xlib
@@ -50,47 +50,22 @@ showdate () {
 }
 
 
-# Usage: tree_timewarp DIRECTION_STR ROLLBACK_BOOL BASE BRANCH
+# Usage: tree_timewarp BASE BRANCH
 tree_timewarp () {
-	dirstr=$1; shift
-	rollback=$1; shift
-	base=$1; shift
-	branch=$1; shift
-
-	patchfile=$(mktemp -t gituncommit.XXXXXX)
-	if [ "$rollback" ]; then
-		cg-diff >$patchfile
-		[ -s "$patchfile" ] &&
-			echo "Warning: uncommitted local changes, trying to bring them $dirstr" >&2
-	else
-		# XXX: This may be suboptimal, but it is also non-trivial to keep
-		# the adds/removes properly.  So this is just a quick hack to get it
-		# working without much fuss.
-		cg-diff -r $branch >$patchfile
-	fi
-
-	git-read-tree -m "$branch" || die "$branch: bad commit"
-	echo "$branch" > $_git/HEAD
-
-	# Kill gone files
-	git-diff-tree -z -r $base $branch | xargs -0 bash -c '
-		while [ "$1" ]; do
-			header="$1"; shift
-			file="$1"; shift
-
-			# match ":100755 000000 14d43b1abf... 000000000... D"
-			if echo "$header" | egrep "^:([^ ][^ ]* ){4}D" >/dev/null; then
-				rm -- "$file"
-			fi
-		done
-	' padding
-	git-checkout-cache -f -a
-
-	# FIXME: Can produce bogus "contains only garbage" messages.
-	cat $patchfile | cg-patch
-	rm $patchfile
+	local conflicts base=$1 branch=$2
 
 	git-update-cache --refresh >/dev/null
+	conflicts=$( (git-diff-tree -r $base $branch; 
+		git-diff-cache -r HEAD) | cut -f2- | sort | uniq -d )
+	[ -z "$conflicts" ] || 
+		die "conflicting uncommitted changes: $conflicts"
+
+	git-read-tree -m $branch || die "read-tree failed"
+	git-diff-tree -r $base $branch | cut -f5- -d' ' | grep '^[NM]' | 
+	cut -f2- | tr \\n \\0 | xargs -0 git-checkout-cache -u -f --
+	git-diff-tree -r $base $branch | cut -f5- -d' ' | grep '^[D]' | 
+	cut -f2- | tr \\n \\0 | xargs -0 rm -f --
+	echo "$branch" > $_git/HEAD
 }
 
 
diff --git a/cg-admin-uncommit b/cg-admin-uncommit
--- a/cg-admin-uncommit
+++ b/cg-admin-uncommit
@@ -39,10 +39,15 @@ commit=$(commit-id "$1") || exit 1
 git-rev-list $base | grep -q $commit || \
 	die "$commit: not an ancestor of HEAD"
 
-parent=$(parent-id "$commit") || exit 1
+parent=$(parent-id "$commit" | head -n 1) || exit 1
 [ "$parent" ] || die "cannot rewind behind the initial commit"
 
 
 echo "Rewinding $base (HEAD) -> $parent" >&2
 
-tree_timewarp "backwards" "$rollback_tree" $base $parent
+if [ "$rollback_tree" ]; then
+	tree_timewarp $base $parent
+else
+	git-read-tree -m $parent || die "git-read-tree failed"
+	echo "$parent" > $_git/HEAD
+fi
diff --git a/cg-merge b/cg-merge
--- a/cg-merge
+++ b/cg-merge
@@ -65,7 +65,7 @@ if [ "$head" = "$base" ]; then
 	echo "Fast-forwarding $base -> $branch" >&2
 	echo -e "\ton top of $head..." >&2
 
-	tree_timewarp "forward" "yes, rollback (or rather rollforth) the tree!" $base $branch
+	tree_timewarp $base $branch
 
 	exit 0
 fi


-
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Received on Tue May 31 08:33:24 2005

This archive was generated by hypermail 2.1.8 : 2005-05-31 08:33:25 EST