Merge branch 'maint-1.7.11' into maint
* maint-1.7.11: Almost 1.7.11.6 gitweb: URL-decode $my_url/$my_uri when stripping PATH_INFO rebase -i: use full onto sha1 in reflog sh-setup: protect from exported IFS receive-pack: do not leak output from auto-gc to standard output t/t5400: demonstrate breakage caused by informational message from prune setup: clarify error messages for file/revisions ambiguity send-email: improve RFC2047 quote parsing fsck: detect null sha1 in tree entries do not write null sha1s to on-disk index diff: do not use null sha1 as a sentinel valuemaint
						commit
						e3f26752b5
					
				|  | @ -4,7 +4,8 @@ Git v1.7.11.6 Release Notes | |||
| Fixes since v1.7.11.5 | ||||
| --------------------- | ||||
|  | ||||
| This is primarily documentation and low-impact code clarification. | ||||
| This consists primarily of documentation updates and low-impact code | ||||
| clarification and bugfixes. | ||||
|  | ||||
|  - "ciabot" script (in contrib/) has been updated with extensive | ||||
|    documentation. | ||||
|  | @ -32,3 +33,30 @@ This is primarily documentation and low-impact code clarification. | |||
|  - "git commit --amend" let the user edit the log message and then | ||||
|    died when the human-readable committer name was given | ||||
|    insufficiently by getpwent(3). | ||||
|  | ||||
|  - The reflog entries left by "git rebase" and "git rebase -i" were | ||||
|    inconsistent (the interactive one gave an abbreviated object name). | ||||
|  | ||||
|  - When the user exports a non-default IFS without HT, scripts that | ||||
|    rely on being able to parse "ls-files -s | while read a b c..." | ||||
|    started to fail.  Protect them from such a misconfiguration. | ||||
|  | ||||
|  - When "git push" triggered the automatic gc on the receiving end, a | ||||
|    message from "git prune" that said it was removing cruft leaked to | ||||
|    the standard output, breaking the communication protocol. | ||||
|  | ||||
|  - "git diff" had a confusion between taking data from a path in the | ||||
|    working tree and taking data from an object that happens to have | ||||
|    name 0{40} recorded in a tree. | ||||
|  | ||||
|  - "git send-email" did not unquote encoded words that appear on the | ||||
|    header correctly, and lost "_" from strings. | ||||
|  | ||||
|  - When the user gives an argument that can be taken as both a | ||||
|    revision name and a pathname without disambiguating with "--", we | ||||
|    used to give a help message "Use '--' to separate".  The message | ||||
|    has been clarified to show where that '--' goes on the command | ||||
|    line. | ||||
|  | ||||
|  - "gitweb" when used with PATH_INFO failed to notice directories with | ||||
|    SP (and other characters that need URL-style quoting) in them. | ||||
|  |  | |||
|  | @ -43,7 +43,7 @@ extern int check_pager_config(const char *cmd); | |||
| struct diff_options; | ||||
| extern void setup_diff_pager(struct diff_options *); | ||||
|  | ||||
| extern int textconv_object(const char *path, unsigned mode, const unsigned char *sha1, char **buf, unsigned long *buf_size); | ||||
| extern int textconv_object(const char *path, unsigned mode, const unsigned char *sha1, int sha1_valid, char **buf, unsigned long *buf_size); | ||||
|  | ||||
| extern int cmd_add(int argc, const char **argv, const char *prefix); | ||||
| extern int cmd_annotate(int argc, const char **argv, const char *prefix); | ||||
|  |  | |||
|  | @ -110,6 +110,7 @@ static int diff_hunks(mmfile_t *file_a, mmfile_t *file_b, long ctxlen, | |||
| int textconv_object(const char *path, | ||||
| 		    unsigned mode, | ||||
| 		    const unsigned char *sha1, | ||||
| 		    int sha1_valid, | ||||
| 		    char **buf, | ||||
| 		    unsigned long *buf_size) | ||||
| { | ||||
|  | @ -117,7 +118,7 @@ int textconv_object(const char *path, | |||
| 	struct userdiff_driver *textconv; | ||||
|  | ||||
| 	df = alloc_filespec(path); | ||||
| 	fill_filespec(df, sha1, mode); | ||||
| 	fill_filespec(df, sha1, sha1_valid, mode); | ||||
| 	textconv = get_textconv(df); | ||||
| 	if (!textconv) { | ||||
| 		free_filespec(df); | ||||
|  | @ -142,7 +143,7 @@ static void fill_origin_blob(struct diff_options *opt, | |||
|  | ||||
| 		num_read_blob++; | ||||
| 		if (DIFF_OPT_TST(opt, ALLOW_TEXTCONV) && | ||||
| 		    textconv_object(o->path, o->mode, o->blob_sha1, &file->ptr, &file_size)) | ||||
| 		    textconv_object(o->path, o->mode, o->blob_sha1, 1, &file->ptr, &file_size)) | ||||
| 			; | ||||
| 		else | ||||
| 			file->ptr = read_sha1_file(o->blob_sha1, &type, &file_size); | ||||
|  | @ -2123,7 +2124,7 @@ static struct commit *fake_working_tree_commit(struct diff_options *opt, | |||
| 		switch (st.st_mode & S_IFMT) { | ||||
| 		case S_IFREG: | ||||
| 			if (DIFF_OPT_TST(opt, ALLOW_TEXTCONV) && | ||||
| 			    textconv_object(read_from, mode, null_sha1, &buf_ptr, &buf_len)) | ||||
| 			    textconv_object(read_from, mode, null_sha1, 0, &buf_ptr, &buf_len)) | ||||
| 				strbuf_attach(&buf, buf_ptr, buf_len, buf_len + 1); | ||||
| 			else if (strbuf_read_file(&buf, read_from, st.st_size) != st.st_size) | ||||
| 				die_errno("cannot open or read '%s'", read_from); | ||||
|  | @ -2516,7 +2517,7 @@ parse_done: | |||
| 			die("no such path %s in %s", path, final_commit_name); | ||||
|  | ||||
| 		if (DIFF_OPT_TST(&sb.revs->diffopt, ALLOW_TEXTCONV) && | ||||
| 		    textconv_object(path, o->mode, o->blob_sha1, (char **) &sb.final_buf, | ||||
| 		    textconv_object(path, o->mode, o->blob_sha1, 1, (char **) &sb.final_buf, | ||||
| 				    &sb.final_buf_size)) | ||||
| 			; | ||||
| 		else | ||||
|  |  | |||
|  | @ -146,7 +146,7 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name) | |||
| 			die("git cat-file --textconv %s: <object> must be <sha1:path>", | ||||
| 			    obj_name); | ||||
|  | ||||
| 		if (!textconv_object(obj_context.path, obj_context.mode, sha1, &buf, &size)) | ||||
| 		if (!textconv_object(obj_context.path, obj_context.mode, sha1, 1, &buf, &size)) | ||||
| 			die("git cat-file --textconv: unable to run textconv on %s", | ||||
| 			    obj_name); | ||||
| 		break; | ||||
|  |  | |||
|  | @ -29,6 +29,8 @@ static void stuff_change(struct diff_options *opt, | |||
| 			 unsigned old_mode, unsigned new_mode, | ||||
| 			 const unsigned char *old_sha1, | ||||
| 			 const unsigned char *new_sha1, | ||||
| 			 int old_sha1_valid, | ||||
| 			 int new_sha1_valid, | ||||
| 			 const char *old_name, | ||||
| 			 const char *new_name) | ||||
| { | ||||
|  | @ -54,8 +56,8 @@ static void stuff_change(struct diff_options *opt, | |||
|  | ||||
| 	one = alloc_filespec(old_name); | ||||
| 	two = alloc_filespec(new_name); | ||||
| 	fill_filespec(one, old_sha1, old_mode); | ||||
| 	fill_filespec(two, new_sha1, new_mode); | ||||
| 	fill_filespec(one, old_sha1, old_sha1_valid, old_mode); | ||||
| 	fill_filespec(two, new_sha1, new_sha1_valid, new_mode); | ||||
|  | ||||
| 	diff_queue(&diff_queued_diff, one, two); | ||||
| } | ||||
|  | @ -84,6 +86,7 @@ static int builtin_diff_b_f(struct rev_info *revs, | |||
| 	stuff_change(&revs->diffopt, | ||||
| 		     blob[0].mode, canon_mode(st.st_mode), | ||||
| 		     blob[0].sha1, null_sha1, | ||||
| 		     1, 0, | ||||
| 		     path, path); | ||||
| 	diffcore_std(&revs->diffopt); | ||||
| 	diff_flush(&revs->diffopt); | ||||
|  | @ -108,6 +111,7 @@ static int builtin_diff_blobs(struct rev_info *revs, | |||
| 	stuff_change(&revs->diffopt, | ||||
| 		     blob[0].mode, blob[1].mode, | ||||
| 		     blob[0].sha1, blob[1].sha1, | ||||
| 		     1, 1, | ||||
| 		     blob[0].name, blob[1].name); | ||||
| 	diffcore_std(&revs->diffopt); | ||||
| 	diff_flush(&revs->diffopt); | ||||
|  |  | |||
|  | @ -977,7 +977,8 @@ int cmd_receive_pack(int argc, const char **argv, const char *prefix) | |||
| 			const char *argv_gc_auto[] = { | ||||
| 				"gc", "--auto", "--quiet", NULL, | ||||
| 			}; | ||||
| 			run_command_v_opt(argv_gc_auto, RUN_GIT_CMD); | ||||
| 			int opt = RUN_GIT_CMD | RUN_COMMAND_STDOUT_TO_STDERR; | ||||
| 			run_command_v_opt(argv_gc_auto, opt); | ||||
| 		} | ||||
| 		if (auto_update_server_info) | ||||
| 			update_server_info(0); | ||||
|  |  | |||
|  | @ -111,7 +111,7 @@ static char *grab_blob(const unsigned char *sha1, unsigned int mode, | |||
| 		return xcalloc(1, 1); | ||||
| 	} else if (textconv) { | ||||
| 		struct diff_filespec *df = alloc_filespec(path); | ||||
| 		fill_filespec(df, sha1, mode); | ||||
| 		fill_filespec(df, sha1, 1, mode); | ||||
| 		*size = fill_textconv(textconv, df, &blob); | ||||
| 		free_filespec(df); | ||||
| 	} else { | ||||
|  | @ -823,7 +823,7 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent, | |||
| 						   &result_size, NULL, NULL); | ||||
| 		} else if (textconv) { | ||||
| 			struct diff_filespec *df = alloc_filespec(elem->path); | ||||
| 			fill_filespec(df, null_sha1, st.st_mode); | ||||
| 			fill_filespec(df, null_sha1, 0, st.st_mode); | ||||
| 			result_size = fill_textconv(textconv, df, &result); | ||||
| 			free_filespec(df); | ||||
| 		} else if (0 <= (fd = open(elem->path, O_RDONLY))) { | ||||
|  |  | |||
							
								
								
									
										20
									
								
								diff-lib.c
								
								
								
								
							
							
						
						
									
										20
									
								
								diff-lib.c
								
								
								
								
							|  | @ -206,7 +206,8 @@ int run_diff_files(struct rev_info *revs, unsigned int option) | |||
| 			if (silent_on_removed) | ||||
| 				continue; | ||||
| 			diff_addremove(&revs->diffopt, '-', ce->ce_mode, | ||||
| 				       ce->sha1, ce->name, 0); | ||||
| 				       ce->sha1, !is_null_sha1(ce->sha1), | ||||
| 				       ce->name, 0); | ||||
| 			continue; | ||||
| 		} | ||||
| 		changed = match_stat_with_submodule(&revs->diffopt, ce, &st, | ||||
|  | @ -220,6 +221,7 @@ int run_diff_files(struct rev_info *revs, unsigned int option) | |||
| 		newmode = ce_mode_from_stat(ce, st.st_mode); | ||||
| 		diff_change(&revs->diffopt, oldmode, newmode, | ||||
| 			    ce->sha1, (changed ? null_sha1 : ce->sha1), | ||||
| 			    !is_null_sha1(ce->sha1), (changed ? 0 : !is_null_sha1(ce->sha1)), | ||||
| 			    ce->name, 0, dirty_submodule); | ||||
|  | ||||
| 	} | ||||
|  | @ -236,11 +238,12 @@ int run_diff_files(struct rev_info *revs, unsigned int option) | |||
| static void diff_index_show_file(struct rev_info *revs, | ||||
| 				 const char *prefix, | ||||
| 				 struct cache_entry *ce, | ||||
| 				 const unsigned char *sha1, unsigned int mode, | ||||
| 				 const unsigned char *sha1, int sha1_valid, | ||||
| 				 unsigned int mode, | ||||
| 				 unsigned dirty_submodule) | ||||
| { | ||||
| 	diff_addremove(&revs->diffopt, prefix[0], mode, | ||||
| 		       sha1, ce->name, dirty_submodule); | ||||
| 		       sha1, sha1_valid, ce->name, dirty_submodule); | ||||
| } | ||||
|  | ||||
| static int get_stat_data(struct cache_entry *ce, | ||||
|  | @ -295,7 +298,7 @@ static void show_new_file(struct rev_info *revs, | |||
| 	    &dirty_submodule, &revs->diffopt) < 0) | ||||
| 		return; | ||||
|  | ||||
| 	diff_index_show_file(revs, "+", new, sha1, mode, dirty_submodule); | ||||
| 	diff_index_show_file(revs, "+", new, sha1, !is_null_sha1(sha1), mode, dirty_submodule); | ||||
| } | ||||
|  | ||||
| static int show_modified(struct rev_info *revs, | ||||
|  | @ -312,7 +315,7 @@ static int show_modified(struct rev_info *revs, | |||
| 			  &dirty_submodule, &revs->diffopt) < 0) { | ||||
| 		if (report_missing) | ||||
| 			diff_index_show_file(revs, "-", old, | ||||
| 					     old->sha1, old->ce_mode, 0); | ||||
| 					     old->sha1, 1, old->ce_mode, 0); | ||||
| 		return -1; | ||||
| 	} | ||||
|  | ||||
|  | @ -347,7 +350,8 @@ static int show_modified(struct rev_info *revs, | |||
| 		return 0; | ||||
|  | ||||
| 	diff_change(&revs->diffopt, oldmode, mode, | ||||
| 		    old->sha1, sha1, old->name, 0, dirty_submodule); | ||||
| 		    old->sha1, sha1, 1, !is_null_sha1(sha1), | ||||
| 		    old->name, 0, dirty_submodule); | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
|  | @ -380,7 +384,7 @@ static void do_oneway_diff(struct unpack_trees_options *o, | |||
| 		struct diff_filepair *pair; | ||||
| 		pair = diff_unmerge(&revs->diffopt, idx->name); | ||||
| 		if (tree) | ||||
| 			fill_filespec(pair->one, tree->sha1, tree->ce_mode); | ||||
| 			fill_filespec(pair->one, tree->sha1, 1, tree->ce_mode); | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
|  | @ -396,7 +400,7 @@ static void do_oneway_diff(struct unpack_trees_options *o, | |||
| 	 * Something removed from the tree? | ||||
| 	 */ | ||||
| 	if (!idx) { | ||||
| 		diff_index_show_file(revs, "-", tree, tree->sha1, tree->ce_mode, 0); | ||||
| 		diff_index_show_file(revs, "-", tree, tree->sha1, 1, tree->ce_mode, 0); | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
|  |  | |||
|  | @ -82,7 +82,7 @@ static struct diff_filespec *noindex_filespec(const char *name, int mode) | |||
| 	if (!name) | ||||
| 		name = "/dev/null"; | ||||
| 	s = alloc_filespec(name); | ||||
| 	fill_filespec(s, null_sha1, mode); | ||||
| 	fill_filespec(s, null_sha1, 0, mode); | ||||
| 	if (name == file_from_standard_input) | ||||
| 		populate_from_stdin(s); | ||||
| 	return s; | ||||
|  |  | |||
							
								
								
									
										16
									
								
								diff.c
								
								
								
								
							
							
						
						
									
										16
									
								
								diff.c
								
								
								
								
							|  | @ -2541,12 +2541,12 @@ void free_filespec(struct diff_filespec *spec) | |||
| } | ||||
|  | ||||
| void fill_filespec(struct diff_filespec *spec, const unsigned char *sha1, | ||||
| 		   unsigned short mode) | ||||
| 		   int sha1_valid, unsigned short mode) | ||||
| { | ||||
| 	if (mode) { | ||||
| 		spec->mode = canon_mode(mode); | ||||
| 		hashcpy(spec->sha1, sha1); | ||||
| 		spec->sha1_valid = !is_null_sha1(sha1); | ||||
| 		spec->sha1_valid = sha1_valid; | ||||
| 	} | ||||
| } | ||||
|  | ||||
|  | @ -4693,6 +4693,7 @@ static int is_submodule_ignored(const char *path, struct diff_options *options) | |||
| void diff_addremove(struct diff_options *options, | ||||
| 		    int addremove, unsigned mode, | ||||
| 		    const unsigned char *sha1, | ||||
| 		    int sha1_valid, | ||||
| 		    const char *concatpath, unsigned dirty_submodule) | ||||
| { | ||||
| 	struct diff_filespec *one, *two; | ||||
|  | @ -4724,9 +4725,9 @@ void diff_addremove(struct diff_options *options, | |||
| 	two = alloc_filespec(concatpath); | ||||
|  | ||||
| 	if (addremove != '+') | ||||
| 		fill_filespec(one, sha1, mode); | ||||
| 		fill_filespec(one, sha1, sha1_valid, mode); | ||||
| 	if (addremove != '-') { | ||||
| 		fill_filespec(two, sha1, mode); | ||||
| 		fill_filespec(two, sha1, sha1_valid, mode); | ||||
| 		two->dirty_submodule = dirty_submodule; | ||||
| 	} | ||||
|  | ||||
|  | @ -4739,6 +4740,7 @@ void diff_change(struct diff_options *options, | |||
| 		 unsigned old_mode, unsigned new_mode, | ||||
| 		 const unsigned char *old_sha1, | ||||
| 		 const unsigned char *new_sha1, | ||||
| 		 int old_sha1_valid, int new_sha1_valid, | ||||
| 		 const char *concatpath, | ||||
| 		 unsigned old_dirty_submodule, unsigned new_dirty_submodule) | ||||
| { | ||||
|  | @ -4753,6 +4755,8 @@ void diff_change(struct diff_options *options, | |||
| 		const unsigned char *tmp_c; | ||||
| 		tmp = old_mode; old_mode = new_mode; new_mode = tmp; | ||||
| 		tmp_c = old_sha1; old_sha1 = new_sha1; new_sha1 = tmp_c; | ||||
| 		tmp = old_sha1_valid; old_sha1_valid = new_sha1_valid; | ||||
| 			new_sha1_valid = tmp; | ||||
| 		tmp = old_dirty_submodule; old_dirty_submodule = new_dirty_submodule; | ||||
| 			new_dirty_submodule = tmp; | ||||
| 	} | ||||
|  | @ -4763,8 +4767,8 @@ void diff_change(struct diff_options *options, | |||
|  | ||||
| 	one = alloc_filespec(concatpath); | ||||
| 	two = alloc_filespec(concatpath); | ||||
| 	fill_filespec(one, old_sha1, old_mode); | ||||
| 	fill_filespec(two, new_sha1, new_mode); | ||||
| 	fill_filespec(one, old_sha1, old_sha1_valid, old_mode); | ||||
| 	fill_filespec(two, new_sha1, new_sha1_valid, new_mode); | ||||
| 	one->dirty_submodule = old_dirty_submodule; | ||||
| 	two->dirty_submodule = new_dirty_submodule; | ||||
|  | ||||
|  |  | |||
							
								
								
									
										5
									
								
								diff.h
								
								
								
								
							
							
						
						
									
										5
									
								
								diff.h
								
								
								
								
							|  | @ -19,12 +19,14 @@ typedef void (*change_fn_t)(struct diff_options *options, | |||
| 		 unsigned old_mode, unsigned new_mode, | ||||
| 		 const unsigned char *old_sha1, | ||||
| 		 const unsigned char *new_sha1, | ||||
| 		 int old_sha1_valid, int new_sha1_valid, | ||||
| 		 const char *fullpath, | ||||
| 		 unsigned old_dirty_submodule, unsigned new_dirty_submodule); | ||||
|  | ||||
| typedef void (*add_remove_fn_t)(struct diff_options *options, | ||||
| 		    int addremove, unsigned mode, | ||||
| 		    const unsigned char *sha1, | ||||
| 		    int sha1_valid, | ||||
| 		    const char *fullpath, unsigned dirty_submodule); | ||||
|  | ||||
| typedef void (*diff_format_fn_t)(struct diff_queue_struct *q, | ||||
|  | @ -214,12 +216,15 @@ extern void diff_addremove(struct diff_options *, | |||
| 			   int addremove, | ||||
| 			   unsigned mode, | ||||
| 			   const unsigned char *sha1, | ||||
| 			   int sha1_valid, | ||||
| 			   const char *fullpath, unsigned dirty_submodule); | ||||
|  | ||||
| extern void diff_change(struct diff_options *, | ||||
| 			unsigned mode1, unsigned mode2, | ||||
| 			const unsigned char *sha1, | ||||
| 			const unsigned char *sha2, | ||||
| 			int sha1_valid, | ||||
| 			int sha2_valid, | ||||
| 			const char *fullpath, | ||||
| 			unsigned dirty_submodule1, unsigned dirty_submodule2); | ||||
|  | ||||
|  |  | |||
|  | @ -48,7 +48,7 @@ static struct diff_rename_dst *locate_rename_dst(struct diff_filespec *two, | |||
| 		memmove(rename_dst + first + 1, rename_dst + first, | ||||
| 			(rename_dst_nr - first - 1) * sizeof(*rename_dst)); | ||||
| 	rename_dst[first].two = alloc_filespec(two->path); | ||||
| 	fill_filespec(rename_dst[first].two, two->sha1, two->mode); | ||||
| 	fill_filespec(rename_dst[first].two, two->sha1, two->sha1_valid, two->mode); | ||||
| 	rename_dst[first].pair = NULL; | ||||
| 	return &(rename_dst[first]); | ||||
| } | ||||
|  |  | |||
|  | @ -55,7 +55,7 @@ struct diff_filespec { | |||
| extern struct diff_filespec *alloc_filespec(const char *); | ||||
| extern void free_filespec(struct diff_filespec *); | ||||
| extern void fill_filespec(struct diff_filespec *, const unsigned char *, | ||||
| 			  unsigned short); | ||||
| 			  int, unsigned short); | ||||
|  | ||||
| extern int diff_populate_filespec(struct diff_filespec *, int); | ||||
| extern void diff_free_filespec_data(struct diff_filespec *); | ||||
|  |  | |||
							
								
								
									
										8
									
								
								fsck.c
								
								
								
								
							
							
						
						
									
										8
									
								
								fsck.c
								
								
								
								
							|  | @ -139,6 +139,7 @@ static int verify_ordered(unsigned mode1, const char *name1, unsigned mode2, con | |||
| static int fsck_tree(struct tree *item, int strict, fsck_error error_func) | ||||
| { | ||||
| 	int retval; | ||||
| 	int has_null_sha1 = 0; | ||||
| 	int has_full_path = 0; | ||||
| 	int has_empty_name = 0; | ||||
| 	int has_zero_pad = 0; | ||||
|  | @ -157,9 +158,12 @@ static int fsck_tree(struct tree *item, int strict, fsck_error error_func) | |||
| 	while (desc.size) { | ||||
| 		unsigned mode; | ||||
| 		const char *name; | ||||
| 		const unsigned char *sha1; | ||||
|  | ||||
| 		tree_entry_extract(&desc, &name, &mode); | ||||
| 		sha1 = tree_entry_extract(&desc, &name, &mode); | ||||
|  | ||||
| 		if (is_null_sha1(sha1)) | ||||
| 			has_null_sha1 = 1; | ||||
| 		if (strchr(name, '/')) | ||||
| 			has_full_path = 1; | ||||
| 		if (!*name) | ||||
|  | @ -207,6 +211,8 @@ static int fsck_tree(struct tree *item, int strict, fsck_error error_func) | |||
| 	} | ||||
|  | ||||
| 	retval = 0; | ||||
| 	if (has_null_sha1) | ||||
| 		retval += error_func(&item->object, FSCK_WARN, "contains entries pointing to null sha1"); | ||||
| 	if (has_full_path) | ||||
| 		retval += error_func(&item->object, FSCK_WARN, "contains full pathnames"); | ||||
| 	if (has_empty_name) | ||||
|  |  | |||
|  | @ -569,11 +569,10 @@ do_next () { | |||
| 	test -s "$todo" && return | ||||
|  | ||||
| 	comment_for_reflog finish && | ||||
| 	shortonto=$(git rev-parse --short $onto) && | ||||
| 	newhead=$(git rev-parse HEAD) && | ||||
| 	case $head_name in | ||||
| 	refs/*) | ||||
| 		message="$GIT_REFLOG_ACTION: $head_name onto $shortonto" && | ||||
| 		message="$GIT_REFLOG_ACTION: $head_name onto $onto" && | ||||
| 		git update-ref -m "$message" $head_name $newhead $orig_head && | ||||
| 		git symbolic-ref \ | ||||
| 		  -m "$GIT_REFLOG_ACTION: returning to $head_name" \ | ||||
|  |  | |||
|  | @ -862,11 +862,13 @@ $time = time - scalar $#files; | |||
| sub unquote_rfc2047 { | ||||
| 	local ($_) = @_; | ||||
| 	my $encoding; | ||||
| 	if (s/=\?([^?]+)\?q\?(.*)\?=/$2/g) { | ||||
| 	s{=\?([^?]+)\?q\?(.*?)\?=}{ | ||||
| 		$encoding = $1; | ||||
| 		s/_/ /g; | ||||
| 		s/=([0-9A-F]{2})/chr(hex($1))/eg; | ||||
| 	} | ||||
| 		my $e = $2; | ||||
| 		$e =~ s/_/ /g; | ||||
| 		$e =~ s/=([0-9A-F]{2})/chr(hex($1))/eg; | ||||
| 		$e; | ||||
| 	}eg; | ||||
| 	return wantarray ? ($_, $encoding) : $_; | ||||
| } | ||||
|  | ||||
|  |  | |||
|  | @ -9,8 +9,12 @@ | |||
| # you would cause "cd" to be taken to unexpected places.  If you | ||||
| # like CDPATH, define it for your interactive shell sessions without | ||||
| # exporting it. | ||||
| # But we protect ourselves from such a user mistake nevertheless. | ||||
| unset CDPATH | ||||
|  | ||||
| # Similarly for IFS | ||||
| unset IFS | ||||
|  | ||||
| git_broken_path_fix () { | ||||
| 	case ":$PATH:" in | ||||
| 	*:$1:*) : ok ;; | ||||
|  |  | |||
|  | @ -54,6 +54,11 @@ sub evaluate_uri { | |||
| 	# to build the base URL ourselves: | ||||
| 	our $path_info = decode_utf8($ENV{"PATH_INFO"}); | ||||
| 	if ($path_info) { | ||||
| 		# $path_info has already been URL-decoded by the web server, but | ||||
| 		# $my_url and $my_uri have not. URL-decode them so we can properly | ||||
| 		# strip $path_info. | ||||
| 		$my_url = unescape($my_url); | ||||
| 		$my_uri = unescape($my_uri); | ||||
| 		if ($my_url =~ s,\Q$path_info\E$,, && | ||||
| 		    $my_uri =~ s,\Q$path_info\E$,, && | ||||
| 		    defined $ENV{'SCRIPT_NAME'}) { | ||||
|  |  | |||
|  | @ -1800,6 +1800,8 @@ int write_index(struct index_state *istate, int newfd) | |||
| 			continue; | ||||
| 		if (!ce_uptodate(ce) && is_racy_timestamp(istate, ce)) | ||||
| 			ce_smudge_racily_clean_entry(ce); | ||||
| 		if (is_null_sha1(ce->sha1)) | ||||
| 			return error("cache entry has null sha1: %s", ce->name); | ||||
| 		if (ce_write_entry(&c, newfd, ce, previous_name) < 0) | ||||
| 			return -1; | ||||
| 	} | ||||
|  |  | |||
|  | @ -345,6 +345,7 @@ static int tree_difference = REV_TREE_SAME; | |||
| static void file_add_remove(struct diff_options *options, | ||||
| 		    int addremove, unsigned mode, | ||||
| 		    const unsigned char *sha1, | ||||
| 		    int sha1_valid, | ||||
| 		    const char *fullpath, unsigned dirty_submodule) | ||||
| { | ||||
| 	int diff = addremove == '+' ? REV_TREE_NEW : REV_TREE_OLD; | ||||
|  | @ -358,6 +359,7 @@ static void file_change(struct diff_options *options, | |||
| 		 unsigned old_mode, unsigned new_mode, | ||||
| 		 const unsigned char *old_sha1, | ||||
| 		 const unsigned char *new_sha1, | ||||
| 		 int old_sha1_valid, int new_sha1_valid, | ||||
| 		 const char *fullpath, | ||||
| 		 unsigned old_dirty_submodule, unsigned new_dirty_submodule) | ||||
| { | ||||
|  |  | |||
							
								
								
									
										8
									
								
								setup.c
								
								
								
								
							
							
						
						
									
										8
									
								
								setup.c
								
								
								
								
							|  | @ -79,7 +79,7 @@ static void NORETURN die_verify_filename(const char *prefix, | |||
| { | ||||
| 	if (!diagnose_misspelt_rev) | ||||
| 		die("%s: no such path in the working tree.\n" | ||||
| 		    "Use '-- <path>...' to specify paths that do not exist locally.", | ||||
| 		    "Use 'git <command> -- <path>...' to specify paths that do not exist locally.", | ||||
| 		    arg); | ||||
| 	/* | ||||
| 	 * Saying "'(icase)foo' does not exist in the index" when the | ||||
|  | @ -92,7 +92,8 @@ static void NORETURN die_verify_filename(const char *prefix, | |||
|  | ||||
| 	/* ... or fall back the most general message. */ | ||||
| 	die("ambiguous argument '%s': unknown revision or path not in the working tree.\n" | ||||
| 	    "Use '--' to separate paths from revisions", arg); | ||||
| 	    "Use '--' to separate paths from revisions, like this:\n" | ||||
| 	    "'git <command> [<revision>...] -- [<file>...]'", arg); | ||||
|  | ||||
| } | ||||
|  | ||||
|  | @ -141,7 +142,8 @@ void verify_non_filename(const char *prefix, const char *arg) | |||
| 	if (!check_filename(prefix, arg)) | ||||
| 		return; | ||||
| 	die("ambiguous argument '%s': both revision and filename\n" | ||||
| 	    "Use '--' to separate filenames from revisions", arg); | ||||
| 	    "Use '--' to separate paths from revisions, like this:\n" | ||||
| 	    "'git <command> [<revision>...] -- [<file>...]'", arg); | ||||
| } | ||||
|  | ||||
| /* | ||||
|  |  | |||
|  | @ -213,4 +213,30 @@ test_expect_success 'rev-list --verify-objects with bad sha1' ' | |||
| 	grep -q "error: sha1 mismatch 63ffffffffffffffffffffffffffffffffffffff" out | ||||
| ' | ||||
|  | ||||
| _bz='\0' | ||||
| _bz5="$_bz$_bz$_bz$_bz$_bz" | ||||
| _bz20="$_bz5$_bz5$_bz5$_bz5" | ||||
|  | ||||
| test_expect_success 'fsck notices blob entry pointing to null sha1' ' | ||||
| 	(git init null-blob && | ||||
| 	 cd null-blob && | ||||
| 	 sha=$(printf "100644 file$_bz$_bz20" | | ||||
| 	       git hash-object -w --stdin -t tree) && | ||||
| 	  git fsck 2>out && | ||||
| 	  cat out && | ||||
| 	  grep "warning.*null sha1" out | ||||
| 	) | ||||
| ' | ||||
|  | ||||
| test_expect_success 'fsck notices submodule entry pointing to null sha1' ' | ||||
| 	(git init null-commit && | ||||
| 	 cd null-commit && | ||||
| 	 sha=$(printf "160000 submodule$_bz$_bz20" | | ||||
| 	       git hash-object -w --stdin -t tree) && | ||||
| 	  git fsck 2>out && | ||||
| 	  cat out && | ||||
| 	  grep "warning.*null sha1" out | ||||
| 	) | ||||
| ' | ||||
|  | ||||
| test_done | ||||
|  |  | |||
|  | @ -29,4 +29,23 @@ test_expect_success 'update-index -h with corrupt index' ' | |||
| 	grep "[Uu]sage: git update-index" broken/usage | ||||
| ' | ||||
|  | ||||
| test_expect_success '--cacheinfo does not accept blob null sha1' ' | ||||
| 	echo content >file && | ||||
| 	git add file && | ||||
| 	git rev-parse :file >expect && | ||||
| 	test_must_fail git update-index --cacheinfo 100644 $_z40 file && | ||||
| 	git rev-parse :file >actual && | ||||
| 	test_cmp expect actual | ||||
| ' | ||||
|  | ||||
| test_expect_success '--cacheinfo does not accept gitlink null sha1' ' | ||||
| 	git init submodule && | ||||
| 	(cd submodule && test_commit foo) && | ||||
| 	git add submodule && | ||||
| 	git rev-parse :submodule >expect && | ||||
| 	test_must_fail git update-index --cacheinfo 160000 $_z40 submodule && | ||||
| 	git rev-parse :submodule >actual && | ||||
| 	test_cmp expect actual | ||||
| ' | ||||
|  | ||||
| test_done | ||||
|  |  | |||
|  | @ -0,0 +1,83 @@ | |||
| #!/bin/sh | ||||
|  | ||||
| test_description='test diff with a bogus tree containing the null sha1' | ||||
| . ./test-lib.sh | ||||
|  | ||||
| empty_tree=4b825dc642cb6eb9a060e54bf8d69288fbee4904 | ||||
|  | ||||
| test_expect_success 'create bogus tree' ' | ||||
| 	bogus_tree=$( | ||||
| 		printf "100644 fooQQQQQQQQQQQQQQQQQQQQQ" | | ||||
| 		q_to_nul | | ||||
| 		git hash-object -w --stdin -t tree | ||||
| 	) | ||||
| ' | ||||
|  | ||||
| test_expect_success 'create tree with matching file' ' | ||||
| 	echo bar >foo && | ||||
| 	git add foo && | ||||
| 	good_tree=$(git write-tree) | ||||
| 	blob=$(git rev-parse :foo) | ||||
| ' | ||||
|  | ||||
| test_expect_success 'raw diff shows null sha1 (addition)' ' | ||||
| 	echo ":000000 100644 $_z40 $_z40 A	foo" >expect && | ||||
| 	git diff-tree $empty_tree $bogus_tree >actual && | ||||
| 	test_cmp expect actual | ||||
| ' | ||||
|  | ||||
| test_expect_success 'raw diff shows null sha1 (removal)' ' | ||||
| 	echo ":100644 000000 $_z40 $_z40 D	foo" >expect && | ||||
| 	git diff-tree $bogus_tree $empty_tree >actual && | ||||
| 	test_cmp expect actual | ||||
| ' | ||||
|  | ||||
| test_expect_success 'raw diff shows null sha1 (modification)' ' | ||||
| 	echo ":100644 100644 $blob $_z40 M	foo" >expect && | ||||
| 	git diff-tree $good_tree $bogus_tree >actual && | ||||
| 	test_cmp expect actual | ||||
| ' | ||||
|  | ||||
| test_expect_success 'raw diff shows null sha1 (other direction)' ' | ||||
| 	echo ":100644 100644 $_z40 $blob M	foo" >expect && | ||||
| 	git diff-tree $bogus_tree $good_tree >actual && | ||||
| 	test_cmp expect actual | ||||
| ' | ||||
|  | ||||
| test_expect_success 'raw diff shows null sha1 (reverse)' ' | ||||
| 	echo ":100644 100644 $_z40 $blob M	foo" >expect && | ||||
| 	git diff-tree -R $good_tree $bogus_tree >actual && | ||||
| 	test_cmp expect actual | ||||
| ' | ||||
|  | ||||
| test_expect_success 'raw diff shows null sha1 (index)' ' | ||||
| 	echo ":100644 100644 $_z40 $blob M	foo" >expect && | ||||
| 	git diff-index $bogus_tree >actual && | ||||
| 	test_cmp expect actual | ||||
| ' | ||||
|  | ||||
| test_expect_success 'patch fails due to bogus sha1 (addition)' ' | ||||
| 	test_must_fail git diff-tree -p $empty_tree $bogus_tree | ||||
| ' | ||||
|  | ||||
| test_expect_success 'patch fails due to bogus sha1 (removal)' ' | ||||
| 	test_must_fail git diff-tree -p $bogus_tree $empty_tree | ||||
| ' | ||||
|  | ||||
| test_expect_success 'patch fails due to bogus sha1 (modification)' ' | ||||
| 	test_must_fail git diff-tree -p $good_tree $bogus_tree | ||||
| ' | ||||
|  | ||||
| test_expect_success 'patch fails due to bogus sha1 (other direction)' ' | ||||
| 	test_must_fail git diff-tree -p $bogus_tree $good_tree | ||||
| ' | ||||
|  | ||||
| test_expect_success 'patch fails due to bogus sha1 (reverse)' ' | ||||
| 	test_must_fail git diff-tree -R -p $good_tree $bogus_tree | ||||
| ' | ||||
|  | ||||
| test_expect_success 'patch fails due to bogus sha1 (index)' ' | ||||
| 	test_must_fail git diff-index -p $bogus_tree | ||||
| ' | ||||
|  | ||||
| test_done | ||||
|  | @ -145,6 +145,41 @@ test_expect_success 'push --all excludes remote-tracking hierarchy' ' | |||
| 	) | ||||
| ' | ||||
|  | ||||
| test_expect_success 'receive-pack runs auto-gc in remote repo' ' | ||||
| 	rm -rf parent child && | ||||
| 	git init parent && | ||||
| 	( | ||||
| 	    # Setup a repo with 2 packs | ||||
| 	    cd parent && | ||||
| 	    echo "Some text" >file.txt && | ||||
| 	    git add . && | ||||
| 	    git commit -m "Initial commit" && | ||||
| 	    git repack -adl && | ||||
| 	    echo "Some more text" >>file.txt && | ||||
| 	    git commit -a -m "Second commit" && | ||||
| 	    git repack | ||||
| 	) && | ||||
| 	cp -a parent child && | ||||
| 	( | ||||
| 	    # Set the child to auto-pack if more than one pack exists | ||||
| 	    cd child && | ||||
| 	    git config gc.autopacklimit 1 && | ||||
| 	    git branch test_auto_gc && | ||||
| 	    # And create a file that follows the temporary object naming | ||||
| 	    # convention for the auto-gc to remove | ||||
| 	    : >.git/objects/tmp_test_object && | ||||
| 	    test-chmtime =-1209601 .git/objects/tmp_test_object | ||||
| 	) && | ||||
| 	( | ||||
| 	    cd parent && | ||||
| 	    echo "Even more text" >>file.txt && | ||||
| 	    git commit -a -m "Third commit" && | ||||
| 	    git send-pack ../child HEAD:refs/heads/test_auto_gc >output 2>&1 && | ||||
| 	    grep "Auto packing the repository for optimum performance." output | ||||
| 	) && | ||||
| 	test ! -e child/.git/objects/tmp_test_object | ||||
| ' | ||||
|  | ||||
| rewound_push_setup() { | ||||
| 	rm -rf parent child && | ||||
| 	mkdir parent && | ||||
|  |  | |||
|  | @ -841,6 +841,19 @@ test_expect_success $PREREQ '--compose adds MIME for utf8 subject' ' | |||
| 	grep "^Subject: =?UTF-8?q?utf8-s=C3=BCbj=C3=ABct?=" msgtxt1 | ||||
| ' | ||||
|  | ||||
| test_expect_success $PREREQ 'utf8 author is correctly passed on' ' | ||||
| 	clean_fake_sendmail && | ||||
| 	test_commit weird_author && | ||||
| 	test_when_finished "git reset --hard HEAD^" && | ||||
| 	git commit --amend --author "Füñný Nâmé <odd_?=mail@example.com>" && | ||||
| 	git format-patch --stdout -1 >funny_name.patch && | ||||
| 	git send-email --from="Example <nobody@example.com>" \ | ||||
| 	  --to=nobody@example.com \ | ||||
| 	  --smtp-server="$(pwd)/fake.sendmail" \ | ||||
| 	  funny_name.patch && | ||||
| 	grep "^From: Füñný Nâmé <odd_?=mail@example.com>" msgtxt1 | ||||
| ' | ||||
|  | ||||
| test_expect_success $PREREQ 'detects ambiguous reference/file conflict' ' | ||||
| 	echo master > master && | ||||
| 	git add master && | ||||
|  |  | |||
|  | @ -49,12 +49,12 @@ static int compare_tree_entry(struct tree_desc *t1, struct tree_desc *t2, | |||
| 	if (DIFF_OPT_TST(opt, RECURSIVE) && S_ISDIR(mode1)) { | ||||
| 		if (DIFF_OPT_TST(opt, TREE_IN_RECURSIVE)) { | ||||
| 			opt->change(opt, mode1, mode2, | ||||
| 				    sha1, sha2, base->buf, 0, 0); | ||||
| 				    sha1, sha2, 1, 1, base->buf, 0, 0); | ||||
| 		} | ||||
| 		strbuf_addch(base, '/'); | ||||
| 		diff_tree_sha1(sha1, sha2, base->buf, opt); | ||||
| 	} else { | ||||
| 		opt->change(opt, mode1, mode2, sha1, sha2, base->buf, 0, 0); | ||||
| 		opt->change(opt, mode1, mode2, sha1, sha2, 1, 1, base->buf, 0, 0); | ||||
| 	} | ||||
| 	strbuf_setlen(base, old_baselen); | ||||
| 	return 0; | ||||
|  | @ -100,7 +100,7 @@ static void show_entry(struct diff_options *opt, const char *prefix, | |||
| 			die("corrupt tree sha %s", sha1_to_hex(sha1)); | ||||
|  | ||||
| 		if (DIFF_OPT_TST(opt, TREE_IN_RECURSIVE)) | ||||
| 			opt->add_remove(opt, *prefix, mode, sha1, base->buf, 0); | ||||
| 			opt->add_remove(opt, *prefix, mode, sha1, 1, base->buf, 0); | ||||
|  | ||||
| 		strbuf_addch(base, '/'); | ||||
|  | ||||
|  | @ -108,7 +108,7 @@ static void show_entry(struct diff_options *opt, const char *prefix, | |||
| 		show_tree(opt, prefix, &inner, base); | ||||
| 		free(tree); | ||||
| 	} else | ||||
| 		opt->add_remove(opt, prefix[0], mode, sha1, base->buf, 0); | ||||
| 		opt->add_remove(opt, prefix[0], mode, sha1, 1, base->buf, 0); | ||||
|  | ||||
| 	strbuf_setlen(base, old_baselen); | ||||
| } | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 Junio C Hamano
						Junio C Hamano