Sometimes (often actually) I do:

          cp -Rl tree1 tree2    # new tree with implied CoW semantics
          cd tree2
          cg-update             # or similar

the latter well frob .git/HEAD or similar by doing echo foo > bar
which obviously breaks the intended CoW semantics.

How would people feel about something like the patch below be?  (RFC
purposes only, please eyeball this before blidnly applying anything.
I may have missed spots or goofed, you never know).



diff --git a/cg-Xlib b/cg-Xlib
--- a/cg-Xlib
+++ b/cg-Xlib
@@ -21,6 +21,12 @@ usage() {
        die "usage: $USAGE"
 }
 
+echo_to_file() {
+    TMPFILE=`mktemp "$2.tmp-XXXXXXX"`
+    echo "$1" > "$TMPFILE"
+    mv "$TMPFILE" "$2"
+}
+
 pager () {
        local line
        # Invoke pager only if there's any actual output
@@ -101,7 +107,7 @@ tree_timewarp () {
        fi
 
        git-read-tree -m "$branch" || die "$branch: bad commit"
-       [ "$no_head_update" ] || echo "$branch" > $_git/HEAD
+       [ "$no_head_update" ] || echo_to_file "$branch" $_git/HEAD
 
        # Kill gone files
        git-diff-tree -z -r $base $branch | xargs -0 bash -c '
diff --git a/cg-branch-add b/cg-branch-add
--- a/cg-branch-add
+++ b/cg-branch-add
@@ -50,4 +50,4 @@ mkdir -p $_git/branches
 [ -s "$_git/branches/$name" ] && die "branch already exists"
 [ -s "$_git/refs/heads/$name" ] && echo "warning: I already have head of this 
branch" >&2
 
-echo "$location" >$_git/branches/$name
+echo_to_file "$location" $_git/branches/$name
diff --git a/cg-branch-chg b/cg-branch-chg
--- a/cg-branch-chg
+++ b/cg-branch-chg
@@ -14,4 +14,4 @@ location=$2
 ([ "$name" ] && [ "$location" ]) || usage
 
 [ -s "$_git/branches/$name" ] || die "branch does not exist"
-echo "$location" >$_git/branches/$name
+echo_to_file "$location" $_git/branches/$name
diff --git a/cg-commit b/cg-commit
--- a/cg-commit
+++ b/cg-commit
@@ -331,7 +331,7 @@ fi
 
 if [ "$newhead" ]; then
        echo "Committed as $newhead."
-       echo $newhead >$_git/HEAD
+       echo_to_file $newhead $_git/HEAD
        [ "$merging" ] && rm $_git/merging $_git/merging-sym $_git/merge-base
 
        # Trigger the postcommit hook
diff --git a/cg-init b/cg-init
--- a/cg-init
+++ b/cg-init
@@ -44,7 +44,7 @@ mkdir $_git/branches
 touch $_git/refs/heads/master
 
 if [ "$uri" ]; then
-       echo "$uri" >$_git/branches/origin
+       echo_to_file "$uri" $_git/branches/origin
        cg-pull origin || die "pull failed"
 
        cp $_git/refs/heads/origin $_git/refs/heads/master
diff --git a/cg-seek b/cg-seek
--- a/cg-seek
+++ b/cg-seek
@@ -44,8 +44,8 @@ fi
 
 if [ "$seek_mode" = "away" ]; then
        rm $_git/HEAD
-       echo "$dstcommit" >$_git/HEAD
-       [ -s $_git/blocked ] || echo "seeked from $_git_head" >$_git/blocked
+       echo_to_file "$dstcommit" $_git/HEAD
+       [ -s $_git/blocked ] || echo_to_file "seeked from $_git_head" 
$_git/blocked
 else
        rm $_git/HEAD
        ln -s "refs/heads/$_git_head" $_git/HEAD
diff --git a/cg-tag b/cg-tag
--- a/cg-tag
+++ b/cg-tag
@@ -79,5 +79,5 @@ SIGEND
 
        rm -rf "$tagdir"
 else
-       echo "$id" >$_git/refs/tags/$name
+       echo_to_file "$id" $_git/refs/tags/$name
 fi
diff --git a/git-branch-script b/git-branch-script
--- a/git-branch-script
+++ b/git-branch-script
@@ -8,4 +8,4 @@ rev=$(git-rev-parse --verify --default H
 [ -z "$branchname" ] && die "git branch: I want a branch name"
 [ -e "$GIT_DIR/refs/heads/$branchname" ] && die "$branchname already exists"
 
-echo $rev > "$GIT_DIR/refs/heads/$branchname"
+echo_to_file $rev "$GIT_DIR/refs/heads/$branchname"
diff --git a/git-checkout-script b/git-checkout-script
--- a/git-checkout-script
+++ b/git-checkout-script
@@ -67,7 +67,7 @@ fi
 #
 if [ "$?" -eq 0 ]; then
        if [ "$newbranch" ]; then
-               echo $new > "$GIT_DIR/refs/heads/$newbranch"
+               echo_to_file $new "$GIT_DIR/refs/heads/$newbranch"
                branch="$newbranch"
        fi
        [ "$branch" ] && ln -sf "refs/heads/$branch" "$GIT_DIR/HEAD"
diff --git a/git-commit-script b/git-commit-script
--- a/git-commit-script
+++ b/git-commit-script
@@ -97,7 +97,7 @@ grep -v '^#' < .editmsg | git-stripspace
 [ -s .cmitmsg ] && 
        tree=$(git-write-tree) &&
        commit=$(cat .cmitmsg | git-commit-tree $tree $PARENTS) &&
-       echo $commit > "$GIT_DIR/HEAD" &&
+       echo_to_file $commit "$GIT_DIR/HEAD" &&
        rm -f -- "$GIT_DIR/MERGE_HEAD"
 ret="$?"
 rm -f .cmitmsg .editmsg
diff --git a/git-fetch-script b/git-fetch-script
--- a/git-fetch-script
+++ b/git-fetch-script
@@ -30,4 +30,4 @@ rsync://*)
        ;;
 esac || exit 1
 git-rev-parse --verify "$head" > /dev/null || exit 1
-echo "$head" > "$GIT_DIR/$destination"
+echo_to_file "$head" "$GIT_DIR/$destination"
diff --git a/git-rebase-script b/git-rebase-script
--- a/git-rebase-script
+++ b/git-rebase-script
@@ -21,7 +21,7 @@ case "$#" in
 esac
 
 git-read-tree -m -u $junio $linus &&
-echo "$linus" >"$GIT_DIR/HEAD" || exit
+echo_to_file "$linus" "$GIT_DIR/HEAD" || exit
 
 tmp=.rebase-tmp$$
 fail=$tmp-fail
diff --git a/git-resolve-script b/git-resolve-script
--- a/git-resolve-script
+++ b/git-resolve-script
@@ -24,8 +24,8 @@ if [ -z "$head" -o -z "$merge" -o -z "$m
 fi
 
 dropheads
-echo $head > "$GIT_DIR"/ORIG_HEAD
-echo $merge > "$GIT_DIR"/LAST_MERGE
+echo_to_file $head "$GIT_DIR"/ORIG_HEAD
+echo_to_file $merge "$GIT_DIR"/LAST_MERGE
 
 common=$(git-merge-base $head $merge)
 if [ -z "$common" ]; then
@@ -40,7 +40,7 @@ fi
 if [ "$common" == "$head" ]; then
        echo "Updating from $head to $merge."
        git-read-tree -u -m $head $merge || exit 1
-       echo $merge > "$GIT_DIR"/HEAD
+       echo_to_file $merge "$GIT_DIR"/HEAD
        git-diff-tree -p $head $merge | git-apply --stat
        dropheads
        exit 0
@@ -52,13 +52,13 @@ if [ $? -ne 0 ]; then
        echo "Simple merge failed, trying Automatic merge"
        git-merge-cache -o git-merge-one-file-script -a
        if [ $? -ne 0 ]; then
-               echo $merge > "$GIT_DIR"/MERGE_HEAD
+               echo_to_file $merge "$GIT_DIR"/MERGE_HEAD
                die "Automatic merge failed, fix up by hand"
        fi
        result_tree=$(git-write-tree) || exit 1
 fi
 result_commit=$(echo "$merge_msg" | git-commit-tree $result_tree -p $head -p 
$merge)
 echo "Committed merge $result_commit"
-echo $result_commit > "$GIT_DIR"/HEAD
+echo_to_file $result_commit "$GIT_DIR"/HEAD
 git-diff-tree -p $head $result_commit | git-apply --stat
 dropheads
-
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to