diff options
Diffstat (limited to 'walker.c')
-rw-r--r-- | walker.c | 127 |
1 files changed, 72 insertions, 55 deletions
@@ -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) |