diff options
| author | Russell Belfer <rb@github.com> | 2012-12-10 15:31:43 -0800 |
|---|---|---|
| committer | Russell Belfer <rb@github.com> | 2013-01-04 15:47:42 -0800 |
| commit | 7e5c8a5b41ca660def7de23fd32b942878a6ee24 (patch) | |
| tree | 477e12bfca0e05c6458ee7bcb25f235ced2714c0 /src/diff.c | |
| parent | cf208031705388a2d1907fb9ec409ff22179f380 (diff) | |
| download | libgit2-7e5c8a5b41ca660def7de23fd32b942878a6ee24.tar.gz | |
More checkout improvements
This flips checkout back to be driven off the changes between
the baseline and the target trees. This reinstates the complex
code for tracking the contents of the working directory, but
overall, I think the resulting logic is easier to follow.
Diffstat (limited to 'src/diff.c')
| -rw-r--r-- | src/diff.c | 43 |
1 files changed, 29 insertions, 14 deletions
diff --git a/src/diff.c b/src/diff.c index 83e73cd03..042cdf451 100644 --- a/src/diff.c +++ b/src/diff.c @@ -164,6 +164,11 @@ static git_diff_delta *diff_delta__last_for_item( if (git_oid_cmp(&delta->new_file.oid, &item->oid) == 0) return delta; break; + case GIT_DELTA_UNTRACKED: + if (diff->strcomp(delta->new_file.path, item->path) == 0 && + git_oid_cmp(&delta->new_file.oid, &item->oid) == 0) + return delta; + break; case GIT_DELTA_MODIFIED: if (git_oid_cmp(&delta->old_file.oid, &item->oid) == 0 || git_oid_cmp(&delta->new_file.oid, &item->oid) == 0) @@ -531,14 +536,14 @@ static bool entry_is_prefixed( { size_t pathlen; - if (!prefix_item || diff->pfxcomp(prefix_item->path, item->path)) + if (!item || diff->pfxcomp(item->path, prefix_item->path) != 0) return false; - pathlen = strlen(item->path); + pathlen = strlen(prefix_item->path); - return (item->path[pathlen - 1] == '/' || - prefix_item->path[pathlen] == '\0' || - prefix_item->path[pathlen] == '/'); + return (prefix_item->path[pathlen - 1] == '/' || + item->path[pathlen] == '\0' || + item->path[pathlen] == '/'); } static int diff_list_init_from_iterators( @@ -616,7 +621,7 @@ int git_diff__from_iterators( * instead of just generating a DELETE record */ if ((diff->opts.flags & GIT_DIFF_INCLUDE_TYPECHANGE_TREES) != 0 && - entry_is_prefixed(diff, oitem, nitem)) + entry_is_prefixed(diff, nitem, oitem)) { /* this entry has become a tree! convert to TYPECHANGE */ git_diff_delta *last = diff_delta__last_for_item(diff, oitem); @@ -624,6 +629,17 @@ int git_diff__from_iterators( last->status = GIT_DELTA_TYPECHANGE; last->new_file.mode = GIT_FILEMODE_TREE; } + + /* If new_iter is a workdir iterator, then this situation + * will certainly be followed by a series of untracked items. + * Unless RECURSE_UNTRACKED_DIRS is set, skip over them... + */ + if (S_ISDIR(nitem->mode) && + !(diff->opts.flags & GIT_DIFF_RECURSE_UNTRACKED_DIRS)) + { + if (git_iterator_advance(new_iter, &nitem) < 0) + goto fail; + } } if (git_iterator_advance(old_iter, &oitem) < 0) @@ -635,6 +651,7 @@ int git_diff__from_iterators( */ else if (cmp > 0) { git_delta_t delta_type = GIT_DELTA_UNTRACKED; + bool contains_oitem = entry_is_prefixed(diff, oitem, nitem); /* check if contained in ignored parent directory */ if (git_buf_len(&ignore_prefix) && @@ -646,14 +663,12 @@ int git_diff__from_iterators( * it or if the user requested the contents of untracked * directories and it is not under an ignored directory. */ - bool contains_tracked = - entry_is_prefixed(diff, nitem, oitem); bool recurse_untracked = (delta_type == GIT_DELTA_UNTRACKED && (diff->opts.flags & GIT_DIFF_RECURSE_UNTRACKED_DIRS) != 0); /* do not advance into directories that contain a .git file */ - if (!contains_tracked && recurse_untracked) { + if (!contains_oitem && recurse_untracked) { git_buf *full = NULL; if (git_iterator_current_workdir_path(new_iter, &full) < 0) goto fail; @@ -661,7 +676,7 @@ int git_diff__from_iterators( recurse_untracked = false; } - if (contains_tracked || recurse_untracked) { + if (contains_oitem || recurse_untracked) { /* if this directory is ignored, remember it as the * "ignore_prefix" for processing contained items */ @@ -707,14 +722,14 @@ int git_diff__from_iterators( goto fail; /* if we are generating TYPECHANGE records then check for that - * instead of just generating an ADD/UNTRACKED record + * instead of just generating an ADDED/UNTRACKED record */ if (delta_type != GIT_DELTA_IGNORED && (diff->opts.flags & GIT_DIFF_INCLUDE_TYPECHANGE_TREES) != 0 && - entry_is_prefixed(diff, nitem, oitem)) + contains_oitem) { - /* this entry was a tree! convert to TYPECHANGE */ - git_diff_delta *last = diff_delta__last_for_item(diff, oitem); + /* this entry was prefixed with a tree - make TYPECHANGE */ + git_diff_delta *last = diff_delta__last_for_item(diff, nitem); if (last) { last->status = GIT_DELTA_TYPECHANGE; last->old_file.mode = GIT_FILEMODE_TREE; |
