uintmax_t last_commit;
uintmax_t num_notes;
unsigned active : 1;
+ unsigned delete : 1;
unsigned pack_id : PACK_ID_BITS;
unsigned char sha1[20];
};
unsigned int i, n;
struct tree_entry *e;
- slash1 = strchr(p, '/');
- if (slash1)
- n = slash1 - p;
- else
- n = strlen(p);
+ slash1 = strchrnul(p, '/');
+ n = slash1 - p;
if (!n)
die("Empty path component found in input");
- if (!slash1 && !S_ISDIR(mode) && subtree)
+ if (!*slash1 && !S_ISDIR(mode) && subtree)
die("Non-directories cannot have subtrees");
if (!root->tree)
for (i = 0; i < t->entry_count; i++) {
e = t->entries[i];
if (e->name->str_len == n && !strncmp_icase(p, e->name->str_dat, n)) {
- if (!slash1) {
+ if (!*slash1) {
if (!S_ISDIR(mode)
&& e->versions[1].mode == mode
&& !hashcmp(e->versions[1].sha1, sha1))
e->versions[0].mode = 0;
hashclr(e->versions[0].sha1);
t->entries[t->entry_count++] = e;
- if (slash1) {
+ if (*slash1) {
e->tree = new_tree_content(8);
e->versions[1].mode = S_IFDIR;
tree_content_set(e, slash1 + 1, sha1, mode, subtree);
unsigned int i, n;
struct tree_entry *e;
- slash1 = strchr(p, '/');
- if (slash1)
- n = slash1 - p;
- else
- n = strlen(p);
+ slash1 = strchrnul(p, '/');
+ n = slash1 - p;
if (!root->tree)
load_tree(root);
for (i = 0; i < t->entry_count; i++) {
e = t->entries[i];
if (e->name->str_len == n && !strncmp_icase(p, e->name->str_dat, n)) {
- if (slash1 && !S_ISDIR(e->versions[1].mode))
+ if (*slash1 && !S_ISDIR(e->versions[1].mode))
/*
* If p names a file in some subdirectory, and a
* file or symlink matching the name of the
* exist and need not be deleted.
*/
return 1;
- if (!slash1 || !S_ISDIR(e->versions[1].mode))
+ if (!*slash1 || !S_ISDIR(e->versions[1].mode))
goto del_entry;
if (!e->tree)
load_tree(e);
unsigned int i, n;
struct tree_entry *e;
- slash1 = strchr(p, '/');
- if (slash1)
- n = slash1 - p;
- else
- n = strlen(p);
+ slash1 = strchrnul(p, '/');
+ n = slash1 - p;
if (!n && !allow_root)
die("Empty path component found in input");
for (i = 0; i < t->entry_count; i++) {
e = t->entries[i];
if (e->name->str_len == n && !strncmp_icase(p, e->name->str_dat, n)) {
- if (!slash1)
+ if (!*slash1)
goto found_entry;
if (!S_ISDIR(e->versions[1].mode))
return 0;
static int update_branch(struct branch *b)
{
static const char *msg = "fast-import";
- struct ref_lock *lock;
+ struct ref_transaction *transaction;
unsigned char old_sha1[20];
+ struct strbuf err = STRBUF_INIT;
- if (is_null_sha1(b->sha1))
- return 0;
if (read_ref(b->name, old_sha1))
hashclr(old_sha1);
- lock = lock_any_ref_for_update(b->name, old_sha1, 0, NULL);
- if (!lock)
- return error("Unable to lock %s", b->name);
+ if (is_null_sha1(b->sha1)) {
+ if (b->delete)
+ delete_ref(b->name, old_sha1, 0);
+ return 0;
+ }
if (!force_update && !is_null_sha1(old_sha1)) {
struct commit *old_cmit, *new_cmit;
old_cmit = lookup_commit_reference_gently(old_sha1, 0);
new_cmit = lookup_commit_reference_gently(b->sha1, 0);
- if (!old_cmit || !new_cmit) {
- unlock_ref(lock);
+ if (!old_cmit || !new_cmit)
return error("Branch %s is missing commits.", b->name);
- }
if (!in_merge_bases(old_cmit, new_cmit)) {
- unlock_ref(lock);
warning("Not updating %s"
" (new tip %s does not contain %s)",
b->name, sha1_to_hex(b->sha1), sha1_to_hex(old_sha1));
return -1;
}
}
- if (write_ref_sha1(lock, b->sha1, msg) < 0)
- return error("Unable to update %s", b->name);
+ transaction = ref_transaction_begin(&err);
+ if (!transaction ||
+ ref_transaction_update(transaction, b->name, b->sha1, old_sha1,
+ 0, 1, &err) ||
+ ref_transaction_commit(transaction, msg, &err)) {
+ ref_transaction_free(transaction);
+ error("%s", err.buf);
+ strbuf_release(&err);
+ return -1;
+ }
+ ref_transaction_free(transaction);
+ strbuf_release(&err);
return 0;
}
{
static const char *msg = "fast-import";
struct tag *t;
- struct ref_lock *lock;
- char ref_name[PATH_MAX];
+ struct strbuf ref_name = STRBUF_INIT;
+ struct strbuf err = STRBUF_INIT;
+ struct ref_transaction *transaction;
+ transaction = ref_transaction_begin(&err);
+ if (!transaction) {
+ failure |= error("%s", err.buf);
+ goto cleanup;
+ }
for (t = first_tag; t; t = t->next_tag) {
- sprintf(ref_name, "tags/%s", t->name);
- lock = lock_ref_sha1(ref_name, NULL);
- if (!lock || write_ref_sha1(lock, t->sha1, msg) < 0)
- failure |= error("Unable to update %s", ref_name);
+ strbuf_reset(&ref_name);
+ strbuf_addf(&ref_name, "refs/tags/%s", t->name);
+
+ if (ref_transaction_update(transaction, ref_name.buf, t->sha1,
+ NULL, 0, 0, &err)) {
+ failure |= error("%s", err.buf);
+ goto cleanup;
+ }
}
+ if (ref_transaction_commit(transaction, msg, &err))
+ failure |= error("%s", err.buf);
+
+ cleanup:
+ ref_transaction_free(transaction);
+ strbuf_release(&ref_name);
+ strbuf_release(&err);
}
static void dump_marks_helper(FILE *f,
free(buf);
} else
parse_from_existing(b);
- } else if (!get_sha1(from, b->sha1))
+ } else if (!get_sha1(from, b->sha1)) {
parse_from_existing(b);
+ if (is_null_sha1(b->sha1))
+ b->delete = 1;
+ }
else
die("Invalid ref name or SHA1 expression: %s", from);