refs.c make ref_transaction_create a wrapper to ref_transaction_update

Signed-off-by: Ronnie Sahlberg <sahlberg@google.com>
refs.c: make ref_transaction_delete a wrapper for ref_transaction_update

Signed-off-by: Ronnie Sahlberg <sahlberg@google.com>
refs.c: rename the transaction functions

Rename the transaction functions. Remove the leading ref_ from the
names and append _sha1 to the names for functions that create/delete/
update sha1 refs.

Signed-off-by: Ronnie Sahlberg <sahlberg@google.com>
refs.c: add a new update_type field to ref_update

Add a field that describes what type of update this refers to. For now
the only type is UPDATE_SHA1 but we will soon add more types.

Signed-off-by: Ronnie Sahlberg <sahlberg@google.com>
refs.c: add a function to append a reflog entry to a fd

Break out the code to create the string and writing it to the file
descriptor from log_ref_write and into a dedicated function log_ref_write_fd.
For now this is only used from log_ref_write but later on we will call
this function from reflog transactions too which means that we will end
up with only a single place where we write a reflog entry to a file instead
of the current two places (log_ref_write and builtin/reflog.c).

Signed-off-by: Ronnie Sahlberg <sahlberg@google.com>
lockfile.c: make hold_lock_file_for_append preserve meaningful errno

Update hold_lock_file_for_append and copy_fd to return a meaningful errno
on failure.

Signed-off-by: Ronnie Sahlberg <sahlberg@google.com>
refs.c: add a transaction function to append a reflog entry

Define a new transaction update type, UPDATE_LOG, and a new function
transaction_update_reflog. This function will lock the reflog and append
an entry to it during transaction commit.

Signed-off-by: Ronnie Sahlberg <sahlberg@google.com>
refs.c: add a flag to allow reflog updates to truncate the log

Add a flag that allows us to truncate the reflog before we write the
update.

Signed-off-by: Ronnie Sahlberg <sahlberg@google.com>
refs.c: only write reflog update if msg is non-NULL

When performing a reflog transaction update, only write to the reflog iff
msg is non-NULL. This can then be combined with REFLOG_TRUNCATE to perform
an update that only truncates but does not write.

Signed-off-by: Ronnie Sahlberg <sahlberg@google.com>
refs.c: allow multiple reflog updates during a single transaction

Allow to make multiple reflog updates to the same ref during a transaction.
This means we only need to lock the reflog once, during the first update
that touches the reflog, and that all further updates can just write the
reflog entry since the reflog is already locked.

This allows us to write code such as:

t = transaction_begin()
transaction_reflog_update(t, "foo", REFLOG_TRUNCATE, NULL);
loop-over-somehting...
   transaction_reflog_update(t, "foo", 0, <message>);
transaction_commit(t)

where we first truncate the reflog and then build the new content one line at a
time.

Signed-off-by: Ronnie Sahlberg <sahlberg@google.com>
reflog.c: use a reflog transaction when writing during expire

Use a transaction for all updates during expire_reflog.

Signed-off-by: Ronnie Sahlberg <sahlberg@google.com>
refs.c: rename log_ref_setup to create_reflog

Change the name from log_ref_setup to create_reflog. Make create_reflog
create the reflog unconditionally, whatever log_all_ref_updates is set to,
and instead check for log_all_ref_updates before calling it in log_ref_write.

Sicne create_reflog no lonber checks log_all_ref_updates we can skip
temporarily setting it to true before calling create_reflog from
checkout.c.

log_ref_setup/create_reflog is relatively expensive, making many system
calls, and the common case will be that the reflog already exists.
Therefore use the much cheaper reflog_exists to check and only call
create_reflog if we actually do need to create the reflog when calling from
log_ref_write.

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