blob: 57a46b2654aa82b154d32eb77addd6a4f89c8e8d [file] [log] [blame]
Stephen Boydc2e86ad2011-03-22 00:51:05 -07001#include "builtin.h"
Linus Torvalds2a9c3fe2005-07-19 07:03:47 -04002#include "commit.h"
Linus Torvalds584c6cc2005-07-08 13:58:40 -07003#include "refs.h"
Linus Torvaldsf3a32142005-06-29 20:50:15 -07004#include "pkt-line.h"
Shawn O. Pearcede1a2fd2009-10-30 17:47:41 -07005#include "sideband.h"
Shawn O. Pearce38b1c662007-03-12 19:00:29 -04006#include "run-command.h"
Daniel Barkalow6b628162007-05-12 11:45:59 -04007#include "remote.h"
Daniel Barkalow96249c02007-10-29 22:03:39 -04008#include "send-pack.h"
Shawn O. Pearcede1a2fd2009-10-30 17:47:41 -07009#include "quote.h"
Michael Lukashovf1863d02010-02-16 23:42:52 +000010#include "transport.h"
Jeff Kingff5effd2012-08-03 12:19:16 -040011#include "version.h"
Linus Torvalds61221472005-06-29 19:09:05 -070012
Junio C Hamano2a245012005-07-14 00:10:05 -070013static const char send_pack_usage[] =
Stephan Beyer1b1dd232008-07-13 15:36:15 +020014"git send-pack [--all | --mirror] [--dry-run] [--force] [--receive-pack=<git-receive-pack>] [--verbose] [--thin] [<host>:]<directory> [<ref>...]\n"
Uwe Kleine-König18bd8822007-01-19 13:43:00 +010015" --all and explicit <ref> specification are mutually exclusive.";
Daniel Barkalow96249c02007-10-29 22:03:39 -040016
Brandon Casey6828f722009-03-26 21:37:53 -050017static struct send_pack_args args;
Linus Torvalds61221472005-06-29 19:09:05 -070018
Shawn O. Pearcede1a2fd2009-10-30 17:47:41 -070019static void print_helper_status(struct ref *ref)
20{
21 struct strbuf buf = STRBUF_INIT;
22
23 for (; ref; ref = ref->next) {
24 const char *msg = NULL;
25 const char *res;
26
27 switch(ref->status) {
28 case REF_STATUS_NONE:
29 res = "error";
30 msg = "no match";
31 break;
32
33 case REF_STATUS_OK:
34 res = "ok";
35 break;
36
37 case REF_STATUS_UPTODATE:
38 res = "ok";
39 msg = "up to date";
40 break;
41
42 case REF_STATUS_REJECT_NONFASTFORWARD:
43 res = "error";
44 msg = "non-fast forward";
45 break;
46
Junio C Hamano75e5c0d2013-01-23 13:55:30 -080047 case REF_STATUS_REJECT_FETCH_FIRST:
48 res = "error";
49 msg = "fetch first";
50 break;
51
52 case REF_STATUS_REJECT_NEEDS_FORCE:
53 res = "error";
54 msg = "needs force";
55 break;
56
Chris Rorvickdbfeddb2012-11-29 19:41:37 -060057 case REF_STATUS_REJECT_ALREADY_EXISTS:
58 res = "error";
59 msg = "already exists";
60 break;
61
Shawn O. Pearcede1a2fd2009-10-30 17:47:41 -070062 case REF_STATUS_REJECT_NODELETE:
63 case REF_STATUS_REMOTE_REJECT:
64 res = "error";
65 break;
66
67 case REF_STATUS_EXPECTING_REPORT:
68 default:
69 continue;
70 }
71
72 strbuf_reset(&buf);
73 strbuf_addf(&buf, "%s %s", res, ref->name);
74 if (ref->remote_status)
75 msg = ref->remote_status;
76 if (msg) {
77 strbuf_addch(&buf, ' ');
78 quote_two_c_style(&buf, "", msg, 0);
79 }
80 strbuf_addch(&buf, '\n');
81
82 safe_write(1, buf.buf, buf.len);
83 }
84 strbuf_release(&buf);
85}
86
Daniel Barkalow96249c02007-10-29 22:03:39 -040087int cmd_send_pack(int argc, const char **argv, const char *prefix)
Linus Torvalds61221472005-06-29 19:09:05 -070088{
Daniel Barkalow64fcef22009-03-08 21:06:07 -040089 int i, nr_refspecs = 0;
90 const char **refspecs = NULL;
Daniel Barkalow96249c02007-10-29 22:03:39 -040091 const char *remote_name = NULL;
Daniel Barkalowb5169682007-05-15 22:50:19 -040092 struct remote *remote = NULL;
Daniel Barkalow96249c02007-10-29 22:03:39 -040093 const char *dest = NULL;
Daniel Barkalow64fcef22009-03-08 21:06:07 -040094 int fd[2];
95 struct child_process *conn;
96 struct extra_have_objects extra_have;
Clemens Buchacher6d2bf962009-05-31 16:26:48 +020097 struct ref *remote_refs, *local_refs;
Daniel Barkalow64fcef22009-03-08 21:06:07 -040098 int ret;
Shawn O. Pearcede1a2fd2009-10-30 17:47:41 -070099 int helper_status = 0;
Daniel Barkalow64fcef22009-03-08 21:06:07 -0400100 int send_all = 0;
101 const char *receivepack = "git-receive-pack";
102 int flags;
Chris Rorvick10643d42012-11-29 19:41:33 -0600103 unsigned int reject_reasons;
Jeff King391b1f22012-05-01 04:42:24 -0400104 int progress = -1;
Junio C Hamano84a9b582006-03-23 23:41:18 -0800105
Linus Torvalds61221472005-06-29 19:09:05 -0700106 argv++;
Linus Torvaldsd0893912005-07-16 13:26:33 -0700107 for (i = 1; i < argc; i++, argv++) {
Daniel Barkalow96249c02007-10-29 22:03:39 -0400108 const char *arg = *argv;
Linus Torvalds61221472005-06-29 19:09:05 -0700109
110 if (*arg == '-') {
Junio C Hamanocc44c762007-02-20 01:53:29 -0800111 if (!prefixcmp(arg, "--receive-pack=")) {
Daniel Barkalow64fcef22009-03-08 21:06:07 -0400112 receivepack = arg + 15;
Uwe Kleine-Königd23842f2007-01-19 13:49:27 +0100113 continue;
114 }
Junio C Hamanocc44c762007-02-20 01:53:29 -0800115 if (!prefixcmp(arg, "--exec=")) {
Daniel Barkalow64fcef22009-03-08 21:06:07 -0400116 receivepack = arg + 7;
Linus Torvalds61221472005-06-29 19:09:05 -0700117 continue;
118 }
Daniel Barkalowb5169682007-05-15 22:50:19 -0400119 if (!prefixcmp(arg, "--remote=")) {
120 remote_name = arg + 9;
121 continue;
122 }
Linus Torvaldsd0893912005-07-16 13:26:33 -0700123 if (!strcmp(arg, "--all")) {
Daniel Barkalow64fcef22009-03-08 21:06:07 -0400124 send_all = 1;
Linus Torvaldsd0893912005-07-16 13:26:33 -0700125 continue;
126 }
Brian Ewinsa63103a2007-10-11 20:32:26 +0100127 if (!strcmp(arg, "--dry-run")) {
Daniel Barkalow96249c02007-10-29 22:03:39 -0400128 args.dry_run = 1;
Brian Ewinsa63103a2007-10-11 20:32:26 +0100129 continue;
130 }
Andy Whitcroft28b9d6e2007-11-09 23:32:10 +0000131 if (!strcmp(arg, "--mirror")) {
132 args.send_mirror = 1;
133 continue;
134 }
Linus Torvalds2a9c3fe2005-07-19 07:03:47 -0400135 if (!strcmp(arg, "--force")) {
Daniel Barkalow96249c02007-10-29 22:03:39 -0400136 args.force_update = 1;
Linus Torvalds2a9c3fe2005-07-19 07:03:47 -0400137 continue;
138 }
Clemens Buchacherc207e342012-01-08 22:06:20 +0100139 if (!strcmp(arg, "--quiet")) {
140 args.quiet = 1;
141 continue;
142 }
Linus Torvalds41f93a22005-12-20 18:13:02 -0800143 if (!strcmp(arg, "--verbose")) {
Daniel Barkalow96249c02007-10-29 22:03:39 -0400144 args.verbose = 1;
Linus Torvalds41f93a22005-12-20 18:13:02 -0800145 continue;
146 }
Jeff King391b1f22012-05-01 04:42:24 -0400147 if (!strcmp(arg, "--progress")) {
148 progress = 1;
149 continue;
150 }
151 if (!strcmp(arg, "--no-progress")) {
152 progress = 0;
153 continue;
154 }
Junio C Hamano2245be32006-02-19 15:03:49 -0800155 if (!strcmp(arg, "--thin")) {
Daniel Barkalow96249c02007-10-29 22:03:39 -0400156 args.use_thin_pack = 1;
Junio C Hamano2245be32006-02-19 15:03:49 -0800157 continue;
158 }
Shawn O. Pearcede1a2fd2009-10-30 17:47:41 -0700159 if (!strcmp(arg, "--stateless-rpc")) {
160 args.stateless_rpc = 1;
161 continue;
162 }
163 if (!strcmp(arg, "--helper-status")) {
164 helper_status = 1;
165 continue;
166 }
Linus Torvalds61221472005-06-29 19:09:05 -0700167 usage(send_pack_usage);
168 }
Linus Torvaldsd0893912005-07-16 13:26:33 -0700169 if (!dest) {
170 dest = arg;
171 continue;
172 }
Daniel Barkalow64fcef22009-03-08 21:06:07 -0400173 refspecs = (const char **) argv;
174 nr_refspecs = argc - i;
Linus Torvalds61221472005-06-29 19:09:05 -0700175 break;
176 }
177 if (!dest)
178 usage(send_pack_usage);
Andy Whitcroft28b9d6e2007-11-09 23:32:10 +0000179 /*
180 * --all and --mirror are incompatible; neither makes sense
181 * with any refspecs.
182 */
Daniel Barkalow64fcef22009-03-08 21:06:07 -0400183 if ((refspecs && (send_all || args.send_mirror)) ||
184 (send_all && args.send_mirror))
Junio C Hamano0bc3cdf2005-08-02 12:20:27 -0700185 usage(send_pack_usage);
Junio C Hamano37adac72006-12-13 10:30:11 -0800186
Daniel Barkalowb5169682007-05-15 22:50:19 -0400187 if (remote_name) {
188 remote = remote_get(remote_name);
Shawn O. Pearce28b91f82007-09-19 00:49:27 -0400189 if (!remote_has_url(remote, dest)) {
Daniel Barkalowb5169682007-05-15 22:50:19 -0400190 die("Destination %s is not a uri for %s",
191 dest, remote_name);
192 }
193 }
194
Jeff King391b1f22012-05-01 04:42:24 -0400195 if (progress == -1)
196 progress = !args.quiet && isatty(2);
197 args.progress = progress;
Jeff King8d32e602012-05-01 04:41:42 -0400198
Shawn O. Pearcede1a2fd2009-10-30 17:47:41 -0700199 if (args.stateless_rpc) {
200 conn = NULL;
201 fd[0] = 0;
202 fd[1] = 1;
203 } else {
Junio C Hamano5a277f32011-09-06 11:06:32 -0700204 conn = git_connect(fd, dest, receivepack,
Shawn O. Pearcede1a2fd2009-10-30 17:47:41 -0700205 args.verbose ? CONNECT_VERBOSE : 0);
206 }
Daniel Barkalow96249c02007-10-29 22:03:39 -0400207
Daniel Barkalow64fcef22009-03-08 21:06:07 -0400208 memset(&extra_have, 0, sizeof(extra_have));
Daniel Barkalow96249c02007-10-29 22:03:39 -0400209
Jeff Kingafe7c5f2011-12-12 19:41:37 -0500210 get_remote_heads(fd[0], &remote_refs, REF_NORMAL, &extra_have);
Daniel Barkalow96249c02007-10-29 22:03:39 -0400211
Michael Lukashovf1863d02010-02-16 23:42:52 +0000212 transport_verify_remote_names(nr_refspecs, refspecs);
Daniel Barkalow96249c02007-10-29 22:03:39 -0400213
Daniel Barkalow64fcef22009-03-08 21:06:07 -0400214 local_refs = get_local_heads();
215
216 flags = MATCH_REFS_NONE;
217
218 if (send_all)
219 flags |= MATCH_REFS_ALL;
220 if (args.send_mirror)
221 flags |= MATCH_REFS_MIRROR;
222
223 /* match them up */
Junio C Hamano29753cd2011-09-09 11:54:58 -0700224 if (match_push_refs(local_refs, &remote_refs, nr_refspecs, refspecs, flags))
Daniel Barkalow64fcef22009-03-08 21:06:07 -0400225 return -1;
Daniel Barkalow64fcef22009-03-08 21:06:07 -0400226
Tay Ray Chuan20e8b462010-01-08 10:12:42 +0800227 set_ref_status_for_push(remote_refs, args.send_mirror,
228 args.force_update);
229
Daniel Barkalow64fcef22009-03-08 21:06:07 -0400230 ret = send_pack(&args, fd, conn, remote_refs, &extra_have);
231
Shawn O. Pearcede1a2fd2009-10-30 17:47:41 -0700232 if (helper_status)
233 print_helper_status(remote_refs);
234
Daniel Barkalow64fcef22009-03-08 21:06:07 -0400235 close(fd[1]);
Linus Torvalds7f8e9822005-06-29 22:50:48 -0700236 close(fd[0]);
Daniel Barkalow64fcef22009-03-08 21:06:07 -0400237
Johannes Sixt98158e92007-10-19 21:47:53 +0200238 ret |= finish_connect(conn);
Daniel Barkalow64fcef22009-03-08 21:06:07 -0400239
Shawn O. Pearcede1a2fd2009-10-30 17:47:41 -0700240 if (!helper_status)
Chris Rorvick10643d42012-11-29 19:41:33 -0600241 transport_print_push_status(dest, remote_refs, args.verbose, 0, &reject_reasons);
Daniel Barkalow64fcef22009-03-08 21:06:07 -0400242
243 if (!args.dry_run && remote) {
244 struct ref *ref;
245 for (ref = remote_refs; ref; ref = ref->next)
Michael Lukashovf1863d02010-02-16 23:42:52 +0000246 transport_update_tracking_ref(remote, ref, args.verbose);
Daniel Barkalow64fcef22009-03-08 21:06:07 -0400247 }
248
Michael Lukashovf1863d02010-02-16 23:42:52 +0000249 if (!ret && !transport_refs_pushed(remote_refs))
Daniel Barkalow64fcef22009-03-08 21:06:07 -0400250 fprintf(stderr, "Everything up-to-date\n");
251
252 return ret;
Linus Torvalds61221472005-06-29 19:09:05 -0700253}