]>
Commit | Line | Data |
---|---|---|
72d0ea00 BW |
1 | #include "cache.h" |
2 | #include "repository.h" | |
3 | #include "refs.h" | |
4 | #include "remote.h" | |
5 | #include "argv-array.h" | |
6 | #include "ls-refs.h" | |
7 | #include "pkt-line.h" | |
8 | ||
9 | /* | |
10 | * Check if one of the prefixes is a prefix of the ref. | |
11 | * If no prefixes were provided, all refs match. | |
12 | */ | |
13 | static int ref_match(const struct argv_array *prefixes, const char *refname) | |
14 | { | |
15 | int i; | |
16 | ||
17 | if (!prefixes->argc) | |
18 | return 1; /* no restriction */ | |
19 | ||
20 | for (i = 0; i < prefixes->argc; i++) { | |
21 | const char *prefix = prefixes->argv[i]; | |
22 | ||
23 | if (starts_with(refname, prefix)) | |
24 | return 1; | |
25 | } | |
26 | ||
27 | return 0; | |
28 | } | |
29 | ||
30 | struct ls_refs_data { | |
31 | unsigned peel; | |
32 | unsigned symrefs; | |
33 | struct argv_array prefixes; | |
34 | }; | |
35 | ||
36 | static int send_ref(const char *refname, const struct object_id *oid, | |
37 | int flag, void *cb_data) | |
38 | { | |
39 | struct ls_refs_data *data = cb_data; | |
40 | const char *refname_nons = strip_namespace(refname); | |
41 | struct strbuf refline = STRBUF_INIT; | |
42 | ||
43 | if (!ref_match(&data->prefixes, refname)) | |
44 | return 0; | |
45 | ||
46 | strbuf_addf(&refline, "%s %s", oid_to_hex(oid), refname_nons); | |
47 | if (data->symrefs && flag & REF_ISSYMREF) { | |
48 | struct object_id unused; | |
49 | const char *symref_target = resolve_ref_unsafe(refname, 0, | |
50 | &unused, | |
51 | &flag); | |
52 | ||
53 | if (!symref_target) | |
54 | die("'%s' is a symref but it is not?", refname); | |
55 | ||
56 | strbuf_addf(&refline, " symref-target:%s", symref_target); | |
57 | } | |
58 | ||
59 | if (data->peel) { | |
60 | struct object_id peeled; | |
61 | if (!peel_ref(refname, &peeled)) | |
62 | strbuf_addf(&refline, " peeled:%s", oid_to_hex(&peeled)); | |
63 | } | |
64 | ||
65 | strbuf_addch(&refline, '\n'); | |
66 | packet_write(1, refline.buf, refline.len); | |
67 | ||
68 | strbuf_release(&refline); | |
69 | return 0; | |
70 | } | |
71 | ||
72 | int ls_refs(struct repository *r, struct argv_array *keys, | |
73 | struct packet_reader *request) | |
74 | { | |
75 | struct ls_refs_data data; | |
76 | ||
77 | memset(&data, 0, sizeof(data)); | |
78 | ||
79 | while (packet_reader_read(request) != PACKET_READ_FLUSH) { | |
80 | const char *arg = request->line; | |
81 | const char *out; | |
82 | ||
83 | if (!strcmp("peel", arg)) | |
84 | data.peel = 1; | |
85 | else if (!strcmp("symrefs", arg)) | |
86 | data.symrefs = 1; | |
87 | else if (skip_prefix(arg, "ref-prefix ", &out)) | |
88 | argv_array_push(&data.prefixes, out); | |
89 | } | |
90 | ||
91 | head_ref_namespaced(send_ref, &data); | |
92 | for_each_namespaced_ref(send_ref, &data); | |
93 | packet_flush(1); | |
94 | argv_array_clear(&data.prefixes); | |
95 | return 0; | |
96 | } |