Merge branch 'jc/commit'
* jc/commit: commit: detect misspelled pathspec while making a partial commit. combine-diff: diff-files fix (#2) combine-diff: diff-files fix.maint
						commit
						756e3ee0c6
					
				|  | @ -630,9 +630,10 @@ static int show_patch_diff(struct combine_diff_path *elem, int num_parent, | ||||||
| 	int i, show_hunks, shown_header = 0; | 	int i, show_hunks, shown_header = 0; | ||||||
| 	char ourtmp_buf[TMPPATHLEN]; | 	char ourtmp_buf[TMPPATHLEN]; | ||||||
| 	char *ourtmp = ourtmp_buf; | 	char *ourtmp = ourtmp_buf; | ||||||
|  | 	int working_tree_file = !memcmp(elem->sha1, null_sha1, 20); | ||||||
|  |  | ||||||
| 	/* Read the result of merge first */ | 	/* Read the result of merge first */ | ||||||
| 	if (memcmp(elem->sha1, null_sha1, 20)) { | 	if (!working_tree_file) { | ||||||
| 		result = grab_blob(elem->sha1, &size); | 		result = grab_blob(elem->sha1, &size); | ||||||
| 		write_to_temp_file(ourtmp, result, size); | 		write_to_temp_file(ourtmp, result, size); | ||||||
| 	} | 	} | ||||||
|  | @ -646,6 +647,7 @@ static int show_patch_diff(struct combine_diff_path *elem, int num_parent, | ||||||
| 			int len = st.st_size; | 			int len = st.st_size; | ||||||
| 			int cnt = 0; | 			int cnt = 0; | ||||||
|  |  | ||||||
|  | 			elem->mode = DIFF_FILE_CANON_MODE(st.st_mode); | ||||||
| 			size = len; | 			size = len; | ||||||
| 			result = xmalloc(len + 1); | 			result = xmalloc(len + 1); | ||||||
| 			while (cnt < len) { | 			while (cnt < len) { | ||||||
|  | @ -661,6 +663,7 @@ static int show_patch_diff(struct combine_diff_path *elem, int num_parent, | ||||||
| 		else { | 		else { | ||||||
| 			/* deleted file */ | 			/* deleted file */ | ||||||
| 			size = 0; | 			size = 0; | ||||||
|  | 			elem->mode = 0; | ||||||
| 			result = xmalloc(1); | 			result = xmalloc(1); | ||||||
| 			result[0] = 0; | 			result[0] = 0; | ||||||
| 			ourtmp = "/dev/null"; | 			ourtmp = "/dev/null"; | ||||||
|  | @ -716,7 +719,7 @@ static int show_patch_diff(struct combine_diff_path *elem, int num_parent, | ||||||
|  |  | ||||||
| 	show_hunks = make_hunks(sline, cnt, num_parent, dense); | 	show_hunks = make_hunks(sline, cnt, num_parent, dense); | ||||||
|  |  | ||||||
| 	if (show_hunks || mode_differs) { | 	if (show_hunks || mode_differs || working_tree_file) { | ||||||
| 		const char *abb; | 		const char *abb; | ||||||
|  |  | ||||||
| 		if (header) { | 		if (header) { | ||||||
|  | @ -731,8 +734,6 @@ static int show_patch_diff(struct combine_diff_path *elem, int num_parent, | ||||||
| 		putchar('\n'); | 		putchar('\n'); | ||||||
| 		printf("index "); | 		printf("index "); | ||||||
| 		for (i = 0; i < num_parent; i++) { | 		for (i = 0; i < num_parent; i++) { | ||||||
| 			if (elem->parent[i].mode != elem->mode) |  | ||||||
| 				mode_differs = 1; |  | ||||||
| 			abb = find_unique_abbrev(elem->parent[i].sha1, | 			abb = find_unique_abbrev(elem->parent[i].sha1, | ||||||
| 						 DEFAULT_ABBREV); | 						 DEFAULT_ABBREV); | ||||||
| 			printf("%s%s", i ? "," : "", abb); | 			printf("%s%s", i ? "," : "", abb); | ||||||
|  |  | ||||||
|  | @ -150,6 +150,8 @@ int main(int argc, const char **argv) | ||||||
| 					       nce->sha1, 20); | 					       nce->sha1, 20); | ||||||
| 					combine.p.parent[stage-2].mode = | 					combine.p.parent[stage-2].mode = | ||||||
| 						DIFF_FILE_CANON_MODE(mode); | 						DIFF_FILE_CANON_MODE(mode); | ||||||
|  | 					combine.p.parent[stage-2].status = | ||||||
|  | 						DIFF_STATUS_MODIFIED; | ||||||
| 				} | 				} | ||||||
|  |  | ||||||
| 				/* diff against the proper unmerged stage */ | 				/* diff against the proper unmerged stage */ | ||||||
|  |  | ||||||
|  | @ -180,6 +180,7 @@ verify=t | ||||||
| verbose= | verbose= | ||||||
| signoff= | signoff= | ||||||
| force_author= | force_author= | ||||||
|  | only_include_assumed= | ||||||
| while case "$#" in 0) break;; esac | while case "$#" in 0) break;; esac | ||||||
| do | do | ||||||
|   case "$1" in |   case "$1" in | ||||||
|  | @ -340,12 +341,8 @@ case "$#,$also$only" in | ||||||
| 0,) | 0,) | ||||||
|   ;; |   ;; | ||||||
| *,) | *,) | ||||||
|   echo >&2 "assuming --only paths..." |   only_include_assumed="# Explicit paths specified without -i nor -o; assuming --only paths..." | ||||||
|   also= |   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 | esac | ||||||
| unset only | unset only | ||||||
|  | @ -380,6 +377,8 @@ t,) | ||||||
| 	;; | 	;; | ||||||
| ,t) | ,t) | ||||||
| 	save_index && | 	save_index && | ||||||
|  | 	git-ls-files --error-unmatch -- "$@" >/dev/null || exit | ||||||
|  |  | ||||||
| 	git-diff-files --name-only -z -- "$@"  | | 	git-diff-files --name-only -z -- "$@"  | | ||||||
| 	( | 	( | ||||||
| 		cd "$TOP" | 		cd "$TOP" | ||||||
|  | @ -408,7 +407,7 @@ t,) | ||||||
| 		refuse_partial "Different in index and the last commit: | 		refuse_partial "Different in index and the last commit: | ||||||
| $dirty_in_index" | $dirty_in_index" | ||||||
| 	    fi | 	    fi | ||||||
| 	    commit_only=`git-ls-files -- "$@"` | 	    commit_only=`git-ls-files --error-unmatch -- "$@"` || exit | ||||||
|  |  | ||||||
| 	    # Build the temporary index and update the real index | 	    # Build the temporary index and update the real index | ||||||
| 	    # the same way. | 	    # the same way. | ||||||
|  | @ -569,7 +568,10 @@ else | ||||||
| 	PARENTS="" | 	PARENTS="" | ||||||
| fi | 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" ] | if [ "$?" != "0" -a ! -f "$GIT_DIR/MERGE_HEAD" ] | ||||||
| then | then | ||||||
| 	rm -f "$GIT_DIR/COMMIT_EDITMSG" | 	rm -f "$GIT_DIR/COMMIT_EDITMSG" | ||||||
|  |  | ||||||
							
								
								
									
										51
									
								
								ls-files.c
								
								
								
								
							
							
						
						
									
										51
									
								
								ls-files.c
								
								
								
								
							|  | @ -25,6 +25,8 @@ static int line_terminator = '\n'; | ||||||
| static int prefix_len = 0, prefix_offset = 0; | static int prefix_len = 0, prefix_offset = 0; | ||||||
| static const char *prefix = NULL; | static const char *prefix = NULL; | ||||||
| static const char **pathspec = 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_cached = ""; | ||||||
| static const char *tag_unmerged = ""; | static const char *tag_unmerged = ""; | ||||||
|  | @ -325,7 +327,8 @@ static int cmp_name(const void *p1, const void *p2) | ||||||
|  * Match a pathspec against a filename. The first "len" characters |  * Match a pathspec against a filename. The first "len" characters | ||||||
|  * are the common prefix |  * 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; | 	const char *m; | ||||||
|  |  | ||||||
|  | @ -333,17 +336,24 @@ static int match(const char **spec, const char *filename, int len) | ||||||
| 		int matchlen = strlen(m + len); | 		int matchlen = strlen(m + len); | ||||||
|  |  | ||||||
| 		if (!matchlen) | 		if (!matchlen) | ||||||
| 			return 1; | 			goto matched; | ||||||
| 		if (!strncmp(m + len, filename + len, matchlen)) { | 		if (!strncmp(m + len, filename + len, matchlen)) { | ||||||
| 			if (m[len + matchlen - 1] == '/') | 			if (m[len + matchlen - 1] == '/') | ||||||
| 				return 1; | 				goto matched; | ||||||
| 			switch (filename[len + matchlen]) { | 			switch (filename[len + matchlen]) { | ||||||
| 			case '/': case '\0': | 			case '/': case '\0': | ||||||
| 				return 1; | 				goto matched; | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		if (!fnmatch(m + len, filename + len, 0)) | 		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; | 	return 0; | ||||||
| } | } | ||||||
|  | @ -356,7 +366,7 @@ static void show_dir_entry(const char *tag, struct nond_on_fs *ent) | ||||||
| 	if (len >= ent->len) | 	if (len >= ent->len) | ||||||
| 		die("git-ls-files: internal error - directory entry not superset of prefix"); | 		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; | 		return; | ||||||
|  |  | ||||||
| 	fputs(tag, stdout); | 	fputs(tag, stdout); | ||||||
|  | @ -444,7 +454,7 @@ static void show_ce_entry(const char *tag, struct cache_entry *ce) | ||||||
| 	if (len >= ce_namelen(ce)) | 	if (len >= ce_namelen(ce)) | ||||||
| 		die("git-ls-files: internal error - cache entry not superset of prefix"); | 		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; | 		return; | ||||||
|  |  | ||||||
| 	if (!show_stage) { | 	if (!show_stage) { | ||||||
|  | @ -699,6 +709,10 @@ int main(int argc, const char **argv) | ||||||
| 			prefix_offset = 0; | 			prefix_offset = 0; | ||||||
| 			continue; | 			continue; | ||||||
| 		} | 		} | ||||||
|  | 		if (!strcmp(arg, "--error-unmatch")) { | ||||||
|  | 			error_unmatch = 1; | ||||||
|  | 			continue; | ||||||
|  | 		} | ||||||
| 		if (*arg == '-') | 		if (*arg == '-') | ||||||
| 			usage(ls_files_usage); | 			usage(ls_files_usage); | ||||||
| 		break; | 		break; | ||||||
|  | @ -710,6 +724,14 @@ int main(int argc, const char **argv) | ||||||
| 	if (pathspec) | 	if (pathspec) | ||||||
| 		verify_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) { | 	if (show_ignored && !exc_given) { | ||||||
| 		fprintf(stderr, "%s: --ignored needs some exclude pattern\n", | 		fprintf(stderr, "%s: --ignored needs some exclude pattern\n", | ||||||
| 			argv[0]); | 			argv[0]); | ||||||
|  | @ -725,5 +747,20 @@ int main(int argc, const char **argv) | ||||||
| 	if (prefix) | 	if (prefix) | ||||||
| 		prune_cache(); | 		prune_cache(); | ||||||
| 	show_files(); | 	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; | 	return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	 Junio C Hamano
						Junio C Hamano