Git fork
1/*
2 * GIT - The information manager from hell
3 */
4#include "builtin.h"
5#include "refs.h"
6#include "setup.h"
7#include "strbuf.h"
8
9static const char builtin_check_ref_format_usage[] =
10"git check-ref-format [--normalize] [<options>] <refname>\n"
11" or: git check-ref-format --branch <branchname-shorthand>";
12
13/*
14 * Return a copy of refname but with leading slashes removed and runs
15 * of adjacent slashes replaced with single slashes.
16 *
17 * This function is similar to normalize_path_copy(), but stripped down
18 * to meet check_ref_format's simpler needs.
19 */
20static char *collapse_slashes(const char *refname)
21{
22 char *ret = xmallocz(strlen(refname));
23 char ch;
24 char prev = '/';
25 char *cp = ret;
26
27 while ((ch = *refname++) != '\0') {
28 if (prev == '/' && ch == prev)
29 continue;
30
31 *cp++ = ch;
32 prev = ch;
33 }
34 *cp = '\0';
35 return ret;
36}
37
38static int check_ref_format_branch(const char *arg)
39{
40 struct strbuf sb = STRBUF_INIT;
41 const char *name;
42 int nongit;
43
44 setup_git_directory_gently(&nongit);
45 if (check_branch_ref(&sb, arg) ||
46 !skip_prefix(sb.buf, "refs/heads/", &name))
47 die("'%s' is not a valid branch name", arg);
48 printf("%s\n", name);
49 strbuf_release(&sb);
50 return 0;
51}
52
53int cmd_check_ref_format(int argc,
54 const char **argv,
55 const char *prefix,
56 struct repository *repo UNUSED)
57{
58 int i;
59 int normalize = 0;
60 int flags = 0;
61 const char *refname;
62 char *to_free = NULL;
63 int ret = 1;
64
65 BUG_ON_NON_EMPTY_PREFIX(prefix);
66
67 show_usage_if_asked(argc, argv,
68 builtin_check_ref_format_usage);
69
70 if (argc == 3 && !strcmp(argv[1], "--branch"))
71 return check_ref_format_branch(argv[2]);
72
73 for (i = 1; i < argc && argv[i][0] == '-'; i++) {
74 if (!strcmp(argv[i], "--normalize") || !strcmp(argv[i], "--print"))
75 normalize = 1;
76 else if (!strcmp(argv[i], "--allow-onelevel"))
77 flags |= REFNAME_ALLOW_ONELEVEL;
78 else if (!strcmp(argv[i], "--no-allow-onelevel"))
79 flags &= ~REFNAME_ALLOW_ONELEVEL;
80 else if (!strcmp(argv[i], "--refspec-pattern"))
81 flags |= REFNAME_REFSPEC_PATTERN;
82 else
83 usage(builtin_check_ref_format_usage);
84 }
85 if (! (i == argc - 1))
86 usage(builtin_check_ref_format_usage);
87
88 refname = argv[i];
89 if (normalize)
90 refname = to_free = collapse_slashes(refname);
91 if (check_refname_format(refname, flags))
92 goto cleanup;
93 if (normalize)
94 printf("%s\n", refname);
95
96 ret = 0;
97cleanup:
98 free(to_free);
99 return ret;
100}