Commit 86c9d3dae2561405ec98506e6e72bf845c8315c1

Alan Rogers 2014-05-21T22:54:34

Return GIT_FILEMODE_UNREADABLE for files that fail to stat.

diff --git a/include/git2/errors.h b/include/git2/errors.h
index 3fb3f56..e22f0d8 100644
--- a/include/git2/errors.h
+++ b/include/git2/errors.h
@@ -41,7 +41,6 @@ typedef enum {
 	GIT_EMERGECONFLICT  = -13,	/*< Merge conflicts prevented operation */
 	GIT_ELOCKED         = -14,	/*< Lock file prevented operation */
 	GIT_EMODIFIED       = -15,	/*< Reference value does not match expected */
-	GIT_EUNREADABLE     = -16,	/*< File or folder is unreadable */
 
 	GIT_PASSTHROUGH     = -30,	/*< Internal only */
 	GIT_ITEROVER        = -31,	/*< Signals end of iteration with iterator */
diff --git a/include/git2/types.h b/include/git2/types.h
index 1b6f4cc..6522ea4 100644
--- a/include/git2/types.h
+++ b/include/git2/types.h
@@ -204,6 +204,7 @@ typedef enum {
 	GIT_FILEMODE_BLOB_EXECUTABLE		= 0100755,
 	GIT_FILEMODE_LINK					= 0120000,
 	GIT_FILEMODE_COMMIT					= 0160000,
+	GIT_FILEMODE_UNREADABLE				= 0170000,
 } git_filemode_t;
 
 typedef struct git_refspec git_refspec;
diff --git a/src/diff.c b/src/diff.c
index 32573a2..c169bda 100644
--- a/src/diff.c
+++ b/src/diff.c
@@ -937,22 +937,17 @@ static int handle_unmatched_new_item(
 		if (recurse_into_dir) {
 			error = git_iterator_advance_into(&info->nitem, info->new_iter);
 
-			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 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 )
-					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;
 		}
 	}
 
@@ -998,8 +993,12 @@ static int handle_unmatched_new_item(
 		}
 	}
 
+	else if (nitem->mode == GIT_FILEMODE_UNREADABLE) {
+		delta_type = GIT_DELTA_UNREADABLE;
+	}
+
 	/* Actually create the record for this item if necessary */
-	if (error != GIT_EUNREADABLE && (error = diff_delta__from_one(diff, delta_type, nitem)) != 0)
+	if ((error = diff_delta__from_one(diff, delta_type, nitem)) != 0)
 		return error;
 
 	/* If user requested TYPECHANGE records, then check for that instead of
diff --git a/src/path.c b/src/path.c
index c3487da..bc89a9b 100644
--- a/src/path.c
+++ b/src/path.c
@@ -560,10 +560,10 @@ int git_path_set_error(int errno_value, const char *path, const char *action)
 	case EEXIST:
 		giterr_set(GITERR_OS, "Failed %s - '%s' already exists", action, path);
 		return GIT_EEXISTS;
-		
+
 	default:
 		giterr_set(GITERR_OS, "Could not %s '%s'", action, path);
-		return GIT_EUNREADABLE;
+		return -1;
 	}
 }
 
@@ -1110,6 +1110,13 @@ int git_path_dirload_with_stat(
 				git_vector_remove(contents, i--);
 				continue;
 			}
+			/* Treat the file as unreadable if we get any other error */
+			if (error != 0) {
+				giterr_clear();
+				error = 0;
+				ps->st.st_mode = GIT_FILEMODE_UNREADABLE;
+				continue;
+			}
 			
 			break;
 		}