update a few Porcelain-ish for ref lock safety.

This updates the use of git-update-ref in git-branch, git-tag
and git-commit to make them safer in a few corner cases as
demonstration.

 - git-tag makes sure that the named tag does not exist, allows
   you to edit tag message and then creates the tag.  If a tag
   with the same name was created by somebody else in the
   meantime, it used to happily overwrote it.  Now it notices
   the situation.

 - git-branch -d and git-commit (for the initial commit) had the
   same issue but with smaller race window, which is plugged
   with this.

Signed-off-by: Junio C Hamano <junkio@cox.net>
This commit is contained in:
Junio C Hamano 2006-09-27 02:06:31 -07:00
parent ac5409e420
commit cede752653
3 changed files with 13 additions and 9 deletions

View File

@ -42,8 +42,7 @@ If you are sure you want to delete it, run 'git branch -D $branch_name'."
esac esac
;; ;;
esac esac
rm -f "$GIT_DIR/logs/refs/heads/$branch_name" git update-ref -d "refs/heads/$branch_name" "$branch"
rm -f "$GIT_DIR/refs/heads/$branch_name"
echo "Deleted branch $branch_name." echo "Deleted branch $branch_name."
done done
exit 0 exit 0
@ -112,6 +111,7 @@ rev=$(git-rev-parse --verify "$head") || exit
git-check-ref-format "heads/$branchname" || git-check-ref-format "heads/$branchname" ||
die "we do not like '$branchname' as a branch name." die "we do not like '$branchname' as a branch name."
prev=''
if git-show-ref --verify --quiet -- "refs/heads/$branchname" if git-show-ref --verify --quiet -- "refs/heads/$branchname"
then then
if test '' = "$force" if test '' = "$force"
@ -121,10 +121,11 @@ then
then then
die "cannot force-update the current branch." die "cannot force-update the current branch."
fi fi
prev=`git rev-parse --verify "refs/heads/$branchname"`
fi fi
if test "$create_log" = 'yes' if test "$create_log" = 'yes'
then then
mkdir -p $(dirname "$GIT_DIR/logs/refs/heads/$branchname") mkdir -p $(dirname "$GIT_DIR/logs/refs/heads/$branchname")
touch "$GIT_DIR/logs/refs/heads/$branchname" touch "$GIT_DIR/logs/refs/heads/$branchname"
fi fi
git update-ref -m "branch: Created from $head" "refs/heads/$branchname" $rev git update-ref -m "branch: Created from $head" "refs/heads/$branchname" "$rev" "$prev"

View File

@ -547,15 +547,15 @@ then
PARENTS=$(git-cat-file commit HEAD | PARENTS=$(git-cat-file commit HEAD |
sed -n -e '/^$/q' -e 's/^parent /-p /p') sed -n -e '/^$/q' -e 's/^parent /-p /p')
fi fi
current=$(git-rev-parse --verify HEAD) current="$(git-rev-parse --verify HEAD)"
else else
if [ -z "$(git-ls-files)" ]; then if [ -z "$(git-ls-files)" ]; then
echo >&2 Nothing to commit echo >&2 Nothing to commit
exit 1 exit 1
fi fi
PARENTS="" PARENTS=""
current=
rloga='commit (initial)' rloga='commit (initial)'
current=''
fi fi
if test -z "$no_edit" if test -z "$no_edit"
@ -631,7 +631,7 @@ then
fi && fi &&
commit=$(cat "$GIT_DIR"/COMMIT_MSG | git-commit-tree $tree $PARENTS) && commit=$(cat "$GIT_DIR"/COMMIT_MSG | git-commit-tree $tree $PARENTS) &&
rlogm=$(sed -e 1q "$GIT_DIR"/COMMIT_MSG) && rlogm=$(sed -e 1q "$GIT_DIR"/COMMIT_MSG) &&
git-update-ref -m "$rloga: $rlogm" HEAD $commit $current && git-update-ref -m "$rloga: $rlogm" HEAD $commit "$current" &&
rm -f -- "$GIT_DIR/MERGE_HEAD" && rm -f -- "$GIT_DIR/MERGE_HEAD" &&
if test -f "$NEXT_INDEX" if test -f "$NEXT_INDEX"
then then

View File

@ -63,8 +63,11 @@ done
name="$1" name="$1"
[ "$name" ] || usage [ "$name" ] || usage
if [ -e "$GIT_DIR/refs/tags/$name" -a -z "$force" ]; then prev=0000000000000000000000000000000000000000
die "tag '$name' already exists" if test -e "$GIT_DIR/refs/tags/$name"
then
test -n "$force" || die "tag '$name' already exists"
prev=`git rev-parse "refs/tags/$name"`
fi fi
shift shift
git-check-ref-format "tags/$name" || git-check-ref-format "tags/$name" ||
@ -109,4 +112,4 @@ fi
leading=`expr "refs/tags/$name" : '\(.*\)/'` && leading=`expr "refs/tags/$name" : '\(.*\)/'` &&
mkdir -p "$GIT_DIR/$leading" && mkdir -p "$GIT_DIR/$leading" &&
echo $object > "$GIT_DIR/refs/tags/$name" GIT_DIR="$GIT_DIR" git update-ref "refs/tags/$name" "$object" "$prev"