Commit 3e57069e by Russell Belfer

Fix --assume-unchanged support

This was never really working right because we were checking the
wrong flag and not checking it in all the places that we need to
be checking it.  I finally got around to writing a test and adding
actual support for it.
parent e7c85120
......@@ -63,13 +63,16 @@ static int diff_notify(
static int diff_delta__from_one(
git_diff *diff,
git_delta_t status,
git_delta_t status,
const git_index_entry *entry)
{
git_diff_delta *delta;
const char *matched_pathspec;
int notify_res;
if ((entry->flags & GIT_IDXENTRY_VALID) != 0)
return 0;
if (status == GIT_DELTA_IGNORED &&
DIFF_FLAG_ISNT_SET(diff, GIT_DIFF_INCLUDE_IGNORED))
return 0;
......@@ -426,7 +429,7 @@ static int diff_list_apply_options(
diff->diffcaps = diff->diffcaps | GIT_DIFFCAPS_HAS_SYMLINKS;
if (!git_repository__cvar(&val, repo, GIT_CVAR_IGNORESTAT) && val)
diff->diffcaps = diff->diffcaps | GIT_DIFFCAPS_ASSUME_UNCHANGED;
diff->diffcaps = diff->diffcaps | GIT_DIFFCAPS_IGNORE_STAT;
if ((diff->opts.flags & GIT_DIFF_IGNORE_FILEMODE) == 0 &&
!git_repository__cvar(&val, repo, GIT_CVAR_FILEMODE) && val)
......@@ -701,9 +704,8 @@ static int maybe_modified(
nmode = (nmode & ~MODE_BITS_MASK) | (omode & MODE_BITS_MASK);
/* support "assume unchanged" (poorly, b/c we still stat everything) */
if ((diff->diffcaps & GIT_DIFFCAPS_ASSUME_UNCHANGED) != 0)
status = (oitem->flags_extended & GIT_IDXENTRY_INTENT_TO_ADD) ?
GIT_DELTA_MODIFIED : GIT_DELTA_UNMODIFIED;
if ((oitem->flags & GIT_IDXENTRY_VALID) != 0)
status = GIT_DELTA_UNMODIFIED;
/* support "skip worktree" index bit */
else if ((oitem->flags_extended & GIT_IDXENTRY_SKIP_WORKTREE) != 0)
......
......@@ -23,7 +23,7 @@
enum {
GIT_DIFFCAPS_HAS_SYMLINKS = (1 << 0), /* symlinks on platform? */
GIT_DIFFCAPS_ASSUME_UNCHANGED = (1 << 1), /* use stat? */
GIT_DIFFCAPS_IGNORE_STAT = (1 << 1), /* use stat? */
GIT_DIFFCAPS_TRUST_MODE_BITS = (1 << 2), /* use st_mode? */
GIT_DIFFCAPS_TRUST_CTIME = (1 << 3), /* use st_ctime? */
GIT_DIFFCAPS_USE_DEV = (1 << 4), /* use st_dev? */
......
......@@ -63,6 +63,60 @@ void test_diff_workdir__to_index(void)
git_diff_free(diff);
}
void test_diff_workdir__to_index_with_assume_unchanged(void)
{
git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
git_diff *diff = NULL;
git_index *idx = NULL;
diff_expects exp;
const git_index_entry *iep;
git_index_entry ie;
g_repo = cl_git_sandbox_init("status");
/* do initial diff */
cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
memset(&exp, 0, sizeof(exp));
cl_git_pass(git_diff_foreach(
diff, diff_file_cb, diff_hunk_cb, diff_line_cb, &exp));
cl_assert_equal_i(8, exp.files);
cl_assert_equal_i(0, exp.file_status[GIT_DELTA_ADDED]);
cl_assert_equal_i(4, exp.file_status[GIT_DELTA_DELETED]);
cl_assert_equal_i(4, exp.file_status[GIT_DELTA_MODIFIED]);
git_diff_free(diff);
/* mark a couple of entries with ASSUME_UNCHANGED */
cl_git_pass(git_repository_index(&idx, g_repo));
cl_assert((iep = git_index_get_bypath(idx, "modified_file", 0)) != NULL);
memcpy(&ie, iep, sizeof(ie));
ie.flags |= GIT_IDXENTRY_VALID;
cl_git_pass(git_index_add(idx, &ie));
cl_assert((iep = git_index_get_bypath(idx, "file_deleted", 0)) != NULL);
memcpy(&ie, iep, sizeof(ie));
ie.flags |= GIT_IDXENTRY_VALID;
cl_git_pass(git_index_add(idx, &ie));
cl_git_pass(git_index_write(idx));
git_index_free(idx);
/* redo diff and see that entries are skipped */
cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
memset(&exp, 0, sizeof(exp));
cl_git_pass(git_diff_foreach(
diff, diff_file_cb, diff_hunk_cb, diff_line_cb, &exp));
cl_assert_equal_i(6, exp.files);
cl_assert_equal_i(0, exp.file_status[GIT_DELTA_ADDED]);
cl_assert_equal_i(3, exp.file_status[GIT_DELTA_DELETED]);
cl_assert_equal_i(3, exp.file_status[GIT_DELTA_MODIFIED]);
git_diff_free(diff);
}
void test_diff_workdir__to_tree(void)
{
/* grabbed a couple of commit oids from the history of the attr repo */
......
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