return 0;
}
+static int get_mode(const char *path, int *mode)
+{
+ struct stat st;
+
+ if (!path || !strcmp(path, "/dev/null"))
+ *mode = 0;
+ else if (!strcmp(path, "-"))
+ *mode = ntohl(create_ce_mode(0666));
+ else if (stat(path, &st))
+ return error("Could not access '%s'", path);
+ else
+ *mode = st.st_mode;
+ return 0;
+}
+
static int queue_diff(struct diff_options *o,
const char *name1, const char *name2)
{
- struct stat st;
int mode1 = 0, mode2 = 0;
- if (name1) {
- if (!strcmp(name1, "-"))
- mode1 = ntohl(create_ce_mode(0666));
- else if (stat(name1, &st))
- return error("Could not access '%s'", name1);
- else
- mode1 = st.st_mode;
- }
- if (name2) {
- if (!strcmp(name2, "-"))
- mode2 = ntohl(create_ce_mode(0666));
- else if (stat(name2, &st))
- return error("Could not access '%s'", name2);
- else
- mode2 = st.st_mode;
- }
+ if (get_mode(name1, &mode1) || get_mode(name2, &mode2))
+ return -1;
if (mode1 && mode2 && S_ISDIR(mode1) != S_ISDIR(mode2))
return error("file/directory conflict: %s, %s", name1, name2);
}
}
+/*
+ * Does the path name a blob in the working tree, or a directory
+ * in the working tree?
+ */
static int is_in_index(const char *path)
{
- int len = strlen(path);
- int pos = cache_name_pos(path, len);
- char c;
-
- if (pos < 0)
- return 0;
- if (strncmp(active_cache[pos]->name, path, len))
- return 0;
- c = active_cache[pos]->name[len];
- return c == '\0' || c == '/';
+ int len, pos;
+ struct cache_entry *ce;
+
+ len = strlen(path);
+ while (path[len-1] == '/')
+ len--;
+ if (!len)
+ return 1; /* "." */
+ pos = cache_name_pos(path, len);
+ if (0 <= pos)
+ return 1;
+ pos = -1 - pos;
+ while (pos < active_nr) {
+ ce = active_cache[pos++];
+ if (ce_namelen(ce) <= len ||
+ strncmp(ce->name, path, len) ||
+ (ce->name[len] > '/'))
+ break; /* path cannot be a prefix */
+ if (ce->name[len] == '/')
+ return 1;
+ }
+ return 0;
}
static int handle_diff_files_args(struct rev_info *revs,
else if (!strcmp(argv[1], "--theirs"))
revs->max_count = 3;
else if (!strcmp(argv[1], "-n") ||
- !strcmp(argv[1], "--no-index"))
+ !strcmp(argv[1], "--no-index")) {
revs->max_count = -2;
+ revs->diffopt.exit_with_status = 1;
+ }
else if (!strcmp(argv[1], "-q"))
*silent = 1;
else
break;
} else if (i < argc - 3 && !strcmp(argv[i], "--no-index")) {
i = argc - 3;
+ revs->diffopt.exit_with_status = 1;
break;
}
if (argc != i + 2 || (!is_outside_repo(argv[i + 1], nongit, prefix) &&
struct cache_entry *ce = active_cache[i];
int changed;
+ if (revs->diffopt.quiet && revs->diffopt.has_changes)
+ break;
+
if (!ce_path_match(ce, revs->prune_data))
continue;
continue;
}
else
- dpath->mode = canon_mode(st.st_mode);
+ dpath->mode = ntohl(ce_mode_from_stat(ce, st.st_mode));
while (i < entries) {
struct cache_entry *nce = active_cache[i];
int mode = ntohl(nce->ce_mode);
num_compare_stages++;
hashcpy(dpath->parent[stage-2].sha1, nce->sha1);
- dpath->parent[stage-2].mode =
- canon_mode(mode);
+ dpath->parent[stage-2].mode = ntohl(ce_mode_from_stat(nce, mode));
dpath->parent[stage-2].status =
DIFF_STATUS_MODIFIED;
}
if (!changed && !revs->diffopt.find_copies_harder)
continue;
oldmode = ntohl(ce->ce_mode);
-
- newmode = canon_mode(st.st_mode);
- if (!trust_executable_bit &&
- S_ISREG(newmode) && S_ISREG(oldmode) &&
- ((newmode ^ oldmode) == 0111))
- newmode = oldmode;
+ newmode = ntohl(ce_mode_from_stat(ce, st.st_mode));
diff_change(&revs->diffopt, oldmode, newmode,
ce->sha1, (changed ? null_sha1 : ce->sha1),
ce->name, NULL);
struct cache_entry *ce = *ac;
int same = (entries > 1) && ce_same_name(ce, ac[1]);
+ if (revs->diffopt.quiet && revs->diffopt.has_changes)
+ break;
+
if (!ce_path_match(ce, pathspec))
goto skip_entry;
const char *tree_name;
int match_missing = 0;
- /*
+ /*
* Backward compatibility wart - "diff-index -m" does
* not mean "do not ignore merges", but totally different.
*/