parse_date(): '@' prefix forces git-timestamp
The only place that the issue this series addresses was observed where we read "cat-file commit" output and put it in GIT_AUTHOR_DATE in order to replay a commit with an ancient timestamp. With the previous patch alone, "git commit --date='20100917 +0900'" can be misinterpreted to mean an ancient timestamp, not September in year 2010. Guard this codepath by requring an extra '@' in front of the raw git timestamp on the parsing side. This of course needs to be compensated by updating get_author_ident_from_commit and the code for "git commit --amend" to prepend '@' to the string read from the existing commit in the GIT_AUTHOR_DATE environment variable. Signed-off-by: Junio C Hamano <gitster@pobox.com>maint
							parent
							
								
									116eb3abfe
								
							
						
					
					
						commit
						2c733fb24c
					
				|  | @ -534,6 +534,7 @@ static void determine_author_info(struct strbuf *author_ident) | |||
|  | ||||
| 	if (author_message) { | ||||
| 		const char *a, *lb, *rb, *eol; | ||||
| 		size_t len; | ||||
|  | ||||
| 		a = strstr(author_message_buffer, "\nauthor "); | ||||
| 		if (!a) | ||||
|  | @ -554,6 +555,11 @@ static void determine_author_info(struct strbuf *author_ident) | |||
| 					 (a + strlen("\nauthor ")))); | ||||
| 		email = xmemdupz(lb + strlen("<"), rb - (lb + strlen("<"))); | ||||
| 		date = xmemdupz(rb + strlen("> "), eol - (rb + strlen("> "))); | ||||
| 		len = eol - (rb + strlen("> ")); | ||||
| 		date = xmalloc(len + 2); | ||||
| 		*date = '@'; | ||||
| 		memcpy(date + 1, rb + strlen("> "), len); | ||||
| 		date[len + 1] = '\0'; | ||||
| 	} | ||||
|  | ||||
| 	if (force_author) { | ||||
|  |  | |||
							
								
								
									
										3
									
								
								date.c
								
								
								
								
							
							
						
						
									
										3
									
								
								date.c
								
								
								
								
							|  | @ -637,7 +637,8 @@ int parse_date_basic(const char *date, unsigned long *timestamp, int *offset) | |||
| 	*offset = -1; | ||||
| 	tm_gmt = 0; | ||||
|  | ||||
| 	if (!match_object_header_date(date, timestamp, offset)) | ||||
| 	if (*date == '@' && | ||||
| 	    !match_object_header_date(date + 1, timestamp, offset)) | ||||
| 		return 0; /* success */ | ||||
| 	for (;;) { | ||||
| 		int match = 0; | ||||
|  |  | |||
|  | @ -200,7 +200,7 @@ get_author_ident_from_commit () { | |||
| 		s/.*/GIT_AUTHOR_EMAIL='\''&'\''/p | ||||
|  | ||||
| 		g | ||||
| 		s/^author [^<]* <[^>]*> \(.*\)$/\1/ | ||||
| 		s/^author [^<]* <[^>]*> \(.*\)$/@\1/ | ||||
| 		s/.*/GIT_AUTHOR_DATE='\''&'\''/p | ||||
|  | ||||
| 		q | ||||
|  |  | |||
|  | @ -218,4 +218,27 @@ test_expect_success 'rebase -m can copy notes' ' | |||
| 	test "a note" = "$(git notes show HEAD)" | ||||
| ' | ||||
|  | ||||
| test_expect_success 'rebase commit with an ancient timestamp' ' | ||||
| 	git reset --hard && | ||||
|  | ||||
| 	>old.one && git add old.one && test_tick && | ||||
| 	git commit --date="@12345 +0400" -m "Old one" && | ||||
| 	>old.two && git add old.two && test_tick && | ||||
| 	git commit --date="@23456 +0500" -m "Old two" && | ||||
| 	>old.three && git add old.three && test_tick && | ||||
| 	git commit --date="@34567 +0600" -m "Old three" && | ||||
|  | ||||
| 	git cat-file commit HEAD^^ >actual && | ||||
| 	grep "author .* 12345 +0400$" actual && | ||||
| 	git cat-file commit HEAD^ >actual && | ||||
| 	grep "author .* 23456 +0500$" actual && | ||||
| 	git cat-file commit HEAD >actual && | ||||
| 	grep "author .* 34567 +0600$" actual && | ||||
|  | ||||
| 	git rebase --onto HEAD^^ HEAD^ && | ||||
|  | ||||
| 	git cat-file commit HEAD >actual && | ||||
| 	grep "author .* 34567 +0600$" actual | ||||
| ' | ||||
|  | ||||
| test_done | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 Junio C Hamano
						Junio C Hamano