archive: add --mtime
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> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
d9d677b2d8
commit
fd2da4b1ea
@ -86,6 +86,11 @@ cases, write an untracked file and use `--add-file` instead.
|
|||||||
Look for attributes in .gitattributes files in the working tree
|
Look for attributes in .gitattributes files in the working tree
|
||||||
as well (see <<ATTRIBUTES>>).
|
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>::
|
<extra>::
|
||||||
This can be any options that the archiver backend understands.
|
This can be any options that the archiver backend understands.
|
||||||
See next section.
|
See next section.
|
||||||
|
@ -472,6 +472,8 @@ static void parse_treeish_arg(const char **argv,
|
|||||||
commit_oid = NULL;
|
commit_oid = NULL;
|
||||||
archive_time = time(NULL);
|
archive_time = time(NULL);
|
||||||
}
|
}
|
||||||
|
if (ar_args->mtime_option)
|
||||||
|
archive_time = approxidate(ar_args->mtime_option);
|
||||||
|
|
||||||
tree = parse_tree_indirect(&oid);
|
tree = parse_tree_indirect(&oid);
|
||||||
if (!tree)
|
if (!tree)
|
||||||
@ -586,6 +588,7 @@ static int parse_archive_args(int argc, const char **argv,
|
|||||||
const char *remote = NULL;
|
const char *remote = NULL;
|
||||||
const char *exec = NULL;
|
const char *exec = NULL;
|
||||||
const char *output = NULL;
|
const char *output = NULL;
|
||||||
|
const char *mtime_option = NULL;
|
||||||
int compression_level = -1;
|
int compression_level = -1;
|
||||||
int verbose = 0;
|
int verbose = 0;
|
||||||
int i;
|
int i;
|
||||||
@ -607,6 +610,9 @@ static int parse_archive_args(int argc, const char **argv,
|
|||||||
OPT_BOOL(0, "worktree-attributes", &worktree_attributes,
|
OPT_BOOL(0, "worktree-attributes", &worktree_attributes,
|
||||||
N_("read .gitattributes in working directory")),
|
N_("read .gitattributes in working directory")),
|
||||||
OPT__VERBOSE(&verbose, N_("report archived files on stderr")),
|
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,
|
OPT_NUMBER_CALLBACK(&compression_level,
|
||||||
N_("set compression level"), number_callback),
|
N_("set compression level"), number_callback),
|
||||||
OPT_GROUP(""),
|
OPT_GROUP(""),
|
||||||
@ -668,6 +674,7 @@ static int parse_archive_args(int argc, const char **argv,
|
|||||||
args->base = base;
|
args->base = base;
|
||||||
args->baselen = strlen(base);
|
args->baselen = strlen(base);
|
||||||
args->worktree_attributes = worktree_attributes;
|
args->worktree_attributes = worktree_attributes;
|
||||||
|
args->mtime_option = mtime_option;
|
||||||
|
|
||||||
return argc;
|
return argc;
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@ struct archiver_args {
|
|||||||
struct tree *tree;
|
struct tree *tree;
|
||||||
const struct object_id *commit_oid;
|
const struct object_id *commit_oid;
|
||||||
const struct commit *commit;
|
const struct commit *commit;
|
||||||
|
const char *mtime_option;
|
||||||
timestamp_t time;
|
timestamp_t time;
|
||||||
struct pathspec pathspec;
|
struct pathspec pathspec;
|
||||||
unsigned int verbose : 1;
|
unsigned int verbose : 1;
|
||||||
|
@ -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_expect_success 'setup' '
|
||||||
test_oid_cache <<-EOF
|
test_oid_cache <<-EOF
|
||||||
obj sha1:19f9c8273ec45a8938e6999cb59b3ff66739902a
|
obj sha1:19f9c8273ec45a8938e6999cb59b3ff66739902a
|
||||||
@ -174,6 +186,13 @@ test_expect_success 'git archive' '
|
|||||||
|
|
||||||
check_tar b
|
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/' '
|
test_expect_success 'git archive --prefix=prefix/' '
|
||||||
git archive --prefix=prefix/ HEAD >with_prefix.tar
|
git archive --prefix=prefix/ HEAD >with_prefix.tar
|
||||||
'
|
'
|
||||||
|
Loading…
Reference in New Issue
Block a user