verbose=
signoff=
force_author=
+only_include_assumed=
while case "$#" in 0) break;; esac
do
case "$1" in
0,)
;;
*,)
- echo >&2 "assuming --include paths..."
+ only_include_assumed="# Explicit paths specified without -i nor -o; assuming --include paths..."
also=t
- # Later when switch the defaults, we will replace them with these:
- # echo >&2 "assuming --only paths..."
- # also=
-
- # If we are going to launch an editor, the message won't be
- # shown without this...
- test -z "$log_given$status_only" && sleep 1
;;
esac
unset only
;;
,t)
save_index &&
+ git-ls-files --error-unmatch -- "$@" >/dev/null || exit
+
git-diff-files --name-only -z -- "$@" |
(
cd "$TOP"
refuse_partial "Different in index and the last commit:
$dirty_in_index"
fi
- commit_only=`git-ls-files -- "$@"`
+ commit_only=`git-ls-files --error-unmatch -- "$@"` || exit
# Build the temporary index and update the real index
# the same way.
PARENTS=""
fi
-run_status >>"$GIT_DIR"/COMMIT_EDITMSG
+{
+ test -z "$only_include_assumed" || echo "$only_include_assumed"
+ run_status
+} >>"$GIT_DIR"/COMMIT_EDITMSG
if [ "$?" != "0" -a ! -f "$GIT_DIR/MERGE_HEAD" ]
then
rm -f "$GIT_DIR/COMMIT_EDITMSG"
static int prefix_len = 0, prefix_offset = 0;
static const char *prefix = NULL;
static const char **pathspec = NULL;
+static int error_unmatch = 0;
+static char *ps_matched = NULL;
static const char *tag_cached = "";
static const char *tag_unmerged = "";
* Match a pathspec against a filename. The first "len" characters
* are the common prefix
*/
-static int match(const char **spec, const char *filename, int len)
+static int match(const char **spec, char *ps_matched,
+ const char *filename, int len)
{
const char *m;
int matchlen = strlen(m + len);
if (!matchlen)
- return 1;
+ goto matched;
if (!strncmp(m + len, filename + len, matchlen)) {
if (m[len + matchlen - 1] == '/')
- return 1;
+ goto matched;
switch (filename[len + matchlen]) {
case '/': case '\0':
- return 1;
+ goto matched;
}
}
if (!fnmatch(m + len, filename + len, 0))
- return 1;
+ goto matched;
+ if (ps_matched)
+ ps_matched++;
+ continue;
+ matched:
+ if (ps_matched)
+ *ps_matched = 1;
+ return 1;
}
return 0;
}
if (len >= ent->len)
die("git-ls-files: internal error - directory entry not superset of prefix");
- if (pathspec && !match(pathspec, ent->name, len))
+ if (pathspec && !match(pathspec, ps_matched, ent->name, len))
return;
fputs(tag, stdout);
if (len >= ce_namelen(ce))
die("git-ls-files: internal error - cache entry not superset of prefix");
- if (pathspec && !match(pathspec, ce->name, len))
+ if (pathspec && !match(pathspec, ps_matched, ce->name, len))
return;
if (!show_stage) {
prefix_offset = 0;
continue;
}
+ if (!strcmp(arg, "--error-unmatch")) {
+ error_unmatch = 1;
+ continue;
+ }
if (*arg == '-')
usage(ls_files_usage);
break;
if (pathspec)
verify_pathspec();
+ /* Treat unmatching pathspec elements as errors */
+ if (pathspec && error_unmatch) {
+ int num;
+ for (num = 0; pathspec[num]; num++)
+ ;
+ ps_matched = xcalloc(1, num);
+ }
+
if (show_ignored && !exc_given) {
fprintf(stderr, "%s: --ignored needs some exclude pattern\n",
argv[0]);
if (prefix)
prune_cache();
show_files();
+
+ if (ps_matched) {
+ /* We need to make sure all pathspec matched otherwise
+ * it is an error.
+ */
+ int num, errors = 0;
+ for (num = 0; pathspec[num]; num++) {
+ if (ps_matched[num])
+ continue;
+ error("pathspec '%s' did not match any.",
+ pathspec[num] + prefix_len);
+ }
+ return errors ? 1 : 0;
+ }
+
return 0;
}