{"thread":{"id":"16065","subject":"[PATCH 3/3] Fix git update-ref --no-deref -d.","startedAt":"2008-10-27T19:50:19Z","lastAt":"2008-10-29T00:05:27Z","messageCount":6,"participants":["Miklos Vajna"],"isPatch":true,"patchVersion":1,"patchTotal":3},"messages":[{"id":"94072","messageId":"cover.1225136865.git.vmiklos@frugalware.org","threadId":"16065","inReplyTo":"20081027085055.GL2273@genesis.frugalware.org","subject":"[PATCH 0/3] symref rename/delete fixes","fromName":"Miklos Vajna","fromEmail":"vmiklos@frugalware.org","sentAt":"2008-10-27T19:50:19Z","receivedAt":"2008-10-27T19:50:19Z","isPatch":true,"sender":{"key":"vmiklos@frugalware.org","avatar":"https://gravatar.com/avatar/401c1cbbb3a5d13e650c691a2c71d6fd0b80df1a01bc74d9f1972675dd58f2bd?d=mp&s=160"},"body":"On Mon, Oct 27, 2008 at 09:50:55AM +0100, Miklos Vajna <vmiklos@frugalware.org> wrote:\n> Ah, I missed that. You convienced me, I'll post updated patches later\n> today. :)\n\nHere they are. The first is updated: the delete_ref() part is unchanged,\nbut the rename_ref() part is dropped and it just bails out with an error\nif it detects a symref. The testcase is updated according to this as\nwell.\n\nThe two others are just rebased on top of the new first one, no\nfunctional changes.\n\nMiklos Vajna (3):\n  Disallow git branch -m for symrefs.\n  rename_ref(): handle the case when the reflog of a ref does not exist\n  Fix git update-ref --no-deref -d.\n\n builtin-branch.c       |    2 +-\n builtin-receive-pack.c |    2 +-\n builtin-remote.c       |    4 ++--\n builtin-reset.c        |    2 +-\n builtin-send-pack.c    |    2 +-\n builtin-tag.c          |    2 +-\n builtin-update-ref.c   |    8 +++++---\n cache.h                |    2 +-\n refs.c                 |   35 ++++++++++++++++++++++++-----------\n t/t1400-update-ref.sh  |    7 +++++++\n t/t3200-branch.sh      |    9 +++++++++\n 11 files changed, 53 insertions(+), 22 deletions(-)\n"},{"id":"94073","messageId":"a18363084130c4c23279667f6f0bd26d585a061d.1225136865.git.vmiklos@frugalware.org","threadId":"16065","inReplyTo":"cover.1225136865.git.vmiklos@frugalware.org","subject":"[PATCH 1/3] Disallow git branch -m for symrefs.","fromName":"Miklos Vajna","fromEmail":"vmiklos@frugalware.org","sentAt":"2008-10-27T19:50:20Z","receivedAt":"2008-10-27T19:50:20Z","isPatch":true,"sender":{"key":"vmiklos@frugalware.org","avatar":"https://gravatar.com/avatar/401c1cbbb3a5d13e650c691a2c71d6fd0b80df1a01bc74d9f1972675dd58f2bd?d=mp&s=160"},"body":"This had two problems with symrefs. First, it copied the actual sha1\ninstead of the \"pointer\", second it failed to remove the old ref after a\nsuccessful rename.\n\nGiven that till now delete_ref() always dereferenced symrefs, a new\nparameters has been introduced to delete_ref() to allow deleting refs\nwithout a dereference.\n\nFor now, we just don't allow renaming symref as no real-word workflow\nneeds it and doing so would be just an accent.\n\nSigned-off-by: Miklos Vajna <vmiklos@frugalware.org>\n---\n builtin-branch.c       |    2 +-\n builtin-receive-pack.c |    2 +-\n builtin-remote.c       |    4 ++--\n builtin-reset.c        |    2 +-\n builtin-send-pack.c    |    2 +-\n builtin-tag.c          |    2 +-\n builtin-update-ref.c   |    2 +-\n cache.h                |    2 +-\n refs.c                 |   33 +++++++++++++++++++++++----------\n t/t3200-branch.sh      |    9 +++++++++\n 10 files changed, 41 insertions(+), 19 deletions(-)\n\ndiff --git a/builtin-branch.c b/builtin-branch.c\nindex 8d634ff..2b3613f 100644\n--- a/builtin-branch.c\n+++ b/builtin-branch.c\n@@ -160,7 +160,7 @@ static int delete_branches(int argc, const char **argv, int force, int kinds)\n \t\t\tcontinue;\n \t\t}\n \n-\t\tif (delete_ref(name, sha1)) {\n+\t\tif (delete_ref(name, sha1, 0)) {\n \t\t\terror(\"Error deleting %sbranch '%s'\", remote,\n \t\t\t       argv[i]);\n \t\t\tret = 1;\ndiff --git a/builtin-receive-pack.c b/builtin-receive-pack.c\nindex 45e3cd9..ab5fa1c 100644\n--- a/builtin-receive-pack.c\n+++ b/builtin-receive-pack.c\n@@ -224,7 +224,7 @@ static const char *update(struct command *cmd)\n \t\t\twarning (\"Allowing deletion of corrupt ref.\");\n \t\t\told_sha1 = NULL;\n \t\t}\n-\t\tif (delete_ref(name, old_sha1)) {\n+\t\tif (delete_ref(name, old_sha1, 0)) {\n \t\t\terror(\"failed to delete %s\", name);\n \t\t\treturn \"failed to delete\";\n \t\t}\ndiff --git a/builtin-remote.c b/builtin-remote.c\nindex df2be06..e396a3a 100644\n--- a/builtin-remote.c\n+++ b/builtin-remote.c\n@@ -337,7 +337,7 @@ static int remove_branches(struct string_list *branches)\n \t\tconst char *refname = item->string;\n \t\tunsigned char *sha1 = item->util;\n \n-\t\tif (delete_ref(refname, sha1))\n+\t\tif (delete_ref(refname, sha1, 0))\n \t\t\tresult |= error(\"Could not remove branch %s\", refname);\n \t}\n \treturn result;\n@@ -565,7 +565,7 @@ static int prune(int argc, const char **argv)\n \t\t\tconst char *refname = states.stale.items[i].util;\n \n \t\t\tif (!dry_run)\n-\t\t\t\tresult |= delete_ref(refname, NULL);\n+\t\t\t\tresult |= delete_ref(refname, NULL, 0);\n \n \t\t\tprintf(\" * [%s] %s\\n\", dry_run ? \"would prune\" : \"pruned\",\n \t\t\t       abbrev_ref(refname, \"refs/remotes/\"));\ndiff --git a/builtin-reset.c b/builtin-reset.c\nindex 16e6bb2..9514b77 100644\n--- a/builtin-reset.c\n+++ b/builtin-reset.c\n@@ -279,7 +279,7 @@ int cmd_reset(int argc, const char **argv, const char *prefix)\n \t\tupdate_ref(msg, \"ORIG_HEAD\", orig, old_orig, 0, MSG_ON_ERR);\n \t}\n \telse if (old_orig)\n-\t\tdelete_ref(\"ORIG_HEAD\", old_orig);\n+\t\tdelete_ref(\"ORIG_HEAD\", old_orig, 0);\n \tprepend_reflog_action(\"updating HEAD\", msg, sizeof(msg));\n \tupdate_ref_status = update_ref(msg, \"HEAD\", sha1, orig, 0, MSG_ON_ERR);\n \ndiff --git a/builtin-send-pack.c b/builtin-send-pack.c\nindex 910db92..bbf6e0a 100644\n--- a/builtin-send-pack.c\n+++ b/builtin-send-pack.c\n@@ -234,7 +234,7 @@ static void update_tracking_ref(struct remote *remote, struct ref *ref)\n \t\tif (args.verbose)\n \t\t\tfprintf(stderr, \"updating local tracking ref '%s'\\n\", rs.dst);\n \t\tif (ref->deletion) {\n-\t\t\tdelete_ref(rs.dst, NULL);\n+\t\t\tdelete_ref(rs.dst, NULL, 0);\n \t\t} else\n \t\t\tupdate_ref(\"update by push\", rs.dst,\n \t\t\t\t\tref->new_sha1, NULL, 0, 0);\ndiff --git a/builtin-tag.c b/builtin-tag.c\nindex b13fa34..1ff7b37 100644\n--- a/builtin-tag.c\n+++ b/builtin-tag.c\n@@ -125,7 +125,7 @@ static int for_each_tag_name(const char **argv, each_tag_name_fn fn)\n static int delete_tag(const char *name, const char *ref,\n \t\t\t\tconst unsigned char *sha1)\n {\n-\tif (delete_ref(ref, sha1))\n+\tif (delete_ref(ref, sha1, 0))\n \t\treturn 1;\n \tprintf(\"Deleted tag '%s'\\n\", name);\n \treturn 0;\ndiff --git a/builtin-update-ref.c b/builtin-update-ref.c\nindex 56a0b1b..d8f3142 100644\n--- a/builtin-update-ref.c\n+++ b/builtin-update-ref.c\n@@ -48,7 +48,7 @@ int cmd_update_ref(int argc, const char **argv, const char *prefix)\n \t\tdie(\"%s: not a valid old SHA1\", oldval);\n \n \tif (delete)\n-\t\treturn delete_ref(refname, oldval ? oldsha1 : NULL);\n+\t\treturn delete_ref(refname, oldval ? oldsha1 : NULL, 0);\n \telse\n \t\treturn update_ref(msg, refname, sha1, oldval ? oldsha1 : NULL,\n \t\t\t\t  no_deref ? REF_NODEREF : 0, DIE_ON_ERR);\ndiff --git a/cache.h b/cache.h\nindex b0edbf9..a3c77f0 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -434,7 +434,7 @@ extern int commit_locked_index(struct lock_file *);\n extern void set_alternate_index_output(const char *);\n extern int close_lock_file(struct lock_file *);\n extern void rollback_lock_file(struct lock_file *);\n-extern int delete_ref(const char *, const unsigned char *sha1);\n+extern int delete_ref(const char *, const unsigned char *sha1, int delopt);\n \n /* Environment bits from configuration mechanism */\n extern int trust_executable_bit;\ndiff --git a/refs.c b/refs.c\nindex 0a126fa..31a2057 100644\n--- a/refs.c\n+++ b/refs.c\n@@ -921,25 +921,33 @@ static int repack_without_ref(const char *refname)\n \treturn commit_lock_file(&packlock);\n }\n \n-int delete_ref(const char *refname, const unsigned char *sha1)\n+int delete_ref(const char *refname, const unsigned char *sha1, int delopt)\n {\n \tstruct ref_lock *lock;\n-\tint err, i, ret = 0, flag = 0;\n+\tint err, i = 0, ret = 0, flag = 0;\n \n \tlock = lock_ref_sha1_basic(refname, sha1, 0, &flag);\n \tif (!lock)\n \t\treturn 1;\n \tif (!(flag & REF_ISPACKED)) {\n \t\t/* loose */\n-\t\ti = strlen(lock->lk->filename) - 5; /* .lock */\n-\t\tlock->lk->filename[i] = 0;\n-\t\terr = unlink(lock->lk->filename);\n+\t\tconst char *path;\n+\n+\t\tif (!(delopt & REF_NODEREF)) {\n+\t\t\ti = strlen(lock->lk->filename) - 5; /* .lock */\n+\t\t\tlock->lk->filename[i] = 0;\n+\t\t\tpath = lock->lk->filename;\n+\t\t} else {\n+\t\t\tpath = git_path(refname);\n+\t\t}\n+\t\terr = unlink(path);\n \t\tif (err && errno != ENOENT) {\n \t\t\tret = 1;\n \t\t\terror(\"unlink(%s) failed: %s\",\n-\t\t\t      lock->lk->filename, strerror(errno));\n+\t\t\t      path, strerror(errno));\n \t\t}\n-\t\tlock->lk->filename[i] = '.';\n+\t\tif (!(delopt & REF_NODEREF))\n+\t\t\tlock->lk->filename[i] = '.';\n \t}\n \t/* removing the loose one could have resurrected an earlier\n \t * packed one.  Also, if it was not loose we need to repack\n@@ -964,11 +972,16 @@ int rename_ref(const char *oldref, const char *newref, const char *logmsg)\n \tstruct ref_lock *lock;\n \tstruct stat loginfo;\n \tint log = !lstat(git_path(\"logs/%s\", oldref), &loginfo);\n+\tconst char *symref = NULL;\n \n \tif (S_ISLNK(loginfo.st_mode))\n \t\treturn error(\"reflog for %s is a symlink\", oldref);\n \n-\tif (!resolve_ref(oldref, orig_sha1, 1, &flag))\n+\tsymref = resolve_ref(oldref, orig_sha1, 1, &flag);\n+\tif (flag & REF_ISSYMREF)\n+\t\treturn error(\"refname %s is a symbolic ref, renaming it is not supported\",\n+\t\t\t\toldref);\n+\tif (!symref)\n \t\treturn error(\"refname %s not found\", oldref);\n \n \tif (!is_refname_available(newref, oldref, get_packed_refs(), 0))\n@@ -988,12 +1001,12 @@ int rename_ref(const char *oldref, const char *newref, const char *logmsg)\n \t\treturn error(\"unable to move logfile logs/%s to tmp-renamed-log: %s\",\n \t\t\toldref, strerror(errno));\n \n-\tif (delete_ref(oldref, orig_sha1)) {\n+\tif (delete_ref(oldref, orig_sha1, 0)) {\n \t\terror(\"unable to delete old %s\", oldref);\n \t\tgoto rollback;\n \t}\n \n-\tif (resolve_ref(newref, sha1, 1, &flag) && delete_ref(newref, sha1)) {\n+\tif (resolve_ref(newref, sha1, 1, &flag) && delete_ref(newref, sha1, 0)) {\n \t\tif (errno==EISDIR) {\n \t\t\tif (remove_empty_directories(git_path(\"%s\", newref))) {\n \t\t\t\terror(\"Directory not empty: %s\", newref);\ndiff --git a/t/t3200-branch.sh b/t/t3200-branch.sh\nindex 2147eac..20b6c18 100755\n--- a/t/t3200-branch.sh\n+++ b/t/t3200-branch.sh\n@@ -112,6 +112,15 @@ test_expect_success 'config information was renamed, too' \\\n \t\"test $(git config branch.s.dummy) = Hello &&\n \t test_must_fail git config branch.s/s/dummy\"\n \n+test_expect_success 'renaming a symref should fail' \\\n+'\n+\tgit symbolic-ref refs/heads/master2 refs/heads/master &&\n+\ttest_must_fail git branch -m master2 master3 &&\n+\tgit symbolic-ref refs/heads/master2 &&\n+\ttest -f .git/refs/heads/master &&\n+\t! test -f .git/refs/heads/master3\n+'\n+\n test_expect_success \\\n     'git branch -m u v should fail when the reflog for u is a symlink' '\n      git branch -l u &&\n-- \n1.6.0.2\n"},{"id":"94071","messageId":"5eea93aa5f6d35405eafee4fd022dc9f0b5d75b6.1225136865.git.vmiklos@frugalware.org","threadId":"16065","inReplyTo":"a18363084130c4c23279667f6f0bd26d585a061d.1225136865.git.vmiklos@frugalware.org","subject":"[PATCH 2/3] rename_ref(): handle the case when the reflog of a ref does not exist","fromName":"Miklos Vajna","fromEmail":"vmiklos@frugalware.org","sentAt":"2008-10-27T19:50:21Z","receivedAt":"2008-10-27T19:50:21Z","isPatch":true,"sender":{"key":"vmiklos@frugalware.org","avatar":"https://gravatar.com/avatar/401c1cbbb3a5d13e650c691a2c71d6fd0b80df1a01bc74d9f1972675dd58f2bd?d=mp&s=160"},"body":"We tried to check if a reflog of a ref is a symlink without first\nchecking if it exists, which is a bug.\n\nSigned-off-by: Miklos Vajna <vmiklos@frugalware.org>\n---\n refs.c |    2 +-\n 1 files changed, 1 insertions(+), 1 deletions(-)\n\ndiff --git a/refs.c b/refs.c\nindex 31a2057..116eb59 100644\n--- a/refs.c\n+++ b/refs.c\n@@ -974,7 +974,7 @@ int rename_ref(const char *oldref, const char *newref, const char *logmsg)\n \tint log = !lstat(git_path(\"logs/%s\", oldref), &loginfo);\n \tconst char *symref = NULL;\n \n-\tif (S_ISLNK(loginfo.st_mode))\n+\tif (log && S_ISLNK(loginfo.st_mode))\n \t\treturn error(\"reflog for %s is a symlink\", oldref);\n \n \tsymref = resolve_ref(oldref, orig_sha1, 1, &flag);\n-- \n1.6.0.2\n"},{"id":"94070","messageId":"509c44856b50b0cf55e72cf8ec56b477a0c89790.1225136865.git.vmiklos@frugalware.org","threadId":"16065","inReplyTo":"5eea93aa5f6d35405eafee4fd022dc9f0b5d75b6.1225136865.git.vmiklos@frugalware.org","subject":"[PATCH 3/3] Fix git update-ref --no-deref -d.","fromName":"Miklos Vajna","fromEmail":"vmiklos@frugalware.org","sentAt":"2008-10-27T19:50:22Z","receivedAt":"2008-10-27T19:50:22Z","isPatch":true,"sender":{"key":"vmiklos@frugalware.org","avatar":"https://gravatar.com/avatar/401c1cbbb3a5d13e650c691a2c71d6fd0b80df1a01bc74d9f1972675dd58f2bd?d=mp&s=160"},"body":"Till now --no-deref was just ignored when deleting refs, fix this.\n\nSigned-off-by: Miklos Vajna <vmiklos@frugalware.org>\n---\n builtin-update-ref.c  |    8 +++++---\n t/t1400-update-ref.sh |    7 +++++++\n 2 files changed, 12 insertions(+), 3 deletions(-)\n\ndiff --git a/builtin-update-ref.c b/builtin-update-ref.c\nindex d8f3142..378dc1b 100644\n--- a/builtin-update-ref.c\n+++ b/builtin-update-ref.c\n@@ -13,7 +13,7 @@ int cmd_update_ref(int argc, const char **argv, const char *prefix)\n {\n \tconst char *refname, *oldval, *msg=NULL;\n \tunsigned char sha1[20], oldsha1[20];\n-\tint delete = 0, no_deref = 0;\n+\tint delete = 0, no_deref = 0, flags = 0;\n \tstruct option options[] = {\n \t\tOPT_STRING( 'm', NULL, &msg, \"reason\", \"reason of the update\"),\n \t\tOPT_BOOLEAN('d', NULL, &delete, \"deletes the reference\"),\n@@ -47,9 +47,11 @@ int cmd_update_ref(int argc, const char **argv, const char *prefix)\n \tif (oldval && *oldval && get_sha1(oldval, oldsha1))\n \t\tdie(\"%s: not a valid old SHA1\", oldval);\n \n+\tif (no_deref)\n+\t\tflags = REF_NODEREF;\n \tif (delete)\n-\t\treturn delete_ref(refname, oldval ? oldsha1 : NULL, 0);\n+\t\treturn delete_ref(refname, oldval ? oldsha1 : NULL, flags);\n \telse\n \t\treturn update_ref(msg, refname, sha1, oldval ? oldsha1 : NULL,\n-\t\t\t\t  no_deref ? REF_NODEREF : 0, DIE_ON_ERR);\n+\t\t\t\t  flags, DIE_ON_ERR);\n }\ndiff --git a/t/t1400-update-ref.sh b/t/t1400-update-ref.sh\nindex 04c2b16..8139cd6 100755\n--- a/t/t1400-update-ref.sh\n+++ b/t/t1400-update-ref.sh\n@@ -75,6 +75,13 @@ test_expect_success \"delete $m (by HEAD)\" '\n '\n rm -f .git/$m\n \n+cp -f .git/HEAD .git/HEAD.orig\n+test_expect_success \"delete symref without dereference\" '\n+\tgit update-ref --no-deref -d HEAD &&\n+\t! test -f .git/HEAD\n+'\n+cp -f .git/HEAD.orig .git/HEAD\n+\n test_expect_success '(not) create HEAD with old sha1' \"\n \ttest_must_fail git update-ref HEAD $A $B\n \"\n-- \n1.6.0.2\n"},{"id":"94149","messageId":"20081028234541.GY24201@genesis.frugalware.org","threadId":"16065","inReplyTo":"cover.1225136865.git.vmiklos@frugalware.org","subject":"Re: [PATCH 0/3] symref rename/delete fixes","fromName":"Miklos Vajna","fromEmail":"vmiklos@frugalware.org","sentAt":"2008-10-28T23:45:41Z","receivedAt":"2008-10-28T23:45:41Z","isPatch":true,"sender":{"key":"vmiklos@frugalware.org","avatar":"https://gravatar.com/avatar/401c1cbbb3a5d13e650c691a2c71d6fd0b80df1a01bc74d9f1972675dd58f2bd?d=mp&s=160"},"body":"On Mon, Oct 27, 2008 at 08:50:19PM +0100, Miklos Vajna <vmiklos@frugalware.org> wrote:\n> Here they are. The first is updated: the delete_ref() part is unchanged,\n> but the rename_ref() part is dropped and it just bails out with an error\n> if it detects a symref. The testcase is updated according to this as\n> well.\n> \n> The two others are just rebased on top of the new first one, no\n> functional changes.\n\nI forgot to fetch and did not notice the previous round is already in\n'next'. Just forget about these patches then, I'll rebase the relevant\npart against mv/maint-branch-m-symref and resend.\n"},{"id":"94152","messageId":"1225238727-12399-1-git-send-email-vmiklos@frugalware.org","threadId":"16065","inReplyTo":"20081028234541.GY24201@genesis.frugalware.org","subject":"[PATCH] git branch -m: forbid renaming of a symref","fromName":"Miklos Vajna","fromEmail":"vmiklos@frugalware.org","sentAt":"2008-10-29T00:05:27Z","receivedAt":"2008-10-29T00:05:27Z","isPatch":true,"sender":{"key":"vmiklos@frugalware.org","avatar":"https://gravatar.com/avatar/401c1cbbb3a5d13e650c691a2c71d6fd0b80df1a01bc74d9f1972675dd58f2bd?d=mp&s=160"},"body":"There may be cases where one would really want to rename the symbolic\nref without changing its value, but \"git branch -m\" is not such a\nuse-case.\n\nSigned-off-by: Miklos Vajna <vmiklos@frugalware.org>\n---\n\nThis applies on top of 'mv/maint-branch-m-symref'.\n\n refs.c            |   29 +++++++++++++----------------\n t/t3200-branch.sh |    8 ++++----\n 2 files changed, 17 insertions(+), 20 deletions(-)\n\ndiff --git a/refs.c b/refs.c\nindex b39e6f2..8a38e08 100644\n--- a/refs.c\n+++ b/refs.c\n@@ -964,14 +964,14 @@ int rename_ref(const char *oldref, const char *newref, const char *logmsg)\n \tstruct stat loginfo;\n \tint log = !lstat(git_path(\"logs/%s\", oldref), &loginfo);\n \tconst char *symref = NULL;\n-\tint is_symref = 0;\n \n \tif (log && S_ISLNK(loginfo.st_mode))\n \t\treturn error(\"reflog for %s is a symlink\", oldref);\n \n \tsymref = resolve_ref(oldref, orig_sha1, 1, &flag);\n \tif (flag & REF_ISSYMREF)\n-\t\tis_symref = 1;\n+\t\treturn error(\"refname %s is a symbolic ref, renaming it is not supported\",\n+\t\t\toldref);\n \tif (!symref)\n \t\treturn error(\"refname %s not found\", oldref);\n \n@@ -1035,20 +1035,17 @@ int rename_ref(const char *oldref, const char *newref, const char *logmsg)\n \t}\n \tlogmoved = log;\n \n-\tif (!is_symref) {\n-\t\tlock = lock_ref_sha1_basic(newref, NULL, 0, NULL);\n-\t\tif (!lock) {\n-\t\t\terror(\"unable to lock %s for update\", newref);\n-\t\t\tgoto rollback;\n-\t\t}\n-\t\tlock->force_write = 1;\n-\t\thashcpy(lock->old_sha1, orig_sha1);\n-\t\tif (write_ref_sha1(lock, orig_sha1, logmsg)) {\n-\t\t\terror(\"unable to write current sha1 into %s\", newref);\n-\t\t\tgoto rollback;\n-\t\t}\n-\t} else\n-\t\tcreate_symref(newref, symref, logmsg);\n+\tlock = lock_ref_sha1_basic(newref, NULL, 0, NULL);\n+\tif (!lock) {\n+\t\terror(\"unable to lock %s for update\", newref);\n+\t\tgoto rollback;\n+\t}\n+\tlock->force_write = 1;\n+\thashcpy(lock->old_sha1, orig_sha1);\n+\tif (write_ref_sha1(lock, orig_sha1, logmsg)) {\n+\t\terror(\"unable to write current sha1 into %s\", newref);\n+\t\tgoto rollback;\n+\t}\n \n \treturn 0;\n \ndiff --git a/t/t3200-branch.sh b/t/t3200-branch.sh\nindex fdeb1f5..25e9971 100755\n--- a/t/t3200-branch.sh\n+++ b/t/t3200-branch.sh\n@@ -112,13 +112,13 @@ test_expect_success 'config information was renamed, too' \\\n \t\"test $(git config branch.s.dummy) = Hello &&\n \t test_must_fail git config branch.s/s/dummy\"\n \n-test_expect_success 'renaming a symref' \\\n+test_expect_success 'renaming a symref is not allowed' \\\n '\n \tgit symbolic-ref refs/heads/master2 refs/heads/master &&\n-\tgit branch -m master2 master3 &&\n-\tgit symbolic-ref refs/heads/master3 &&\n+\ttest_must_fail git branch -m master2 master3 &&\n+\tgit symbolic-ref refs/heads/master2 &&\n \ttest -f .git/refs/heads/master &&\n-\t! test -f .git/refs/heads/master2\n+\t! test -f .git/refs/heads/master3\n '\n \n test_expect_success \\\n-- \n1.6.0.2\n"}]}