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

[PATCH] archive: add --mtime

From
René Scharfe <l.s.r@web.de>
Date
Feb 18, 2023, 08:36 UTC
Message-ID
<91a73f5d-ca3e-6cb0-4ba3-38d703074ee6@web.de>
In-Reply-To
<Y+6G9n6cWRT9EKyl@google.com>

Allow users to specify the modification time of archive entries. The new option --mtime uses approxidate() to parse a time specification and overrides the default of using the current time for trees and the commit time for tags and commits. It can be used to create a reproducible archive for a tree, or to use a specific mtime without creating a commit with GIT_COMMITTER_DATE set.

This implementation doesn't support the negated form of the new option, i.e. --no-mtime is not accepted. It is not possible to have no mtime at all. We could use the Unix epoch or revert to the default behavior, but since negation is not necessary for the intended use it's left undecided for now.

Requested-by: Raul E Rangel <rrangel@chromium.org>
Suggested-by: demerphq <demerphq@gmail.com>
Signed-off-by: René Scharfe <l.s.r@web.de>
---
 Documentation/git-archive.txt |  5 +++++
 archive.c                     |  7 +++++++
 archive.h                     |  1 +
 t/t5000-tar-tree.sh           | 19 +++++++++++++++++++
 4 files changed, 32 insertions(+)
diff --git a/Documentation/git-archive.txt b/Documentation/git-archive.txt
index 60c040988b..6bab201d37 100644
--- a/Documentation/git-archive.txt
+++ b/Documentation/git-archive.txt
@@ -86,6 +86,11 @@ cases, write an untracked file and use `--add-file` instead.
 	Look for attributes in .gitattributes files in the working tree
 	as well (see <<ATTRIBUTES>>).

+--mtime=<time>::
+	Set modification time of archive entries.  Without this option
+	the committer time is used if `<tree-ish>` is a commit or tag,
+	and the current time if it is a tree.
+
 <extra>::
 	This can be any options that the archiver backend understands.
 	See next section.
diff --git a/archive.c b/archive.c
index 81ff76fce9..122860b39d 100644
--- a/archive.c
+++ b/archive.c
@@ -472,6 +472,8 @@ static void parse_treeish_arg(const char **argv,
 		commit_oid = NULL;
 		archive_time = time(NULL);
 	}
+	if (ar_args->mtime_option)
+		archive_time = approxidate(ar_args->mtime_option);

 	tree = parse_tree_indirect(&oid);
 	if (!tree)
@@ -586,6 +588,7 @@ static int parse_archive_args(int argc, const char **argv,
 	const char *remote = NULL;
 	const char *exec = NULL;
 	const char *output = NULL;
+	const char *mtime_option = NULL;
 	int compression_level = -1;
 	int verbose = 0;
 	int i;
@@ -607,6 +610,9 @@ static int parse_archive_args(int argc, const char **argv,
 		OPT_BOOL(0, "worktree-attributes", &worktree_attributes,
 			N_("read .gitattributes in working directory")),
 		OPT__VERBOSE(&verbose, N_("report archived files on stderr")),
+		{ OPTION_STRING, 0, "mtime", &mtime_option, N_("time"),
+		  N_("set modification time of archive entries"),
+		  PARSE_OPT_NONEG },
 		OPT_NUMBER_CALLBACK(&compression_level,
 			N_("set compression level"), number_callback),
 		OPT_GROUP(""),
@@ -668,6 +674,7 @@ static int parse_archive_args(int argc, const char **argv,
 	args->base = base;
 	args->baselen = strlen(base);
 	args->worktree_attributes = worktree_attributes;
+	args->mtime_option = mtime_option;

 	return argc;
 }
diff --git a/archive.h b/archive.h
index 08bed3ed3a..7178e2a9a2 100644
--- a/archive.h
+++ b/archive.h
@@ -16,6 +16,7 @@ struct archiver_args {
 	struct tree *tree;
 	const struct object_id *commit_oid;
 	const struct commit *commit;
+	const char *mtime_option;
 	timestamp_t time;
 	struct pathspec pathspec;
 	unsigned int verbose : 1;
diff --git a/t/t5000-tar-tree.sh b/t/t5000-tar-tree.sh
index eb3214bc17..918a2fc7c6 100755
--- a/t/t5000-tar-tree.sh
+++ b/t/t5000-tar-tree.sh
@@ -105,6 +105,18 @@ check_added() {
 	'
 }

+check_mtime() {
+	dir=$1
+	path_in_archive=$2
+	mtime=$3
+
+	test_expect_success " validate mtime of $path_in_archive" '
+		test-tool chmtime --get $dir/$path_in_archive >actual.mtime &&
+		echo $mtime >expect.mtime &&
+		test_cmp expect.mtime actual.mtime
+	'
+}
+
 test_expect_success 'setup' '
 	test_oid_cache <<-EOF
 	obj sha1:19f9c8273ec45a8938e6999cb59b3ff66739902a
@@ -174,6 +186,13 @@ test_expect_success 'git archive' '

 check_tar b

+test_expect_success 'git archive --mtime' '
+	git archive --mtime=2002-02-02T02:02:02-0200 HEAD >with_mtime.tar
+'
+
+check_tar with_mtime
+check_mtime with_mtime a/a 1012622522
+
 test_expect_success 'git archive --prefix=prefix/' '
 	git archive --prefix=prefix/ HEAD >with_prefix.tar
 '
--
2.39.2
Previous: brian m. carlsonNext: Junio C Hamano
Message 11 of 16 in “Feature request: Add --mtime option to git archive”
  1. Raul E RangelFeb 16, 2023
  2. Jeff KingFeb 16, 2023
  3. Junio C HamanoFeb 16, 2023
  4. Jeff KingFeb 17, 2023
  5. Junio C HamanoFeb 17, 2023
  6. Raul RangelFeb 17, 2023
  7. René ScharfeFeb 17, 2023
  8. Jeff KingFeb 17, 2023
  9. demerphqFeb 18, 2023
  10. brian m. carlsonFeb 18, 2023
  11. archive: add --mtimeRené Scharfe, Feb 18, 2023
  12. Junio C HamanoFeb 18, 2023
  13. René ScharfeFeb 19, 2023
  14. Junio C HamanoFeb 21, 2023
  15. Jeff KingFeb 22, 2023
  16. Junio C HamanoFeb 22, 2023

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.