initial_ref_transaction_commit(): function for initial ref creation
"git clone" uses shortcuts when creating the initial set of references: * It writes them directly to packed-refs. * It doesn't lock the individual references (though it does lock the packed-refs file). * It doesn't check for refname conflicts between two new references or between one new reference and any hypothetical old ones. * It doesn't create reflog entries for the reference creations. This functionality was implemented in builtin/clone.c. But really that file shouldn't have such intimate knowledge of how references are stored. So provide a new function in the refs API, initial_ref_transaction_commit(), which can be used for initial reference creation. The new function is based on the ref_transaction interface. This means that we can make some other functions private to the refs module. That will be done in a followup commit. It would seem to make sense to add a test here that there are no existing references, because that is how the function *should* be used. But in fact, the "testgit" remote helper appears to call it *after* having set up refs/remotes/<name>/HEAD and refs/remotes/<name>/master, so we can't be so strict. For now, the function trusts its caller to only call it when it makes sense. Future commits will add some more limited sanity checks. Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:

committed by
Junio C Hamano

parent
79e4d8a9b8
commit
58f233ce1e
47
refs.c
47
refs.c
@ -4076,6 +4076,53 @@ cleanup:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int initial_ref_transaction_commit(struct ref_transaction *transaction,
|
||||
struct strbuf *err)
|
||||
{
|
||||
int ret = 0, i;
|
||||
int n = transaction->nr;
|
||||
struct ref_update **updates = transaction->updates;
|
||||
|
||||
assert(err);
|
||||
|
||||
if (transaction->state != REF_TRANSACTION_OPEN)
|
||||
die("BUG: commit called for transaction that is not open");
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
struct ref_update *update = updates[i];
|
||||
|
||||
if ((update->flags & REF_HAVE_OLD) &&
|
||||
!is_null_sha1(update->old_sha1))
|
||||
die("BUG: initial ref transaction with old_sha1 set");
|
||||
}
|
||||
|
||||
if (lock_packed_refs(0)) {
|
||||
strbuf_addf(err, "unable to lock packed-refs file: %s",
|
||||
strerror(errno));
|
||||
ret = TRANSACTION_GENERIC_ERROR;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
struct ref_update *update = updates[i];
|
||||
|
||||
if ((update->flags & REF_HAVE_NEW) &&
|
||||
!is_null_sha1(update->new_sha1))
|
||||
add_packed_ref(update->refname, update->new_sha1);
|
||||
}
|
||||
|
||||
if (commit_packed_refs()) {
|
||||
strbuf_addf(err, "unable to commit packed-refs file: %s",
|
||||
strerror(errno));
|
||||
ret = TRANSACTION_GENERIC_ERROR;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
cleanup:
|
||||
transaction->state = REF_TRANSACTION_CLOSED;
|
||||
return ret;
|
||||
}
|
||||
|
||||
char *shorten_unambiguous_ref(const char *refname, int strict)
|
||||
{
|
||||
int i;
|
||||
|
Reference in New Issue
Block a user