Skip to content

Commit 429bb35

Browse files
authored
Merge pull request libgit2#4318 from Uncommon/amend_status
Add git_status_file_at
2 parents 344b4ea + 4ccacdc commit 429bb35

File tree

3 files changed

+47
-7
lines changed

3 files changed

+47
-7
lines changed

include/git2/status.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,12 +173,16 @@ typedef enum {
173173
* The `pathspec` is an array of path patterns to match (using
174174
* fnmatch-style matching), or just an array of paths to match exactly if
175175
* `GIT_STATUS_OPT_DISABLE_PATHSPEC_MATCH` is specified in the flags.
176+
*
177+
* The `baseline` is the tree to be used for comparison to the working directory
178+
* and index; defaults to HEAD.
176179
*/
177180
typedef struct {
178181
unsigned int version;
179182
git_status_show_t show;
180183
unsigned int flags;
181184
git_strarray pathspec;
185+
git_tree *baseline;
182186
} git_status_options;
183187

184188
#define GIT_STATUS_OPTIONS_VERSION 1

src/status.c

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -280,12 +280,16 @@ int git_status_list_new(
280280
if ((error = git_repository__ensure_not_bare(repo, "status")) < 0 ||
281281
(error = git_repository_index(&index, repo)) < 0)
282282
return error;
283-
284-
/* if there is no HEAD, that's okay - we'll make an empty iterator */
285-
if ((error = git_repository_head_tree(&head, repo)) < 0) {
286-
if (error != GIT_ENOTFOUND && error != GIT_EUNBORNBRANCH)
287-
goto done;
288-
giterr_clear();
283+
284+
if (opts != NULL && opts->baseline != NULL) {
285+
head = opts->baseline;
286+
} else {
287+
/* if there is no HEAD, that's okay - we'll make an empty iterator */
288+
if ((error = git_repository_head_tree(&head, repo)) < 0) {
289+
if (error != GIT_ENOTFOUND && error != GIT_EUNBORNBRANCH)
290+
goto done;
291+
giterr_clear();
292+
}
289293
}
290294

291295
/* refresh index from disk unless prevented */
@@ -377,7 +381,8 @@ int git_status_list_new(
377381

378382
*out = status;
379383

380-
git_tree_free(head);
384+
if (opts == NULL || opts->baseline != head)
385+
git_tree_free(head);
381386
git_index_free(index);
382387

383388
return error;

tests/status/worktree.c

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1280,3 +1280,34 @@ void test_status_worktree__with_directory_in_pathlist(void)
12801280
git_status_list_free(statuslist);
12811281
}
12821282

1283+
void test_status_worktree__at_head_parent(void)
1284+
{
1285+
git_repository *repo = cl_git_sandbox_init("empty_standard_repo");
1286+
git_status_options opts = GIT_STATUS_OPTIONS_INIT;
1287+
git_status_list *statuslist;
1288+
git_tree *parent_tree;
1289+
const git_status_entry *status;
1290+
1291+
cl_git_mkfile("empty_standard_repo/file1", "ping");
1292+
stage_and_commit(repo, "file1");
1293+
1294+
cl_git_pass(git_repository_head_tree(&parent_tree, repo));
1295+
1296+
cl_git_mkfile("empty_standard_repo/file2", "pong");
1297+
stage_and_commit(repo, "file2");
1298+
1299+
cl_git_rewritefile("empty_standard_repo/file2", "pyng");
1300+
1301+
opts.show = GIT_STATUS_SHOW_INDEX_AND_WORKDIR;
1302+
opts.baseline = parent_tree;
1303+
cl_git_pass(git_status_list_new(&statuslist, repo, &opts));
1304+
1305+
cl_assert_equal_sz(1, git_status_list_entrycount(statuslist));
1306+
status = git_status_byindex(statuslist, 0);
1307+
cl_assert(status != NULL);
1308+
cl_assert_equal_s("file2", status->index_to_workdir->old_file.path);
1309+
cl_assert_equal_i(GIT_STATUS_WT_MODIFIED | GIT_STATUS_INDEX_NEW, status->status);
1310+
1311+
git_tree_free(parent_tree);
1312+
git_status_list_free(statuslist);
1313+
}

0 commit comments

Comments
 (0)