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