diff options
author | Edward Thomson <ethomson@edwardthomson.com> | 2017-12-01 11:45:53 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-12-01 11:45:53 +0000 |
commit | 429bb3575474a3d25ee1c9814612d8d01b3378e8 (patch) | |
tree | ed7e479004d8a848fbb69174b3290ee352b71ce6 | |
parent | 344b4ead60da5fc3514f602a8e1a6af15173cc31 (diff) | |
parent | 4ccacdc8ec7524065b0d78a10c9deccd04bcbda7 (diff) | |
download | libgit2-429bb3575474a3d25ee1c9814612d8d01b3378e8.tar.gz |
Merge pull request #4318 from Uncommon/amend_status
Add git_status_file_at
-rw-r--r-- | include/git2/status.h | 4 | ||||
-rw-r--r-- | src/status.c | 19 | ||||
-rw-r--r-- | tests/status/worktree.c | 31 |
3 files changed, 47 insertions, 7 deletions
diff --git a/include/git2/status.h b/include/git2/status.h index 671113955..4b86818b7 100644 --- a/include/git2/status.h +++ b/include/git2/status.h @@ -173,12 +173,16 @@ typedef enum { * The `pathspec` is an array of path patterns to match (using * fnmatch-style matching), or just an array of paths to match exactly if * `GIT_STATUS_OPT_DISABLE_PATHSPEC_MATCH` is specified in the flags. + * + * The `baseline` is the tree to be used for comparison to the working directory + * and index; defaults to HEAD. */ typedef struct { unsigned int version; git_status_show_t show; unsigned int flags; git_strarray pathspec; + git_tree *baseline; } git_status_options; #define GIT_STATUS_OPTIONS_VERSION 1 diff --git a/src/status.c b/src/status.c index 03682bc72..f547bd466 100644 --- a/src/status.c +++ b/src/status.c @@ -280,12 +280,16 @@ int git_status_list_new( if ((error = git_repository__ensure_not_bare(repo, "status")) < 0 || (error = git_repository_index(&index, repo)) < 0) return error; - - /* if there is no HEAD, that's okay - we'll make an empty iterator */ - if ((error = git_repository_head_tree(&head, repo)) < 0) { - if (error != GIT_ENOTFOUND && error != GIT_EUNBORNBRANCH) - goto done; - giterr_clear(); + + if (opts != NULL && opts->baseline != NULL) { + head = opts->baseline; + } else { + /* if there is no HEAD, that's okay - we'll make an empty iterator */ + if ((error = git_repository_head_tree(&head, repo)) < 0) { + if (error != GIT_ENOTFOUND && error != GIT_EUNBORNBRANCH) + goto done; + giterr_clear(); + } } /* refresh index from disk unless prevented */ @@ -377,7 +381,8 @@ done: *out = status; - git_tree_free(head); + if (opts == NULL || opts->baseline != head) + git_tree_free(head); git_index_free(index); return error; diff --git a/tests/status/worktree.c b/tests/status/worktree.c index 1345dbfd2..44ed324f1 100644 --- a/tests/status/worktree.c +++ b/tests/status/worktree.c @@ -1280,3 +1280,34 @@ void test_status_worktree__with_directory_in_pathlist(void) git_status_list_free(statuslist); } +void test_status_worktree__at_head_parent(void) +{ + git_repository *repo = cl_git_sandbox_init("empty_standard_repo"); + git_status_options opts = GIT_STATUS_OPTIONS_INIT; + git_status_list *statuslist; + git_tree *parent_tree; + const git_status_entry *status; + + cl_git_mkfile("empty_standard_repo/file1", "ping"); + stage_and_commit(repo, "file1"); + + cl_git_pass(git_repository_head_tree(&parent_tree, repo)); + + cl_git_mkfile("empty_standard_repo/file2", "pong"); + stage_and_commit(repo, "file2"); + + cl_git_rewritefile("empty_standard_repo/file2", "pyng"); + + opts.show = GIT_STATUS_SHOW_INDEX_AND_WORKDIR; + opts.baseline = parent_tree; + cl_git_pass(git_status_list_new(&statuslist, repo, &opts)); + + cl_assert_equal_sz(1, git_status_list_entrycount(statuslist)); + status = git_status_byindex(statuslist, 0); + cl_assert(status != NULL); + cl_assert_equal_s("file2", status->index_to_workdir->old_file.path); + cl_assert_equal_i(GIT_STATUS_WT_MODIFIED | GIT_STATUS_INDEX_NEW, status->status); + + git_tree_free(parent_tree); + git_status_list_free(statuslist); +} |