diff options
author | Daniel Barkalow <barkalow@iabervon.org> | 2007-09-10 23:02:45 -0400 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2007-09-19 03:22:30 -0700 |
commit | 30ae764b1e11f10b5fca723a876a0f3de3ca11ab (patch) | |
tree | b947d1e54e9bb87327e45395f28d4356821988c9 /fetch.c | |
parent | fbdeef948bbc085124f9634d5108940dce5fc688 (diff) | |
download | git-30ae764b1e11f10b5fca723a876a0f3de3ca11ab.tar.gz git-30ae764b1e11f10b5fca723a876a0f3de3ca11ab.tar.xz |
Modularize commit-walker
This turns the extern functions to be provided by the backend into a
struct of pointers, renames the functions to be more
namespace-friendly, and updates http-fetch to this interface. It
removes the unused include from http-push.c. It makes git-http-fetch a
builtin (with the implementation a separate file, accessible
directly).
Signed-off-by: Daniel Barkalow <barkalow@iabervon.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'fetch.c')
-rw-r--r-- | fetch.c | 317 |
1 files changed, 0 insertions, 317 deletions
diff --git a/fetch.c b/fetch.c deleted file mode 100644 index 811be87a3..000000000 --- a/fetch.c +++ /dev/null @@ -1,317 +0,0 @@ -#include "cache.h" -#include "fetch.h" -#include "commit.h" -#include "tree.h" -#include "tree-walk.h" -#include "tag.h" -#include "blob.h" -#include "refs.h" -#include "strbuf.h" - -int get_tree = 0; -int get_history = 0; -int get_all = 0; -int get_verbosely = 0; -int get_recover = 0; -static unsigned char current_commit_sha1[20]; - -void pull_say(const char *fmt, const char *hex) -{ - if (get_verbosely) - fprintf(stderr, fmt, hex); -} - -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); - if (!is_null_sha1(current_commit_sha1)) - fprintf(stderr, "while processing commit %s.\n", - sha1_to_hex(current_commit_sha1)); -} - -static int process(struct object *obj); - -static int process_tree(struct tree *tree) -{ - struct tree_desc desc; - struct name_entry entry; - - if (parse_tree(tree)) - return -1; - - init_tree_desc(&desc, tree->buffer, tree->size); - while (tree_entry(&desc, &entry)) { - struct object *obj = NULL; - - /* submodule commits are not stored in the superproject */ - if (S_ISGITLINK(entry.mode)) - continue; - if (S_ISDIR(entry.mode)) { - struct tree *tree = lookup_tree(entry.sha1); - if (tree) - obj = &tree->object; - } - else { - struct blob *blob = lookup_blob(entry.sha1); - if (blob) - obj = &blob->object; - } - if (!obj || process(obj)) - return -1; - } - free(tree->buffer); - tree->buffer = NULL; - tree->size = 0; - return 0; -} - -#define COMPLETE (1U << 0) -#define SEEN (1U << 1) -#define TO_SCAN (1U << 2) - -static struct commit_list *complete = NULL; - -static int process_commit(struct commit *commit) -{ - if (parse_commit(commit)) - return -1; - - while (complete && complete->item->date >= commit->date) { - pop_most_recent_commit(&complete, COMPLETE); - } - - if (commit->object.flags & COMPLETE) - return 0; - - hashcpy(current_commit_sha1, commit->object.sha1); - - pull_say("walk %s\n", sha1_to_hex(commit->object.sha1)); - - if (get_tree) { - if (process(&commit->tree->object)) - return -1; - if (!get_all) - get_tree = 0; - } - if (get_history) { - struct commit_list *parents = commit->parents; - for (; parents; parents = parents->next) { - if (process(&parents->item->object)) - return -1; - } - } - return 0; -} - -static int process_tag(struct tag *tag) -{ - if (parse_tag(tag)) - return -1; - return process(tag->tagged); -} - -static struct object_list *process_queue = NULL; -static struct object_list **process_queue_end = &process_queue; - -static int process_object(struct object *obj) -{ - if (obj->type == OBJ_COMMIT) { - if (process_commit((struct commit *)obj)) - return -1; - return 0; - } - if (obj->type == OBJ_TREE) { - if (process_tree((struct tree *)obj)) - return -1; - return 0; - } - if (obj->type == OBJ_BLOB) { - return 0; - } - if (obj->type == OBJ_TAG) { - if (process_tag((struct tag *)obj)) - return -1; - return 0; - } - return error("Unable to determine requirements " - "of type %s for %s", - typename(obj->type), sha1_to_hex(obj->sha1)); -} - -static int process(struct object *obj) -{ - if (obj->flags & SEEN) - return 0; - obj->flags |= SEEN; - - if (has_sha1_file(obj->sha1)) { - /* We already have it, so we should scan it now. */ - obj->flags |= TO_SCAN; - } - else { - if (obj->flags & COMPLETE) - return 0; - prefetch(obj->sha1); - } - - object_list_insert(obj, process_queue_end); - process_queue_end = &(*process_queue_end)->next; - return 0; -} - -static int loop(void) -{ - struct object_list *elem; - - while (process_queue) { - struct object *obj = process_queue->item; - elem = process_queue; - process_queue = elem->next; - free(elem); - if (!process_queue) - process_queue_end = &process_queue; - - /* If we are not scanning this object, we placed it in - * the queue because we needed to fetch it first. - */ - if (! (obj->flags & TO_SCAN)) { - if (fetch(obj->sha1)) { - report_missing(obj); - return -1; - } - } - if (!obj->type) - parse_object(obj->sha1); - if (process_object(obj)) - return -1; - } - return 0; -} - -static int interpret_target(char *target, unsigned char *sha1) -{ - if (!get_sha1_hex(target, sha1)) - return 0; - if (!check_ref_format(target)) { - if (!fetch_ref(target, sha1)) { - return 0; - } - } - return -1; -} - -static int mark_complete(const char *path, const unsigned char *sha1, int flag, void *cb_data) -{ - struct commit *commit = lookup_commit_reference_gently(sha1, 1); - if (commit) { - commit->object.flags |= COMPLETE; - insert_by_date(commit, &complete); - } - return 0; -} - -int pull_targets_stdin(char ***target, const char ***write_ref) -{ - int targets = 0, targets_alloc = 0; - struct strbuf buf; - *target = NULL; *write_ref = NULL; - strbuf_init(&buf); - while (1) { - char *rf_one = NULL; - char *tg_one; - - read_line(&buf, stdin, '\n'); - if (buf.eof) - break; - tg_one = buf.buf; - rf_one = strchr(tg_one, '\t'); - if (rf_one) - *rf_one++ = 0; - - 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)); - } - (*target)[targets] = xstrdup(tg_one); - (*write_ref)[targets] = rf_one ? xstrdup(rf_one) : NULL; - targets++; - } - return targets; -} - -void pull_targets_free(int targets, char **target, const char **write_ref) -{ - while (targets--) { - free(target[targets]); - if (write_ref && write_ref[targets]) - free((char *) write_ref[targets]); - } -} - -int pull(int targets, char **target, const char **write_ref, - const char *write_ref_log_details) -{ - struct ref_lock **lock = xcalloc(targets, sizeof(struct ref_lock *)); - unsigned char *sha1 = xmalloc(targets * 20); - char *msg; - int ret; - int i; - - save_commit_buffer = 0; - track_object_refs = 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 (!get_recover) - for_each_ref(mark_complete, NULL); - - for (i = 0; i < targets; i++) { - if (interpret_target(target[i], &sha1[20 * i])) { - error("Could not interpret %s as something to pull", target[i]); - goto unlock_and_fail; - } - if (process(lookup_unknown_object(&sha1[20 * i]))) - goto unlock_and_fail; - } - - if (loop()) - goto unlock_and_fail; - - if (write_ref_log_details) { - msg = xmalloc(strlen(write_ref_log_details) + 12); - sprintf(msg, "fetch from %s", write_ref_log_details); - } else { - msg = NULL; - } - for (i = 0; i < targets; i++) { - if (!write_ref || !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; - } - free(msg); - - return 0; - - -unlock_and_fail: - for (i = 0; i < targets; i++) - if (lock[i]) - unlock_ref(lock[i]); - return -1; -} |