mirror of
https://git.proxmox.com/git/libgit2
synced 2025-05-03 14:12:22 +00:00
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.
This commit is contained in:
parent
e7c85120ea
commit
3e57069e82
12
src/diff.c
12
src/diff.c
@ -63,13 +63,16 @@ static int diff_notify(
|
|||||||
|
|
||||||
static int diff_delta__from_one(
|
static int diff_delta__from_one(
|
||||||
git_diff *diff,
|
git_diff *diff,
|
||||||
git_delta_t status,
|
git_delta_t status,
|
||||||
const git_index_entry *entry)
|
const git_index_entry *entry)
|
||||||
{
|
{
|
||||||
git_diff_delta *delta;
|
git_diff_delta *delta;
|
||||||
const char *matched_pathspec;
|
const char *matched_pathspec;
|
||||||
int notify_res;
|
int notify_res;
|
||||||
|
|
||||||
|
if ((entry->flags & GIT_IDXENTRY_VALID) != 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (status == GIT_DELTA_IGNORED &&
|
if (status == GIT_DELTA_IGNORED &&
|
||||||
DIFF_FLAG_ISNT_SET(diff, GIT_DIFF_INCLUDE_IGNORED))
|
DIFF_FLAG_ISNT_SET(diff, GIT_DIFF_INCLUDE_IGNORED))
|
||||||
return 0;
|
return 0;
|
||||||
@ -426,7 +429,7 @@ static int diff_list_apply_options(
|
|||||||
diff->diffcaps = diff->diffcaps | GIT_DIFFCAPS_HAS_SYMLINKS;
|
diff->diffcaps = diff->diffcaps | GIT_DIFFCAPS_HAS_SYMLINKS;
|
||||||
|
|
||||||
if (!git_repository__cvar(&val, repo, GIT_CVAR_IGNORESTAT) && val)
|
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 &&
|
if ((diff->opts.flags & GIT_DIFF_IGNORE_FILEMODE) == 0 &&
|
||||||
!git_repository__cvar(&val, repo, GIT_CVAR_FILEMODE) && val)
|
!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);
|
nmode = (nmode & ~MODE_BITS_MASK) | (omode & MODE_BITS_MASK);
|
||||||
|
|
||||||
/* support "assume unchanged" (poorly, b/c we still stat everything) */
|
/* support "assume unchanged" (poorly, b/c we still stat everything) */
|
||||||
if ((diff->diffcaps & GIT_DIFFCAPS_ASSUME_UNCHANGED) != 0)
|
if ((oitem->flags & GIT_IDXENTRY_VALID) != 0)
|
||||||
status = (oitem->flags_extended & GIT_IDXENTRY_INTENT_TO_ADD) ?
|
status = GIT_DELTA_UNMODIFIED;
|
||||||
GIT_DELTA_MODIFIED : GIT_DELTA_UNMODIFIED;
|
|
||||||
|
|
||||||
/* support "skip worktree" index bit */
|
/* support "skip worktree" index bit */
|
||||||
else if ((oitem->flags_extended & GIT_IDXENTRY_SKIP_WORKTREE) != 0)
|
else if ((oitem->flags_extended & GIT_IDXENTRY_SKIP_WORKTREE) != 0)
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
|
|
||||||
enum {
|
enum {
|
||||||
GIT_DIFFCAPS_HAS_SYMLINKS = (1 << 0), /* symlinks on platform? */
|
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_MODE_BITS = (1 << 2), /* use st_mode? */
|
||||||
GIT_DIFFCAPS_TRUST_CTIME = (1 << 3), /* use st_ctime? */
|
GIT_DIFFCAPS_TRUST_CTIME = (1 << 3), /* use st_ctime? */
|
||||||
GIT_DIFFCAPS_USE_DEV = (1 << 4), /* use st_dev? */
|
GIT_DIFFCAPS_USE_DEV = (1 << 4), /* use st_dev? */
|
||||||
|
@ -63,6 +63,60 @@ void test_diff_workdir__to_index(void)
|
|||||||
git_diff_free(diff);
|
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)
|
void test_diff_workdir__to_tree(void)
|
||||||
{
|
{
|
||||||
/* grabbed a couple of commit oids from the history of the attr repo */
|
/* grabbed a couple of commit oids from the history of the attr repo */
|
||||||
|
Loading…
Reference in New Issue
Block a user