Skip to content

Commit

Permalink
Merge branch 'rs/ref-transaction-0'
Browse files Browse the repository at this point in the history
Early part of the "ref transaction" topic.

* rs/ref-transaction-0:
  refs.c: change ref_transaction_update() to do error checking and return status
  refs.c: remove the onerr argument to ref_transaction_commit
  update-ref: use err argument to get error from ref_transaction_commit
  refs.c: make update_ref_write update a strbuf on failure
  refs.c: make ref_update_reject_duplicates take a strbuf argument for errors
  refs.c: log_ref_write should try to return meaningful errno
  refs.c: make resolve_ref_unsafe set errno to something meaningful on error
  refs.c: commit_packed_refs to return a meaningful errno on failure
  refs.c: make remove_empty_directories always set errno to something sane
  refs.c: verify_lock should set errno to something meaningful
  refs.c: make sure log_ref_setup returns a meaningful errno
  refs.c: add an err argument to repack_without_refs
  lockfile.c: make lock_file return a meaningful errno on failurei
  lockfile.c: add a new public function unable_to_lock_message
  refs.c: add a strbuf argument to ref_transaction_commit for error logging
  refs.c: allow passing NULL to ref_transaction_free
  refs.c: constify the sha arguments for ref_transaction_create|delete|update
  refs.c: ref_transaction_commit should not free the transaction
  refs.c: remove ref_transaction_rollback
  • Loading branch information
Junio C Hamano committed Jul 21, 2014
2 parents ad25da0 + 8e34800 commit 19a249b
Show file tree
Hide file tree
Showing 6 changed files with 199 additions and 100 deletions.
5 changes: 3 additions & 2 deletions builtin/remote.c
Original file line number Diff line number Diff line change
Expand Up @@ -754,7 +754,7 @@ static int remove_branches(struct string_list *branches)
branch_names = xmalloc(branches->nr * sizeof(*branch_names));
for (i = 0; i < branches->nr; i++)
branch_names[i] = branches->items[i].string;
result |= repack_without_refs(branch_names, branches->nr);
result |= repack_without_refs(branch_names, branches->nr, NULL);
free(branch_names);

for (i = 0; i < branches->nr; i++) {
Expand Down Expand Up @@ -1332,7 +1332,8 @@ static int prune_remote(const char *remote, int dry_run)
for (i = 0; i < states.stale.nr; i++)
delete_refs[i] = states.stale.items[i].util;
if (!dry_run)
result |= repack_without_refs(delete_refs, states.stale.nr);
result |= repack_without_refs(delete_refs,
states.stale.nr, NULL);
free(delete_refs);
}

Expand Down
20 changes: 11 additions & 9 deletions builtin/update-ref.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ static struct ref_transaction *transaction;

static char line_termination = '\n';
static int update_flags;
static struct strbuf err = STRBUF_INIT;

