summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Rogers <alan@github.com>2014-05-20 23:57:40 +1000
committerAlan Rogers <alan@github.com>2014-05-20 23:57:40 +1000
commit61bef72dc35c593e632dc2008c4eec271a264869 (patch)
treee85096c82d51a1dc81d529b627fb7504c1059d29
parentf47bc8ff5e844fec15e705e8ebd11bae742b8039 (diff)
downloadlibgit2-61bef72dc35c593e632dc2008c4eec271a264869.tar.gz
Start adding GIT_DELTA_UNREADABLE and GIT_STATUS_WT_UNREADABLE.
-rw-r--r--include/git2/diff.h4
-rw-r--r--include/git2/status.h1
-rw-r--r--src/checkout.c2
-rw-r--r--src/diff.c38
-rw-r--r--src/diff_file.c1
-rw-r--r--src/diff_print.c18
-rw-r--r--src/diff_tform.c4
-rw-r--r--src/status.c3
8 files changed, 52 insertions, 19 deletions
diff --git a/include/git2/diff.h b/include/git2/diff.h
index b40cc6135..ebf47e3c0 100644
--- a/include/git2/diff.h
+++ b/include/git2/diff.h
@@ -191,6 +191,9 @@ typedef enum {
* can apply given diff information to binary files.
*/
GIT_DIFF_SHOW_BINARY = (1 << 30),
+
+ /** Include unreadable files in the diff */
+ GIT_DIFF_INCLUDE_UNREADABLE = (1 << 31),
} git_diff_option_t;
/**
@@ -237,6 +240,7 @@ typedef enum {
GIT_DELTA_IGNORED = 6, /** entry is ignored item in workdir */
GIT_DELTA_UNTRACKED = 7, /** entry is untracked item in workdir */
GIT_DELTA_TYPECHANGE = 8, /** type of entry changed between old and new */
+ GIT_DELTA_UNREADABLE = 9, /** entry is unreadable */
} git_delta_t;
/**
diff --git a/include/git2/status.h b/include/git2/status.h
index effe5e1ea..794a629af 100644
--- a/include/git2/status.h
+++ b/include/git2/status.h
@@ -43,6 +43,7 @@ typedef enum {
GIT_STATUS_WT_DELETED = (1u << 9),
GIT_STATUS_WT_TYPECHANGE = (1u << 10),
GIT_STATUS_WT_RENAMED = (1u << 11),
+ GIT_STATUS_WT_UNREADABLE = (1u << 12),
GIT_STATUS_IGNORED = (1u << 14),
} git_status_t;
diff --git a/src/checkout.c b/src/checkout.c
index 20763fd35..1f793d412 100644
--- a/src/checkout.c
+++ b/src/checkout.c
@@ -116,6 +116,7 @@ static int checkout_notify(
case GIT_DELTA_ADDED:
case GIT_DELTA_IGNORED:
case GIT_DELTA_UNTRACKED:
+ case GIT_DELTA_UNREADABLE:
target = &delta->new_file;
break;
case GIT_DELTA_DELETED:
@@ -2063,6 +2064,7 @@ int git_checkout_iterator(
diff_opts.flags =
GIT_DIFF_INCLUDE_UNMODIFIED |
+ GIT_DIFF_INCLUDE_UNREADABLE |
GIT_DIFF_INCLUDE_UNTRACKED |
GIT_DIFF_RECURSE_UNTRACKED_DIRS | /* needed to match baseline */
GIT_DIFF_INCLUDE_IGNORED |
diff --git a/src/diff.c b/src/diff.c
index a0cfb5890..32573a270 100644
--- a/src/diff.c
+++ b/src/diff.c
@@ -92,6 +92,10 @@ static int diff_delta__from_one(
if (status == GIT_DELTA_UNTRACKED &&
DIFF_FLAG_ISNT_SET(diff, GIT_DIFF_INCLUDE_UNTRACKED))
return 0;
+
+ if (status == GIT_DELTA_UNREADABLE &&
+ DIFF_FLAG_ISNT_SET(diff, GIT_DIFF_INCLUDE_UNREADABLE))
+ return 0;
if (!git_pathspec__match(
&diff->pathspec, entry->path,
@@ -201,6 +205,11 @@ static git_diff_delta *diff_delta__last_for_item(
git_oid__cmp(&delta->new_file.id, &item->id) == 0)
return delta;
break;
+ case GIT_DELTA_UNREADABLE:
+ if (diff->strcomp(delta->new_file.path, item->path) == 0 &&
+ git_oid__cmp(&delta->new_file.id, &item->id) == 0)
+ return delta;
+ break;
case GIT_DELTA_MODIFIED:
if (git_oid__cmp(&delta->old_file.id, &item->id) == 0 ||
git_oid__cmp(&delta->new_file.id, &item->id) == 0)
@@ -293,6 +302,10 @@ bool git_diff_delta__should_skip(
(flags & GIT_DIFF_INCLUDE_UNTRACKED) == 0)
return true;
+ if (delta->status == GIT_DELTA_UNREADABLE &&
+ (flags & GIT_DIFF_INCLUDE_UNREADABLE) == 0)
+ return true;
+
return false;
}
@@ -924,17 +937,22 @@ static int handle_unmatched_new_item(
if (recurse_into_dir) {
error = git_iterator_advance_into(&info->nitem, info->new_iter);
- /* if real error or no error, proceed with iteration */
- if (error != GIT_ENOTFOUND && error != GIT_EUNREADABLE)
- return error;
- giterr_clear();
+ printf("error advancing into diff %d\n", error);
+ if (error == GIT_EUNREADABLE) {
+ delta_type = GIT_DELTA_UNREADABLE;
+ } else {
+ /* if real error or no error, proceed with iteration */
+ if (error != GIT_ENOTFOUND)
+ return error;
+ giterr_clear();
- /* if directory is empty, can't advance into it, so either skip
- * it or ignore it
- */
- if (contains_oitem && error != GIT_EUNREADABLE)
- return git_iterator_advance(&info->nitem, info->new_iter);
- delta_type = GIT_DELTA_IGNORED;
+ /* if directory is empty, can't advance into it, so either skip
+ * it or ignore it
+ */
+ if (contains_oitem )
+ return git_iterator_advance(&info->nitem, info->new_iter);
+ delta_type = GIT_DELTA_IGNORED;
+ }
}
}
diff --git a/src/diff_file.c b/src/diff_file.c
index f2a1d5099..96be0942b 100644
--- a/src/diff_file.c
+++ b/src/diff_file.c
@@ -112,6 +112,7 @@ int git_diff_file_content__init_from_diff(
has_data = !use_old &&
(diff->opts.flags & GIT_DIFF_SHOW_UNTRACKED_CONTENT) != 0;
break;
+ case GIT_DELTA_UNREADABLE:
case GIT_DELTA_MODIFIED:
case GIT_DELTA_COPIED:
case GIT_DELTA_RENAMED:
diff --git a/src/diff_print.c b/src/diff_print.c
index 08e1e7f90..964c49540 100644
--- a/src/diff_print.c
+++ b/src/diff_print.c
@@ -82,14 +82,15 @@ char git_diff_status_char(git_delta_t status)
char code;
switch (status) {
- case GIT_DELTA_ADDED: code = 'A'; break;
- case GIT_DELTA_DELETED: code = 'D'; break;
- case GIT_DELTA_MODIFIED: code = 'M'; break;
- case GIT_DELTA_RENAMED: code = 'R'; break;
- case GIT_DELTA_COPIED: code = 'C'; break;
- case GIT_DELTA_IGNORED: code = 'I'; break;
- case GIT_DELTA_UNTRACKED: code = '?'; break;
- default: code = ' '; break;
+ case GIT_DELTA_ADDED: code = 'A'; break;
+ case GIT_DELTA_DELETED: code = 'D'; break;
+ case GIT_DELTA_MODIFIED: code = 'M'; break;
+ case GIT_DELTA_RENAMED: code = 'R'; break;
+ case GIT_DELTA_COPIED: code = 'C'; break;
+ case GIT_DELTA_IGNORED: code = 'I'; break;
+ case GIT_DELTA_UNTRACKED: code = '?'; break;
+ case GIT_DELTA_UNREADABLE: code = 'X'; break;
+ default: code = ' '; break;
}
return code;
@@ -414,6 +415,7 @@ static int diff_print_patch_file(
if (S_ISDIR(delta->new_file.mode) ||
delta->status == GIT_DELTA_UNMODIFIED ||
delta->status == GIT_DELTA_IGNORED ||
+ delta->status == GIT_DELTA_UNREADABLE ||
(delta->status == GIT_DELTA_UNTRACKED &&
(pi->flags & GIT_DIFF_SHOW_UNTRACKED_CONTENT) == 0))
return 0;
diff --git a/src/diff_tform.c b/src/diff_tform.c
index a2dab0ae2..423a0ca33 100644
--- a/src/diff_tform.c
+++ b/src/diff_tform.c
@@ -114,7 +114,7 @@ static git_diff_delta *diff_delta__merge_like_cgit_reversed(
if ((dup = diff_delta__dup(a, pool)) == NULL)
return NULL;
- if (b->status == GIT_DELTA_UNMODIFIED || b->status == GIT_DELTA_UNTRACKED)
+ if (b->status == GIT_DELTA_UNMODIFIED || b->status == GIT_DELTA_UNTRACKED || b->status == GIT_DELTA_UNREADABLE)
return dup;
if (dup->status == GIT_DELTA_DELETED) {
@@ -732,6 +732,7 @@ static bool is_rename_source(
switch (delta->status) {
case GIT_DELTA_ADDED:
case GIT_DELTA_UNTRACKED:
+ case GIT_DELTA_UNREADABLE:
case GIT_DELTA_IGNORED:
return false;
@@ -786,6 +787,7 @@ GIT_INLINE(bool) delta_is_new_only(git_diff_delta *delta)
{
return (delta->status == GIT_DELTA_ADDED ||
delta->status == GIT_DELTA_UNTRACKED ||
+ delta->status == GIT_DELTA_UNREADABLE ||
delta->status == GIT_DELTA_IGNORED);
}
diff --git a/src/status.c b/src/status.c
index 061c9d5e1..6b8009854 100644
--- a/src/status.c
+++ b/src/status.c
@@ -62,6 +62,9 @@ static unsigned int workdir_delta2status(
case GIT_DELTA_UNTRACKED:
st = GIT_STATUS_WT_NEW;
break;
+ case GIT_DELTA_UNREADABLE:
+ st = GIT_STATUS_WT_UNREADABLE;
+ break;
case GIT_DELTA_DELETED:
st = GIT_STATUS_WT_DELETED;
break;