git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[RFC/PATCH 2/2] parse_date(): '@' prefix forces git-timestamp

From
Junio C Hamano <gitster@pobox.com>
Date
Feb 2, 2012, 21:41 UTC
Message-ID
<1328218903-5681-3-git-send-email-gitster@pobox.com>
In-Reply-To
<1328218903-5681-1-git-send-email-gitster@pobox.com>

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>
---
 builtin/commit.c  |    6 ++++++
 date.c            |    3 ++-
 git-sh-setup.sh   |    2 +-
 t/t3400-rebase.sh |   23 +++++++++++++++++++++++
 4 files changed, 32 insertions(+), 2 deletions(-)
diff --git a/builtin/commit.c b/builtin/commit.c
index cbc9613..bcb0db2 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -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) {
diff --git a/date.c b/date.c
index c212946..ca60767 100644
--- a/date.c
+++ b/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;
diff --git a/git-sh-setup.sh b/git-sh-setup.sh
index 8e427da..015fe6e 100644
--- a/git-sh-setup.sh
+++ b/git-sh-setup.sh
@@ -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
diff --git a/t/t3400-rebase.sh b/t/t3400-rebase.sh
index 6eaecec..e26e14d 100755
--- a/t/t3400-rebase.sh
+++ b/t/t3400-rebase.sh
@@ -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
-- 
1.7.9.172.ge26ae
Previous: Junio C HamanoNext: Thomas Rast
Message 3 of 6 in “Commits with ancient timestamps”
  1. 0/2 Commits with ancient timestampsJunio C Hamano, Feb 2, 2012
  2. 1/2 parse_date(): allow ancient git-timestampJunio C Hamano, Feb 2, 2012
  3. 2/2 parse_date(): '@' prefix forces git-timestampJunio C Hamano, Feb 2, 2012
  4. Thomas RastFeb 3, 2012
  5. Junio C HamanoFeb 3, 2012
  6. Han-Wen NienhuysFeb 3, 2012

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.