From dbeca7969871a00826d662e68cfb4039e77c619b Mon Sep 17 00:00:00 2001 From: Russell Belfer Date: Fri, 13 Apr 2012 10:43:47 -0700 Subject: [PATCH] Remove old status implementation This removes the code for the old status implementation. --- src/status.c | 368 +-------------------------------------------------- 1 file changed, 1 insertion(+), 367 deletions(-) diff --git a/src/status.c b/src/status.c index 0732d4a9f..8d2c7de14 100644 --- a/src/status.c +++ b/src/status.c @@ -345,316 +345,6 @@ static int status_entry_update_ignore(struct status_entry *e, git_ignores *ignor return 0; } -struct status_st { - git_repository *repo; - git_vector *vector; - git_index *index; - git_tree *tree; - git_ignores *ignores; - - int workdir_path_len; - git_buf head_tree_relative_path; - int head_tree_relative_path_len; - unsigned int tree_position; - unsigned int index_position; - int is_dir:1; -}; - -static int retrieve_head_tree(git_tree **tree_out, git_repository *repo) -{ - git_reference *resolved_head_ref; - git_commit *head_commit = NULL; - git_tree *tree; - int error = 0; - - *tree_out = NULL; - - if ((error = git_repository_head(&resolved_head_ref, repo)) < 0) { - /* Assume that a situation where HEAD exists but can not be resolved - * is valid. A new repository fits this description for instance. - */ - if (error == GIT_ENOTFOUND) - return 0; - return error; - } - - if ((error = git_commit_lookup( - &head_commit, repo, git_reference_oid(resolved_head_ref))) < 0) - return error; - - git_reference_free(resolved_head_ref); - - if ((error = git_commit_tree(&tree, head_commit)) == 0) - *tree_out = tree; - - git_commit_free(head_commit); - return error; -} - -enum path_type { - GIT_STATUS_PATH_NULL, - GIT_STATUS_PATH_IGNORE, - GIT_STATUS_PATH_FILE, - GIT_STATUS_PATH_FOLDER, -}; - -static int dirent_cb(void *state, git_buf *full_path); -static int alphasorted_futils_direach( - git_buf *path, int (*fn)(void *, git_buf *), void *arg); - -static int process_folder( - struct status_st *st, - const git_tree_entry *tree_entry, - git_buf *full_path, - enum path_type path_type) -{ - git_object *subtree = NULL; - git_tree *pushed_tree = NULL; - int error, pushed_tree_position = 0; - git_otype tree_entry_type = GIT_OBJ_BAD; - - if (tree_entry != NULL) { - tree_entry_type = git_tree_entry_type(tree_entry); - - switch (tree_entry_type) { - case GIT_OBJ_TREE: - error = git_tree_entry_2object(&subtree, ((git_object *)(st->tree))->repo, tree_entry); - pushed_tree = st->tree; - pushed_tree_position = st->tree_position; - st->tree = (git_tree *)subtree; - st->tree_position = 0; - st->head_tree_relative_path_len += 1 + tree_entry->filename_len; /* path + '/' + name */ - break; - - case GIT_OBJ_BLOB: - /* No op */ - break; - - case GIT_OBJ_COMMIT: - /* TODO: proper submodule support */ - break; - - default: - giterr_set(GITERR_REPOSITORY, "Unexpected tree entry type"); - return -1; - } - } - - - if (full_path != NULL && path_type == GIT_STATUS_PATH_FOLDER) { - git_ignores ignores, *old_ignores; - - if ((error = git_ignore__for_path(st->repo, - full_path->ptr + st->workdir_path_len, &ignores)) == 0) - { - old_ignores = st->ignores; - st->ignores = &ignores; - - error = alphasorted_futils_direach(full_path, dirent_cb, st); - - git_ignore__free(st->ignores); - st->ignores = old_ignores; - } - } else { - error = dirent_cb(st, NULL); - } - - if (tree_entry_type == GIT_OBJ_TREE) { - git_object_free(subtree); - st->head_tree_relative_path_len -= 1 + tree_entry->filename_len; - st->tree = pushed_tree; - st->tree_position = pushed_tree_position; - st->tree_position++; - } - - return error; -} - -static int store_if_changed(struct status_st *st, struct status_entry *e) -{ - int error = status_entry_update_flags(e); - if (error < 0) - return error; - - if (status_entry_is_ignorable(e) && - (error = status_entry_update_ignore(e, st->ignores, e->path)) < 0) - return error; - - if (e->status_flags == GIT_STATUS_CURRENT) { - git__free(e); - return 0; - } - - return git_vector_insert(st->vector, e); -} - -static int determine_status( - struct status_st *st, - int in_head, int in_index, int in_workdir, - const git_tree_entry *tree_entry, - const git_index_entry *index_entry, - git_buf *full_path, - const char *status_path, - enum path_type path_type) -{ - struct status_entry *e; - int error = 0; - git_otype tree_entry_type = GIT_OBJ_BAD; - - if (tree_entry != NULL) - tree_entry_type = git_tree_entry_type(tree_entry); - - /* If we're dealing with a directory in the workdir, let's recursively tackle it first */ - if (path_type == GIT_STATUS_PATH_FOLDER) - return process_folder(st, tree_entry, full_path, path_type); - - /* Are we dealing with a file somewhere? */ - if (in_workdir || in_index || (in_head && tree_entry_type == GIT_OBJ_BLOB)) { - e = status_entry_new(NULL, status_path); - - if (in_head && tree_entry_type == GIT_OBJ_BLOB) { - status_entry_update_from_tree_entry(e, tree_entry); - st->tree_position++; - } - - if (in_index) { - status_entry_update_from_index_entry(e, index_entry); - st->index_position++; - } - - if (in_workdir && - (error = status_entry_update_from_workdir(e, full_path->ptr)) < 0) - return error; /* The callee has already set the error message */ - - return store_if_changed(st, e); - } - - /* Are we dealing with a subtree? */ - if (tree_entry_type == GIT_OBJ_TREE) { - assert(in_head && !in_index && !in_workdir); - return process_folder(st, tree_entry, full_path, path_type); - } - - /* We're dealing with something else -- most likely a submodule; - * skip it for now */ - if (in_head) - st->tree_position++; - if (in_index) - st->index_position++; - return 0; -} - -static int path_type_from(git_buf *full_path, int is_dir) -{ - if (full_path == NULL) - return GIT_STATUS_PATH_NULL; - - if (!is_dir) - return GIT_STATUS_PATH_FILE; - - if (!git__suffixcmp(full_path->ptr, "/" DOT_GIT "/")) - return GIT_STATUS_PATH_IGNORE; - - return GIT_STATUS_PATH_FOLDER; -} - -static const char *status_path( - const char *first, const char *second, const char *third) -{ - /* At least one of them can not be NULL */ - assert(first != NULL || second != NULL || third != NULL); - - /* TODO: Fixme. Ensure that when non null, they're all equal */ - if (first != NULL) - return first; - - if (second != NULL) - return second; - - return third; -} - -static int compare(const char *left, const char *right) -{ - if (left == NULL && right == NULL) - return 0; - - if (left == NULL) - return 1; - - if (right == NULL) - return -1; - - return strcmp(left, right); -} - -/* Greatly inspired from JGit IndexTreeWalker */ -/* https://github.com/spearce/jgit/blob/ed47e29c777accfa78c6f50685a5df2b8f5b8ff5/org.spearce.jgit/src/org/spearce/jgit/lib/IndexTreeWalker.java#L88 */ - -static int dirent_cb(void *state, git_buf *a) -{ - const git_tree_entry *m; - const git_index_entry *entry; - enum path_type path_type; - int cmpma, cmpmi, cmpai, error; - const char *pm, *pa, *pi; - const char *m_name, *i_name, *a_name; - struct status_st *st = (struct status_st *)state; - - path_type = path_type_from(a, st->is_dir); - - if (path_type == GIT_STATUS_PATH_IGNORE) - return 0; /* Let's skip the ".git" directory */ - - a_name = (path_type != GIT_STATUS_PATH_NULL) ? a->ptr + st->workdir_path_len : NULL; - - /* Loop over head tree and index up to and including this workdir file */ - while (1) { - if (st->tree == NULL) - m = NULL; - else - m = git_tree_entry_byindex(st->tree, st->tree_position); - - entry = git_index_get(st->index, st->index_position); - - if ((m == NULL) && (a == NULL) && (entry == NULL)) - return 0; - - if (m != NULL) { - git_buf_truncate(&st->head_tree_relative_path, - st->head_tree_relative_path_len); - git_buf_joinpath(&st->head_tree_relative_path, - st->head_tree_relative_path.ptr, m->filename); - /* When the tree entry is a folder, append a forward slash to its name */ - if (git_tree_entry_type(m) == GIT_OBJ_TREE) - git_path_to_dir(&st->head_tree_relative_path); - - if (git_buf_oom(&st->head_tree_relative_path)) - return -1; - - m_name = st->head_tree_relative_path.ptr; - } else - m_name = NULL; - - i_name = (entry != NULL) ? entry->path : NULL; - - cmpma = compare(m_name, a_name); - cmpmi = compare(m_name, i_name); - cmpai = compare(a_name, i_name); - - pm = ((cmpma <= 0) && (cmpmi <= 0)) ? m_name : NULL; - pa = ((cmpma >= 0) && (cmpai <= 0)) ? a_name : NULL; - pi = ((cmpmi >= 0) && (cmpai >= 0)) ? i_name : NULL; - - if ((error = determine_status(st, pm != NULL, pi != NULL, pa != NULL, - m, entry, a, status_path(pm, pi, pa), path_type)) < 0) - return error; - - if ((pa != NULL) || (path_type == GIT_STATUS_PATH_FOLDER)) - return 0; - } -} - static int recurse_tree_entry(git_tree *tree, struct status_entry *e, const char *path) { char *dir_sep; @@ -728,7 +418,7 @@ int git_status_file( status_entry_update_from_index(e, index); /* Try to find file in HEAD */ - if ((error = retrieve_head_tree(&tree, repo)) < 0) + if ((error = resolve_head_to_tree(&tree, repo)) < 0) goto cleanup; if (tree != NULL) { @@ -761,62 +451,6 @@ cleanup: return error; } -/* - * git_path_direach is not supposed to return entries in an ordered manner. - * alphasorted_futils_direach wraps git_path_dirload and invokes the - * callback function by passing it alphabetically sorted path parameters. - * - */ -static int alphasorted_futils_direach( - git_buf *path, - int (*fn)(void *, git_buf *), - void *arg) -{ - int error; - char *entry; - git_vector entry_names; - unsigned int idx; - - if (git_vector_init(&entry_names, 16, git__strcmp_cb) < 0) - return -1; - - if ((error = git_path_dirload(path->ptr, 0, 1, &entry_names)) < 0) - return error; - - git_vector_foreach(&entry_names, idx, entry) { - size_t entry_len = strlen(entry); - if (git_path_isdir(entry)) { - /* dirload allocated 1 extra byte so there is space for slash */ - entry[entry_len++] = '/'; - entry[entry_len] = '\0'; - } - } - - git_vector_sort(&entry_names); - - git_vector_foreach(&entry_names, idx, entry) { - /* Walk the entire vector even if there is an error, in order to - * free up memory, but stop making callbacks after an error. - */ - if (!error) { - git_buf entry_path = GIT_BUF_INIT; - git_buf_attach(&entry_path, entry, 0); - - ((struct status_st *)arg)->is_dir = - (entry_path.ptr[entry_path.size - 1] == '/'); - - error = fn(arg, &entry_path); - } - - git__free(entry); - } - - git_vector_free(&entry_names); - - return error; -} - - int git_status_should_ignore(git_repository *repo, const char *path, int *ignored) { int error;