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