diff options
author | Russell Belfer <rb@github.com> | 2013-03-25 23:58:40 -0700 |
---|---|---|
committer | Russell Belfer <rb@github.com> | 2013-03-25 23:58:40 -0700 |
commit | ccfa68055cbd7cdc0baa99af8ce5c0bbcca19254 (patch) | |
tree | 2eece976fc48a2d98bc1394ba309b3298210e2ec /src | |
parent | 37ee70fab4e6dcf35afc08c0edbe9f101d4abf2d (diff) | |
download | libgit2-ccfa68055cbd7cdc0baa99af8ce5c0bbcca19254.tar.gz |
Fix some diff ignores and submodule dirty workdir
This started out trying to look at the problems from issue #1425
and gradually grew to a broader set of fixes. There are two core
things fixed here:
1. When you had an ignore like "/bin" which is rooted at the top
of your tree, instead of immediately adding the "bin/" entry
as an ignored item in the diff, we were returning all of the
direct descendants of the directory as ignored items. This
changes things to immediately ignore the directory. Note that
this effects the behavior in test_status_ignore__subdirectories
so that we no longer exactly match core gits ignore behavior,
but the new behavior probably makes more sense (i.e. we now
will include an ignored directory inside an untracked directory
that we previously would have left off).
2. When a submodule only contained working directory changes, the
diff code was always considering it unmodified which was just
an outright bug. The HEAD SHA of the submodule matches the SHA
in the parent repo index, and since the SHAs matches, the diff
code was overwriting the actual status with UNMODIFIED.
These fixes broke existing tests test_diff_workdir__submodules and
test_status_ignore__subdirectories but looking it over, I actually
think the new results are correct and the old results were wrong.
@nulltoken had actually commented on the subdirectory ignore issue
previously.
I also included in the tests some debugging versions of the
shared iteration callback routines that print status or diff
information. These aren't used actively in the tests, but can be
quickly swapped in to test code to give a better picture of what
is being scanned in some of the complex test scenarios.
Diffstat (limited to 'src')
-rw-r--r-- | src/diff.c | 28 |
1 files changed, 20 insertions, 8 deletions
diff --git a/src/diff.c b/src/diff.c index 61fd18d89..7152683e7 100644 --- a/src/diff.c +++ b/src/diff.c @@ -572,7 +572,13 @@ static int maybe_modified( return -1; use_noid = &noid; } - if (omode == nmode && git_oid_equal(&oitem->oid, use_noid)) + + /* if oid matches, then mark unmodified (except submodules, where + * the filesystem content may be modified even if the oid still + * matches between the index and the workdir HEAD) + */ + if (omode == nmode && !S_ISGITLINK(omode) && + git_oid_equal(&oitem->oid, use_noid)) status = GIT_DELTA_UNMODIFIED; } @@ -725,14 +731,20 @@ int git_diff__from_iterators( recurse_into_dir = false; } - if (contains_oitem || recurse_into_dir) { - /* if this directory is ignored, remember it as the - * "ignore_prefix" for processing contained items - */ - if (delta_type == GIT_DELTA_UNTRACKED && - git_iterator_current_is_ignored(new_iter)) - git_buf_sets(&ignore_prefix, nitem->path); + /* if directory is ignored, remember ignore_prefix */ + if ((contains_oitem || recurse_into_dir) && + delta_type == GIT_DELTA_UNTRACKED && + git_iterator_current_is_ignored(new_iter)) + { + git_buf_sets(&ignore_prefix, nitem->path); + delta_type = GIT_DELTA_IGNORED; + /* skip recursion if we've just learned this is ignored */ + if (DIFF_FLAG_ISNT_SET(diff, GIT_DIFF_RECURSE_IGNORED_DIRS)) + recurse_into_dir = false; + } + + if (contains_oitem || recurse_into_dir) { /* advance into directory */ error = git_iterator_advance_into(&nitem, new_iter); |