]> git.ipfire.org Git - thirdparty/git.git/commit - refs/refs-internal.h
lock_ref_for_update(): don't resolve symrefs
authorMichael Haggerty <mhagger@alum.mit.edu>
Mon, 25 Apr 2016 15:48:32 +0000 (17:48 +0200)
committerMichael Haggerty <mhagger@alum.mit.edu>
Mon, 13 Jun 2016 09:23:50 +0000 (11:23 +0200)
commit6e30b2f652d0a6748e2041dee5b5612cafca29b2
treeccbaead4bf43149ce01d8af6fcae26d50491527e
parent8169d0d06ad721aa54d95f044f4b097d79151ea2
lock_ref_for_update(): don't resolve symrefs

If a transaction includes a non-NODEREF update to a symbolic reference,
we don't have to look it up in lock_ref_for_update(). The reference will
be dereferenced anyway when the split-off update is processed.

This change requires that we store a backpointer from the split-off
update to its parent update, for two reasons:

* We still want to report the original reference name in error messages.
  So if an error occurs when checking the split-off update's old_sha1,
  walk the parent_update pointers back to find the original reference
  name, and report that one.

* We still need to write the old_sha1 of the symref to its reflog. So
  after we read the split-off update's reference value, walk the
  parent_update pointers back and fill in their old_sha1 fields.

Aside from eliminating unnecessary reads, this change fixes a
subtle (though not very serious) race condition: in the old code, the
old_sha1 of the symref was resolved before the reference that it pointed
at was locked. So it was possible that the old_sha1 value logged to the
symref's reflog could be wrong if another process changed the downstream
reference before it was locked.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
refs/files-backend.c
refs/refs-internal.h