Git fork
at reftables-rust 98 lines 2.9 kB view raw
1#define USE_THE_REPOSITORY_VARIABLE 2#include "builtin.h" 3#include "config.h" 4#include "environment.h" 5#include "gettext.h" 6#include "refs.h" 7#include "parse-options.h" 8#include "strbuf.h" 9 10static const char * const git_symbolic_ref_usage[] = { 11 N_("git symbolic-ref [-m <reason>] <name> <ref>"), 12 N_("git symbolic-ref [-q] [--short] [--no-recurse] <name>"), 13 N_("git symbolic-ref --delete [-q] <name>"), 14 NULL 15}; 16 17static int check_symref(const char *HEAD, int quiet, int shorten, int recurse, int print) 18{ 19 int resolve_flags, flag; 20 const char *refname; 21 22 resolve_flags = (recurse ? 0 : RESOLVE_REF_NO_RECURSE); 23 refname = refs_resolve_ref_unsafe(get_main_ref_store(the_repository), 24 HEAD, resolve_flags, NULL, &flag); 25 26 if (!refname) 27 die("No such ref: %s", HEAD); 28 else if (!(flag & REF_ISSYMREF)) { 29 if (!quiet) 30 die("ref %s is not a symbolic ref", HEAD); 31 else 32 return 1; 33 } 34 if (print) { 35 char *to_free = NULL; 36 if (shorten) 37 refname = to_free = refs_shorten_unambiguous_ref(get_main_ref_store(the_repository), 38 refname, 39 0); 40 puts(refname); 41 free(to_free); 42 } 43 return 0; 44} 45 46int cmd_symbolic_ref(int argc, 47 const char **argv, 48 const char *prefix, 49 struct repository *repo UNUSED) 50{ 51 int quiet = 0, delete = 0, shorten = 0, recurse = 1, ret = 0; 52 const char *msg = NULL; 53 struct option options[] = { 54 OPT__QUIET(&quiet, 55 N_("suppress error message for non-symbolic (detached) refs")), 56 OPT_BOOL('d', "delete", &delete, N_("delete symbolic ref")), 57 OPT_BOOL(0, "short", &shorten, N_("shorten ref output")), 58 OPT_BOOL(0, "recurse", &recurse, N_("recursively dereference (default)")), 59 OPT_STRING('m', NULL, &msg, N_("reason"), N_("reason of the update")), 60 OPT_END(), 61 }; 62 63 repo_config(the_repository, git_default_config, NULL); 64 argc = parse_options(argc, argv, prefix, options, 65 git_symbolic_ref_usage, 0); 66 if (msg && !*msg) 67 die("Refusing to perform update with empty message"); 68 69 if (delete) { 70 if (argc != 1) 71 usage_with_options(git_symbolic_ref_usage, options); 72 ret = check_symref(argv[0], 1, 0, 0, 0); 73 if (ret) 74 die("Cannot delete %s, not a symbolic ref", argv[0]); 75 if (!strcmp(argv[0], "HEAD")) 76 die("deleting '%s' is not allowed", argv[0]); 77 return refs_delete_ref(get_main_ref_store(the_repository), 78 NULL, argv[0], NULL, REF_NO_DEREF); 79 } 80 81 switch (argc) { 82 case 1: 83 ret = check_symref(argv[0], quiet, shorten, recurse, 1); 84 break; 85 case 2: 86 if (!strcmp(argv[0], "HEAD") && 87 !starts_with(argv[1], "refs/")) 88 die("Refusing to point HEAD outside of refs/"); 89 if (check_refname_format(argv[1], REFNAME_ALLOW_ONELEVEL) < 0) 90 die("Refusing to set '%s' to invalid ref '%s'", argv[0], argv[1]); 91 ret = !!refs_update_symref(get_main_ref_store(the_repository), 92 argv[0], argv[1], msg); 93 break; 94 default: 95 usage_with_options(git_symbolic_ref_usage, options); 96 } 97 return ret; 98}