refs.c: update the list of deleted refs during _update instead of _commit

When deleting refs during a transaction, update the list of the refs to be
deleted already during _update instead of waiting until the _commit stage.

Signed-off-by: Ronnie Sahlberg <sahlberg@google.com>
refs.c: return error instead of dying when locking fails during transaction

Change lock_ref_sha1_basic to return an error instead of dying when
we fail to lock a file during a transaction.

Signed-off-by: Ronnie Sahlberg <sahlberg@google.com>
tests: move tests for -z update/delete/verify to after the ref is created

The tests for stdin -z fails for update/delete/verify are of the form
update refs/heads/a $m $m $m
and rely on the fact that when parsed we will first parse everything except
the trailing $m. And once that command has completed it will start parsing
the next command, find the trailing $m from before and fail because this
would not look like a proper command. I.e. we do not detect that there are
too many arguments so much as detect that the next command looks like
garbage.

But since the ref refs/heads/a does not exist at this point in the test we
actually have two failures that trigger. We have one error that is due to
update refs/heads/a $m $m would be invalid because the ref does not exist
and we have a second error that is due to the trailing $m causing a "too
many arguments". The current test depends on the order of check for these two
which makes the test fragile (and would break after the next patch).

Move these tests further down in the test to occur after we have created
refs/heads/a so that there is only one error condition in the test and that
we no longer depend on in which order the checks for error occur.

Signed-off-by: Ronnie Sahlberg <sahlberg@google.com>
refs.c: lock the ref during _update instead of during _commit

Try to lock the ref during the transaction update instead of later during the
commit phase. This allows us to do things such as :

t = transaction_begin()
transaction_update_sha1(t, ref, ...)   /* locking ref */
...
do stuff while we know that ref is locked
...
transaction_commit(t)

Signed-off-by: Ronnie Sahlberg <sahlberg@google.com>
refs.c: check for lock conflicts already in _update

Check for lock conflicts in _update and flag the transaction as errored
instead of waiting until _commit for doing these checks. If there was a lock
failure we check if this was due to a previous update in the same transaction
or not. This so that we can preserve the current error messages on lock failure
and log "Multiple updates for ref '%s' not allowed." when we have multiple
updates in the same transaction and "Cannot lock the ref '%s'." for any other
reason that the lock failed.

This also means that we no longer need to sort all the refs and check for
duplicates during _commit so all that code can be removed too.

Signed-off-by: Ronnie Sahlberg <sahlberg@google.com>
refs.c allow multiple updates of the same ref in a transaction

Allow multiple updates of a ref in the same transaction as long as
each update has have_old and old_sha1 matches the new_sha1 of the
previous update.

Add a test that verifies that a valid sequence such as
  create ref a
  update ref b a
  update ref c b
works and a test that an invalid sequence such as this still fails:
  update ref a c
  update ref b b
  update ref c c

Signed-off-by: Ronnie Sahlberg <sahlberg@google.com>
refs.c: release all remaining locks during transaction_free

If there are remaining locks held when we free a transaction, make sure that
we release them instead of relying on the atexit magic to release them for
us. Otherwise, if we perform two transactions on the same ref and the first
transaction is aborted then the second transaction will fail to lock the ref.
This can currently not trigger since there are no commands that use multiple
transactions.

This sequence illustrates the bug:

t = transaction_begin()  /* first transaction */
transaction_update_sha1(t, ref, ...)  /* ref is locked */
transaction_free(t)

t = transaction_begin() /* second transaction */
transaction_update_sha1(t, ref, ...) /* will fail since ref was locked above */

Signed-off-by: Ronnie Sahlberg <sahlberg@google.com>
reflog.c: use the existing transaction to also lock and update the ref

reflog.c has a transaction for updating the reflog. Use this transaction
also for locking the ref itself and updating the ref instead of
locking the file directly and writing to it. This now completely eliminates
the refs and reflog implementation from reflog.c.

Signed-off-by: Ronnie Sahlberg <sahlberg@google.com>
refs.c: make unlock_ref static

We no longer need to export unlock_ref. Make the function static.

Signed-off-by: Ronnie Sahlberg <sahlberg@google.com>
refs.c: make close_ref static

We no longer need to export close_ref. Make the function static.

Signed-off-by: Ronnie Sahlberg <sahlberg@google.com>
refs.c: make commit_ref static

We no longer need to export commit_ref. Make the function static.

Signed-off-by: Ronnie Sahlberg <sahlberg@google.com>
refs.c: remove the function lock_any_ref_for_update

We no longer need the function lock_any_ref_for_update so lets remove it.

Signed-off-by: Ronnie Sahlberg <sahlberg@google.com>
refs.c: make struct ref_lock private to refs.c

We no longer need to expose the ref_lock structure to any external callers.
Make it private to refs.c.

Signed-off-by: Ronnie Sahlberg <sahlberg@google.com>
refs.c: allow passing raw git_committer_info as email to _update_reflog

In many places in the code we do not have access to the individual fields
in the committer data. Instead we might only have access to prebaked data
such as what is returned by git_committer_info() containing a string
that consists of email, timestamp, zone etc.

This makes it inconvenient to use transaction_update_reflog since it means you
would have to first parse git_committer_info before you can call update_reflog.

Add a new flag REFLOG_EMAIL_IS_COMMITTER to _update_reflog to tell it
that what we pass in as email is already the fully baked committer string
we can use as-is.

Signed-off-by: Ronnie Sahlberg <sahlberg@google.com>

Conflicts:
	refs.c
refs.c: move ref_update and other definitions to earlier in the file

Move the struct ref_update definition and some enums to earlier in the file.
This does not change any actual code or definitions but just moves them
to a different place in the code since we will soon reference some of these
from the rename_ref function.

Signed-off-by: Ronnie Sahlberg <sahlberg@google.com>

Conflicts:
	refs.c
refs.c: use the transaction to manage the reflog in rename_refs

We have a transaction in rename_ref to managing the ref during the rename.
Use this transaction to manage the changes to the reflog too.
This now means that rename_ref is almost completely agnostic about how refs
storage is implemented and should be easier to migrate if/when we allow a
different store for refs, such as a database.

Signed-off-by: Ronnie Sahlberg <sahlberg@google.com>