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.htmlReceived on Tue May 31 08:33:24 2005
This archive was generated by hypermail 2.1.8 : 2005-05-31 08:33:25 EST