зеркало из https://github.com/microsoft/git.git
Merge branch 'ab/reflog-parse-options'
"git reflog" command now uses parse-options API to parse its command line options. * ab/reflog-parse-options: reflog: fix 'show' subcommand's argv reflog [show]: display sensible -h output reflog: convert to parse_options() API reflog exists: use parse_options() API git reflog [expire|delete]: make -h output consistent with SYNOPSIS reflog: move "usage" variables and use macros reflog tests: add missing "git reflog exists" tests reflog: refactor cmd_reflog() to "if" branches reflog.c: indent argument lists
This commit is contained in:
Коммит
3ff8cbfe8a
146
builtin/reflog.c
146
builtin/reflog.c
|
@ -5,8 +5,48 @@
|
|||
#include "worktree.h"
|
||||
#include "reflog.h"
|
||||
|
||||
static const char reflog_exists_usage[] =
|
||||
N_("git reflog exists <ref>");
|
||||
#define BUILTIN_REFLOG_SHOW_USAGE \
|
||||
N_("git reflog [show] [<log-options>] [<ref>]")
|
||||
|
||||
#define BUILTIN_REFLOG_EXPIRE_USAGE \
|
||||
N_("git reflog expire [--expire=<time>] [--expire-unreachable=<time>]\n" \
|
||||
" [--rewrite] [--updateref] [--stale-fix]\n" \
|
||||
" [--dry-run | -n] [--verbose] [--all [--single-worktree] | <refs>...]")
|
||||
|
||||
#define BUILTIN_REFLOG_DELETE_USAGE \
|
||||
N_("git reflog delete [--rewrite] [--updateref]\n" \
|
||||
" [--dry-run | -n] [--verbose] <ref>@{<specifier>}...")
|
||||
|
||||
#define BUILTIN_REFLOG_EXISTS_USAGE \
|
||||
N_("git reflog exists <ref>")
|
||||
|
||||
static const char *const reflog_show_usage[] = {
|
||||
BUILTIN_REFLOG_SHOW_USAGE,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static const char *const reflog_expire_usage[] = {
|
||||
BUILTIN_REFLOG_EXPIRE_USAGE,
|
||||
NULL
|
||||
};
|
||||
|
||||
static const char *const reflog_delete_usage[] = {
|
||||
BUILTIN_REFLOG_DELETE_USAGE,
|
||||
NULL
|
||||
};
|
||||
|
||||
static const char *const reflog_exists_usage[] = {
|
||||
BUILTIN_REFLOG_EXISTS_USAGE,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static const char *const reflog_usage[] = {
|
||||
BUILTIN_REFLOG_SHOW_USAGE,
|
||||
BUILTIN_REFLOG_EXPIRE_USAGE,
|
||||
BUILTIN_REFLOG_DELETE_USAGE,
|
||||
BUILTIN_REFLOG_EXISTS_USAGE,
|
||||
NULL
|
||||
};
|
||||
|
||||
static timestamp_t default_reflog_expire;
|
||||
static timestamp_t default_reflog_expire_unreachable;
|
||||
|
@ -147,14 +187,6 @@ static void set_reflog_expiry_param(struct cmd_reflog_expire_cb *cb, const char
|
|||
cb->expire_unreachable = default_reflog_expire_unreachable;
|
||||
}
|
||||
|
||||
static const char * reflog_expire_usage[] = {
|
||||
N_("git reflog expire [--expire=<time>] "
|
||||
"[--expire-unreachable=<time>] "
|
||||
"[--rewrite] [--updateref] [--stale-fix] [--dry-run | -n] "
|
||||
"[--verbose] [--all] <refs>..."),
|
||||
NULL
|
||||
};
|
||||
|
||||
static int expire_unreachable_callback(const struct option *opt,
|
||||
const char *arg,
|
||||
int unset)
|
||||
|
@ -183,6 +215,19 @@ static int expire_total_callback(const struct option *opt,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int cmd_reflog_show(int argc, const char **argv, const char *prefix)
|
||||
{
|
||||
struct option options[] = {
|
||||
OPT_END()
|
||||
};
|
||||
|
||||
parse_options(argc, argv, prefix, options, reflog_show_usage,
|
||||
PARSE_OPT_KEEP_DASHDASH | PARSE_OPT_KEEP_ARGV0 |
|
||||
PARSE_OPT_KEEP_UNKNOWN);
|
||||
|
||||
return cmd_log_reflog(argc, argv, prefix);
|
||||
}
|
||||
|
||||
static int cmd_reflog_expire(int argc, const char **argv, const char *prefix)
|
||||
{
|
||||
struct cmd_reflog_expire_cb cmd = { 0 };
|
||||
|
@ -304,12 +349,6 @@ static int cmd_reflog_expire(int argc, const char **argv, const char *prefix)
|
|||
return status;
|
||||
}
|
||||
|
||||
static const char * reflog_delete_usage[] = {
|
||||
N_("git reflog delete [--rewrite] [--updateref] "
|
||||
"[--dry-run | -n] [--verbose] <refs>..."),
|
||||
NULL
|
||||
};
|
||||
|
||||
static int cmd_reflog_delete(int argc, const char **argv, const char *prefix)
|
||||
{
|
||||
int i, status = 0;
|
||||
|
@ -342,57 +381,62 @@ static int cmd_reflog_delete(int argc, const char **argv, const char *prefix)
|
|||
|
||||
static int cmd_reflog_exists(int argc, const char **argv, const char *prefix)
|
||||
{
|
||||
int i, start = 0;
|
||||
struct option options[] = {
|
||||
OPT_END()
|
||||
};
|
||||
const char *refname;
|
||||
|
||||
for (i = 1; i < argc; i++) {
|
||||
const char *arg = argv[i];
|
||||
if (!strcmp(arg, "--")) {
|
||||
i++;
|
||||
break;
|
||||
}
|
||||
else if (arg[0] == '-')
|
||||
usage(_(reflog_exists_usage));
|
||||
else
|
||||
break;
|
||||
}
|
||||
argc = parse_options(argc, argv, prefix, options, reflog_exists_usage,
|
||||
0);
|
||||
if (!argc)
|
||||
usage_with_options(reflog_exists_usage, options);
|
||||
|
||||
start = i;
|
||||
|
||||
if (argc - start != 1)
|
||||
usage(_(reflog_exists_usage));
|
||||
|
||||
if (check_refname_format(argv[start], REFNAME_ALLOW_ONELEVEL))
|
||||
die(_("invalid ref format: %s"), argv[start]);
|
||||
return !reflog_exists(argv[start]);
|
||||
refname = argv[0];
|
||||
if (check_refname_format(refname, REFNAME_ALLOW_ONELEVEL))
|
||||
die(_("invalid ref format: %s"), refname);
|
||||
return !reflog_exists(refname);
|
||||
}
|
||||
|
||||
/*
|
||||
* main "reflog"
|
||||
*/
|
||||
|
||||
static const char reflog_usage[] =
|
||||
"git reflog [ show | expire | delete | exists ]";
|
||||
|
||||
int cmd_reflog(int argc, const char **argv, const char *prefix)
|
||||
{
|
||||
if (argc > 1 && !strcmp(argv[1], "-h"))
|
||||
usage(_(reflog_usage));
|
||||
struct option options[] = {
|
||||
OPT_END()
|
||||
};
|
||||
|
||||
/* With no command, we default to showing it. */
|
||||
if (argc < 2 || *argv[1] == '-')
|
||||
return cmd_log_reflog(argc, argv, prefix);
|
||||
argc = parse_options(argc, argv, prefix, options, reflog_usage,
|
||||
PARSE_OPT_KEEP_DASHDASH | PARSE_OPT_KEEP_ARGV0 |
|
||||
PARSE_OPT_KEEP_UNKNOWN |
|
||||
PARSE_OPT_NO_INTERNAL_HELP);
|
||||
|
||||
/*
|
||||
* With "git reflog" we default to showing it. !argc is
|
||||
* impossible with PARSE_OPT_KEEP_ARGV0.
|
||||
*/
|
||||
if (argc == 1)
|
||||
goto log_reflog;
|
||||
|
||||
if (!strcmp(argv[1], "-h"))
|
||||
usage_with_options(reflog_usage, options);
|
||||
else if (*argv[1] == '-')
|
||||
goto log_reflog;
|
||||
|
||||
if (!strcmp(argv[1], "show"))
|
||||
return cmd_log_reflog(argc - 1, argv + 1, prefix);
|
||||
|
||||
if (!strcmp(argv[1], "expire"))
|
||||
return cmd_reflog_show(argc - 1, argv + 1, prefix);
|
||||
else if (!strcmp(argv[1], "expire"))
|
||||
return cmd_reflog_expire(argc - 1, argv + 1, prefix);
|
||||
|
||||
if (!strcmp(argv[1], "delete"))
|
||||
else if (!strcmp(argv[1], "delete"))
|
||||
return cmd_reflog_delete(argc - 1, argv + 1, prefix);
|
||||
|
||||
if (!strcmp(argv[1], "exists"))
|
||||
else if (!strcmp(argv[1], "exists"))
|
||||
return cmd_reflog_exists(argc - 1, argv + 1, prefix);
|
||||
|
||||
/*
|
||||
* Fall-through for e.g. "git reflog -1", "git reflog master",
|
||||
* as well as the plain "git reflog" above goto above.
|
||||
*/
|
||||
log_reflog:
|
||||
return cmd_log_reflog(argc, argv, prefix);
|
||||
}
|
||||
|
|
20
reflog.c
20
reflog.c
|
@ -240,8 +240,8 @@ static int unreachable(struct expire_reflog_policy_cb *cb, struct commit *commit
|
|||
* Return true iff the specified reflog entry should be expired.
|
||||
*/
|
||||
int should_expire_reflog_ent(struct object_id *ooid, struct object_id *noid,
|
||||
const char *email, timestamp_t timestamp, int tz,
|
||||
const char *message, void *cb_data)
|
||||
const char *email, timestamp_t timestamp, int tz,
|
||||
const char *message, void *cb_data)
|
||||
{
|
||||
struct expire_reflog_policy_cb *cb = cb_data;
|
||||
struct commit *old_commit, *new_commit;
|
||||
|
@ -273,10 +273,10 @@ int should_expire_reflog_ent(struct object_id *ooid, struct object_id *noid,
|
|||
}
|
||||
|
||||
int should_expire_reflog_ent_verbose(struct object_id *ooid,
|
||||
struct object_id *noid,
|
||||
const char *email,
|
||||
timestamp_t timestamp, int tz,
|
||||
const char *message, void *cb_data)
|
||||
struct object_id *noid,
|
||||
const char *email,
|
||||
timestamp_t timestamp, int tz,
|
||||
const char *message, void *cb_data)
|
||||
{
|
||||
struct expire_reflog_policy_cb *cb = cb_data;
|
||||
int expire;
|
||||
|
@ -323,8 +323,8 @@ static int is_head(const char *refname)
|
|||
}
|
||||
|
||||
void reflog_expiry_prepare(const char *refname,
|
||||
const struct object_id *oid,
|
||||
void *cb_data)
|
||||
const struct object_id *oid,
|
||||
void *cb_data)
|
||||
{
|
||||
struct expire_reflog_policy_cb *cb = cb_data;
|
||||
struct commit_list *elem;
|
||||
|
@ -379,8 +379,8 @@ void reflog_expiry_cleanup(void *cb_data)
|
|||
}
|
||||
|
||||
int count_reflog_ent(struct object_id *ooid, struct object_id *noid,
|
||||
const char *email, timestamp_t timestamp, int tz,
|
||||
const char *message, void *cb_data)
|
||||
const char *email, timestamp_t timestamp, int tz,
|
||||
const char *message, void *cb_data)
|
||||
{
|
||||
struct cmd_reflog_expire_cb *cb = cb_data;
|
||||
if (!cb->expire_total || timestamp < cb->expire_total)
|
||||
|
|
|
@ -106,6 +106,28 @@ test_expect_success setup '
|
|||
test_line_count = 4 output
|
||||
'
|
||||
|
||||
test_expect_success 'correct usage on sub-command -h' '
|
||||
test_expect_code 129 git reflog expire -h >err &&
|
||||
grep "git reflog expire" err
|
||||
'
|
||||
|
||||
test_expect_success 'correct usage on "git reflog show -h"' '
|
||||
test_expect_code 129 git reflog show -h >err &&
|
||||
grep -F "git reflog [show]" err
|
||||
'
|
||||
|
||||
test_expect_success 'pass through -- to sub-command' '
|
||||
test_when_finished "rm -rf repo" &&
|
||||
git init repo &&
|
||||
test_commit -C repo message --a-file contents dash-tag &&
|
||||
|
||||
git -C repo reflog show -- --does-not-exist >out &&
|
||||
test_must_be_empty out &&
|
||||
git -C repo reflog show >expect &&
|
||||
git -C repo reflog show -- --a-file >actual &&
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
test_expect_success rewind '
|
||||
test_tick && git reset --hard HEAD~2 &&
|
||||
test -f C &&
|
||||
|
|
|
@ -169,9 +169,4 @@ test_expect_success 'git log -g -p shows diffs vs. parents' '
|
|||
test_cmp expect actual
|
||||
'
|
||||
|
||||
test_expect_success 'reflog exists works' '
|
||||
git reflog exists refs/heads/main &&
|
||||
! git reflog exists refs/heads/nonexistent
|
||||
'
|
||||
|
||||
test_done
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
#!/bin/sh
|
||||
|
||||
test_description='Test reflog display routines'
|
||||
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
|
||||
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
|
||||
|
||||
. ./test-lib.sh
|
||||
|
||||
test_expect_success 'setup' '
|
||||
test_commit A
|
||||
'
|
||||
|
||||
test_expect_success 'usage' '
|
||||
test_expect_code 129 git reflog exists &&
|
||||
test_expect_code 129 git reflog exists -h
|
||||
'
|
||||
|
||||
test_expect_success 'usage: unknown option' '
|
||||
test_expect_code 129 git reflog exists --unknown-option
|
||||
'
|
||||
|
||||
test_expect_success 'reflog exists works' '
|
||||
git reflog exists refs/heads/main &&
|
||||
test_must_fail git reflog exists refs/heads/nonexistent
|
||||
'
|
||||
|
||||
test_expect_success 'reflog exists works with a "--" delimiter' '
|
||||
git reflog exists -- refs/heads/main &&
|
||||
test_must_fail git reflog exists -- refs/heads/nonexistent
|
||||
'
|
||||
|
||||
test_expect_success 'reflog exists works with a "--end-of-options" delimiter' '
|
||||
git reflog exists --end-of-options refs/heads/main &&
|
||||
test_must_fail git reflog exists --end-of-options refs/heads/nonexistent
|
||||
'
|
||||
|
||||
test_done
|
|
@ -329,7 +329,7 @@ test_commit () {
|
|||
else
|
||||
$echo "${3-$1}" >"$indir$file"
|
||||
fi &&
|
||||
git ${indir:+ -C "$indir"} add "$file" &&
|
||||
git ${indir:+ -C "$indir"} add -- "$file" &&
|
||||
if test -z "$notick"
|
||||
then
|
||||
test_tick
|
||||
|
|
Загрузка…
Ссылка в новой задаче