/*
* Parse one whitespace- or NUL-terminated, possibly C-quoted argument
Expand Down Expand Up @@ -197,8 +198,9 @@ static const char *parse_cmd_update(struct strbuf *input, const char *next)
if (*next != line_termination)
die("update %s: extra input: %s", refname, next);

ref_transaction_update(transaction, refname, new_sha1, old_sha1,
update_flags, have_old);
if (ref_transaction_update(transaction, refname, new_sha1, old_sha1,
update_flags, have_old, &err))
die("%s", err.buf);

update_flags = 0;
free(refname);
Expand Down Expand Up @@ -286,8 +288,9 @@ static const char *parse_cmd_verify(struct strbuf *input, const char *next)
if (*next != line_termination)
die("verify %s: extra input: %s", refname, next);

ref_transaction_update(transaction, refname, new_sha1, old_sha1,
update_flags, have_old);
if (ref_transaction_update(transaction, refname, new_sha1, old_sha1,
update_flags, have_old, &err))
die("%s", err.buf);

update_flags = 0;
free(refname);
Expand Down Expand Up @@ -359,17 +362,16 @@ int cmd_update_ref(int argc, const char **argv, const char *prefix)
die("Refusing to perform update with empty message.");

if (read_stdin) {
int ret;
transaction = ref_transaction_begin();

if (delete || no_deref || argc > 0)
usage_with_options(git_update_ref_usage, options);
if (end_null)
line_termination = '\0';
update_refs_stdin();
ret = ref_transaction_commit(transaction, msg,
UPDATE_REFS_DIE_ON_ERR);
return ret;
if (ref_transaction_commit(transaction, msg, &err))
die("%s", err.buf);
ref_transaction_free(transaction);
return 0;
}

if (end_null)
Expand Down
4 changes: 3 additions & 1 deletion cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -578,6 +578,8 @@ struct lock_file {
#define LOCK_DIE_ON_ERROR 1
#define LOCK_NODEREF 2
extern int unable_to_lock_error(const char *path, int err);
extern void unable_to_lock_message(const char *path, int err,
struct strbuf *buf);
extern NORETURN void unable_to_lock_index_die(const char *path, int err);
extern int hold_lock_file_for_update(struct lock_file *, const char *path, int);
extern int hold_lock_file_for_append(struct lock_file *, const char *path, int);
Expand Down Expand Up @@ -995,7 +997,7 @@ extern int read_ref(const char *refname, unsigned char *sha1);
* NULL. If more than MAXDEPTH recursive symbolic lookups are needed,
* give up and return NULL.
*
* errno is sometimes set on errors, but not always.
* errno is set to something meaningful on error.
*/
extern const char *resolve_ref_unsafe(const char *ref, unsigned char *sha1, int reading, int *flag);
extern char *resolve_refdup(const char *ref, unsigned char *sha1, int reading, int *flag);
Expand Down
39 changes: 24 additions & 15 deletions lockfile.c
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ static char *resolve_symlink(char *p, size_t s)
return p;
}


/* Make sure errno contains a meaningful value on error */
static int lock_file(struct lock_file *lk, const char *path, int flags)
{
/*
Expand All @@ -129,8 +129,10 @@ static int lock_file(struct lock_file *lk, const char *path, int flags)
*/
static const size_t max_path_len = sizeof(lk->filename) - 5;

if (strlen(path) >= max_path_len)
if (strlen(path) >= max_path_len) {
errno = ENAMETOOLONG;
return -1;
}
strcpy(lk->filename, path);
if (!(flags & LOCK_NODEREF))
resolve_symlink(lk->filename, max_path_len);
Expand All @@ -147,44 +149,51 @@ static int lock_file(struct lock_file *lk, const char *path, int flags)
lock_file_list = lk;
lk->on_list = 1;
}
if (adjust_shared_perm(lk->filename))
return error("cannot fix permission bits on %s",
lk->filename);
if (adjust_shared_perm(lk->filename)) {
int save_errno = errno;
error("cannot fix permission bits on %s",
lk->filename);
errno = save_errno;
return -1;
}
}
else
lk->filename[0] = 0;
return lk->fd;
}

static char *unable_to_lock_message(const char *path, int err)
void unable_to_lock_message(const char *path, int err, struct strbuf *buf)
{
struct strbuf buf = STRBUF_INIT;

if (err == EEXIST) {
strbuf_addf(&buf, "Unable to create '%s.lock': %s.\n\n"
strbuf_addf(buf, "Unable to create '%s.lock': %s.\n\n"
"If no other git process is currently running, this probably means a\n"
"git process crashed in this repository earlier. Make sure no other git\n"
"process is running and remove the file manually to continue.",
absolute_path(path), strerror(err));
} else
strbuf_addf(&buf, "Unable to create '%s.lock': %s",
strbuf_addf(buf, "Unable to create '%s.lock': %s",
absolute_path(path), strerror(err));
return strbuf_detach(&buf, NULL);
}

int unable_to_lock_error(const char *path, int err)
{
char *msg = unable_to_lock_message(path, err);
error("%s", msg);
free(msg);
struct strbuf buf = STRBUF_INIT;

unable_to_lock_message(path, err, &buf);
error("%s", buf.buf);
strbuf_release(&buf);
return -1;
}

NORETURN void unable_to_lock_index_die(const char *path, int err)
{
die("%s", unable_to_lock_message(path, err));
struct strbuf buf = STRBUF_INIT;

unable_to_lock_message(path, err, &buf);
die("%s", buf.buf);
}

/* This should return a meaningful errno on failure */
int hold_lock_file_for_update(struct lock_file *lk, const char *path, int flags)
{
int fd = lock_file(lk, path, flags);
Expand Down
Loading

0 comments on commit 19a249b

Please sign in to comment.