]> git.proxmox.com Git - libgit2.git/blame - examples/remote.c
examples: add remote example.
[libgit2.git] / examples / remote.c
CommitLineData
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
25enum subcmd {
26 subcmd_add,
27 subcmd_remove,
28 subcmd_rename,
29 subcmd_seturl,
30 subcmd_show,
31};
32
33struct opts {
34 enum subcmd cmd;
35
36 /* for command-specific args */
37 int argc;
38 char **argv;
39};
40
41static int cmd_add(git_repository *repo, struct opts *o);
42static int cmd_remove(git_repository *repo, struct opts *o);
43static int cmd_rename(git_repository *repo, struct opts *o);
44static int cmd_seturl(git_repository *repo, struct opts *o);
45static int cmd_show(git_repository *repo, struct opts *o);
46
47static void parse_subcmd(
48 struct opts *opt, int argc, char **argv);
49static void usage(const char *msg, const char *arg);
50
51int 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
93static 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
110static 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
125static 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
150static 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
190static 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
236static 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
264static 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}