Skip to content

Commit 5e572aa

Browse files
committed
Merge branch 'rs/archive-mtime'
"git archive HEAD^{tree}" records the paths with the current timestamp in the archive, making it harder to obtain a stable output. The command learned the --mtime option to specify an arbitrary timestamp (e.g. --mtime="@0 +0000" for the epoch). * rs/archive-mtime: archive: add --mtime
2 parents b8840a7 + fd2da4b commit 5e572aa

File tree

4 files changed

+32
-0
lines changed

4 files changed

+32
-0
lines changed

Documentation/git-archive.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,11 @@ cases, write an untracked file and use `--add-file` instead.
8686
Look for attributes in .gitattributes files in the working tree
8787
as well (see <<ATTRIBUTES>>).
8888

89+
--mtime=<time>::
90+
Set modification time of archive entries. Without this option
91+
the committer time is used if `<tree-ish>` is a commit or tag,
92+
and the current time if it is a tree.
93+
8994
<extra>::
9095
This can be any options that the archiver backend understands.
9196
See next section.

archive.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -472,6 +472,8 @@ static void parse_treeish_arg(const char **argv,
472472
commit_oid = NULL;
473473
archive_time = time(NULL);
474474
}
475+
if (ar_args->mtime_option)
476+
archive_time = approxidate(ar_args->mtime_option);
475477

476478
tree = parse_tree_indirect(&oid);
477479
if (!tree)
@@ -586,6 +588,7 @@ static int parse_archive_args(int argc, const char **argv,
586588
const char *remote = NULL;
587589
const char *exec = NULL;
588590
const char *output = NULL;
591+
const char *mtime_option = NULL;
589592
int compression_level = -1;
590593
int verbose = 0;
591594
int i;
@@ -607,6 +610,9 @@ static int parse_archive_args(int argc, const char **argv,
607610
OPT_BOOL(0, "worktree-attributes", &worktree_attributes,
608611
N_("read .gitattributes in working directory")),
609612
OPT__VERBOSE(&verbose, N_("report archived files on stderr")),
613+
{ OPTION_STRING, 0, "mtime", &mtime_option, N_("time"),
614+
N_("set modification time of archive entries"),
615+
PARSE_OPT_NONEG },
610616
OPT_NUMBER_CALLBACK(&compression_level,
611617
N_("set compression level"), number_callback),
612618
OPT_GROUP(""),
@@ -668,6 +674,7 @@ static int parse_archive_args(int argc, const char **argv,
668674
args->base = base;
669675
args->baselen = strlen(base);
670676
args->worktree_attributes = worktree_attributes;
677+
args->mtime_option = mtime_option;
671678

672679
return argc;
673680
}

archive.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ struct archiver_args {
1616
struct tree *tree;
1717
const struct object_id *commit_oid;
1818
const struct commit *commit;
19+
const char *mtime_option;
1920
timestamp_t time;
2021
struct pathspec pathspec;
2122
unsigned int verbose : 1;

t/t5000-tar-tree.sh

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,18 @@ check_added() {
105105
'
106106
}
107107

108+
check_mtime() {
109+
dir=$1
110+
path_in_archive=$2
111+
mtime=$3
112+
113+
test_expect_success " validate mtime of $path_in_archive" '
114+
test-tool chmtime --get $dir/$path_in_archive >actual.mtime &&
115+
echo $mtime >expect.mtime &&
116+
test_cmp expect.mtime actual.mtime
117+
'
118+
}
119+
108120
test_expect_success 'setup' '
109121
test_oid_cache <<-EOF
110122
obj sha1:19f9c8273ec45a8938e6999cb59b3ff66739902a
@@ -174,6 +186,13 @@ test_expect_success 'git archive' '
174186

175187
check_tar b
176188

189+
test_expect_success 'git archive --mtime' '
190+
git archive --mtime=2002-02-02T02:02:02-0200 HEAD >with_mtime.tar
191+
'
192+
193+
check_tar with_mtime
194+
check_mtime with_mtime a/a 1012622522
195+
177196
test_expect_success 'git archive --prefix=prefix/' '
178197
git archive --prefix=prefix/ HEAD >with_prefix.tar
179198
'

0 commit comments

Comments
 (0)