diff options
author | Russell Belfer <rb@github.com> | 2012-10-08 15:14:12 -0700 |
---|---|---|
committer | Russell Belfer <rb@github.com> | 2012-10-08 15:22:40 -0700 |
commit | dfbff793b8f39995d3a8744d6b7d75d5cc7201a0 (patch) | |
tree | 0ffa00f2e946fc65596b08b6064ac2fee25a0963 /src/diff.c | |
parent | 543864b677704845660085d2b2b2249cabb084a4 (diff) | |
download | libgit2-dfbff793b8f39995d3a8744d6b7d75d5cc7201a0.tar.gz |
Fix a few diff bugs with directory content
There are a few cases where diff should leave directories in
the diff list if we want to match core git, such as when the
directory contains a .git dir. That feature was lost when I
introduced some of the new submodule handling.
This restores that and then fixes a couple of related to diff
output that are triggered by having diffs with directories in
them.
Also, this adds a new flag that can be passed to diff if you
want diff output to actually include the file content of any
untracked files.
Diffstat (limited to 'src/diff.c')
-rw-r--r-- | src/diff.c | 22 |
1 files changed, 18 insertions, 4 deletions
diff --git a/src/diff.c b/src/diff.c index 7a0051ae3..8718e5ada 100644 --- a/src/diff.c +++ b/src/diff.c @@ -669,7 +669,8 @@ static int diff_from_iterators( /* check if contained in ignored parent directory */ if (git_buf_len(&ignore_prefix) && - ITERATOR_PREFIXCMP(*old_iter, nitem->path, git_buf_cstr(&ignore_prefix)) == 0) + ITERATOR_PREFIXCMP(*old_iter, nitem->path, + git_buf_cstr(&ignore_prefix)) == 0) delta_type = GIT_DELTA_IGNORED; if (S_ISDIR(nitem->mode)) { @@ -677,10 +678,23 @@ static int diff_from_iterators( * it or if the user requested the contents of untracked * directories and it is not under an ignored directory. */ - if ((oitem && ITERATOR_PREFIXCMP(*old_iter, oitem->path, nitem->path) == 0) || + bool contains_tracked = + (oitem && + !ITERATOR_PREFIXCMP(*old_iter, oitem->path, nitem->path)); + bool recurse_untracked = (delta_type == GIT_DELTA_UNTRACKED && - (diff->opts.flags & GIT_DIFF_RECURSE_UNTRACKED_DIRS) != 0)) - { + (diff->opts.flags & GIT_DIFF_RECURSE_UNTRACKED_DIRS) != 0); + + /* do not advance into directories that contain a .git file */ + if (!contains_tracked && recurse_untracked) { + git_buf *full = NULL; + if (git_iterator_current_workdir_path(new_iter, &full) < 0) + goto fail; + if (git_path_contains_dir(full, DOT_GIT)) + recurse_untracked = false; + } + + if (contains_tracked || recurse_untracked) { /* if this directory is ignored, remember it as the * "ignore_prefix" for processing contained items */ |