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
This commit is contained in:
Junio C Hamano 2023-02-27 10:08:57 -08:00
commit 5e572aaa5d
4 changed files with 32 additions and 0 deletions

View File

@ -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.

View File

@ -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;
}

View File

@ -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;

View File

@ -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
'