]>
Commit | Line | Data |
---|---|---|
755225de LT |
1 | /* |
2 | * "git push" | |
3 | */ | |
4 | #include "cache.h" | |
5 | #include "refs.h" | |
6 | #include "run-command.h" | |
7 | #include "builtin.h" | |
5751f490 | 8 | #include "remote.h" |
755225de | 9 | |
d23842fd | 10 | static const char push_usage[] = "git-push [--all] [--tags] [--receive-pack=<git-receive-pack>] [--repo=all] [-f | --force] [-v] [<repository> <refspec>...]"; |
755225de | 11 | |
8558fd9e | 12 | static int all, force, thin = 1, verbose; |
d23842fd | 13 | static const char *receivepack; |
755225de | 14 | |
96f1e58f DR |
15 | static const char **refspec; |
16 | static int refspec_nr; | |
755225de LT |
17 | |
18 | static void add_refspec(const char *ref) | |
19 | { | |
20 | int nr = refspec_nr + 1; | |
21 | refspec = xrealloc(refspec, nr * sizeof(char *)); | |
22 | refspec[nr-1] = ref; | |
23 | refspec_nr = nr; | |
24 | } | |
25 | ||
755225de LT |
26 | static void set_refspecs(const char **refs, int nr) |
27 | { | |
8558fd9e DB |
28 | int i; |
29 | for (i = 0; i < nr; i++) { | |
30 | const char *ref = refs[i]; | |
31 | if (!strcmp("tag", ref)) { | |
32 | char *tag; | |
33 | int len; | |
34 | if (nr <= ++i) | |
35 | die("tag shorthand without <tag>"); | |
36 | len = strlen(refs[i]) + 11; | |
37 | tag = xmalloc(len); | |
38 | strcpy(tag, "refs/tags/"); | |
39 | strcat(tag, refs[i]); | |
40 | ref = tag; | |
411fb8ba | 41 | } |
8558fd9e | 42 | add_refspec(ref); |
755225de | 43 | } |
755225de LT |
44 | } |
45 | ||
755225de LT |
46 | static int do_push(const char *repo) |
47 | { | |
5751f490 | 48 | int i, errs; |
441c823e | 49 | int common_argc; |
755225de LT |
50 | const char **argv; |
51 | int argc; | |
5751f490 | 52 | struct remote *remote = remote_get(repo); |
755225de | 53 | |
5751f490 | 54 | if (!remote) |
755225de LT |
55 | die("bad repository '%s'", repo); |
56 | ||
5751f490 DB |
57 | if (remote->receivepack) { |
58 | char *rp = xmalloc(strlen(remote->receivepack) + 16); | |
59 | sprintf(rp, "--receive-pack=%s", remote->receivepack); | |
60 | receivepack = rp; | |
61 | } | |
8558fd9e DB |
62 | if (!refspec && !all && remote->push_refspec_nr) { |
63 | refspec = remote->push_refspec; | |
64 | refspec_nr = remote->push_refspec_nr; | |
5751f490 DB |
65 | } |
66 | ||
755225de LT |
67 | argv = xmalloc((refspec_nr + 10) * sizeof(char *)); |
68 | argv[0] = "dummy-send-pack"; | |
69 | argc = 1; | |
70 | if (all) | |
71 | argv[argc++] = "--all"; | |
72 | if (force) | |
73 | argv[argc++] = "--force"; | |
d23842fd UKK |
74 | if (receivepack) |
75 | argv[argc++] = receivepack; | |
441c823e | 76 | common_argc = argc; |
755225de | 77 | |
fd1d1b05 | 78 | errs = 0; |
5751f490 | 79 | for (i = 0; i < remote->uri_nr; i++) { |
60b7f38e | 80 | int err; |
441c823e NH |
81 | int dest_argc = common_argc; |
82 | int dest_refspec_nr = refspec_nr; | |
83 | const char **dest_refspec = refspec; | |
5751f490 | 84 | const char *dest = remote->uri[i]; |
df91ba36 | 85 | const char *sender = "send-pack"; |
cc44c765 JH |
86 | if (!prefixcmp(dest, "http://") || |
87 | !prefixcmp(dest, "https://")) | |
df91ba36 | 88 | sender = "http-push"; |
b516968f DB |
89 | else { |
90 | char *rem = xmalloc(strlen(remote->name) + 10); | |
91 | sprintf(rem, "--remote=%s", remote->name); | |
92 | argv[dest_argc++] = rem; | |
93 | if (thin) | |
94 | argv[dest_argc++] = "--thin"; | |
95 | } | |
755225de | 96 | argv[0] = sender; |
441c823e NH |
97 | argv[dest_argc++] = dest; |
98 | while (dest_refspec_nr--) | |
99 | argv[dest_argc++] = *dest_refspec++; | |
100 | argv[dest_argc] = NULL; | |
bcc785f6 LT |
101 | if (verbose) |
102 | fprintf(stderr, "Pushing to %s\n", dest); | |
df91ba36 | 103 | err = run_command_v_opt(argv, RUN_GIT_CMD); |
60b7f38e | 104 | if (!err) |
755225de | 105 | continue; |
39878b0c | 106 | |
5751f490 | 107 | error("failed to push to '%s'", remote->uri[i]); |
60b7f38e | 108 | switch (err) { |
755225de | 109 | case -ERR_RUN_COMMAND_FORK: |
fd1d1b05 | 110 | error("unable to fork for %s", sender); |
755225de | 111 | case -ERR_RUN_COMMAND_EXEC: |
fd1d1b05 JH |
112 | error("unable to exec %s", sender); |
113 | break; | |
755225de LT |
114 | case -ERR_RUN_COMMAND_WAITPID: |
115 | case -ERR_RUN_COMMAND_WAITPID_WRONG_PID: | |
116 | case -ERR_RUN_COMMAND_WAITPID_SIGNAL: | |
117 | case -ERR_RUN_COMMAND_WAITPID_NOEXIT: | |
fd1d1b05 | 118 | error("%s died with strange error", sender); |
755225de | 119 | } |
fd1d1b05 | 120 | errs++; |
755225de | 121 | } |
fd1d1b05 | 122 | return !!errs; |
755225de LT |
123 | } |
124 | ||
a633fca0 | 125 | int cmd_push(int argc, const char **argv, const char *prefix) |
755225de LT |
126 | { |
127 | int i; | |
5751f490 | 128 | const char *repo = NULL; /* default repository */ |
755225de LT |
129 | |
130 | for (i = 1; i < argc; i++) { | |
131 | const char *arg = argv[i]; | |
132 | ||
133 | if (arg[0] != '-') { | |
134 | repo = arg; | |
135 | i++; | |
136 | break; | |
137 | } | |
bcc785f6 LT |
138 | if (!strcmp(arg, "-v")) { |
139 | verbose=1; | |
140 | continue; | |
141 | } | |
cc44c765 | 142 | if (!prefixcmp(arg, "--repo=")) { |
bcc785f6 LT |
143 | repo = arg+7; |
144 | continue; | |
145 | } | |
755225de LT |
146 | if (!strcmp(arg, "--all")) { |
147 | all = 1; | |
148 | continue; | |
149 | } | |
150 | if (!strcmp(arg, "--tags")) { | |
8558fd9e | 151 | add_refspec("refs/tags/*"); |
755225de LT |
152 | continue; |
153 | } | |
8f615493 | 154 | if (!strcmp(arg, "--force") || !strcmp(arg, "-f")) { |
755225de LT |
155 | force = 1; |
156 | continue; | |
157 | } | |
158 | if (!strcmp(arg, "--thin")) { | |
159 | thin = 1; | |
160 | continue; | |
161 | } | |
162 | if (!strcmp(arg, "--no-thin")) { | |
163 | thin = 0; | |
164 | continue; | |
165 | } | |
cc44c765 | 166 | if (!prefixcmp(arg, "--receive-pack=")) { |
d23842fd UKK |
167 | receivepack = arg; |
168 | continue; | |
169 | } | |
cc44c765 | 170 | if (!prefixcmp(arg, "--exec=")) { |
d23842fd | 171 | receivepack = arg; |
755225de LT |
172 | continue; |
173 | } | |
174 | usage(push_usage); | |
175 | } | |
176 | set_refspecs(argv + i, argc - i); | |
8558fd9e DB |
177 | if (all && refspec) |
178 | usage(push_usage); | |
179 | ||
755225de LT |
180 | return do_push(repo); |
181 | } |