]> git.proxmox.com Git - libgit2.git/blob - examples/remote.c
Merge pull request #3118 from libgit2/cmn/stream-size
[libgit2.git] / examples / remote.c
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
155 for (i = 0; i < o->argc; i++) {
156 char *arg = o->argv[i];
157
158 if (!strcmp(arg, "--push")) {
159 push = 1;
160 } else if (arg[0] != '-' && name == NULL) {
161 name = arg;
162 } else if (arg[0] != '-' && url == NULL) {
163 url = arg;
164 } else {
165 usage("invalid argument to set-url", arg);
166 }
167 }
168
169 if (name == NULL || url == NULL)
170 usage("you need to specify remote and the new URL", NULL);
171
172 if (push)
173 retval = git_remote_set_pushurl(repo, name, url);
174 else
175 retval = git_remote_set_url(repo, name, url);
176
177 check_lg2(retval, "could not set URL", url);
178
179 return 0;
180 }
181
182 static int cmd_show(git_repository *repo, struct opts *o)
183 {
184 int i;
185 const char *arg, *name, *fetch, *push;
186 int verbose = 0;
187 git_strarray remotes = {0};
188 git_remote *remote = {0};
189
190 for (i = 0; i < o->argc; i++) {
191 arg = o->argv[i];
192
193 if (!strcmp(arg, "-v") || !strcmp(arg, "--verbose")) {
194 verbose = 1;
195 }
196 }
197
198 check_lg2(git_remote_list(&remotes, repo),
199 "could not retrieve remotes", NULL);
200
201 for (i = 0; i < (int) remotes.count; i++) {
202 name = remotes.strings[i];
203 if (!verbose) {
204 puts(name);
205 continue;
206 }
207
208 check_lg2(git_remote_lookup(&remote, repo, name),
209 "could not look up remote", name);
210
211 fetch = git_remote_url(remote);
212 if (fetch)
213 printf("%s\t%s (fetch)\n", name, fetch);
214 push = git_remote_pushurl(remote);
215 /* use fetch URL if no distinct push URL has been set */
216 push = push ? push : fetch;
217 if (push)
218 printf("%s\t%s (push)\n", name, push);
219
220 git_remote_free(remote);
221 }
222
223 git_strarray_free(&remotes);
224
225 return 0;
226 }
227
228 static void parse_subcmd(
229 struct opts *opt, int argc, char **argv)
230 {
231 char *arg = argv[1];
232 enum subcmd cmd = 0;
233
234 if (argc < 2)
235 usage("no command specified", NULL);
236
237 if (!strcmp(arg, "add")) {
238 cmd = subcmd_add;
239 } else if (!strcmp(arg, "remove")) {
240 cmd = subcmd_remove;
241 } else if (!strcmp(arg, "rename")) {
242 cmd = subcmd_rename;
243 } else if (!strcmp(arg, "set-url")) {
244 cmd = subcmd_seturl;
245 } else if (!strcmp(arg, "show")) {
246 cmd = subcmd_show;
247 } else {
248 usage("command is not valid", arg);
249 }
250 opt->cmd = cmd;
251
252 opt->argc = argc - 2; /* executable and subcommand are removed */
253 opt->argv = argv + 2;
254 }
255
256 static void usage(const char *msg, const char *arg)
257 {
258 fputs("usage: remote add <name> <url>\n", stderr);
259 fputs(" remote remove <name>\n", stderr);
260 fputs(" remote rename <old> <new>\n", stderr);
261 fputs(" remote set-url [--push] <name> <newurl>\n", stderr);
262 fputs(" remote show [-v|--verbose]\n", stderr);
263
264 if (msg && !arg)
265 fprintf(stderr, "\n%s\n", msg);
266 else if (msg && arg)
267 fprintf(stderr, "\n%s: %s\n", msg, arg);
268 exit(1);
269 }