Stephen Boyd | c2e86ad | 2011-03-22 00:51:05 -0700 | [diff] [blame] | 1 | #include "builtin.h" |
Linus Torvalds | 2a9c3fe | 2005-07-19 07:03:47 -0400 | [diff] [blame] | 2 | #include "commit.h" |
Linus Torvalds | 584c6cc | 2005-07-08 13:58:40 -0700 | [diff] [blame] | 3 | #include "refs.h" |
Linus Torvalds | f3a3214 | 2005-06-29 20:50:15 -0700 | [diff] [blame] | 4 | #include "pkt-line.h" |
Shawn O. Pearce | de1a2fd | 2009-10-30 17:47:41 -0700 | [diff] [blame] | 5 | #include "sideband.h" |
Shawn O. Pearce | 38b1c66 | 2007-03-12 19:00:29 -0400 | [diff] [blame] | 6 | #include "run-command.h" |
Daniel Barkalow | 6b62816 | 2007-05-12 11:45:59 -0400 | [diff] [blame] | 7 | #include "remote.h" |
Daniel Barkalow | 96249c0 | 2007-10-29 22:03:39 -0400 | [diff] [blame] | 8 | #include "send-pack.h" |
Shawn O. Pearce | de1a2fd | 2009-10-30 17:47:41 -0700 | [diff] [blame] | 9 | #include "quote.h" |
Michael Lukashov | f1863d0 | 2010-02-16 23:42:52 +0000 | [diff] [blame] | 10 | #include "transport.h" |
Linus Torvalds | 6122147 | 2005-06-29 19:09:05 -0700 | [diff] [blame] | 11 | |
Junio C Hamano | 2a24501 | 2005-07-14 00:10:05 -0700 | [diff] [blame] | 12 | static const char send_pack_usage[] = |
Stephan Beyer | 1b1dd23 | 2008-07-13 15:36:15 +0200 | [diff] [blame] | 13 | "git send-pack [--all | --mirror] [--dry-run] [--force] [--receive-pack=<git-receive-pack>] [--verbose] [--thin] [<host>:]<directory> [<ref>...]\n" |
Uwe Kleine-König | 18bd882 | 2007-01-19 13:43:00 +0100 | [diff] [blame] | 14 | " --all and explicit <ref> specification are mutually exclusive."; |
Daniel Barkalow | 96249c0 | 2007-10-29 22:03:39 -0400 | [diff] [blame] | 15 | |
Brandon Casey | 6828f72 | 2009-03-26 21:37:53 -0500 | [diff] [blame] | 16 | static struct send_pack_args args; |
Linus Torvalds | 6122147 | 2005-06-29 19:09:05 -0700 | [diff] [blame] | 17 | |
Junio C Hamano | 02322e1 | 2009-01-27 20:21:31 -0800 | [diff] [blame] | 18 | static int feed_object(const unsigned char *sha1, int fd, int negative) |
| 19 | { |
| 20 | char buf[42]; |
| 21 | |
| 22 | if (negative && !has_sha1_file(sha1)) |
| 23 | return 1; |
| 24 | |
| 25 | memcpy(buf + negative, sha1_to_hex(sha1), 40); |
| 26 | if (negative) |
| 27 | buf[0] = '^'; |
| 28 | buf[40 + negative] = '\n'; |
| 29 | return write_or_whine(fd, buf, 41 + negative, "send-pack: send refs"); |
| 30 | } |
| 31 | |
Andy Whitcroft | c727fe2 | 2006-09-05 22:52:12 +0100 | [diff] [blame] | 32 | /* |
Junio C Hamano | 0ae5f98 | 2006-12-31 01:26:53 -0800 | [diff] [blame] | 33 | * Make a pack stream and spit it out into file descriptor fd |
Andy Whitcroft | c727fe2 | 2006-09-05 22:52:12 +0100 | [diff] [blame] | 34 | */ |
Daniel Barkalow | 64fcef2 | 2009-03-08 21:06:07 -0400 | [diff] [blame] | 35 | static int pack_objects(int fd, struct ref *refs, struct extra_have_objects *extra, struct send_pack_args *args) |
Linus Torvalds | 94fdb7a | 2005-06-30 10:17:39 -0700 | [diff] [blame] | 36 | { |
Shawn O. Pearce | 38b1c66 | 2007-03-12 19:00:29 -0400 | [diff] [blame] | 37 | /* |
| 38 | * The child becomes pack-objects --revs; we feed |
| 39 | * the revision parameters to it via its stdin and |
| 40 | * let its stdout go back to the other end. |
| 41 | */ |
Daniel Barkalow | 96249c0 | 2007-10-29 22:03:39 -0400 | [diff] [blame] | 42 | const char *argv[] = { |
Shawn O. Pearce | 38b1c66 | 2007-03-12 19:00:29 -0400 | [diff] [blame] | 43 | "pack-objects", |
Nicolas Pitre | 4f36627 | 2009-11-23 12:43:50 -0500 | [diff] [blame] | 44 | "--all-progress-implied", |
Shawn O. Pearce | 38b1c66 | 2007-03-12 19:00:29 -0400 | [diff] [blame] | 45 | "--revs", |
| 46 | "--stdout", |
| 47 | NULL, |
| 48 | NULL, |
Nicolas Pitre | b74fce1 | 2009-05-01 16:56:47 -0400 | [diff] [blame] | 49 | NULL, |
Jeff King | 1207032 | 2009-08-05 16:22:36 -0400 | [diff] [blame] | 50 | NULL, |
Jeff King | d7c411b | 2010-10-17 02:37:03 +0800 | [diff] [blame] | 51 | NULL, |
Shawn O. Pearce | 38b1c66 | 2007-03-12 19:00:29 -0400 | [diff] [blame] | 52 | }; |
| 53 | struct child_process po; |
Junio C Hamano | 40c155f | 2008-09-09 01:27:09 -0700 | [diff] [blame] | 54 | int i; |
Linus Torvalds | 94fdb7a | 2005-06-30 10:17:39 -0700 | [diff] [blame] | 55 | |
Nicolas Pitre | b74fce1 | 2009-05-01 16:56:47 -0400 | [diff] [blame] | 56 | i = 4; |
Daniel Barkalow | 64fcef2 | 2009-03-08 21:06:07 -0400 | [diff] [blame] | 57 | if (args->use_thin_pack) |
Nicolas Pitre | b74fce1 | 2009-05-01 16:56:47 -0400 | [diff] [blame] | 58 | argv[i++] = "--thin"; |
| 59 | if (args->use_ofs_delta) |
| 60 | argv[i++] = "--delta-base-offset"; |
Jeff King | 1207032 | 2009-08-05 16:22:36 -0400 | [diff] [blame] | 61 | if (args->quiet) |
| 62 | argv[i++] = "-q"; |
Jeff King | d7c411b | 2010-10-17 02:37:03 +0800 | [diff] [blame] | 63 | if (args->progress) |
| 64 | argv[i++] = "--progress"; |
Shawn O. Pearce | 38b1c66 | 2007-03-12 19:00:29 -0400 | [diff] [blame] | 65 | memset(&po, 0, sizeof(po)); |
Daniel Barkalow | 96249c0 | 2007-10-29 22:03:39 -0400 | [diff] [blame] | 66 | po.argv = argv; |
Shawn O. Pearce | 38b1c66 | 2007-03-12 19:00:29 -0400 | [diff] [blame] | 67 | po.in = -1; |
Shawn O. Pearce | de1a2fd | 2009-10-30 17:47:41 -0700 | [diff] [blame] | 68 | po.out = args->stateless_rpc ? -1 : fd; |
Shawn O. Pearce | 38b1c66 | 2007-03-12 19:00:29 -0400 | [diff] [blame] | 69 | po.git_cmd = 1; |
| 70 | if (start_command(&po)) |
Thomas Rast | d824cbb | 2009-06-27 17:58:46 +0200 | [diff] [blame] | 71 | die_errno("git pack-objects failed"); |
Andy Whitcroft | c727fe2 | 2006-09-05 22:52:12 +0100 | [diff] [blame] | 72 | |
Junio C Hamano | 0ae5f98 | 2006-12-31 01:26:53 -0800 | [diff] [blame] | 73 | /* |
| 74 | * We feed the pack-objects we just spawned with revision |
| 75 | * parameters by writing to the pipe. |
Andy Whitcroft | c727fe2 | 2006-09-05 22:52:12 +0100 | [diff] [blame] | 76 | */ |
Junio C Hamano | 02322e1 | 2009-01-27 20:21:31 -0800 | [diff] [blame] | 77 | for (i = 0; i < extra->nr; i++) |
| 78 | if (!feed_object(extra->array[i], po.in, 1)) |
Junio C Hamano | 40c155f | 2008-09-09 01:27:09 -0700 | [diff] [blame] | 79 | break; |
Andy Whitcroft | c727fe2 | 2006-09-05 22:52:12 +0100 | [diff] [blame] | 80 | |
Junio C Hamano | 40c155f | 2008-09-09 01:27:09 -0700 | [diff] [blame] | 81 | while (refs) { |
Andy Whitcroft | c727fe2 | 2006-09-05 22:52:12 +0100 | [diff] [blame] | 82 | if (!is_null_sha1(refs->old_sha1) && |
Junio C Hamano | 02322e1 | 2009-01-27 20:21:31 -0800 | [diff] [blame] | 83 | !feed_object(refs->old_sha1, po.in, 1)) |
| 84 | break; |
| 85 | if (!is_null_sha1(refs->new_sha1) && |
| 86 | !feed_object(refs->new_sha1, po.in, 0)) |
| 87 | break; |
Andy Whitcroft | c727fe2 | 2006-09-05 22:52:12 +0100 | [diff] [blame] | 88 | refs = refs->next; |
| 89 | } |
Andy Whitcroft | c727fe2 | 2006-09-05 22:52:12 +0100 | [diff] [blame] | 90 | |
Johannes Sixt | e72ae28 | 2008-02-16 18:36:38 +0100 | [diff] [blame] | 91 | close(po.in); |
Shawn O. Pearce | de1a2fd | 2009-10-30 17:47:41 -0700 | [diff] [blame] | 92 | |
| 93 | if (args->stateless_rpc) { |
| 94 | char *buf = xmalloc(LARGE_PACKET_MAX); |
| 95 | while (1) { |
| 96 | ssize_t n = xread(po.out, buf, LARGE_PACKET_MAX); |
| 97 | if (n <= 0) |
| 98 | break; |
| 99 | send_sideband(fd, -1, buf, n, LARGE_PACKET_MAX); |
| 100 | } |
| 101 | free(buf); |
| 102 | close(po.out); |
| 103 | po.out = -1; |
| 104 | } |
| 105 | |
Shawn O. Pearce | 38b1c66 | 2007-03-12 19:00:29 -0400 | [diff] [blame] | 106 | if (finish_command(&po)) |
Jonathan Nieder | 64f003a | 2010-10-16 12:09:54 -0500 | [diff] [blame] | 107 | return -1; |
Shawn O. Pearce | 38b1c66 | 2007-03-12 19:00:29 -0400 | [diff] [blame] | 108 | return 0; |
Linus Torvalds | 94fdb7a | 2005-06-30 10:17:39 -0700 | [diff] [blame] | 109 | } |
Linus Torvalds | e4b5c7f | 2005-06-29 22:31:41 -0700 | [diff] [blame] | 110 | |
Jeff King | ca74c45 | 2007-11-17 07:56:03 -0500 | [diff] [blame] | 111 | static int receive_status(int in, struct ref *refs) |
| 112 | { |
| 113 | struct ref *hint; |
Junio C Hamano | cfee10a | 2005-12-25 23:18:37 -0800 | [diff] [blame] | 114 | char line[1000]; |
| 115 | int ret = 0; |
| 116 | int len = packet_read_line(in, line, sizeof(line)); |
Jeff King | 2a0fe89 | 2007-11-18 02:16:52 -0500 | [diff] [blame] | 117 | if (len < 10 || memcmp(line, "unpack ", 7)) |
| 118 | return error("did not receive remote status"); |
Junio C Hamano | cfee10a | 2005-12-25 23:18:37 -0800 | [diff] [blame] | 119 | if (memcmp(line, "unpack ok\n", 10)) { |
Jeff King | 2a0fe89 | 2007-11-18 02:16:52 -0500 | [diff] [blame] | 120 | char *p = line + strlen(line) - 1; |
| 121 | if (*p == '\n') |
| 122 | *p = '\0'; |
| 123 | error("unpack failed: %s", line + 7); |
Junio C Hamano | cfee10a | 2005-12-25 23:18:37 -0800 | [diff] [blame] | 124 | ret = -1; |
| 125 | } |
Jeff King | ca74c45 | 2007-11-17 07:56:03 -0500 | [diff] [blame] | 126 | hint = NULL; |
Junio C Hamano | cfee10a | 2005-12-25 23:18:37 -0800 | [diff] [blame] | 127 | while (1) { |
Jeff King | 2a0fe89 | 2007-11-18 02:16:52 -0500 | [diff] [blame] | 128 | char *refname; |
| 129 | char *msg; |
Junio C Hamano | cfee10a | 2005-12-25 23:18:37 -0800 | [diff] [blame] | 130 | len = packet_read_line(in, line, sizeof(line)); |
| 131 | if (!len) |
| 132 | break; |
| 133 | if (len < 3 || |
Jeff King | 2a0fe89 | 2007-11-18 02:16:52 -0500 | [diff] [blame] | 134 | (memcmp(line, "ok ", 3) && memcmp(line, "ng ", 3))) { |
Junio C Hamano | cfee10a | 2005-12-25 23:18:37 -0800 | [diff] [blame] | 135 | fprintf(stderr, "protocol error: %s\n", line); |
| 136 | ret = -1; |
| 137 | break; |
| 138 | } |
Jeff King | 2a0fe89 | 2007-11-18 02:16:52 -0500 | [diff] [blame] | 139 | |
| 140 | line[strlen(line)-1] = '\0'; |
| 141 | refname = line + 3; |
| 142 | msg = strchr(refname, ' '); |
| 143 | if (msg) |
| 144 | *msg++ = '\0'; |
| 145 | |
| 146 | /* first try searching at our hint, falling back to all refs */ |
Jeff King | ca74c45 | 2007-11-17 07:56:03 -0500 | [diff] [blame] | 147 | if (hint) |
Jeff King | 2a0fe89 | 2007-11-18 02:16:52 -0500 | [diff] [blame] | 148 | hint = find_ref_by_name(hint, refname); |
Jeff King | ca74c45 | 2007-11-17 07:56:03 -0500 | [diff] [blame] | 149 | if (!hint) |
Jeff King | 2a0fe89 | 2007-11-18 02:16:52 -0500 | [diff] [blame] | 150 | hint = find_ref_by_name(refs, refname); |
| 151 | if (!hint) { |
| 152 | warning("remote reported status on unknown ref: %s", |
| 153 | refname); |
| 154 | continue; |
| 155 | } |
| 156 | if (hint->status != REF_STATUS_EXPECTING_REPORT) { |
| 157 | warning("remote reported status on unexpected ref: %s", |
| 158 | refname); |
| 159 | continue; |
| 160 | } |
| 161 | |
| 162 | if (line[0] == 'o' && line[1] == 'k') |
| 163 | hint->status = REF_STATUS_OK; |
| 164 | else { |
| 165 | hint->status = REF_STATUS_REMOTE_REJECT; |
| 166 | ret = -1; |
| 167 | } |
| 168 | if (msg) |
| 169 | hint->remote_status = xstrdup(msg); |
| 170 | /* start our next search from the next ref */ |
| 171 | hint = hint->next; |
Junio C Hamano | cfee10a | 2005-12-25 23:18:37 -0800 | [diff] [blame] | 172 | } |
| 173 | return ret; |
| 174 | } |
| 175 | |
Shawn O. Pearce | de1a2fd | 2009-10-30 17:47:41 -0700 | [diff] [blame] | 176 | static void print_helper_status(struct ref *ref) |
| 177 | { |
| 178 | struct strbuf buf = STRBUF_INIT; |
| 179 | |
| 180 | for (; ref; ref = ref->next) { |
| 181 | const char *msg = NULL; |
| 182 | const char *res; |
| 183 | |
| 184 | switch(ref->status) { |
| 185 | case REF_STATUS_NONE: |
| 186 | res = "error"; |
| 187 | msg = "no match"; |
| 188 | break; |
| 189 | |
| 190 | case REF_STATUS_OK: |
| 191 | res = "ok"; |
| 192 | break; |
| 193 | |
| 194 | case REF_STATUS_UPTODATE: |
| 195 | res = "ok"; |
| 196 | msg = "up to date"; |
| 197 | break; |
| 198 | |
| 199 | case REF_STATUS_REJECT_NONFASTFORWARD: |
| 200 | res = "error"; |
| 201 | msg = "non-fast forward"; |
| 202 | break; |
| 203 | |
| 204 | case REF_STATUS_REJECT_NODELETE: |
| 205 | case REF_STATUS_REMOTE_REJECT: |
| 206 | res = "error"; |
| 207 | break; |
| 208 | |
| 209 | case REF_STATUS_EXPECTING_REPORT: |
| 210 | default: |
| 211 | continue; |
| 212 | } |
| 213 | |
| 214 | strbuf_reset(&buf); |
| 215 | strbuf_addf(&buf, "%s %s", res, ref->name); |
| 216 | if (ref->remote_status) |
| 217 | msg = ref->remote_status; |
| 218 | if (msg) { |
| 219 | strbuf_addch(&buf, ' '); |
| 220 | quote_two_c_style(&buf, "", msg, 0); |
| 221 | } |
| 222 | strbuf_addch(&buf, '\n'); |
| 223 | |
| 224 | safe_write(1, buf.buf, buf.len); |
| 225 | } |
| 226 | strbuf_release(&buf); |
| 227 | } |
| 228 | |
Shawn O. Pearce | 0c499ea | 2010-02-05 12:57:39 -0800 | [diff] [blame] | 229 | static int sideband_demux(int in, int out, void *data) |
| 230 | { |
Junio C Hamano | 6143214 | 2011-05-16 16:19:49 -0700 | [diff] [blame] | 231 | int *fd = data, ret; |
Junio C Hamano | 73776dc | 2011-04-25 15:20:39 -0700 | [diff] [blame] | 232 | #ifdef NO_PTHREADS |
Johannes Sixt | 09c9957 | 2011-04-25 23:04:10 +0200 | [diff] [blame] | 233 | close(fd[1]); |
| 234 | #endif |
Junio C Hamano | 6143214 | 2011-05-16 16:19:49 -0700 | [diff] [blame] | 235 | ret = recv_sideband("send-pack", fd[0], out); |
Shawn O. Pearce | 0c499ea | 2010-02-05 12:57:39 -0800 | [diff] [blame] | 236 | close(out); |
| 237 | return ret; |
| 238 | } |
| 239 | |
Daniel Barkalow | 64fcef2 | 2009-03-08 21:06:07 -0400 | [diff] [blame] | 240 | int send_pack(struct send_pack_args *args, |
| 241 | int fd[], struct child_process *conn, |
| 242 | struct ref *remote_refs, |
| 243 | struct extra_have_objects *extra_have) |
Junio C Hamano | f88395a | 2005-08-03 16:35:29 -0700 | [diff] [blame] | 244 | { |
Daniel Barkalow | 64fcef2 | 2009-03-08 21:06:07 -0400 | [diff] [blame] | 245 | int in = fd[0]; |
| 246 | int out = fd[1]; |
Shawn O. Pearce | de1a2fd | 2009-10-30 17:47:41 -0700 | [diff] [blame] | 247 | struct strbuf req_buf = STRBUF_INIT; |
Daniel Barkalow | 64fcef2 | 2009-03-08 21:06:07 -0400 | [diff] [blame] | 248 | struct ref *ref; |
Linus Torvalds | 584c6cc | 2005-07-08 13:58:40 -0700 | [diff] [blame] | 249 | int new_refs; |
Junio C Hamano | d4f694b | 2006-11-24 00:26:49 -0800 | [diff] [blame] | 250 | int allow_deleting_refs = 0; |
Shawn O. Pearce | 0c499ea | 2010-02-05 12:57:39 -0800 | [diff] [blame] | 251 | int status_report = 0; |
| 252 | int use_sideband = 0; |
| 253 | unsigned cmds_sent = 0; |
Jeff King | ca74c45 | 2007-11-17 07:56:03 -0500 | [diff] [blame] | 254 | int ret; |
Shawn O. Pearce | 0c499ea | 2010-02-05 12:57:39 -0800 | [diff] [blame] | 255 | struct async demux; |
Linus Torvalds | 7f8e982 | 2005-06-29 22:50:48 -0700 | [diff] [blame] | 256 | |
Junio C Hamano | cfee10a | 2005-12-25 23:18:37 -0800 | [diff] [blame] | 257 | /* Does the other end support the reporting? */ |
| 258 | if (server_supports("report-status")) |
Shawn O. Pearce | 0c499ea | 2010-02-05 12:57:39 -0800 | [diff] [blame] | 259 | status_report = 1; |
Junio C Hamano | d4f694b | 2006-11-24 00:26:49 -0800 | [diff] [blame] | 260 | if (server_supports("delete-refs")) |
| 261 | allow_deleting_refs = 1; |
Nicolas Pitre | b74fce1 | 2009-05-01 16:56:47 -0400 | [diff] [blame] | 262 | if (server_supports("ofs-delta")) |
| 263 | args->use_ofs_delta = 1; |
Shawn O. Pearce | 0c499ea | 2010-02-05 12:57:39 -0800 | [diff] [blame] | 264 | if (server_supports("side-band-64k")) |
| 265 | use_sideband = 1; |
Junio C Hamano | cfee10a | 2005-12-25 23:18:37 -0800 | [diff] [blame] | 266 | |
Daniel Barkalow | 4c353e8 | 2005-12-04 11:59:37 -0500 | [diff] [blame] | 267 | if (!remote_refs) { |
Andrew Clausen | 7e23b06 | 2007-10-16 17:16:05 -0400 | [diff] [blame] | 268 | fprintf(stderr, "No refs in common and none specified; doing nothing.\n" |
| 269 | "Perhaps you should specify a branch such as 'master'.\n"); |
Daniel Barkalow | 4c353e8 | 2005-12-04 11:59:37 -0500 | [diff] [blame] | 270 | return 0; |
| 271 | } |
| 272 | |
Linus Torvalds | 584c6cc | 2005-07-08 13:58:40 -0700 | [diff] [blame] | 273 | /* |
| 274 | * Finally, tell the other end! |
| 275 | */ |
| 276 | new_refs = 0; |
Junio C Hamano | f88395a | 2005-08-03 16:35:29 -0700 | [diff] [blame] | 277 | for (ref = remote_refs; ref; ref = ref->next) { |
Tay Ray Chuan | 20e8b46 | 2010-01-08 10:12:42 +0800 | [diff] [blame] | 278 | if (!ref->peer_ref && !args->send_mirror) |
Clemens Buchacher | 16ed2f4 | 2008-11-05 21:55:54 +0100 | [diff] [blame] | 279 | continue; |
Junio C Hamano | d4f694b | 2006-11-24 00:26:49 -0800 | [diff] [blame] | 280 | |
Tay Ray Chuan | 20e8b46 | 2010-01-08 10:12:42 +0800 | [diff] [blame] | 281 | /* Check for statuses set by set_ref_status_for_push() */ |
| 282 | switch (ref->status) { |
| 283 | case REF_STATUS_REJECT_NONFASTFORWARD: |
| 284 | case REF_STATUS_UPTODATE: |
| 285 | continue; |
| 286 | default: |
| 287 | ; /* do nothing */ |
| 288 | } |
| 289 | |
Jeff King | 8736a84 | 2007-11-17 07:54:27 -0500 | [diff] [blame] | 290 | if (ref->deletion && !allow_deleting_refs) { |
| 291 | ref->status = REF_STATUS_REJECT_NODELETE; |
Junio C Hamano | d4f694b | 2006-11-24 00:26:49 -0800 | [diff] [blame] | 292 | continue; |
| 293 | } |
Jeff King | 8736a84 | 2007-11-17 07:54:27 -0500 | [diff] [blame] | 294 | |
Jeff King | 8736a84 | 2007-11-17 07:54:27 -0500 | [diff] [blame] | 295 | if (!ref->deletion) |
Junio C Hamano | d4f694b | 2006-11-24 00:26:49 -0800 | [diff] [blame] | 296 | new_refs++; |
Junio C Hamano | cfee10a | 2005-12-25 23:18:37 -0800 | [diff] [blame] | 297 | |
Shawn O. Pearce | 0c499ea | 2010-02-05 12:57:39 -0800 | [diff] [blame] | 298 | if (args->dry_run) { |
| 299 | ref->status = REF_STATUS_OK; |
| 300 | } else { |
Jeff King | 8736a84 | 2007-11-17 07:54:27 -0500 | [diff] [blame] | 301 | char *old_hex = sha1_to_hex(ref->old_sha1); |
| 302 | char *new_hex = sha1_to_hex(ref->new_sha1); |
| 303 | |
Shawn O. Pearce | 0c499ea | 2010-02-05 12:57:39 -0800 | [diff] [blame] | 304 | if (!cmds_sent && (status_report || use_sideband)) { |
| 305 | packet_buf_write(&req_buf, "%s %s %s%c%s%s", |
Brian Ewins | a63103a | 2007-10-11 20:32:26 +0100 | [diff] [blame] | 306 | old_hex, new_hex, ref->name, 0, |
Shawn O. Pearce | 0c499ea | 2010-02-05 12:57:39 -0800 | [diff] [blame] | 307 | status_report ? " report-status" : "", |
| 308 | use_sideband ? " side-band-64k" : ""); |
Brian Ewins | a63103a | 2007-10-11 20:32:26 +0100 | [diff] [blame] | 309 | } |
| 310 | else |
Shawn O. Pearce | de1a2fd | 2009-10-30 17:47:41 -0700 | [diff] [blame] | 311 | packet_buf_write(&req_buf, "%s %s %s", |
Brian Ewins | a63103a | 2007-10-11 20:32:26 +0100 | [diff] [blame] | 312 | old_hex, new_hex, ref->name); |
Shawn O. Pearce | 0c499ea | 2010-02-05 12:57:39 -0800 | [diff] [blame] | 313 | ref->status = status_report ? |
| 314 | REF_STATUS_EXPECTING_REPORT : |
| 315 | REF_STATUS_OK; |
| 316 | cmds_sent++; |
Junio C Hamano | cfee10a | 2005-12-25 23:18:37 -0800 | [diff] [blame] | 317 | } |
Linus Torvalds | 7f8e982 | 2005-06-29 22:50:48 -0700 | [diff] [blame] | 318 | } |
Junio C Hamano | f88395a | 2005-08-03 16:35:29 -0700 | [diff] [blame] | 319 | |
Shawn O. Pearce | de1a2fd | 2009-10-30 17:47:41 -0700 | [diff] [blame] | 320 | if (args->stateless_rpc) { |
Shawn O. Pearce | 0c499ea | 2010-02-05 12:57:39 -0800 | [diff] [blame] | 321 | if (!args->dry_run && cmds_sent) { |
Shawn O. Pearce | de1a2fd | 2009-10-30 17:47:41 -0700 | [diff] [blame] | 322 | packet_buf_flush(&req_buf); |
| 323 | send_sideband(out, -1, req_buf.buf, req_buf.len, LARGE_PACKET_MAX); |
| 324 | } |
| 325 | } else { |
| 326 | safe_write(out, req_buf.buf, req_buf.len); |
| 327 | packet_flush(out); |
| 328 | } |
| 329 | strbuf_release(&req_buf); |
| 330 | |
Shawn O. Pearce | 0c499ea | 2010-02-05 12:57:39 -0800 | [diff] [blame] | 331 | if (use_sideband && cmds_sent) { |
| 332 | memset(&demux, 0, sizeof(demux)); |
| 333 | demux.proc = sideband_demux; |
| 334 | demux.data = fd; |
| 335 | demux.out = -1; |
| 336 | if (start_async(&demux)) |
| 337 | die("receive-pack: unable to fork off sideband demultiplexer"); |
| 338 | in = demux.out; |
| 339 | } |
| 340 | |
| 341 | if (new_refs && cmds_sent) { |
Daniel Barkalow | 64fcef2 | 2009-03-08 21:06:07 -0400 | [diff] [blame] | 342 | if (pack_objects(out, remote_refs, extra_have, args) < 0) { |
| 343 | for (ref = remote_refs; ref; ref = ref->next) |
| 344 | ref->status = REF_STATUS_NONE; |
Jeff King | e07fd15 | 2011-05-05 02:18:45 -0400 | [diff] [blame] | 345 | if (args->stateless_rpc) |
| 346 | close(out); |
Jeff King | a1a3fd1 | 2011-05-16 02:52:57 -0400 | [diff] [blame] | 347 | if (git_connection_is_socket(conn)) |
| 348 | shutdown(fd[0], SHUT_WR); |
Shawn O. Pearce | 0c499ea | 2010-02-05 12:57:39 -0800 | [diff] [blame] | 349 | if (use_sideband) |
| 350 | finish_async(&demux); |
Jeff King | 8736a84 | 2007-11-17 07:54:27 -0500 | [diff] [blame] | 351 | return -1; |
Daniel Barkalow | 64fcef2 | 2009-03-08 21:06:07 -0400 | [diff] [blame] | 352 | } |
Jeff King | 8736a84 | 2007-11-17 07:54:27 -0500 | [diff] [blame] | 353 | } |
Shawn O. Pearce | 0c499ea | 2010-02-05 12:57:39 -0800 | [diff] [blame] | 354 | if (args->stateless_rpc && cmds_sent) |
Shawn O. Pearce | de1a2fd | 2009-10-30 17:47:41 -0700 | [diff] [blame] | 355 | packet_flush(out); |
Junio C Hamano | cfee10a | 2005-12-25 23:18:37 -0800 | [diff] [blame] | 356 | |
Shawn O. Pearce | 0c499ea | 2010-02-05 12:57:39 -0800 | [diff] [blame] | 357 | if (status_report && cmds_sent) |
Jeff King | ca74c45 | 2007-11-17 07:56:03 -0500 | [diff] [blame] | 358 | ret = receive_status(in, remote_refs); |
Jeff King | ca74c45 | 2007-11-17 07:56:03 -0500 | [diff] [blame] | 359 | else |
| 360 | ret = 0; |
Shawn O. Pearce | de1a2fd | 2009-10-30 17:47:41 -0700 | [diff] [blame] | 361 | if (args->stateless_rpc) |
| 362 | packet_flush(out); |
Jeff King | ca74c45 | 2007-11-17 07:56:03 -0500 | [diff] [blame] | 363 | |
Shawn O. Pearce | 0c499ea | 2010-02-05 12:57:39 -0800 | [diff] [blame] | 364 | if (use_sideband && cmds_sent) { |
| 365 | if (finish_async(&demux)) { |
| 366 | error("error in sideband demultiplexer"); |
| 367 | ret = -1; |
| 368 | } |
| 369 | close(demux.out); |
| 370 | } |
| 371 | |
Jeff King | ca74c45 | 2007-11-17 07:56:03 -0500 | [diff] [blame] | 372 | if (ret < 0) |
| 373 | return ret; |
Larry D'Anna | 7755585 | 2010-02-26 23:52:15 -0500 | [diff] [blame] | 374 | |
| 375 | if (args->porcelain) |
| 376 | return 0; |
| 377 | |
Jeff King | 8736a84 | 2007-11-17 07:54:27 -0500 | [diff] [blame] | 378 | for (ref = remote_refs; ref; ref = ref->next) { |
| 379 | switch (ref->status) { |
| 380 | case REF_STATUS_NONE: |
| 381 | case REF_STATUS_UPTODATE: |
| 382 | case REF_STATUS_OK: |
| 383 | break; |
| 384 | default: |
| 385 | return -1; |
| 386 | } |
| 387 | } |
| 388 | return 0; |
Linus Torvalds | 6122147 | 2005-06-29 19:09:05 -0700 | [diff] [blame] | 389 | } |
| 390 | |
Daniel Barkalow | 96249c0 | 2007-10-29 22:03:39 -0400 | [diff] [blame] | 391 | int cmd_send_pack(int argc, const char **argv, const char *prefix) |
Linus Torvalds | 6122147 | 2005-06-29 19:09:05 -0700 | [diff] [blame] | 392 | { |
Daniel Barkalow | 64fcef2 | 2009-03-08 21:06:07 -0400 | [diff] [blame] | 393 | int i, nr_refspecs = 0; |
| 394 | const char **refspecs = NULL; |
Daniel Barkalow | 96249c0 | 2007-10-29 22:03:39 -0400 | [diff] [blame] | 395 | const char *remote_name = NULL; |
Daniel Barkalow | b516968 | 2007-05-15 22:50:19 -0400 | [diff] [blame] | 396 | struct remote *remote = NULL; |
Daniel Barkalow | 96249c0 | 2007-10-29 22:03:39 -0400 | [diff] [blame] | 397 | const char *dest = NULL; |
Daniel Barkalow | 64fcef2 | 2009-03-08 21:06:07 -0400 | [diff] [blame] | 398 | int fd[2]; |
| 399 | struct child_process *conn; |
| 400 | struct extra_have_objects extra_have; |
Clemens Buchacher | 6d2bf96 | 2009-05-31 16:26:48 +0200 | [diff] [blame] | 401 | struct ref *remote_refs, *local_refs; |
Daniel Barkalow | 64fcef2 | 2009-03-08 21:06:07 -0400 | [diff] [blame] | 402 | int ret; |
Shawn O. Pearce | de1a2fd | 2009-10-30 17:47:41 -0700 | [diff] [blame] | 403 | int helper_status = 0; |
Daniel Barkalow | 64fcef2 | 2009-03-08 21:06:07 -0400 | [diff] [blame] | 404 | int send_all = 0; |
| 405 | const char *receivepack = "git-receive-pack"; |
| 406 | int flags; |
Michael Lukashov | f1863d0 | 2010-02-16 23:42:52 +0000 | [diff] [blame] | 407 | int nonfastforward = 0; |
Junio C Hamano | 84a9b58 | 2006-03-23 23:41:18 -0800 | [diff] [blame] | 408 | |
Linus Torvalds | 6122147 | 2005-06-29 19:09:05 -0700 | [diff] [blame] | 409 | argv++; |
Linus Torvalds | d089391 | 2005-07-16 13:26:33 -0700 | [diff] [blame] | 410 | for (i = 1; i < argc; i++, argv++) { |
Daniel Barkalow | 96249c0 | 2007-10-29 22:03:39 -0400 | [diff] [blame] | 411 | const char *arg = *argv; |
Linus Torvalds | 6122147 | 2005-06-29 19:09:05 -0700 | [diff] [blame] | 412 | |
| 413 | if (*arg == '-') { |
Junio C Hamano | cc44c76 | 2007-02-20 01:53:29 -0800 | [diff] [blame] | 414 | if (!prefixcmp(arg, "--receive-pack=")) { |
Daniel Barkalow | 64fcef2 | 2009-03-08 21:06:07 -0400 | [diff] [blame] | 415 | receivepack = arg + 15; |
Uwe Kleine-König | d23842f | 2007-01-19 13:49:27 +0100 | [diff] [blame] | 416 | continue; |
| 417 | } |
Junio C Hamano | cc44c76 | 2007-02-20 01:53:29 -0800 | [diff] [blame] | 418 | if (!prefixcmp(arg, "--exec=")) { |
Daniel Barkalow | 64fcef2 | 2009-03-08 21:06:07 -0400 | [diff] [blame] | 419 | receivepack = arg + 7; |
Linus Torvalds | 6122147 | 2005-06-29 19:09:05 -0700 | [diff] [blame] | 420 | continue; |
| 421 | } |
Daniel Barkalow | b516968 | 2007-05-15 22:50:19 -0400 | [diff] [blame] | 422 | if (!prefixcmp(arg, "--remote=")) { |
| 423 | remote_name = arg + 9; |
| 424 | continue; |
| 425 | } |
Linus Torvalds | d089391 | 2005-07-16 13:26:33 -0700 | [diff] [blame] | 426 | if (!strcmp(arg, "--all")) { |
Daniel Barkalow | 64fcef2 | 2009-03-08 21:06:07 -0400 | [diff] [blame] | 427 | send_all = 1; |
Linus Torvalds | d089391 | 2005-07-16 13:26:33 -0700 | [diff] [blame] | 428 | continue; |
| 429 | } |
Brian Ewins | a63103a | 2007-10-11 20:32:26 +0100 | [diff] [blame] | 430 | if (!strcmp(arg, "--dry-run")) { |
Daniel Barkalow | 96249c0 | 2007-10-29 22:03:39 -0400 | [diff] [blame] | 431 | args.dry_run = 1; |
Brian Ewins | a63103a | 2007-10-11 20:32:26 +0100 | [diff] [blame] | 432 | continue; |
| 433 | } |
Andy Whitcroft | 28b9d6e | 2007-11-09 23:32:10 +0000 | [diff] [blame] | 434 | if (!strcmp(arg, "--mirror")) { |
| 435 | args.send_mirror = 1; |
| 436 | continue; |
| 437 | } |
Linus Torvalds | 2a9c3fe | 2005-07-19 07:03:47 -0400 | [diff] [blame] | 438 | if (!strcmp(arg, "--force")) { |
Daniel Barkalow | 96249c0 | 2007-10-29 22:03:39 -0400 | [diff] [blame] | 439 | args.force_update = 1; |
Linus Torvalds | 2a9c3fe | 2005-07-19 07:03:47 -0400 | [diff] [blame] | 440 | continue; |
| 441 | } |
Linus Torvalds | 41f93a2 | 2005-12-20 18:13:02 -0800 | [diff] [blame] | 442 | if (!strcmp(arg, "--verbose")) { |
Daniel Barkalow | 96249c0 | 2007-10-29 22:03:39 -0400 | [diff] [blame] | 443 | args.verbose = 1; |
Linus Torvalds | 41f93a2 | 2005-12-20 18:13:02 -0800 | [diff] [blame] | 444 | continue; |
| 445 | } |
Junio C Hamano | 2245be3 | 2006-02-19 15:03:49 -0800 | [diff] [blame] | 446 | if (!strcmp(arg, "--thin")) { |
Daniel Barkalow | 96249c0 | 2007-10-29 22:03:39 -0400 | [diff] [blame] | 447 | args.use_thin_pack = 1; |
Junio C Hamano | 2245be3 | 2006-02-19 15:03:49 -0800 | [diff] [blame] | 448 | continue; |
| 449 | } |
Shawn O. Pearce | de1a2fd | 2009-10-30 17:47:41 -0700 | [diff] [blame] | 450 | if (!strcmp(arg, "--stateless-rpc")) { |
| 451 | args.stateless_rpc = 1; |
| 452 | continue; |
| 453 | } |
| 454 | if (!strcmp(arg, "--helper-status")) { |
| 455 | helper_status = 1; |
| 456 | continue; |
| 457 | } |
Linus Torvalds | 6122147 | 2005-06-29 19:09:05 -0700 | [diff] [blame] | 458 | usage(send_pack_usage); |
| 459 | } |
Linus Torvalds | d089391 | 2005-07-16 13:26:33 -0700 | [diff] [blame] | 460 | if (!dest) { |
| 461 | dest = arg; |
| 462 | continue; |
| 463 | } |
Daniel Barkalow | 64fcef2 | 2009-03-08 21:06:07 -0400 | [diff] [blame] | 464 | refspecs = (const char **) argv; |
| 465 | nr_refspecs = argc - i; |
Linus Torvalds | 6122147 | 2005-06-29 19:09:05 -0700 | [diff] [blame] | 466 | break; |
| 467 | } |
| 468 | if (!dest) |
| 469 | usage(send_pack_usage); |
Andy Whitcroft | 28b9d6e | 2007-11-09 23:32:10 +0000 | [diff] [blame] | 470 | /* |
| 471 | * --all and --mirror are incompatible; neither makes sense |
| 472 | * with any refspecs. |
| 473 | */ |
Daniel Barkalow | 64fcef2 | 2009-03-08 21:06:07 -0400 | [diff] [blame] | 474 | if ((refspecs && (send_all || args.send_mirror)) || |
| 475 | (send_all && args.send_mirror)) |
Junio C Hamano | 0bc3cdf | 2005-08-02 12:20:27 -0700 | [diff] [blame] | 476 | usage(send_pack_usage); |
Junio C Hamano | 37adac7 | 2006-12-13 10:30:11 -0800 | [diff] [blame] | 477 | |
Daniel Barkalow | b516968 | 2007-05-15 22:50:19 -0400 | [diff] [blame] | 478 | if (remote_name) { |
| 479 | remote = remote_get(remote_name); |
Shawn O. Pearce | 28b91f8 | 2007-09-19 00:49:27 -0400 | [diff] [blame] | 480 | if (!remote_has_url(remote, dest)) { |
Daniel Barkalow | b516968 | 2007-05-15 22:50:19 -0400 | [diff] [blame] | 481 | die("Destination %s is not a uri for %s", |
| 482 | dest, remote_name); |
| 483 | } |
| 484 | } |
| 485 | |
Shawn O. Pearce | de1a2fd | 2009-10-30 17:47:41 -0700 | [diff] [blame] | 486 | if (args.stateless_rpc) { |
| 487 | conn = NULL; |
| 488 | fd[0] = 0; |
| 489 | fd[1] = 1; |
| 490 | } else { |
Junio C Hamano | 5a277f3 | 2011-09-06 11:06:32 -0700 | [diff] [blame] | 491 | conn = git_connect(fd, dest, receivepack, |
Shawn O. Pearce | de1a2fd | 2009-10-30 17:47:41 -0700 | [diff] [blame] | 492 | args.verbose ? CONNECT_VERBOSE : 0); |
| 493 | } |
Daniel Barkalow | 96249c0 | 2007-10-29 22:03:39 -0400 | [diff] [blame] | 494 | |
Daniel Barkalow | 64fcef2 | 2009-03-08 21:06:07 -0400 | [diff] [blame] | 495 | memset(&extra_have, 0, sizeof(extra_have)); |
Daniel Barkalow | 96249c0 | 2007-10-29 22:03:39 -0400 | [diff] [blame] | 496 | |
Daniel Barkalow | 64fcef2 | 2009-03-08 21:06:07 -0400 | [diff] [blame] | 497 | get_remote_heads(fd[0], &remote_refs, 0, NULL, REF_NORMAL, |
| 498 | &extra_have); |
Daniel Barkalow | 96249c0 | 2007-10-29 22:03:39 -0400 | [diff] [blame] | 499 | |
Michael Lukashov | f1863d0 | 2010-02-16 23:42:52 +0000 | [diff] [blame] | 500 | transport_verify_remote_names(nr_refspecs, refspecs); |
Daniel Barkalow | 96249c0 | 2007-10-29 22:03:39 -0400 | [diff] [blame] | 501 | |
Daniel Barkalow | 64fcef2 | 2009-03-08 21:06:07 -0400 | [diff] [blame] | 502 | local_refs = get_local_heads(); |
| 503 | |
| 504 | flags = MATCH_REFS_NONE; |
| 505 | |
| 506 | if (send_all) |
| 507 | flags |= MATCH_REFS_ALL; |
| 508 | if (args.send_mirror) |
| 509 | flags |= MATCH_REFS_MIRROR; |
| 510 | |
| 511 | /* match them up */ |
Clemens Buchacher | 6d2bf96 | 2009-05-31 16:26:48 +0200 | [diff] [blame] | 512 | if (match_refs(local_refs, &remote_refs, nr_refspecs, refspecs, flags)) |
Daniel Barkalow | 64fcef2 | 2009-03-08 21:06:07 -0400 | [diff] [blame] | 513 | return -1; |
Daniel Barkalow | 64fcef2 | 2009-03-08 21:06:07 -0400 | [diff] [blame] | 514 | |
Tay Ray Chuan | 20e8b46 | 2010-01-08 10:12:42 +0800 | [diff] [blame] | 515 | set_ref_status_for_push(remote_refs, args.send_mirror, |
| 516 | args.force_update); |
| 517 | |
Daniel Barkalow | 64fcef2 | 2009-03-08 21:06:07 -0400 | [diff] [blame] | 518 | ret = send_pack(&args, fd, conn, remote_refs, &extra_have); |
| 519 | |
Shawn O. Pearce | de1a2fd | 2009-10-30 17:47:41 -0700 | [diff] [blame] | 520 | if (helper_status) |
| 521 | print_helper_status(remote_refs); |
| 522 | |
Daniel Barkalow | 64fcef2 | 2009-03-08 21:06:07 -0400 | [diff] [blame] | 523 | close(fd[1]); |
Linus Torvalds | 7f8e982 | 2005-06-29 22:50:48 -0700 | [diff] [blame] | 524 | close(fd[0]); |
Daniel Barkalow | 64fcef2 | 2009-03-08 21:06:07 -0400 | [diff] [blame] | 525 | |
Johannes Sixt | 98158e9 | 2007-10-19 21:47:53 +0200 | [diff] [blame] | 526 | ret |= finish_connect(conn); |
Daniel Barkalow | 64fcef2 | 2009-03-08 21:06:07 -0400 | [diff] [blame] | 527 | |
Shawn O. Pearce | de1a2fd | 2009-10-30 17:47:41 -0700 | [diff] [blame] | 528 | if (!helper_status) |
Michael Lukashov | f1863d0 | 2010-02-16 23:42:52 +0000 | [diff] [blame] | 529 | transport_print_push_status(dest, remote_refs, args.verbose, 0, &nonfastforward); |
Daniel Barkalow | 64fcef2 | 2009-03-08 21:06:07 -0400 | [diff] [blame] | 530 | |
| 531 | if (!args.dry_run && remote) { |
| 532 | struct ref *ref; |
| 533 | for (ref = remote_refs; ref; ref = ref->next) |
Michael Lukashov | f1863d0 | 2010-02-16 23:42:52 +0000 | [diff] [blame] | 534 | transport_update_tracking_ref(remote, ref, args.verbose); |
Daniel Barkalow | 64fcef2 | 2009-03-08 21:06:07 -0400 | [diff] [blame] | 535 | } |
| 536 | |
Michael Lukashov | f1863d0 | 2010-02-16 23:42:52 +0000 | [diff] [blame] | 537 | if (!ret && !transport_refs_pushed(remote_refs)) |
Daniel Barkalow | 64fcef2 | 2009-03-08 21:06:07 -0400 | [diff] [blame] | 538 | fprintf(stderr, "Everything up-to-date\n"); |
| 539 | |
| 540 | return ret; |
Linus Torvalds | 6122147 | 2005-06-29 19:09:05 -0700 | [diff] [blame] | 541 | } |