summaryrefslogtreecommitdiff
path: root/walker.c
diff options
context:
space:
mode:
Diffstat (limited to 'walker.c')
-rw-r--r--walker.c127
1 files changed, 72 insertions, 55 deletions
diff --git a/walker.c b/walker.c
index 633596e06f..2c86e406f9 100644
--- a/walker.c
+++ b/walker.c
@@ -9,18 +9,21 @@
static unsigned char current_commit_sha1[20];
-void walker_say(struct walker *walker, const char *fmt, const char *hex)
+void walker_say(struct walker *walker, const char *fmt, ...)
{
- if (walker->get_verbosely)
- fprintf(stderr, fmt, hex);
+ if (walker->get_verbosely) {
+ va_list ap;
+ va_start(ap, fmt);
+ vfprintf(stderr, fmt, ap);
+ va_end(ap);
+ }
}
static void report_missing(const struct object *obj)
{
- char missing_hex[41];
- strcpy(missing_hex, sha1_to_hex(obj->sha1));
fprintf(stderr, "Cannot obtain needed %s %s\n",
- obj->type ? typename(obj->type): "object", missing_hex);
+ obj->type ? typename(obj->type): "object",
+ oid_to_hex(&obj->oid));
if (!is_null_sha1(current_commit_sha1))
fprintf(stderr, "while processing commit %s.\n",
sha1_to_hex(current_commit_sha1));
@@ -44,12 +47,12 @@ static int process_tree(struct walker *walker, struct tree *tree)
if (S_ISGITLINK(entry.mode))
continue;
if (S_ISDIR(entry.mode)) {
- struct tree *tree = lookup_tree(entry.sha1);
+ struct tree *tree = lookup_tree(entry.oid->hash);
if (tree)
obj = &tree->object;
}
else {
- struct blob *blob = lookup_blob(entry.sha1);
+ struct blob *blob = lookup_blob(entry.oid->hash);
if (blob)
obj = &blob->object;
}
@@ -60,6 +63,7 @@ static int process_tree(struct walker *walker, struct tree *tree)
return 0;
}
+/* Remember to update object flag allocation in object.h */
#define COMPLETE (1U << 0)
#define SEEN (1U << 1)
#define TO_SCAN (1U << 2)
@@ -78,9 +82,9 @@ static int process_commit(struct walker *walker, struct commit *commit)
if (commit->object.flags & COMPLETE)
return 0;
- hashcpy(current_commit_sha1, commit->object.sha1);
+ hashcpy(current_commit_sha1, commit->object.oid.hash);
- walker_say(walker, "walk %s\n", sha1_to_hex(commit->object.sha1));
+ walker_say(walker, "walk %s\n", oid_to_hex(&commit->object.oid));
if (walker->get_tree) {
if (process(walker, &commit->tree->object))
@@ -130,7 +134,7 @@ static int process_object(struct walker *walker, struct object *obj)
}
return error("Unable to determine requirements "
"of type %s for %s",
- typename(obj->type), sha1_to_hex(obj->sha1));
+ typename(obj->type), oid_to_hex(&obj->oid));
}
static int process(struct walker *walker, struct object *obj)
@@ -139,14 +143,14 @@ static int process(struct walker *walker, struct object *obj)
return 0;
obj->flags |= SEEN;
- if (has_sha1_file(obj->sha1)) {
+ if (has_object_file(&obj->oid)) {
/* We already have it, so we should scan it now. */
obj->flags |= TO_SCAN;
}
else {
if (obj->flags & COMPLETE)
return 0;
- walker->prefetch(walker, obj->sha1);
+ walker->prefetch(walker, obj->oid.hash);
}
object_list_insert(obj, process_queue_end);
@@ -170,13 +174,13 @@ static int loop(struct walker *walker)
* the queue because we needed to fetch it first.
*/
if (! (obj->flags & TO_SCAN)) {
- if (walker->fetch(walker, obj->sha1)) {
+ if (walker->fetch(walker, obj->oid.hash)) {
report_missing(obj);
return -1;
}
}
if (!obj->type)
- parse_object(obj->sha1);
+ parse_object(obj->oid.hash);
if (process_object(walker, obj))
return -1;
}
@@ -190,7 +194,7 @@ static int interpret_target(struct walker *walker, char *target, unsigned char *
if (!check_refname_format(target, 0)) {
struct ref *ref = alloc_ref(target);
if (!walker->fetch_ref(walker, ref)) {
- hashcpy(sha1, ref->old_sha1);
+ hashcpy(sha1, ref->old_oid.hash);
free(ref);
return 0;
}
@@ -199,12 +203,14 @@ static int interpret_target(struct walker *walker, char *target, unsigned char *
return -1;
}
-static int mark_complete(const char *path, const unsigned char *sha1, int flag, void *cb_data)
+static int mark_complete(const char *path, const struct object_id *oid,
+ int flag, void *cb_data)
{
- struct commit *commit = lookup_commit_reference_gently(sha1, 1);
+ struct commit *commit = lookup_commit_reference_gently(oid->hash, 1);
+
if (commit) {
commit->object.flags |= COMPLETE;
- commit_list_insert_by_date(commit, &complete);
+ commit_list_insert(commit, &complete);
}
return 0;
}
@@ -218,7 +224,7 @@ int walker_targets_stdin(char ***target, const char ***write_ref)
char *rf_one = NULL;
char *tg_one;
- if (strbuf_getline(&buf, stdin, '\n') == EOF)
+ if (strbuf_getline_lf(&buf, stdin) == EOF)
break;
tg_one = buf.buf;
rf_one = strchr(tg_one, '\t');
@@ -227,11 +233,11 @@ int walker_targets_stdin(char ***target, const char ***write_ref)
if (targets >= targets_alloc) {
targets_alloc = targets_alloc ? targets_alloc * 2 : 64;
- *target = xrealloc(*target, targets_alloc * sizeof(**target));
- *write_ref = xrealloc(*write_ref, targets_alloc * sizeof(**write_ref));
+ REALLOC_ARRAY(*target, targets_alloc);
+ REALLOC_ARRAY(*write_ref, targets_alloc);
}
(*target)[targets] = xstrdup(tg_one);
- (*write_ref)[targets] = rf_one ? xstrdup(rf_one) : NULL;
+ (*write_ref)[targets] = xstrdup_or_null(rf_one);
targets++;
}
strbuf_release(&buf);
@@ -250,64 +256,75 @@ void walker_targets_free(int targets, char **target, const char **write_ref)
int walker_fetch(struct walker *walker, int targets, char **target,
const char **write_ref, const char *write_ref_log_details)
{
- struct ref_lock **lock = xcalloc(targets, sizeof(struct ref_lock *));
+ struct strbuf refname = STRBUF_INIT;
+ struct strbuf err = STRBUF_INIT;
+ struct ref_transaction *transaction = NULL;
unsigned char *sha1 = xmalloc(targets * 20);
- char *msg;
- int ret;
- int i;
+ char *msg = NULL;
+ int i, ret = -1;
save_commit_buffer = 0;
- for (i = 0; i < targets; i++) {
- if (!write_ref || !write_ref[i])
- continue;
-
- lock[i] = lock_ref_sha1(write_ref[i], NULL);
- if (!lock[i]) {
- error("Can't lock ref %s", write_ref[i]);
- goto unlock_and_fail;
+ if (write_ref) {
+ transaction = ref_transaction_begin(&err);
+ if (!transaction) {
+ error("%s", err.buf);
+ goto done;
}
}
- if (!walker->get_recover)
+ if (!walker->get_recover) {
for_each_ref(mark_complete, NULL);
+ commit_list_sort_by_date(&complete);
+ }
for (i = 0; i < targets; i++) {
if (interpret_target(walker, target[i], &sha1[20 * i])) {
error("Could not interpret response from server '%s' as something to pull", target[i]);
- goto unlock_and_fail;
+ goto done;
}
if (process(walker, lookup_unknown_object(&sha1[20 * i])))
- goto unlock_and_fail;
+ goto done;
}
if (loop(walker))
- goto unlock_and_fail;
-
+ goto done;
+ if (!write_ref) {
+ ret = 0;
+ goto done;
+ }
if (write_ref_log_details) {
- msg = xmalloc(strlen(write_ref_log_details) + 12);
- sprintf(msg, "fetch from %s", write_ref_log_details);
+ msg = xstrfmt("fetch from %s", write_ref_log_details);
} else {
msg = NULL;
}
for (i = 0; i < targets; i++) {
- if (!write_ref || !write_ref[i])
+ if (!write_ref[i])
continue;
- ret = write_ref_sha1(lock[i], &sha1[20 * i], msg ? msg : "fetch (unknown)");
- lock[i] = NULL;
- if (ret)
- goto unlock_and_fail;
+ strbuf_reset(&refname);
+ strbuf_addf(&refname, "refs/%s", write_ref[i]);
+ if (ref_transaction_update(transaction, refname.buf,
+ &sha1[20 * i], NULL, 0,
+ msg ? msg : "fetch (unknown)",
+ &err)) {
+ error("%s", err.buf);
+ goto done;
+ }
+ }
+ if (ref_transaction_commit(transaction, &err)) {
+ error("%s", err.buf);
+ goto done;
}
- free(msg);
-
- return 0;
-unlock_and_fail:
- for (i = 0; i < targets; i++)
- if (lock[i])
- unlock_ref(lock[i]);
+ ret = 0;
- return -1;
+done:
+ ref_transaction_free(transaction);
+ free(msg);
+ free(sha1);
+ strbuf_release(&err);
+ strbuf_release(&refname);
+ return ret;
}
void walker_free(struct walker *walker)