]>
Commit | Line | Data |
---|---|---|
0a2f99fd PS |
1 | /* |
2 | * libgit2 "remote" example - shows how to modify remotes for a repo | |
3 | * | |
4 | * Written by the libgit2 contributors | |
5 | * | |
6 | * To the extent possible under law, the author(s) have dedicated all copyright | |
7 | * and related and neighboring rights to this software to the public domain | |
8 | * worldwide. This software is distributed without any warranty. | |
9 | * | |
10 | * You should have received a copy of the CC0 Public Domain Dedication along | |
11 | * with this software. If not, see | |
12 | * <http://creativecommons.org/publicdomain/zero/1.0/>. | |
13 | */ | |
14 | ||
15 | #include "common.h" | |
16 | ||
17 | /** | |
18 | * This is a sample program that is similar to "git remote". See the | |
19 | * documentation for that (try "git help remote") to understand what this | |
20 | * program is emulating. | |
21 | * | |
22 | * This demonstrates using the libgit2 APIs to modify remotes of a repository. | |
23 | */ | |
24 | ||
25 | enum subcmd { | |
26 | subcmd_add, | |
27 | subcmd_remove, | |
28 | subcmd_rename, | |
29 | subcmd_seturl, | |
30 | subcmd_show, | |
31 | }; | |
32 | ||
33 | struct opts { | |
34 | enum subcmd cmd; | |
35 | ||
36 | /* for command-specific args */ | |
37 | int argc; | |
38 | char **argv; | |
39 | }; | |
40 | ||
41 | static int cmd_add(git_repository *repo, struct opts *o); | |
42 | static int cmd_remove(git_repository *repo, struct opts *o); | |
43 | static int cmd_rename(git_repository *repo, struct opts *o); | |
44 | static int cmd_seturl(git_repository *repo, struct opts *o); | |
45 | static int cmd_show(git_repository *repo, struct opts *o); | |
46 | ||
47 | static void parse_subcmd( | |
48 | struct opts *opt, int argc, char **argv); | |
49 | static void usage(const char *msg, const char *arg); | |
50 | ||
51 | int main(int argc, char *argv[]) | |
52 | { | |
53 | int retval = 0; | |
54 | struct opts opt = {0}; | |
55 | git_buf buf = GIT_BUF_INIT_CONST(NULL, 0); | |
56 | git_repository *repo = NULL; | |
57 | ||
58 | parse_subcmd(&opt, argc, argv); | |
59 | ||
60 | git_libgit2_init(); | |
61 | ||
62 | check_lg2(git_repository_discover(&buf, ".", 0, NULL), | |
63 | "Could not find repository", NULL); | |
64 | ||
65 | check_lg2(git_repository_open(&repo, buf.ptr), | |
66 | "Could not open repository", NULL); | |
67 | git_buf_free(&buf); | |
68 | ||
69 | switch (opt.cmd) | |
70 | { | |
71 | case subcmd_add: | |
72 | retval = cmd_add(repo, &opt); | |
73 | break; | |
74 | case subcmd_remove: | |
75 | retval = cmd_remove(repo, &opt); | |
76 | break; | |
77 | case subcmd_rename: | |
78 | retval = cmd_rename(repo, &opt); | |
79 | break; | |
80 | case subcmd_seturl: | |
81 | retval = cmd_seturl(repo, &opt); | |
82 | break; | |
83 | case subcmd_show: | |
84 | retval = cmd_show(repo, &opt); | |
85 | break; | |
86 | } | |
87 | ||
88 | git_libgit2_shutdown(); | |
89 | ||
90 | return retval; | |
91 | } | |
92 | ||
93 | static int cmd_add(git_repository *repo, struct opts *o) | |
94 | { | |
95 | char *name, *url; | |
96 | git_remote *remote = {0}; | |
97 | ||
98 | if (o->argc != 2) | |
99 | usage("you need to specify a name and URL", NULL); | |
100 | ||
101 | name = o->argv[0]; | |
102 | url = o->argv[1]; | |
103 | ||
104 | check_lg2(git_remote_create(&remote, repo, name, url), | |
105 | "could not create remote", NULL); | |
106 | ||
107 | return 0; | |
108 | } | |
109 | ||
110 | static int cmd_remove(git_repository *repo, struct opts *o) | |
111 | { | |
112 | char *name; | |
113 | ||
114 | if (o->argc != 1) | |
115 | usage("you need to specify a name", NULL); | |
116 | ||
117 | name = o->argv[0]; | |
118 | ||
119 | check_lg2(git_remote_delete(repo, name), | |
120 | "could not delete remote", name); | |
121 | ||
122 | return 0; | |
123 | } | |
124 | ||
125 | static int cmd_rename(git_repository *repo, struct opts *o) | |
126 | { | |
127 | int i, retval; | |
128 | char *old, *new; | |
129 | git_strarray problems = {0}; | |
130 | ||
131 | if (o->argc != 2) | |
132 | usage("you need to specify old and new remote name", NULL); | |
133 | ||
134 | old = o->argv[0]; | |
135 | new = o->argv[1]; | |
136 | ||
137 | retval = git_remote_rename(&problems, repo, old, new); | |
138 | if (!retval) | |
139 | return 0; | |
140 | ||
141 | for (i = 0; i < (int) problems.count; i++) { | |
142 | puts(problems.strings[0]); | |
143 | } | |
144 | ||
145 | git_strarray_free(&problems); | |
146 | ||
147 | return retval; | |
148 | } | |
149 | ||
150 | static int cmd_seturl(git_repository *repo, struct opts *o) | |
151 | { | |
152 | int i, retval, push = 0; | |
153 | char *name = NULL, *url = NULL; | |
154 | git_remote *remote; | |
155 | ||
156 | for (i = 0; i < o->argc; i++) { | |
157 | char *arg = o->argv[i]; | |
158 | ||
159 | if (!strcmp(arg, "--push")) { | |
160 | push = 1; | |
161 | } else if (arg[0] != '-' && name == NULL) { | |
162 | name = arg; | |
163 | } else if (arg[0] != '-' && url == NULL) { | |
164 | url = arg; | |
165 | } else { | |
166 | usage("invalid argument to set-url", arg); | |
167 | } | |
168 | } | |
169 | ||
170 | if (name == NULL || url == NULL) | |
171 | usage("you need to specify remote and the new URL", NULL); | |
172 | ||
173 | check_lg2(git_remote_lookup(&remote, repo, name), | |
174 | "could not look up remote", name); | |
175 | ||
176 | if (push) | |
177 | retval = git_remote_set_pushurl(remote, url); | |
178 | else | |
179 | retval = git_remote_set_url(remote, url); | |
180 | check_lg2(retval, "could not set URL", url); | |
181 | ||
182 | check_lg2(git_remote_save(remote), | |
183 | "could not save remote", NULL); | |
184 | ||
185 | git_remote_free(remote); | |
186 | ||
187 | return 0; | |
188 | } | |
189 | ||
190 | static int cmd_show(git_repository *repo, struct opts *o) | |
191 | { | |
192 | int i; | |
193 | const char *arg, *name, *fetch, *push; | |
194 | int verbose = 0; | |
195 | git_strarray remotes = {0}; | |
196 | git_remote *remote = {0}; | |
197 | ||
198 | for (i = 0; i < o->argc; i++) { | |
199 | arg = o->argv[i]; | |
200 | ||
201 | if (!strcmp(arg, "-v") || !strcmp(arg, "--verbose")) { | |
202 | verbose = 1; | |
203 | } | |
204 | } | |
205 | ||
206 | check_lg2(git_remote_list(&remotes, repo), | |
207 | "could not retrieve remotes", NULL); | |
208 | ||
209 | for (i = 0; i < (int) remotes.count; i++) { | |
210 | name = remotes.strings[i]; | |
211 | if (!verbose) { | |
212 | puts(name); | |
213 | continue; | |
214 | } | |
215 | ||
216 | check_lg2(git_remote_lookup(&remote, repo, name), | |
217 | "could not look up remote", name); | |
218 | ||
219 | fetch = git_remote_url(remote); | |
220 | if (fetch) | |
221 | printf("%s\t%s (fetch)\n", name, fetch); | |
222 | push = git_remote_pushurl(remote); | |
223 | /* use fetch URL if no distinct push URL has been set */ | |
224 | push = push ? push : fetch; | |
225 | if (push) | |
226 | printf("%s\t%s (push)\n", name, push); | |
227 | ||
228 | git_remote_free(remote); | |
229 | } | |
230 | ||
231 | git_strarray_free(&remotes); | |
232 | ||
233 | return 0; | |
234 | } | |
235 | ||
236 | static void parse_subcmd( | |
237 | struct opts *opt, int argc, char **argv) | |
238 | { | |
239 | char *arg = argv[1]; | |
240 | enum subcmd cmd = 0; | |
241 | ||
242 | if (argc < 2) | |
243 | usage("no command specified", NULL); | |
244 | ||
245 | if (!strcmp(arg, "add")) { | |
246 | cmd = subcmd_add; | |
247 | } else if (!strcmp(arg, "remove")) { | |
248 | cmd = subcmd_remove; | |
249 | } else if (!strcmp(arg, "rename")) { | |
250 | cmd = subcmd_rename; | |
251 | } else if (!strcmp(arg, "set-url")) { | |
252 | cmd = subcmd_seturl; | |
253 | } else if (!strcmp(arg, "show")) { | |
254 | cmd = subcmd_show; | |
255 | } else { | |
256 | usage("command is not valid", arg); | |
257 | } | |
258 | opt->cmd = cmd; | |
259 | ||
260 | opt->argc = argc - 2; /* executable and subcommand are removed */ | |
261 | opt->argv = argv + 2; | |
262 | } | |
263 | ||
264 | static void usage(const char *msg, const char *arg) | |
265 | { | |
266 | fputs("usage: remote add <name> <url>\n", stderr); | |
267 | fputs(" remote remove <name>\n", stderr); | |
268 | fputs(" remote rename <old> <new>\n", stderr); | |
269 | fputs(" remote set-url [--push] <name> <newurl>\n", stderr); | |
270 | fputs(" remote show [-v|--verbose]\n", stderr); | |
271 | ||
272 | if (msg && !arg) | |
273 | fprintf(stderr, "\n%s\n", msg); | |
274 | else if (msg && arg) | |
275 | fprintf(stderr, "\n%s: %s\n", msg, arg); | |
276 | exit(1); | |
277 | } |