]>
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, | |
e579e0f7 | 30 | subcmd_show |
0a2f99fd PS |
31 | }; |
32 | ||
22a2d3d5 | 33 | struct remote_opts { |
0a2f99fd PS |
34 | enum subcmd cmd; |
35 | ||
36 | /* for command-specific args */ | |
37 | int argc; | |
38 | char **argv; | |
39 | }; | |
40 | ||
22a2d3d5 UG |
41 | static int cmd_add(git_repository *repo, struct remote_opts *o); |
42 | static int cmd_remove(git_repository *repo, struct remote_opts *o); | |
43 | static int cmd_rename(git_repository *repo, struct remote_opts *o); | |
44 | static int cmd_seturl(git_repository *repo, struct remote_opts *o); | |
45 | static int cmd_show(git_repository *repo, struct remote_opts *o); | |
0a2f99fd PS |
46 | |
47 | static void parse_subcmd( | |
22a2d3d5 | 48 | struct remote_opts *opt, int argc, char **argv); |
0a2f99fd PS |
49 | static void usage(const char *msg, const char *arg); |
50 | ||
22a2d3d5 | 51 | int lg2_remote(git_repository *repo, int argc, char *argv[]) |
0a2f99fd PS |
52 | { |
53 | int retval = 0; | |
22a2d3d5 | 54 | struct remote_opts opt = {0}; |
0a2f99fd PS |
55 | |
56 | parse_subcmd(&opt, argc, argv); | |
57 | ||
0a2f99fd PS |
58 | switch (opt.cmd) |
59 | { | |
60 | case subcmd_add: | |
61 | retval = cmd_add(repo, &opt); | |
62 | break; | |
63 | case subcmd_remove: | |
64 | retval = cmd_remove(repo, &opt); | |
65 | break; | |
66 | case subcmd_rename: | |
67 | retval = cmd_rename(repo, &opt); | |
68 | break; | |
69 | case subcmd_seturl: | |
70 | retval = cmd_seturl(repo, &opt); | |
71 | break; | |
72 | case subcmd_show: | |
73 | retval = cmd_show(repo, &opt); | |
74 | break; | |
75 | } | |
76 | ||
0a2f99fd PS |
77 | return retval; |
78 | } | |
79 | ||
22a2d3d5 | 80 | static int cmd_add(git_repository *repo, struct remote_opts *o) |
0a2f99fd PS |
81 | { |
82 | char *name, *url; | |
83 | git_remote *remote = {0}; | |
84 | ||
85 | if (o->argc != 2) | |
86 | usage("you need to specify a name and URL", NULL); | |
87 | ||
88 | name = o->argv[0]; | |
89 | url = o->argv[1]; | |
90 | ||
91 | check_lg2(git_remote_create(&remote, repo, name, url), | |
92 | "could not create remote", NULL); | |
93 | ||
94 | return 0; | |
95 | } | |
96 | ||
22a2d3d5 | 97 | static int cmd_remove(git_repository *repo, struct remote_opts *o) |
0a2f99fd PS |
98 | { |
99 | char *name; | |
100 | ||
101 | if (o->argc != 1) | |
102 | usage("you need to specify a name", NULL); | |
103 | ||
104 | name = o->argv[0]; | |
105 | ||
106 | check_lg2(git_remote_delete(repo, name), | |
107 | "could not delete remote", name); | |
108 | ||
109 | return 0; | |
110 | } | |
111 | ||
22a2d3d5 | 112 | static int cmd_rename(git_repository *repo, struct remote_opts *o) |
0a2f99fd PS |
113 | { |
114 | int i, retval; | |
115 | char *old, *new; | |
116 | git_strarray problems = {0}; | |
117 | ||
118 | if (o->argc != 2) | |
119 | usage("you need to specify old and new remote name", NULL); | |
120 | ||
121 | old = o->argv[0]; | |
122 | new = o->argv[1]; | |
123 | ||
124 | retval = git_remote_rename(&problems, repo, old, new); | |
125 | if (!retval) | |
126 | return 0; | |
127 | ||
128 | for (i = 0; i < (int) problems.count; i++) { | |
129 | puts(problems.strings[0]); | |
130 | } | |
131 | ||
22a2d3d5 | 132 | git_strarray_dispose(&problems); |
0a2f99fd PS |
133 | |
134 | return retval; | |
135 | } | |
136 | ||
22a2d3d5 | 137 | static int cmd_seturl(git_repository *repo, struct remote_opts *o) |
0a2f99fd PS |
138 | { |
139 | int i, retval, push = 0; | |
140 | char *name = NULL, *url = NULL; | |
0a2f99fd PS |
141 | |
142 | for (i = 0; i < o->argc; i++) { | |
143 | char *arg = o->argv[i]; | |
144 | ||
145 | if (!strcmp(arg, "--push")) { | |
146 | push = 1; | |
147 | } else if (arg[0] != '-' && name == NULL) { | |
148 | name = arg; | |
149 | } else if (arg[0] != '-' && url == NULL) { | |
150 | url = arg; | |
151 | } else { | |
152 | usage("invalid argument to set-url", arg); | |
153 | } | |
154 | } | |
155 | ||
156 | if (name == NULL || url == NULL) | |
157 | usage("you need to specify remote and the new URL", NULL); | |
158 | ||
0a2f99fd | 159 | if (push) |
3fec548a | 160 | retval = git_remote_set_pushurl(repo, name, url); |
0a2f99fd | 161 | else |
3fec548a | 162 | retval = git_remote_set_url(repo, name, url); |
0a2f99fd | 163 | |
3fec548a | 164 | check_lg2(retval, "could not set URL", url); |
0a2f99fd PS |
165 | |
166 | return 0; | |
167 | } | |
168 | ||
22a2d3d5 | 169 | static int cmd_show(git_repository *repo, struct remote_opts *o) |
0a2f99fd PS |
170 | { |
171 | int i; | |
172 | const char *arg, *name, *fetch, *push; | |
173 | int verbose = 0; | |
174 | git_strarray remotes = {0}; | |
175 | git_remote *remote = {0}; | |
176 | ||
177 | for (i = 0; i < o->argc; i++) { | |
178 | arg = o->argv[i]; | |
179 | ||
180 | if (!strcmp(arg, "-v") || !strcmp(arg, "--verbose")) { | |
181 | verbose = 1; | |
182 | } | |
183 | } | |
184 | ||
185 | check_lg2(git_remote_list(&remotes, repo), | |
186 | "could not retrieve remotes", NULL); | |
187 | ||
188 | for (i = 0; i < (int) remotes.count; i++) { | |
189 | name = remotes.strings[i]; | |
190 | if (!verbose) { | |
191 | puts(name); | |
192 | continue; | |
193 | } | |
194 | ||
195 | check_lg2(git_remote_lookup(&remote, repo, name), | |
196 | "could not look up remote", name); | |
197 | ||
198 | fetch = git_remote_url(remote); | |
199 | if (fetch) | |
200 | printf("%s\t%s (fetch)\n", name, fetch); | |
201 | push = git_remote_pushurl(remote); | |
202 | /* use fetch URL if no distinct push URL has been set */ | |
203 | push = push ? push : fetch; | |
204 | if (push) | |
205 | printf("%s\t%s (push)\n", name, push); | |
206 | ||
207 | git_remote_free(remote); | |
208 | } | |
209 | ||
22a2d3d5 | 210 | git_strarray_dispose(&remotes); |
0a2f99fd PS |
211 | |
212 | return 0; | |
213 | } | |
214 | ||
215 | static void parse_subcmd( | |
22a2d3d5 | 216 | struct remote_opts *opt, int argc, char **argv) |
0a2f99fd PS |
217 | { |
218 | char *arg = argv[1]; | |
219 | enum subcmd cmd = 0; | |
220 | ||
221 | if (argc < 2) | |
222 | usage("no command specified", NULL); | |
223 | ||
224 | if (!strcmp(arg, "add")) { | |
225 | cmd = subcmd_add; | |
226 | } else if (!strcmp(arg, "remove")) { | |
227 | cmd = subcmd_remove; | |
228 | } else if (!strcmp(arg, "rename")) { | |
229 | cmd = subcmd_rename; | |
230 | } else if (!strcmp(arg, "set-url")) { | |
231 | cmd = subcmd_seturl; | |
232 | } else if (!strcmp(arg, "show")) { | |
233 | cmd = subcmd_show; | |
234 | } else { | |
235 | usage("command is not valid", arg); | |
236 | } | |
237 | opt->cmd = cmd; | |
238 | ||
239 | opt->argc = argc - 2; /* executable and subcommand are removed */ | |
240 | opt->argv = argv + 2; | |
241 | } | |
242 | ||
243 | static void usage(const char *msg, const char *arg) | |
244 | { | |
245 | fputs("usage: remote add <name> <url>\n", stderr); | |
246 | fputs(" remote remove <name>\n", stderr); | |
247 | fputs(" remote rename <old> <new>\n", stderr); | |
248 | fputs(" remote set-url [--push] <name> <newurl>\n", stderr); | |
249 | fputs(" remote show [-v|--verbose]\n", stderr); | |
250 | ||
251 | if (msg && !arg) | |
252 | fprintf(stderr, "\n%s\n", msg); | |
253 | else if (msg && arg) | |
254 | fprintf(stderr, "\n%s: %s\n", msg, arg); | |
255 | exit(1); | |
256 | } |