Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/libgit2.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/checkout.c10
-rw-r--r--src/diff.c11
-rw-r--r--src/iterator.c17
-rw-r--r--src/iterator.h23
4 files changed, 39 insertions, 22 deletions
diff --git a/src/checkout.c b/src/checkout.c
index a412c4c4e..bc976b854 100644
--- a/src/checkout.c
+++ b/src/checkout.c
@@ -336,22 +336,22 @@ static int checkout_action_wd_only(
error = git_iterator_advance(wditem, workdir);
} else {
/* untracked or ignored - can't know which until we advance through */
- bool ignored, over = false;
- bool removable = wd_item_is_removable(workdir, wd);
+ bool over = false, removable = wd_item_is_removable(workdir, wd);
+ git_iterator_status_t untracked_state;
/* copy the entry for issuing notification callback later */
git_index_entry saved_wd = *wd;
git_buf_sets(&data->tmp, wd->path);
saved_wd.path = data->tmp.ptr;
- error = git_iterator_advance_over_and_check_ignored(
- wditem, &ignored, workdir);
+ error = git_iterator_advance_over_with_status(
+ wditem, &untracked_state, workdir);
if (error == GIT_ITEROVER)
over = true;
else if (error < 0)
return error;
- if (ignored) {
+ if (untracked_state == GIT_ITERATOR_STATUS_IGNORED) {
notify = GIT_CHECKOUT_NOTIFY_IGNORED;
remove = ((data->strategy & GIT_CHECKOUT_REMOVE_IGNORED) != 0);
} else {
diff --git a/src/diff.c b/src/diff.c
index f1c1b0543..18cd52c55 100644
--- a/src/diff.c
+++ b/src/diff.c
@@ -839,7 +839,7 @@ static int handle_unmatched_new_item(
DIFF_FLAG_ISNT_SET(diff, GIT_DIFF_ENABLE_FAST_UNTRACKED_DIRS))
{
git_diff_delta *last;
- bool ignored;
+ git_iterator_status_t untracked_state;
/* attempt to insert record for this directory */
if ((error = diff_delta__from_one(diff, delta_type, nitem)) != 0)
@@ -851,13 +851,14 @@ static int handle_unmatched_new_item(
return git_iterator_advance(&info->nitem, info->new_iter);
/* iterate into dir looking for an actual untracked file */
- if ((error = git_iterator_advance_over_and_check_ignored(
- &info->nitem, &ignored, info->new_iter)) < 0 &&
+ if ((error = git_iterator_advance_over_with_status(
+ &info->nitem, &untracked_state, info->new_iter)) < 0 &&
error != GIT_ITEROVER)
return error;
- /* it iteration only found ignored items, update the record */
- if (ignored) {
+ /* if we found nothing or just ignored items, update the record */
+ if (untracked_state == GIT_ITERATOR_STATUS_IGNORED ||
+ untracked_state == GIT_ITERATOR_STATUS_EMPTY) {
last->status = GIT_DELTA_IGNORED;
/* remove the record if we don't want ignored records */
diff --git a/src/iterator.c b/src/iterator.c
index 1a24dad10..dfa79977d 100644
--- a/src/iterator.c
+++ b/src/iterator.c
@@ -1529,15 +1529,17 @@ int git_iterator_current_workdir_path(git_buf **path, git_iterator *iter)
return 0;
}
-int git_iterator_advance_over_and_check_ignored(
- const git_index_entry **entryptr, bool *ignored, git_iterator *iter)
+int git_iterator_advance_over_with_status(
+ const git_index_entry **entryptr,
+ git_iterator_status_t *status,
+ git_iterator *iter)
{
int error = 0;
workdir_iterator *wi = (workdir_iterator *)iter;
char *base = NULL;
const git_index_entry *entry;
- *ignored = false;
+ *status = GIT_ITERATOR_STATUS_NORMAL;
if (iter->type != GIT_ITERATOR_TYPE_WORKDIR)
return git_iterator_advance(entryptr, iter);
@@ -1548,11 +1550,12 @@ int git_iterator_advance_over_and_check_ignored(
if (git_ignore__lookup(
&wi->ignores, wi->fi.entry.path, &wi->is_ignored) < 0)
wi->is_ignored = true;
- *ignored = wi->is_ignored;
+ if (wi->is_ignored)
+ *status = GIT_ITERATOR_STATUS_IGNORED;
return git_iterator_advance(entryptr, iter);
}
- *ignored = true;
+ *status = GIT_ITERATOR_STATUS_EMPTY;
base = git__strdup(entry->path);
GITERR_CHECK_ALLOC(base);
@@ -1577,9 +1580,11 @@ int git_iterator_advance_over_and_check_ignored(
/* if we found a non-ignored item, treat parent as untracked */
if (!wi->is_ignored) {
- *ignored = false;
+ *status = GIT_ITERATOR_STATUS_NORMAL;
break;
}
+ if (entry && !S_ISDIR(entry->mode))
+ *status = GIT_ITERATOR_STATUS_IGNORED;
if ((error = git_iterator_advance(&entry, iter)) < 0)
break;
diff --git a/src/iterator.h b/src/iterator.h
index dcedbd530..ba9c1e486 100644
--- a/src/iterator.h
+++ b/src/iterator.h
@@ -258,12 +258,23 @@ extern int git_iterator_current_workdir_path(
/* Return index pointer if index iterator, else NULL */
extern git_index *git_iterator_get_index(git_iterator *iter);
-/* Special type of advance that can be called when looking at a tree in
- * the working directory that leaves the iterator on the next item after
- * the tree, but also scans the tree contents looking for any items that
- * are not ignored.
+typedef enum {
+ GIT_ITERATOR_STATUS_NORMAL = 0,
+ GIT_ITERATOR_STATUS_IGNORED = 1,
+ GIT_ITERATOR_STATUS_EMPTY = 2
+} git_iterator_status_t;
+
+/* Advance over a directory and check if it contains no files or just
+ * ignored files.
+ *
+ * In a tree or the index, all directories will contain files, but in the
+ * working directory it is possible to have an empty directory tree or a
+ * tree that only contains ignored files. Many Git operations treat these
+ * cases specially. This advances over a directory (presumably an
+ * untracked directory) but checks during the scan if there are any files
+ * and any non-ignored files.
*/
-extern int git_iterator_advance_over_and_check_ignored(
- const git_index_entry **entry, bool *ignored, git_iterator *iter);
+extern int git_iterator_advance_over_with_status(
+ const git_index_entry **entry, git_iterator_status_t *status, git_iterator *iter);
#endif