Commit f2d110f1 by Vicent Martí

Merge pull request #1662 from arrbee/examples-like-git

Command line status example (with bug fixes)
parents 8b2fa181 94ef2a35
......@@ -3,7 +3,7 @@
CC = gcc
CFLAGS = -g -I../include -I../src -Wall -Wextra -Wmissing-prototypes -Wno-missing-field-initializers
LFLAGS = -L../build -lgit2 -lz
APPS = general showindex diff rev-list cat-file
APPS = general showindex diff rev-list cat-file status
all: $(APPS)
......
/*
* Copyright (C) the libgit2 contributors. All rights reserved.
*
* This file is part of libgit2, distributed under the GNU GPL v2 with
* a Linking Exception. For full terms see the included COPYING file.
*/
#include <git2.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
enum {
FORMAT_DEFAULT = 0,
FORMAT_LONG = 1,
FORMAT_SHORT = 2,
FORMAT_PORCELAIN = 3,
};
#define MAX_PATHSPEC 8
/*
* This example demonstrates the use of the libgit2 status APIs,
* particularly the `git_status_list` object, to roughly simulate the
* output of running `git status`. It serves as a simple example of
* using those APIs to get basic status information.
*
* This does not have:
* - Robust error handling
* - Colorized or paginated output formatting
*
* This does have:
* - Examples of translating command line arguments to the status
* options settings to mimic `git status` results.
* - A sample status formatter that matches the default "long" format
* from `git status`
* - A sample status formatter that matches the "short" format
*/
static void check(int error, const char *message, const char *extra)
{
const git_error *lg2err;
const char *lg2msg = "", *lg2spacer = "";
if (!error)
return;
if ((lg2err = giterr_last()) != NULL && lg2err->message != NULL) {
lg2msg = lg2err->message;
lg2spacer = " - ";
}
if (extra)
fprintf(stderr, "%s '%s' [%d]%s%s\n",
message, extra, error, lg2spacer, lg2msg);
else
fprintf(stderr, "%s [%d]%s%s\n",
message, error, lg2spacer, lg2msg);
exit(1);
}
static void fail(const char *message)
{
check(-1, message, NULL);
}
static void show_branch(git_repository *repo, int format)
{
int error = 0;
const char *branch = NULL;
git_reference *head = NULL;
error = git_repository_head(&head, repo);
if (error == GIT_EORPHANEDHEAD || error == GIT_ENOTFOUND)
branch = NULL;
else if (!error) {
branch = git_reference_name(head);
if (!strncmp(branch, "refs/heads/", strlen("refs/heads/")))
branch += strlen("refs/heads/");
} else
check(error, "failed to get current branch", NULL);
if (format == FORMAT_LONG)
printf("# On branch %s\n",
branch ? branch : "Not currently on any branch.");
else
printf("## %s\n", branch ? branch : "HEAD (no branch)");
git_reference_free(head);
}
static void print_long(git_repository *repo, git_status_list *status)
{
size_t i, maxi = git_status_list_entrycount(status);
const git_status_entry *s;
int header = 0, changes_in_index = 0;
int changed_in_workdir = 0, rm_in_workdir = 0;
const char *old_path, *new_path;
(void)repo;
/* print index changes */
for (i = 0; i < maxi; ++i) {
char *istatus = NULL;
s = git_status_byindex(status, i);
if (s->status == GIT_STATUS_CURRENT)
continue;
if (s->status & GIT_STATUS_WT_DELETED)
rm_in_workdir = 1;
if (s->status & GIT_STATUS_INDEX_NEW)
istatus = "new file: ";
if (s->status & GIT_STATUS_INDEX_MODIFIED)
istatus = "modified: ";
if (s->status & GIT_STATUS_INDEX_DELETED)
istatus = "deleted: ";
if (s->status & GIT_STATUS_INDEX_RENAMED)
istatus = "renamed: ";
if (s->status & GIT_STATUS_INDEX_TYPECHANGE)
istatus = "typechange:";
if (istatus == NULL)
continue;
if (!header) {
printf("# Changes to be committed:\n");
printf("# (use \"git reset HEAD <file>...\" to unstage)\n");
printf("#\n");
header = 1;
}
old_path = s->head_to_index->old_file.path;
new_path = s->head_to_index->new_file.path;
if (old_path && new_path && strcmp(old_path, new_path))
printf("#\t%s %s -> %s\n", istatus, old_path, new_path);
else
printf("#\t%s %s\n", istatus, old_path ? old_path : new_path);
}
if (header) {
changes_in_index = 1;
printf("#\n");
}
header = 0;
/* print workdir changes to tracked files */
for (i = 0; i < maxi; ++i) {
char *wstatus = NULL;
s = git_status_byindex(status, i);
if (s->status == GIT_STATUS_CURRENT || s->index_to_workdir == NULL)
continue;
if (s->status & GIT_STATUS_WT_MODIFIED)
wstatus = "modified: ";
if (s->status & GIT_STATUS_WT_DELETED)
wstatus = "deleted: ";
if (s->status & GIT_STATUS_WT_RENAMED)
wstatus = "renamed: ";
if (s->status & GIT_STATUS_WT_TYPECHANGE)
wstatus = "typechange:";
if (wstatus == NULL)
continue;
if (!header) {
printf("# Changes not staged for commit:\n");
printf("# (use \"git add%s <file>...\" to update what will be committed)\n", rm_in_workdir ? "/rm" : "");
printf("# (use \"git checkout -- <file>...\" to discard changes in working directory)\n");
printf("#\n");
header = 1;
}
old_path = s->index_to_workdir->old_file.path;
new_path = s->index_to_workdir->new_file.path;
if (old_path && new_path && strcmp(old_path, new_path))
printf("#\t%s %s -> %s\n", wstatus, old_path, new_path);
else
printf("#\t%s %s\n", wstatus, old_path ? old_path : new_path);
}
if (header) {
changed_in_workdir = 1;
printf("#\n");
}
header = 0;
/* print untracked files */
header = 0;
for (i = 0; i < maxi; ++i) {
s = git_status_byindex(status, i);
if (s->status == GIT_STATUS_WT_NEW) {
if (!header) {
printf("# Untracked files:\n");
printf("# (use \"git add <file>...\" to include in what will be committed)\n");
printf("#\n");
header = 1;
}
printf("#\t%s\n", s->index_to_workdir->old_file.path);
}
}
header = 0;
/* print ignored files */
for (i = 0; i < maxi; ++i) {
s = git_status_byindex(status, i);
if (s->status == GIT_STATUS_IGNORED) {
if (!header) {
printf("# Ignored files:\n");
printf("# (use \"git add -f <file>...\" to include in what will be committed)\n");
printf("#\n");
header = 1;
}
printf("#\t%s\n", s->index_to_workdir->old_file.path);
}
}
if (!changes_in_index && changed_in_workdir)
printf("no changes added to commit (use \"git add\" and/or \"git commit -a\")\n");
}
static void print_short(git_repository *repo, git_status_list *status)
{
size_t i, maxi = git_status_list_entrycount(status);
const git_status_entry *s;
char istatus, wstatus;
const char *extra, *a, *b, *c;
for (i = 0; i < maxi; ++i) {
s = git_status_byindex(status, i);
if (s->status == GIT_STATUS_CURRENT)
continue;
a = b = c = NULL;
istatus = wstatus = ' ';
extra = "";
if (s->status & GIT_STATUS_INDEX_NEW)
istatus = 'A';
if (s->status & GIT_STATUS_INDEX_MODIFIED)
istatus = 'M';
if (s->status & GIT_STATUS_INDEX_DELETED)
istatus = 'D';
if (s->status & GIT_STATUS_INDEX_RENAMED)
istatus = 'R';
if (s->status & GIT_STATUS_INDEX_TYPECHANGE)
istatus = 'T';
if (s->status & GIT_STATUS_WT_NEW) {
if (istatus == ' ')
istatus = '?';
wstatus = '?';
}
if (s->status & GIT_STATUS_WT_MODIFIED)
wstatus = 'M';
if (s->status & GIT_STATUS_WT_DELETED)
wstatus = 'D';
if (s->status & GIT_STATUS_WT_RENAMED)
wstatus = 'R';
if (s->status & GIT_STATUS_WT_TYPECHANGE)
wstatus = 'T';
if (s->status & GIT_STATUS_IGNORED) {
istatus = '!';
wstatus = '!';
}
if (istatus == '?' && wstatus == '?')
continue;
if (s->index_to_workdir &&
s->index_to_workdir->new_file.mode == GIT_FILEMODE_COMMIT)
{
git_submodule *sm = NULL;
unsigned int smstatus = 0;
if (!git_submodule_lookup(
&sm, repo, s->index_to_workdir->new_file.path) &&
!git_submodule_status(&smstatus, sm))
{
if (smstatus & GIT_SUBMODULE_STATUS_WD_MODIFIED)
extra = " (new commits)";
else if (smstatus & GIT_SUBMODULE_STATUS_WD_INDEX_MODIFIED)
extra = " (modified content)";
else if (smstatus & GIT_SUBMODULE_STATUS_WD_WD_MODIFIED)
extra = " (modified content)";
else if (smstatus & GIT_SUBMODULE_STATUS_WD_UNTRACKED)
extra = " (untracked content)";
}
}
if (s->head_to_index) {
a = s->head_to_index->old_file.path;
b = s->head_to_index->new_file.path;
}
if (s->index_to_workdir) {
if (!a)
a = s->index_to_workdir->old_file.path;
if (!b)
b = s->index_to_workdir->old_file.path;
c = s->index_to_workdir->new_file.path;
}
if (istatus == 'R') {
if (wstatus == 'R')
printf("%c%c %s %s %s%s\n", istatus, wstatus, a, b, c, extra);
else
printf("%c%c %s %s%s\n", istatus, wstatus, a, b, extra);
} else {
if (wstatus == 'R')
printf("%c%c %s %s%s\n", istatus, wstatus, a, c, extra);
else
printf("%c%c %s%s\n", istatus, wstatus, a, extra);
}
}
for (i = 0; i < maxi; ++i) {
s = git_status_byindex(status, i);
if (s->status == GIT_STATUS_WT_NEW)
printf("?? %s\n", s->index_to_workdir->old_file.path);
}
}
int main(int argc, char *argv[])
{
git_repository *repo = NULL;
int i, npaths = 0, format = FORMAT_DEFAULT, zterm = 0, showbranch = 0;
git_status_options opt = GIT_STATUS_OPTIONS_INIT;
git_status_list *status;
char *repodir = ".", *pathspec[MAX_PATHSPEC];
opt.show = GIT_STATUS_SHOW_INDEX_AND_WORKDIR;
opt.flags = GIT_STATUS_OPT_INCLUDE_UNTRACKED |
GIT_STATUS_OPT_RENAMES_HEAD_TO_INDEX |
GIT_STATUS_OPT_SORT_CASE_SENSITIVELY;
for (i = 1; i < argc; ++i) {
if (argv[i][0] != '-') {
if (npaths < MAX_PATHSPEC)
pathspec[npaths++] = argv[i];
else
fail("Example only supports a limited pathspec");
}
else if (!strcmp(argv[i], "-s") || !strcmp(argv[i], "--short"))
format = FORMAT_SHORT;
else if (!strcmp(argv[i], "--long"))
format = FORMAT_LONG;
else if (!strcmp(argv[i], "--porcelain"))
format = FORMAT_PORCELAIN;
else if (!strcmp(argv[i], "-b") || !strcmp(argv[i], "--branch"))
showbranch = 1;
else if (!strcmp(argv[i], "-z")) {
zterm = 1;
if (format == FORMAT_DEFAULT)
format = FORMAT_PORCELAIN;
}
else if (!strcmp(argv[i], "--ignored"))
opt.flags |= GIT_STATUS_OPT_INCLUDE_IGNORED;
else if (!strcmp(argv[i], "-uno") ||
!strcmp(argv[i], "--untracked-files=no"))
opt.flags &= ~GIT_STATUS_OPT_INCLUDE_UNTRACKED;
else if (!strcmp(argv[i], "-unormal") ||
!strcmp(argv[i], "--untracked-files=normal"))
opt.flags |= GIT_STATUS_OPT_INCLUDE_UNTRACKED;
else if (!strcmp(argv[i], "-uall") ||
!strcmp(argv[i], "--untracked-files=all"))
opt.flags |= GIT_STATUS_OPT_INCLUDE_UNTRACKED |
GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS;
else if (!strcmp(argv[i], "--ignore-submodules=all"))
opt.flags |= GIT_STATUS_OPT_EXCLUDE_SUBMODULES;
else if (!strncmp(argv[i], "--git-dir=", strlen("--git-dir=")))
repodir = argv[i] + strlen("--git-dir=");
else
check(-1, "Unsupported option", argv[i]);
}
if (format == FORMAT_DEFAULT)
format = FORMAT_LONG;
if (format == FORMAT_LONG)
showbranch = 1;
if (npaths > 0) {
opt.pathspec.strings = pathspec;
opt.pathspec.count = npaths;
}
/*
* Try to open the repository at the given path (or at the current
* directory if none was given).
*/
check(git_repository_open_ext(&repo, repodir, 0, NULL),
"Could not open repository", repodir);
if (git_repository_is_bare(repo))
fail("Cannot report status on bare repository");
/*
* Run status on the repository
*
* Because we want to simluate a full "git status" run and want to
* support some command line options, we use `git_status_foreach_ext()`
* instead of just the plain status call. This allows (a) iterating
* over the index and then the workdir and (b) extra flags that control
* which files are included. If you just want simple status (e.g. to
* enumerate files that are modified) then you probably don't need the
* extended API.
*/
check(git_status_list_new(&status, repo, &opt),
"Could not get status", NULL);
if (showbranch)
show_branch(repo, format);
if (format == FORMAT_LONG)
print_long(repo, status);
else
print_short(repo, status);
git_status_list_free(status);
git_repository_free(repo);
return 0;
}
......@@ -111,6 +111,12 @@ typedef enum {
* - GIT_STATUS_OPT_RENAMES_INDEX_TO_WORKDIR indicates tha rename
* detection should be run between the index and the working directory
* and enabled GIT_STATUS_WT_RENAMED as a possible status flag.
* - GIT_STATUS_OPT_SORT_CASE_SENSITIVELY overrides the native case
* sensitivity for the file system and forces the output to be in
* case-sensitive order
* - GIT_STATUS_OPT_SORT_CASE_INSENSITIVELY overrides the native case
* sensitivity for the file system and forces the output to be in
* case-insensitive order
*
* Calling `git_status_foreach()` is like calling the extended version
* with: GIT_STATUS_OPT_INCLUDE_IGNORED, GIT_STATUS_OPT_INCLUDE_UNTRACKED,
......@@ -127,6 +133,8 @@ typedef enum {
GIT_STATUS_OPT_RECURSE_IGNORED_DIRS = (1u << 6),
GIT_STATUS_OPT_RENAMES_HEAD_TO_INDEX = (1u << 7),
GIT_STATUS_OPT_RENAMES_INDEX_TO_WORKDIR = (1u << 8),
GIT_STATUS_OPT_SORT_CASE_SENSITIVELY = (1u << 9),
GIT_STATUS_OPT_SORT_CASE_INSENSITIVELY = (1u << 10),
} git_status_opt_t;
#define GIT_STATUS_OPT_DEFAULTS \
......
......@@ -498,7 +498,7 @@ int git_attr_assignment__parse(
assert(assigns && !assigns->length);
assigns->_cmp = sort_by_hash_and_name;
git_vector_set_cmp(assigns, sort_by_hash_and_name);
while (*scan && *scan != '\n') {
const char *name_start, *value_start;
......
......@@ -365,7 +365,7 @@ static git_diff_list *diff_list_alloc(
diff->pfxcomp = git__prefixcmp_icase;
diff->entrycomp = git_index_entry__cmp_icase;
diff->deltas._cmp = git_diff_delta__casecmp;
git_vector_set_cmp(&diff->deltas, git_diff_delta__casecmp);
}
return diff;
......@@ -786,10 +786,15 @@ static int diff_scan_inside_untracked_dir(
/* need to recurse into non-ignored directories */
if (!is_ignored && S_ISDIR(info->nitem->mode)) {
if ((error = git_iterator_advance_into(
&info->nitem, info->new_iter)) < 0)
break;
continue;
error = git_iterator_advance_into(&info->nitem, info->new_iter);
if (!error)
continue;
else if (error == GIT_ENOTFOUND) {
error = 0;
is_ignored = true; /* treat empty as ignored */
} else
break; /* real error, must stop */
}
/* found a non-ignored item - treat parent dir as untracked */
......@@ -1160,7 +1165,7 @@ int git_diff_tree_to_index(
d->pfxcomp = git__prefixcmp_icase;
d->entrycomp = git_index_entry__cmp_icase;
d->deltas._cmp = git_diff_delta__casecmp;
git_vector_set_cmp(&d->deltas, git_diff_delta__casecmp);
git_vector_sort(&d->deltas);
}
}
......@@ -1261,10 +1266,10 @@ int git_diff__paired_foreach(
/* force case-sensitive delta sort */
if (icase_mismatch) {
if (head2idx->opts.flags & GIT_DIFF_DELTAS_ARE_ICASE) {
head2idx->deltas._cmp = git_diff_delta__cmp;
git_vector_set_cmp(&head2idx->deltas, git_diff_delta__cmp);
git_vector_sort(&head2idx->deltas);
} else {
idx2wd->deltas._cmp = git_diff_delta__cmp;
git_vector_set_cmp(&idx2wd->deltas, git_diff_delta__cmp);
git_vector_sort(&idx2wd->deltas);
}
}
......@@ -1296,10 +1301,10 @@ int git_diff__paired_foreach(
/* restore case-insensitive delta sort */
if (icase_mismatch) {
if (head2idx->opts.flags & GIT_DIFF_DELTAS_ARE_ICASE) {
head2idx->deltas._cmp = git_diff_delta__casecmp;
git_vector_set_cmp(&head2idx->deltas, git_diff_delta__casecmp);
git_vector_sort(&head2idx->deltas);
} else {
idx2wd->deltas._cmp = git_diff_delta__casecmp;
git_vector_set_cmp(&idx2wd->deltas, git_diff_delta__casecmp);
git_vector_sort(&idx2wd->deltas);
}
}
......
......@@ -290,16 +290,16 @@ void git_index__set_ignore_case(git_index *index, bool ignore_case)
{
index->ignore_case = ignore_case;
index->entries._cmp = ignore_case ? index_icmp : index_cmp;
index->entries_cmp_path = ignore_case ? index_icmp_path : index_cmp_path;
index->entries_search = ignore_case ? index_isrch : index_srch;
index->entries_search_path = ignore_case ? index_isrch_path : index_srch_path;
index->entries.sorted = 0;
git_vector_set_cmp(&index->entries, ignore_case ? index_icmp : index_cmp);
git_vector_sort(&index->entries);
index->reuc._cmp = ignore_case ? reuc_icmp : reuc_cmp;
index->reuc_search = ignore_case ? reuc_isrch : reuc_srch;
index->reuc.sorted = 0;
git_vector_set_cmp(&index->reuc, ignore_case ? reuc_icmp : reuc_cmp);
git_vector_sort(&index->reuc);
}
......@@ -2024,7 +2024,7 @@ int git_index_read_tree(git_index *index, const git_tree *tree)
git_vector_sort(&index->entries);
entries._cmp = index->entries._cmp;
git_vector_set_cmp(&entries, index->entries._cmp);
git_vector_swap(&entries, &index->entries);
git_index_clear(index);
......
......@@ -335,8 +335,16 @@ int git_status_list_new(
status->head2idx, status->idx2wd, status_collect, status)) < 0)
goto done;
if ((flags & GIT_STATUS_OPT_RENAMES_HEAD_TO_INDEX) != 0 ||
(flags & GIT_STATUS_OPT_RENAMES_INDEX_TO_WORKDIR) != 0)
if (flags & GIT_STATUS_OPT_SORT_CASE_SENSITIVELY)
git_vector_set_cmp(&status->paired, status_entry_cmp);
if (flags & GIT_STATUS_OPT_SORT_CASE_INSENSITIVELY)
git_vector_set_cmp(&status->paired, status_entry_icmp);
if ((flags &
(GIT_STATUS_OPT_RENAMES_HEAD_TO_INDEX |
GIT_STATUS_OPT_RENAMES_INDEX_TO_WORKDIR |
GIT_STATUS_OPT_SORT_CASE_SENSITIVELY |
GIT_STATUS_OPT_SORT_CASE_INSENSITIVELY)) != 0)
git_vector_sort(&status->paired);
done:
......
......@@ -151,7 +151,7 @@ int git_submodule_foreach(
int error;
git_submodule *sm;
git_vector seen = GIT_VECTOR_INIT;
seen._cmp = submodule_cmp;
git_vector_set_cmp(&seen, submodule_cmp);
assert(repo && callback);
......
......@@ -78,4 +78,13 @@ void git_vector_remove_matching(
int git_vector_resize_to(git_vector *v, size_t new_length);
int git_vector_set(void **old, git_vector *v, size_t position, void *value);
/** Set the comparison function used for sorting the vector */
GIT_INLINE(void) git_vector_set_cmp(git_vector *v, git_vector_cmp cmp)
{
if (cmp != v->_cmp) {
v->_cmp = cmp;
v->sorted = 0;
}
}
#endif
......@@ -1109,6 +1109,26 @@ void test_diff_workdir__untracked_directory_scenarios(void)
git_diff_list_free(diff);
/* empty directory in empty directory */
cl_git_pass(p_mkdir("status/subdir/directory/empty", 0777));
memset(&exp, 0, sizeof(exp));
exp.names = files1;
cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
cl_git_pass(git_diff_foreach(diff, diff_file_cb, NULL, NULL, &exp));
cl_assert_equal_i(4, exp.files);
cl_assert_equal_i(0, exp.file_status[GIT_DELTA_ADDED]);
cl_assert_equal_i(1, exp.file_status[GIT_DELTA_DELETED]);
cl_assert_equal_i(1, exp.file_status[GIT_DELTA_MODIFIED]);
cl_assert_equal_i(1, exp.file_status[GIT_DELTA_IGNORED]);
cl_assert_equal_i(1, exp.file_status[GIT_DELTA_UNTRACKED]);
git_diff_list_free(diff);
/* directory with only ignored files */
cl_git_pass(p_mkdir("status/subdir/directory/deeper", 0777));
......
......@@ -6,6 +6,9 @@ int cb_status__normal(
{
status_entry_counts *counts = payload;
if (counts->debug)
cb_status__print(path, status_flags, NULL);
if (counts->entry_count >= counts->expected_entry_count) {
counts->wrong_status_flags_count++;
goto exit;
......
......@@ -8,6 +8,7 @@ typedef struct {
const unsigned int* expected_statuses;
const char** expected_paths;
int expected_entry_count;
bool debug;
} status_entry_counts;
/* cb_status__normal takes payload of "status_entry_counts *" */
......
......@@ -743,3 +743,83 @@ void test_status_worktree__simple_delete_indexed(void)
GIT_STATUS_WT_DELETED, git_status_byindex(status, 0)->status);
git_status_list_free(status);
}
static const char *icase_paths[] = { "B", "c", "g", "H" };
static unsigned int icase_statuses[] = {
GIT_STATUS_WT_MODIFIED, GIT_STATUS_WT_DELETED,
GIT_STATUS_WT_MODIFIED, GIT_STATUS_WT_DELETED,
};
static const char *case_paths[] = { "B", "H", "c", "g" };
static unsigned int case_statuses[] = {
GIT_STATUS_WT_MODIFIED, GIT_STATUS_WT_DELETED,
GIT_STATUS_WT_DELETED, GIT_STATUS_WT_MODIFIED,
};
void test_status_worktree__sorting_by_case(void)
{
git_repository *repo = cl_git_sandbox_init("icase");
git_index *index;
git_status_options opts = GIT_STATUS_OPTIONS_INIT;
bool native_ignore_case;
status_entry_counts counts;
cl_git_pass(git_repository_index(&index, repo));
native_ignore_case =
(git_index_caps(index) & GIT_INDEXCAP_IGNORE_CASE) != 0;
git_index_free(index);
memset(&counts, 0, sizeof(counts));
counts.expected_entry_count = 0;
counts.expected_paths = NULL;
counts.expected_statuses = NULL;
cl_git_pass(
git_status_foreach_ext(repo, &opts, cb_status__normal, &counts));
cl_assert_equal_i(counts.expected_entry_count, counts.entry_count);
cl_assert_equal_i(0, counts.wrong_status_flags_count);
cl_assert_equal_i(0, counts.wrong_sorted_path);
cl_git_rewritefile("icase/B", "new stuff");
cl_must_pass(p_unlink("icase/c"));
cl_git_rewritefile("icase/g", "new stuff");
cl_must_pass(p_unlink("icase/H"));
memset(&counts, 0, sizeof(counts));
counts.expected_entry_count = 4;
if (native_ignore_case) {
counts.expected_paths = icase_paths;
counts.expected_statuses = icase_statuses;
} else {
counts.expected_paths = case_paths;
counts.expected_statuses = case_statuses;
}
cl_git_pass(
git_status_foreach_ext(repo, &opts, cb_status__normal, &counts));
cl_assert_equal_i(counts.expected_entry_count, counts.entry_count);
cl_assert_equal_i(0, counts.wrong_status_flags_count);
cl_assert_equal_i(0, counts.wrong_sorted_path);
opts.flags = GIT_STATUS_OPT_SORT_CASE_SENSITIVELY;
memset(&counts, 0, sizeof(counts));
counts.expected_entry_count = 4;
counts.expected_paths = case_paths;
counts.expected_statuses = case_statuses;
cl_git_pass(
git_status_foreach_ext(repo, &opts, cb_status__normal, &counts));
cl_assert_equal_i(counts.expected_entry_count, counts.entry_count);
cl_assert_equal_i(0, counts.wrong_status_flags_count);
cl_assert_equal_i(0, counts.wrong_sorted_path);
opts.flags = GIT_STATUS_OPT_SORT_CASE_INSENSITIVELY;
memset(&counts, 0, sizeof(counts));
counts.expected_entry_count = 4;
counts.expected_paths = icase_paths;
counts.expected_statuses = icase_statuses;
cl_git_pass(
git_status_foreach_ext(repo, &opts, cb_status__normal, &counts));
cl_assert_equal_i(counts.expected_entry_count, counts.entry_count);
cl_assert_equal_i(0, counts.wrong_status_flags_count);
cl_assert_equal_i(0, counts.wrong_sorted_path);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment