]>
Commit | Line | Data |
---|---|---|
640ce105 | 1 | #include "builtin.h" |
b2141fc1 | 2 | #include "config.h" |
f394e093 | 3 | #include "gettext.h" |
8da19775 | 4 | #include "refs.h" |
78558614 | 5 | #include "parse-options.h" |
fda5d959 | 6 | #include "strbuf.h" |
8098a178 | 7 | |
78558614 | 8 | static const char * const git_symbolic_ref_usage[] = { |
8c9e292d | 9 | N_("git symbolic-ref [-m <reason>] <name> <ref>"), |
7b9b634c | 10 | N_("git symbolic-ref [-q] [--short] [--no-recurse] <name>"), |
8c9e292d | 11 | N_("git symbolic-ref --delete [-q] <name>"), |
78558614 PH |
12 | NULL |
13 | }; | |
8098a178 | 14 | |
b77e3bdd | 15 | static int check_symref(const char *HEAD, int quiet, int shorten, int recurse, int print) |
8098a178 | 16 | { |
b77e3bdd JH |
17 | int resolve_flags, flag; |
18 | const char *refname; | |
19 | ||
20 | resolve_flags = (recurse ? 0 : RESOLVE_REF_NO_RECURSE); | |
21 | refname = resolve_ref_unsafe(HEAD, resolve_flags, NULL, &flag); | |
ed378ec7 | 22 | |
42b00599 | 23 | if (!refname) |
8098a178 | 24 | die("No such ref: %s", HEAD); |
a0f4280f JH |
25 | else if (!(flag & REF_ISSYMREF)) { |
26 | if (!quiet) | |
27 | die("ref %s is not a symbolic ref", HEAD); | |
28 | else | |
9ab55daa JH |
29 | return 1; |
30 | } | |
31 | if (print) { | |
f63b8886 | 32 | char *to_free = NULL; |
9ab55daa | 33 | if (shorten) |
f63b8886 | 34 | refname = to_free = shorten_unambiguous_ref(refname, 0); |
9ab55daa | 35 | puts(refname); |
f63b8886 | 36 | free(to_free); |
a0f4280f | 37 | } |
9ab55daa | 38 | return 0; |
8098a178 JH |
39 | } |
40 | ||
640ce105 | 41 | int cmd_symbolic_ref(int argc, const char **argv, const char *prefix) |
8098a178 | 42 | { |
b77e3bdd | 43 | int quiet = 0, delete = 0, shorten = 0, recurse = 1, ret = 0; |
8b5157e4 | 44 | const char *msg = NULL; |
78558614 | 45 | struct option options[] = { |
8c839683 | 46 | OPT__QUIET(&quiet, |
b10bf3fa | 47 | N_("suppress error message for non-symbolic (detached) refs")), |
9ab55daa | 48 | OPT_BOOL('d', "delete", &delete, N_("delete symbolic ref")), |
b10bf3fa | 49 | OPT_BOOL(0, "short", &shorten, N_("shorten ref output")), |
b77e3bdd | 50 | OPT_BOOL(0, "recurse", &recurse, N_("recursively dereference (default)")), |
b10bf3fa | 51 | OPT_STRING('m', NULL, &msg, N_("reason"), N_("reason of the update")), |
78558614 PH |
52 | OPT_END(), |
53 | }; | |
a0f4280f | 54 | |
ef90d6d4 | 55 | git_config(git_default_config, NULL); |
37782920 SB |
56 | argc = parse_options(argc, argv, prefix, options, |
57 | git_symbolic_ref_usage, 0); | |
c01499ef | 58 | if (msg && !*msg) |
78558614 | 59 | die("Refusing to perform update with empty message"); |
9ab55daa JH |
60 | |
61 | if (delete) { | |
62 | if (argc != 1) | |
63 | usage_with_options(git_symbolic_ref_usage, options); | |
b77e3bdd | 64 | ret = check_symref(argv[0], 1, 0, 0, 0); |
9ab55daa JH |
65 | if (ret) |
66 | die("Cannot delete %s, not a symbolic ref", argv[0]); | |
12cfa792 JH |
67 | if (!strcmp(argv[0], "HEAD")) |
68 | die("deleting '%s' is not allowed", argv[0]); | |
91774afc | 69 | return delete_ref(NULL, argv[0], NULL, REF_NO_DEREF); |
9ab55daa JH |
70 | } |
71 | ||
8098a178 | 72 | switch (argc) { |
78558614 | 73 | case 1: |
b77e3bdd | 74 | ret = check_symref(argv[0], quiet, shorten, recurse, 1); |
8098a178 | 75 | break; |
78558614 | 76 | case 2: |
afe5d3d5 | 77 | if (!strcmp(argv[0], "HEAD") && |
59556548 | 78 | !starts_with(argv[1], "refs/")) |
e9cc02f0 | 79 | die("Refusing to point HEAD outside of refs/"); |
04ede972 LT |
80 | if (check_refname_format(argv[1], REFNAME_ALLOW_ONELEVEL) < 0) |
81 | die("Refusing to set '%s' to invalid ref '%s'", argv[0], argv[1]); | |
3e4068ed | 82 | ret = !!create_symref(argv[0], argv[1], msg); |
8098a178 JH |
83 | break; |
84 | default: | |
78558614 | 85 | usage_with_options(git_symbolic_ref_usage, options); |
8098a178 | 86 | } |
9ab55daa | 87 | return ret; |
8098a178 | 88 | } |