mirror of
https://github.com/git/git
synced 2024-11-05 18:59:29 +00:00
Files given on the command line are relative to $cwd
When running "git commit -F file" and "git tag -F file" from a subdirectory, we should take it as relative to the directory we started from, not relative to the top-level directory. This adds a helper function "parse_options_fix_filename()" to make it more convenient to fix this class of issues. Ideally, parse_options() should support a new type of option, "OPT_FILENAME", to do this uniformly, but this patch is meant to go to 'maint' to fix it minimally. One thing to note is that value for "commit template file" that comes from the command line is taken as relative to $cwd just like other parameters, but when it comes from the configuration varilable 'commit.template', it is taken as relative to the working tree root as before. I think this difference actually is sensible (not that I particularly think commit.template itself is sensible). Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
eabbc99a21
commit
dbd0f5c769
6 changed files with 72 additions and 5 deletions
|
@ -45,7 +45,7 @@ static enum {
|
||||||
COMMIT_PARTIAL,
|
COMMIT_PARTIAL,
|
||||||
} commit_style;
|
} commit_style;
|
||||||
|
|
||||||
static char *logfile, *force_author;
|
static const char *logfile, *force_author;
|
||||||
static const char *template_file;
|
static const char *template_file;
|
||||||
static char *edit_message, *use_message;
|
static char *edit_message, *use_message;
|
||||||
static char *author_name, *author_email, *author_date;
|
static char *author_name, *author_email, *author_date;
|
||||||
|
@ -700,11 +700,14 @@ static int message_is_empty(struct strbuf *sb, int start)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int parse_and_validate_options(int argc, const char *argv[],
|
static int parse_and_validate_options(int argc, const char *argv[],
|
||||||
const char * const usage[])
|
const char * const usage[],
|
||||||
|
const char *prefix)
|
||||||
{
|
{
|
||||||
int f = 0;
|
int f = 0;
|
||||||
|
|
||||||
argc = parse_options(argc, argv, builtin_commit_options, usage, 0);
|
argc = parse_options(argc, argv, builtin_commit_options, usage, 0);
|
||||||
|
logfile = parse_options_fix_filename(prefix, logfile);
|
||||||
|
template_file = parse_options_fix_filename(prefix, template_file);
|
||||||
|
|
||||||
if (logfile || message.len || use_message)
|
if (logfile || message.len || use_message)
|
||||||
use_editor = 0;
|
use_editor = 0;
|
||||||
|
@ -814,7 +817,7 @@ int cmd_status(int argc, const char **argv, const char *prefix)
|
||||||
if (wt_status_use_color == -1)
|
if (wt_status_use_color == -1)
|
||||||
wt_status_use_color = git_use_color_default;
|
wt_status_use_color = git_use_color_default;
|
||||||
|
|
||||||
argc = parse_and_validate_options(argc, argv, builtin_status_usage);
|
argc = parse_and_validate_options(argc, argv, builtin_status_usage, prefix);
|
||||||
|
|
||||||
index_file = prepare_index(argc, argv, prefix);
|
index_file = prepare_index(argc, argv, prefix);
|
||||||
|
|
||||||
|
@ -907,7 +910,7 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
|
||||||
|
|
||||||
git_config(git_commit_config, NULL);
|
git_config(git_commit_config, NULL);
|
||||||
|
|
||||||
argc = parse_and_validate_options(argc, argv, builtin_commit_usage);
|
argc = parse_and_validate_options(argc, argv, builtin_commit_usage, prefix);
|
||||||
|
|
||||||
index_file = prepare_index(argc, argv, prefix);
|
index_file = prepare_index(argc, argv, prefix);
|
||||||
|
|
||||||
|
|
|
@ -385,7 +385,7 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
|
||||||
|
|
||||||
int annotate = 0, sign = 0, force = 0, lines = 0,
|
int annotate = 0, sign = 0, force = 0, lines = 0,
|
||||||
list = 0, delete = 0, verify = 0;
|
list = 0, delete = 0, verify = 0;
|
||||||
char *msgfile = NULL, *keyid = NULL;
|
const char *msgfile = NULL, *keyid = NULL;
|
||||||
struct msg_arg msg = { 0, STRBUF_INIT };
|
struct msg_arg msg = { 0, STRBUF_INIT };
|
||||||
struct option options[] = {
|
struct option options[] = {
|
||||||
OPT_BOOLEAN('l', NULL, &list, "list tag names"),
|
OPT_BOOLEAN('l', NULL, &list, "list tag names"),
|
||||||
|
@ -411,6 +411,7 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
|
||||||
git_config(git_tag_config, NULL);
|
git_config(git_tag_config, NULL);
|
||||||
|
|
||||||
argc = parse_options(argc, argv, options, git_tag_usage, 0);
|
argc = parse_options(argc, argv, options, git_tag_usage, 0);
|
||||||
|
msgfile = parse_options_fix_filename(prefix, msgfile);
|
||||||
|
|
||||||
if (keyid) {
|
if (keyid) {
|
||||||
sign = 1;
|
sign = 1;
|
||||||
|
|
|
@ -425,3 +425,15 @@ int parse_opt_approxidate_cb(const struct option *opt, const char *arg,
|
||||||
*(unsigned long *)(opt->value) = approxidate(arg);
|
*(unsigned long *)(opt->value) = approxidate(arg);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This should really be OPTION_FILENAME type as a part of
|
||||||
|
* parse_options that take prefix to do this while parsing.
|
||||||
|
*/
|
||||||
|
extern const char *parse_options_fix_filename(const char *prefix, const char *file)
|
||||||
|
{
|
||||||
|
if (!file || !prefix || is_absolute_path(file) || !strcmp("-", file))
|
||||||
|
return file;
|
||||||
|
return prefix_filename(prefix, strlen(prefix), file);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -123,4 +123,6 @@ extern int parse_opt_approxidate_cb(const struct option *, const char *, int);
|
||||||
"use <n> digits to display SHA-1s", \
|
"use <n> digits to display SHA-1s", \
|
||||||
PARSE_OPT_OPTARG, &parse_opt_abbrev_cb, 0 }
|
PARSE_OPT_OPTARG, &parse_opt_abbrev_cb, 0 }
|
||||||
|
|
||||||
|
extern const char *parse_options_fix_filename(const char *prefix, const char *file);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1067,4 +1067,24 @@ test_expect_success \
|
||||||
test_cmp expect actual
|
test_cmp expect actual
|
||||||
'
|
'
|
||||||
|
|
||||||
|
test_expect_success 'filename for the message is relative to cwd' '
|
||||||
|
mkdir subdir &&
|
||||||
|
echo "Tag message in top directory" >msgfile-5 &&
|
||||||
|
echo "Tag message in sub directory" >subdir/msgfile-5 &&
|
||||||
|
(
|
||||||
|
cd subdir &&
|
||||||
|
git tag -a -F msgfile-5 tag-from-subdir
|
||||||
|
) &&
|
||||||
|
git cat-file tag tag-from-subdir | grep "in sub directory"
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'filename for the message is relative to cwd' '
|
||||||
|
echo "Tag message in sub directory" >subdir/msgfile-6 &&
|
||||||
|
(
|
||||||
|
cd subdir &&
|
||||||
|
git tag -a -F msgfile-6 tag-from-subdir-2
|
||||||
|
) &&
|
||||||
|
git cat-file tag tag-from-subdir-2 | grep "in sub directory"
|
||||||
|
'
|
||||||
|
|
||||||
test_done
|
test_done
|
||||||
|
|
|
@ -138,4 +138,33 @@ test_expect_success '--signoff' '
|
||||||
diff expect output
|
diff expect output
|
||||||
'
|
'
|
||||||
|
|
||||||
|
test_expect_success 'commit message from file (1)' '
|
||||||
|
mkdir subdir &&
|
||||||
|
echo "Log in top directory" >log &&
|
||||||
|
echo "Log in sub directory" >subdir/log &&
|
||||||
|
(
|
||||||
|
cd subdir &&
|
||||||
|
git commit --allow-empty -F log
|
||||||
|
) &&
|
||||||
|
commit_msg_is "Log in sub directory"
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'commit message from file (2)' '
|
||||||
|
rm -f log &&
|
||||||
|
echo "Log in sub directory" >subdir/log &&
|
||||||
|
(
|
||||||
|
cd subdir &&
|
||||||
|
git commit --allow-empty -F log
|
||||||
|
) &&
|
||||||
|
commit_msg_is "Log in sub directory"
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'commit message from stdin' '
|
||||||
|
(
|
||||||
|
cd subdir &&
|
||||||
|
echo "Log with foo word" | git commit --allow-empty -F -
|
||||||
|
) &&
|
||||||
|
commit_msg_is "Log with foo word"
|
||||||
|
'
|
||||||
|
|
||||||
test_done
|
test_done
|
||||||
|
|
Loading…
Reference in a new issue