Linus Torvalds | 6122147 | 2005-06-29 19:09:05 -0700 | [diff] [blame] | 1 | #include "cache.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" |
Linus Torvalds | 6122147 | 2005-06-29 19:09:05 -0700 | [diff] [blame] | 10 | |
Junio C Hamano | 2a24501 | 2005-07-14 00:10:05 -0700 | [diff] [blame] | 11 | static const char send_pack_usage[] = |
Stephan Beyer | 1b1dd23 | 2008-07-13 15:36:15 +0200 | [diff] [blame] | 12 | "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] | 13 | " --all and explicit <ref> specification are mutually exclusive."; |
Daniel Barkalow | 96249c0 | 2007-10-29 22:03:39 -0400 | [diff] [blame] | 14 | |
Brandon Casey | 6828f72 | 2009-03-26 21:37:53 -0500 | [diff] [blame] | 15 | static struct send_pack_args args; |
Linus Torvalds | 6122147 | 2005-06-29 19:09:05 -0700 | [diff] [blame] | 16 | |
Junio C Hamano | 02322e1 | 2009-01-27 20:21:31 -0800 | [diff] [blame] | 17 | static int feed_object(const unsigned char *sha1, int fd, int negative) |
| 18 | { |
| 19 | char buf[42]; |
| 20 | |
| 21 | if (negative && !has_sha1_file(sha1)) |
| 22 | return 1; |
| 23 | |
| 24 | memcpy(buf + negative, sha1_to_hex(sha1), 40); |
| 25 | if (negative) |
| 26 | buf[0] = '^'; |
| 27 | buf[40 + negative] = '\n'; |
| 28 | return write_or_whine(fd, buf, 41 + negative, "send-pack: send refs"); |
| 29 | } |
| 30 | |
Andy Whitcroft | c727fe2 | 2006-09-05 22:52:12 +0100 | [diff] [blame] | 31 | /* |
Junio C Hamano | 0ae5f98 | 2006-12-31 01:26:53 -0800 | [diff] [blame] | 32 | * Make a pack stream and spit it out into file descriptor fd |
Andy Whitcroft | c727fe2 | 2006-09-05 22:52:12 +0100 | [diff] [blame] | 33 | */ |
Daniel Barkalow | 64fcef2 | 2009-03-08 21:06:07 -0400 | [diff] [blame] | 34 | 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] | 35 | { |
Shawn O. Pearce | 38b1c66 | 2007-03-12 19:00:29 -0400 | [diff] [blame] | 36 | /* |
| 37 | * The child becomes pack-objects --revs; we feed |
| 38 | * the revision parameters to it via its stdin and |
| 39 | * let its stdout go back to the other end. |
| 40 | */ |
Daniel Barkalow | 96249c0 | 2007-10-29 22:03:39 -0400 | [diff] [blame] | 41 | const char *argv[] = { |
Shawn O. Pearce | 38b1c66 | 2007-03-12 19:00:29 -0400 | [diff] [blame] | 42 | "pack-objects", |
Nicolas Pitre | 4f36627 | 2009-11-23 12:43:50 -0500 | [diff] [blame] | 43 | "--all-progress-implied", |
Shawn O. Pearce | 38b1c66 | 2007-03-12 19:00:29 -0400 | [diff] [blame] | 44 | "--revs", |
| 45 | "--stdout", |
| 46 | NULL, |
| 47 | NULL, |
Nicolas Pitre | b74fce1 | 2009-05-01 16:56:47 -0400 | [diff] [blame] | 48 | NULL, |
Jeff King | 1207032 | 2009-08-05 16:22:36 -0400 | [diff] [blame] | 49 | NULL, |
Shawn O. Pearce | 38b1c66 | 2007-03-12 19:00:29 -0400 | [diff] [blame] | 50 | }; |
| 51 | struct child_process po; |
Junio C Hamano | 40c155f | 2008-09-09 01:27:09 -0700 | [diff] [blame] | 52 | int i; |
Linus Torvalds | 94fdb7a | 2005-06-30 10:17:39 -0700 | [diff] [blame] | 53 | |
Nicolas Pitre | b74fce1 | 2009-05-01 16:56:47 -0400 | [diff] [blame] | 54 | i = 4; |
Daniel Barkalow | 64fcef2 | 2009-03-08 21:06:07 -0400 | [diff] [blame] | 55 | if (args->use_thin_pack) |
Nicolas Pitre | b74fce1 | 2009-05-01 16:56:47 -0400 | [diff] [blame] | 56 | argv[i++] = "--thin"; |
| 57 | if (args->use_ofs_delta) |
| 58 | argv[i++] = "--delta-base-offset"; |
Jeff King | 1207032 | 2009-08-05 16:22:36 -0400 | [diff] [blame] | 59 | if (args->quiet) |
| 60 | argv[i++] = "-q"; |
Shawn O. Pearce | 38b1c66 | 2007-03-12 19:00:29 -0400 | [diff] [blame] | 61 | memset(&po, 0, sizeof(po)); |
Daniel Barkalow | 96249c0 | 2007-10-29 22:03:39 -0400 | [diff] [blame] | 62 | po.argv = argv; |
Shawn O. Pearce | 38b1c66 | 2007-03-12 19:00:29 -0400 | [diff] [blame] | 63 | po.in = -1; |
Shawn O. Pearce | de1a2fd | 2009-10-30 17:47:41 -0700 | [diff] [blame] | 64 | po.out = args->stateless_rpc ? -1 : fd; |
Shawn O. Pearce | 38b1c66 | 2007-03-12 19:00:29 -0400 | [diff] [blame] | 65 | po.git_cmd = 1; |
| 66 | if (start_command(&po)) |
Thomas Rast | d824cbb | 2009-06-27 17:58:46 +0200 | [diff] [blame] | 67 | die_errno("git pack-objects failed"); |
Andy Whitcroft | c727fe2 | 2006-09-05 22:52:12 +0100 | [diff] [blame] | 68 | |
Junio C Hamano | 0ae5f98 | 2006-12-31 01:26:53 -0800 | [diff] [blame] | 69 | /* |
| 70 | * We feed the pack-objects we just spawned with revision |
| 71 | * parameters by writing to the pipe. |
Andy Whitcroft | c727fe2 | 2006-09-05 22:52:12 +0100 | [diff] [blame] | 72 | */ |
Junio C Hamano | 02322e1 | 2009-01-27 20:21:31 -0800 | [diff] [blame] | 73 | for (i = 0; i < extra->nr; i++) |
| 74 | if (!feed_object(extra->array[i], po.in, 1)) |
Junio C Hamano | 40c155f | 2008-09-09 01:27:09 -0700 | [diff] [blame] | 75 | break; |
Andy Whitcroft | c727fe2 | 2006-09-05 22:52:12 +0100 | [diff] [blame] | 76 | |
Junio C Hamano | 40c155f | 2008-09-09 01:27:09 -0700 | [diff] [blame] | 77 | while (refs) { |
Andy Whitcroft | c727fe2 | 2006-09-05 22:52:12 +0100 | [diff] [blame] | 78 | if (!is_null_sha1(refs->old_sha1) && |
Junio C Hamano | 02322e1 | 2009-01-27 20:21:31 -0800 | [diff] [blame] | 79 | !feed_object(refs->old_sha1, po.in, 1)) |
| 80 | break; |
| 81 | if (!is_null_sha1(refs->new_sha1) && |
| 82 | !feed_object(refs->new_sha1, po.in, 0)) |
| 83 | break; |
Andy Whitcroft | c727fe2 | 2006-09-05 22:52:12 +0100 | [diff] [blame] | 84 | refs = refs->next; |
| 85 | } |
Andy Whitcroft | c727fe2 | 2006-09-05 22:52:12 +0100 | [diff] [blame] | 86 | |
Johannes Sixt | e72ae28 | 2008-02-16 18:36:38 +0100 | [diff] [blame] | 87 | close(po.in); |
Shawn O. Pearce | de1a2fd | 2009-10-30 17:47:41 -0700 | [diff] [blame] | 88 | |
| 89 | if (args->stateless_rpc) { |
| 90 | char *buf = xmalloc(LARGE_PACKET_MAX); |
| 91 | while (1) { |
| 92 | ssize_t n = xread(po.out, buf, LARGE_PACKET_MAX); |
| 93 | if (n <= 0) |
| 94 | break; |
| 95 | send_sideband(fd, -1, buf, n, LARGE_PACKET_MAX); |
| 96 | } |
| 97 | free(buf); |
| 98 | close(po.out); |
| 99 | po.out = -1; |
| 100 | } |
| 101 | |
Shawn O. Pearce | 38b1c66 | 2007-03-12 19:00:29 -0400 | [diff] [blame] | 102 | if (finish_command(&po)) |
| 103 | return error("pack-objects died with strange error"); |
| 104 | return 0; |
Linus Torvalds | 94fdb7a | 2005-06-30 10:17:39 -0700 | [diff] [blame] | 105 | } |
Linus Torvalds | e4b5c7f | 2005-06-29 22:31:41 -0700 | [diff] [blame] | 106 | |
Jeff King | ca74c45 | 2007-11-17 07:56:03 -0500 | [diff] [blame] | 107 | static int receive_status(int in, struct ref *refs) |
| 108 | { |
| 109 | struct ref *hint; |
Junio C Hamano | cfee10a | 2005-12-25 23:18:37 -0800 | [diff] [blame] | 110 | char line[1000]; |
| 111 | int ret = 0; |
| 112 | int len = packet_read_line(in, line, sizeof(line)); |
Jeff King | 2a0fe89 | 2007-11-18 02:16:52 -0500 | [diff] [blame] | 113 | if (len < 10 || memcmp(line, "unpack ", 7)) |
| 114 | return error("did not receive remote status"); |
Junio C Hamano | cfee10a | 2005-12-25 23:18:37 -0800 | [diff] [blame] | 115 | if (memcmp(line, "unpack ok\n", 10)) { |
Jeff King | 2a0fe89 | 2007-11-18 02:16:52 -0500 | [diff] [blame] | 116 | char *p = line + strlen(line) - 1; |
| 117 | if (*p == '\n') |
| 118 | *p = '\0'; |
| 119 | error("unpack failed: %s", line + 7); |
Junio C Hamano | cfee10a | 2005-12-25 23:18:37 -0800 | [diff] [blame] | 120 | ret = -1; |
| 121 | } |
Jeff King | ca74c45 | 2007-11-17 07:56:03 -0500 | [diff] [blame] | 122 | hint = NULL; |
Junio C Hamano | cfee10a | 2005-12-25 23:18:37 -0800 | [diff] [blame] | 123 | while (1) { |
Jeff King | 2a0fe89 | 2007-11-18 02:16:52 -0500 | [diff] [blame] | 124 | char *refname; |
| 125 | char *msg; |
Junio C Hamano | cfee10a | 2005-12-25 23:18:37 -0800 | [diff] [blame] | 126 | len = packet_read_line(in, line, sizeof(line)); |
| 127 | if (!len) |
| 128 | break; |
| 129 | if (len < 3 || |
Jeff King | 2a0fe89 | 2007-11-18 02:16:52 -0500 | [diff] [blame] | 130 | (memcmp(line, "ok ", 3) && memcmp(line, "ng ", 3))) { |
Junio C Hamano | cfee10a | 2005-12-25 23:18:37 -0800 | [diff] [blame] | 131 | fprintf(stderr, "protocol error: %s\n", line); |
| 132 | ret = -1; |
| 133 | break; |
| 134 | } |
Jeff King | 2a0fe89 | 2007-11-18 02:16:52 -0500 | [diff] [blame] | 135 | |
| 136 | line[strlen(line)-1] = '\0'; |
| 137 | refname = line + 3; |
| 138 | msg = strchr(refname, ' '); |
| 139 | if (msg) |
| 140 | *msg++ = '\0'; |
| 141 | |
| 142 | /* first try searching at our hint, falling back to all refs */ |
Jeff King | ca74c45 | 2007-11-17 07:56:03 -0500 | [diff] [blame] | 143 | if (hint) |
Jeff King | 2a0fe89 | 2007-11-18 02:16:52 -0500 | [diff] [blame] | 144 | hint = find_ref_by_name(hint, refname); |
Jeff King | ca74c45 | 2007-11-17 07:56:03 -0500 | [diff] [blame] | 145 | if (!hint) |
Jeff King | 2a0fe89 | 2007-11-18 02:16:52 -0500 | [diff] [blame] | 146 | hint = find_ref_by_name(refs, refname); |
| 147 | if (!hint) { |
| 148 | warning("remote reported status on unknown ref: %s", |
| 149 | refname); |
| 150 | continue; |
| 151 | } |
| 152 | if (hint->status != REF_STATUS_EXPECTING_REPORT) { |
| 153 | warning("remote reported status on unexpected ref: %s", |
| 154 | refname); |
| 155 | continue; |
| 156 | } |
| 157 | |
| 158 | if (line[0] == 'o' && line[1] == 'k') |
| 159 | hint->status = REF_STATUS_OK; |
| 160 | else { |
| 161 | hint->status = REF_STATUS_REMOTE_REJECT; |
| 162 | ret = -1; |
| 163 | } |
| 164 | if (msg) |
| 165 | hint->remote_status = xstrdup(msg); |
| 166 | /* start our next search from the next ref */ |
| 167 | hint = hint->next; |
Junio C Hamano | cfee10a | 2005-12-25 23:18:37 -0800 | [diff] [blame] | 168 | } |
| 169 | return ret; |
| 170 | } |
| 171 | |
Jeff King | 334f483 | 2007-10-18 02:19:15 -0400 | [diff] [blame] | 172 | static void update_tracking_ref(struct remote *remote, struct ref *ref) |
| 173 | { |
| 174 | struct refspec rs; |
Jeff King | 1f0e2a1 | 2007-11-17 07:55:15 -0500 | [diff] [blame] | 175 | |
Clemens Buchacher | 16ed2f4 | 2008-11-05 21:55:54 +0100 | [diff] [blame] | 176 | if (ref->status != REF_STATUS_OK && ref->status != REF_STATUS_UPTODATE) |
Jeff King | 1f0e2a1 | 2007-11-17 07:55:15 -0500 | [diff] [blame] | 177 | return; |
Jeff King | 334f483 | 2007-10-18 02:19:15 -0400 | [diff] [blame] | 178 | |
| 179 | rs.src = ref->name; |
| 180 | rs.dst = NULL; |
| 181 | |
Jeff King | 334f483 | 2007-10-18 02:19:15 -0400 | [diff] [blame] | 182 | if (!remote_find_tracking(remote, &rs)) { |
Jeff King | b50fa2b | 2007-11-05 00:12:18 -0500 | [diff] [blame] | 183 | if (args.verbose) |
| 184 | fprintf(stderr, "updating local tracking ref '%s'\n", rs.dst); |
Jeff King | 1f0e2a1 | 2007-11-17 07:55:15 -0500 | [diff] [blame] | 185 | if (ref->deletion) { |
Miklos Vajna | eca35a2 | 2008-10-26 03:33:56 +0100 | [diff] [blame] | 186 | delete_ref(rs.dst, NULL, 0); |
Jeff King | 334f483 | 2007-10-18 02:19:15 -0400 | [diff] [blame] | 187 | } else |
| 188 | update_ref("update by push", rs.dst, |
| 189 | ref->new_sha1, NULL, 0, 0); |
| 190 | free(rs.dst); |
| 191 | } |
| 192 | } |
| 193 | |
Jeff King | f767349 | 2007-11-05 00:11:15 -0500 | [diff] [blame] | 194 | #define SUMMARY_WIDTH (2 * DEFAULT_ABBREV + 3) |
| 195 | |
Jeff King | 8736a84 | 2007-11-17 07:54:27 -0500 | [diff] [blame] | 196 | static void print_ref_status(char flag, const char *summary, struct ref *to, struct ref *from, const char *msg) |
| 197 | { |
| 198 | fprintf(stderr, " %c %-*s ", flag, SUMMARY_WIDTH, summary); |
| 199 | if (from) |
Felipe Contreras | 4577e48 | 2009-05-14 00:22:04 +0300 | [diff] [blame] | 200 | fprintf(stderr, "%s -> %s", prettify_refname(from->name), prettify_refname(to->name)); |
Jeff King | 8736a84 | 2007-11-17 07:54:27 -0500 | [diff] [blame] | 201 | else |
Felipe Contreras | 4577e48 | 2009-05-14 00:22:04 +0300 | [diff] [blame] | 202 | fputs(prettify_refname(to->name), stderr); |
Jeff King | 8736a84 | 2007-11-17 07:54:27 -0500 | [diff] [blame] | 203 | if (msg) { |
| 204 | fputs(" (", stderr); |
| 205 | fputs(msg, stderr); |
| 206 | fputc(')', stderr); |
| 207 | } |
| 208 | fputc('\n', stderr); |
| 209 | } |
| 210 | |
| 211 | static const char *status_abbrev(unsigned char sha1[20]) |
| 212 | { |
Junio C Hamano | 2efb3b0 | 2008-03-01 23:43:32 -0800 | [diff] [blame] | 213 | return find_unique_abbrev(sha1, DEFAULT_ABBREV); |
Jeff King | 8736a84 | 2007-11-17 07:54:27 -0500 | [diff] [blame] | 214 | } |
| 215 | |
| 216 | static void print_ok_ref_status(struct ref *ref) |
| 217 | { |
| 218 | if (ref->deletion) |
| 219 | print_ref_status('-', "[deleted]", ref, NULL, NULL); |
| 220 | else if (is_null_sha1(ref->old_sha1)) |
| 221 | print_ref_status('*', |
| 222 | (!prefixcmp(ref->name, "refs/tags/") ? "[new tag]" : |
| 223 | "[new branch]"), |
| 224 | ref, ref->peer_ref, NULL); |
| 225 | else { |
| 226 | char quickref[84]; |
| 227 | char type; |
| 228 | const char *msg; |
| 229 | |
| 230 | strcpy(quickref, status_abbrev(ref->old_sha1)); |
| 231 | if (ref->nonfastforward) { |
| 232 | strcat(quickref, "..."); |
| 233 | type = '+'; |
| 234 | msg = "forced update"; |
| 235 | } else { |
| 236 | strcat(quickref, ".."); |
| 237 | type = ' '; |
| 238 | msg = NULL; |
| 239 | } |
| 240 | strcat(quickref, status_abbrev(ref->new_sha1)); |
| 241 | |
| 242 | print_ref_status(type, quickref, ref, ref->peer_ref, msg); |
| 243 | } |
| 244 | } |
| 245 | |
Jeff King | 07f5071 | 2007-11-20 06:18:01 -0500 | [diff] [blame] | 246 | static int print_one_push_status(struct ref *ref, const char *dest, int count) |
| 247 | { |
| 248 | if (!count) |
| 249 | fprintf(stderr, "To %s\n", dest); |
| 250 | |
| 251 | switch(ref->status) { |
| 252 | case REF_STATUS_NONE: |
| 253 | print_ref_status('X', "[no match]", ref, NULL, NULL); |
| 254 | break; |
| 255 | case REF_STATUS_REJECT_NODELETE: |
| 256 | print_ref_status('!', "[rejected]", ref, NULL, |
| 257 | "remote does not support deleting refs"); |
| 258 | break; |
| 259 | case REF_STATUS_UPTODATE: |
| 260 | print_ref_status('=', "[up to date]", ref, |
| 261 | ref->peer_ref, NULL); |
| 262 | break; |
| 263 | case REF_STATUS_REJECT_NONFASTFORWARD: |
| 264 | print_ref_status('!', "[rejected]", ref, ref->peer_ref, |
Felipe Contreras | a75d7b5 | 2009-10-24 11:31:32 +0300 | [diff] [blame] | 265 | "non-fast-forward"); |
Jeff King | 07f5071 | 2007-11-20 06:18:01 -0500 | [diff] [blame] | 266 | break; |
| 267 | case REF_STATUS_REMOTE_REJECT: |
| 268 | print_ref_status('!', "[remote rejected]", ref, |
| 269 | ref->deletion ? NULL : ref->peer_ref, |
| 270 | ref->remote_status); |
| 271 | break; |
| 272 | case REF_STATUS_EXPECTING_REPORT: |
| 273 | print_ref_status('!', "[remote failure]", ref, |
| 274 | ref->deletion ? NULL : ref->peer_ref, |
| 275 | "remote failed to report status"); |
| 276 | break; |
| 277 | case REF_STATUS_OK: |
| 278 | print_ok_ref_status(ref); |
| 279 | break; |
| 280 | } |
| 281 | |
| 282 | return 1; |
| 283 | } |
| 284 | |
Jeff King | 8736a84 | 2007-11-17 07:54:27 -0500 | [diff] [blame] | 285 | static void print_push_status(const char *dest, struct ref *refs) |
| 286 | { |
| 287 | struct ref *ref; |
Jeff King | 07f5071 | 2007-11-20 06:18:01 -0500 | [diff] [blame] | 288 | int n = 0; |
| 289 | |
| 290 | if (args.verbose) { |
| 291 | for (ref = refs; ref; ref = ref->next) |
| 292 | if (ref->status == REF_STATUS_UPTODATE) |
| 293 | n += print_one_push_status(ref, dest, n); |
| 294 | } |
| 295 | |
| 296 | for (ref = refs; ref; ref = ref->next) |
| 297 | if (ref->status == REF_STATUS_OK) |
| 298 | n += print_one_push_status(ref, dest, n); |
Jeff King | 8736a84 | 2007-11-17 07:54:27 -0500 | [diff] [blame] | 299 | |
| 300 | for (ref = refs; ref; ref = ref->next) { |
Jeff King | 07f5071 | 2007-11-20 06:18:01 -0500 | [diff] [blame] | 301 | if (ref->status != REF_STATUS_NONE && |
| 302 | ref->status != REF_STATUS_UPTODATE && |
| 303 | ref->status != REF_STATUS_OK) |
| 304 | n += print_one_push_status(ref, dest, n); |
Jeff King | 8736a84 | 2007-11-17 07:54:27 -0500 | [diff] [blame] | 305 | } |
| 306 | } |
| 307 | |
Jeff King | 73fa0b4 | 2007-11-18 03:08:22 -0500 | [diff] [blame] | 308 | static int refs_pushed(struct ref *ref) |
| 309 | { |
| 310 | for (; ref; ref = ref->next) { |
| 311 | switch(ref->status) { |
| 312 | case REF_STATUS_NONE: |
| 313 | case REF_STATUS_UPTODATE: |
| 314 | break; |
| 315 | default: |
| 316 | return 1; |
| 317 | } |
| 318 | } |
| 319 | return 0; |
| 320 | } |
| 321 | |
Shawn O. Pearce | de1a2fd | 2009-10-30 17:47:41 -0700 | [diff] [blame] | 322 | static void print_helper_status(struct ref *ref) |
| 323 | { |
| 324 | struct strbuf buf = STRBUF_INIT; |
| 325 | |
| 326 | for (; ref; ref = ref->next) { |
| 327 | const char *msg = NULL; |
| 328 | const char *res; |
| 329 | |
| 330 | switch(ref->status) { |
| 331 | case REF_STATUS_NONE: |
| 332 | res = "error"; |
| 333 | msg = "no match"; |
| 334 | break; |
| 335 | |
| 336 | case REF_STATUS_OK: |
| 337 | res = "ok"; |
| 338 | break; |
| 339 | |
| 340 | case REF_STATUS_UPTODATE: |
| 341 | res = "ok"; |
| 342 | msg = "up to date"; |
| 343 | break; |
| 344 | |
| 345 | case REF_STATUS_REJECT_NONFASTFORWARD: |
| 346 | res = "error"; |
| 347 | msg = "non-fast forward"; |
| 348 | break; |
| 349 | |
| 350 | case REF_STATUS_REJECT_NODELETE: |
| 351 | case REF_STATUS_REMOTE_REJECT: |
| 352 | res = "error"; |
| 353 | break; |
| 354 | |
| 355 | case REF_STATUS_EXPECTING_REPORT: |
| 356 | default: |
| 357 | continue; |
| 358 | } |
| 359 | |
| 360 | strbuf_reset(&buf); |
| 361 | strbuf_addf(&buf, "%s %s", res, ref->name); |
| 362 | if (ref->remote_status) |
| 363 | msg = ref->remote_status; |
| 364 | if (msg) { |
| 365 | strbuf_addch(&buf, ' '); |
| 366 | quote_two_c_style(&buf, "", msg, 0); |
| 367 | } |
| 368 | strbuf_addch(&buf, '\n'); |
| 369 | |
| 370 | safe_write(1, buf.buf, buf.len); |
| 371 | } |
| 372 | strbuf_release(&buf); |
| 373 | } |
| 374 | |
Shawn O. Pearce | 0c499ea | 2010-02-05 12:57:39 -0800 | [diff] [blame] | 375 | static int sideband_demux(int in, int out, void *data) |
| 376 | { |
| 377 | int *fd = data; |
| 378 | int ret = recv_sideband("send-pack", fd[0], out); |
| 379 | close(out); |
| 380 | return ret; |
| 381 | } |
| 382 | |
Daniel Barkalow | 64fcef2 | 2009-03-08 21:06:07 -0400 | [diff] [blame] | 383 | int send_pack(struct send_pack_args *args, |
| 384 | int fd[], struct child_process *conn, |
| 385 | struct ref *remote_refs, |
| 386 | struct extra_have_objects *extra_have) |
Junio C Hamano | f88395a | 2005-08-03 16:35:29 -0700 | [diff] [blame] | 387 | { |
Daniel Barkalow | 64fcef2 | 2009-03-08 21:06:07 -0400 | [diff] [blame] | 388 | int in = fd[0]; |
| 389 | int out = fd[1]; |
Shawn O. Pearce | de1a2fd | 2009-10-30 17:47:41 -0700 | [diff] [blame] | 390 | struct strbuf req_buf = STRBUF_INIT; |
Daniel Barkalow | 64fcef2 | 2009-03-08 21:06:07 -0400 | [diff] [blame] | 391 | struct ref *ref; |
Linus Torvalds | 584c6cc | 2005-07-08 13:58:40 -0700 | [diff] [blame] | 392 | int new_refs; |
Junio C Hamano | d4f694b | 2006-11-24 00:26:49 -0800 | [diff] [blame] | 393 | int allow_deleting_refs = 0; |
Shawn O. Pearce | 0c499ea | 2010-02-05 12:57:39 -0800 | [diff] [blame] | 394 | int status_report = 0; |
| 395 | int use_sideband = 0; |
| 396 | unsigned cmds_sent = 0; |
Jeff King | ca74c45 | 2007-11-17 07:56:03 -0500 | [diff] [blame] | 397 | int ret; |
Shawn O. Pearce | 0c499ea | 2010-02-05 12:57:39 -0800 | [diff] [blame] | 398 | struct async demux; |
Linus Torvalds | 7f8e982 | 2005-06-29 22:50:48 -0700 | [diff] [blame] | 399 | |
Junio C Hamano | cfee10a | 2005-12-25 23:18:37 -0800 | [diff] [blame] | 400 | /* Does the other end support the reporting? */ |
| 401 | if (server_supports("report-status")) |
Shawn O. Pearce | 0c499ea | 2010-02-05 12:57:39 -0800 | [diff] [blame] | 402 | status_report = 1; |
Junio C Hamano | d4f694b | 2006-11-24 00:26:49 -0800 | [diff] [blame] | 403 | if (server_supports("delete-refs")) |
| 404 | allow_deleting_refs = 1; |
Nicolas Pitre | b74fce1 | 2009-05-01 16:56:47 -0400 | [diff] [blame] | 405 | if (server_supports("ofs-delta")) |
| 406 | args->use_ofs_delta = 1; |
Shawn O. Pearce | 0c499ea | 2010-02-05 12:57:39 -0800 | [diff] [blame] | 407 | if (server_supports("side-band-64k")) |
| 408 | use_sideband = 1; |
Junio C Hamano | cfee10a | 2005-12-25 23:18:37 -0800 | [diff] [blame] | 409 | |
Daniel Barkalow | 4c353e8 | 2005-12-04 11:59:37 -0500 | [diff] [blame] | 410 | if (!remote_refs) { |
Andrew Clausen | 7e23b06 | 2007-10-16 17:16:05 -0400 | [diff] [blame] | 411 | fprintf(stderr, "No refs in common and none specified; doing nothing.\n" |
| 412 | "Perhaps you should specify a branch such as 'master'.\n"); |
Daniel Barkalow | 4c353e8 | 2005-12-04 11:59:37 -0500 | [diff] [blame] | 413 | return 0; |
| 414 | } |
| 415 | |
Linus Torvalds | 584c6cc | 2005-07-08 13:58:40 -0700 | [diff] [blame] | 416 | /* |
| 417 | * Finally, tell the other end! |
| 418 | */ |
| 419 | new_refs = 0; |
Junio C Hamano | f88395a | 2005-08-03 16:35:29 -0700 | [diff] [blame] | 420 | for (ref = remote_refs; ref; ref = ref->next) { |
Junio C Hamano | d4f694b | 2006-11-24 00:26:49 -0800 | [diff] [blame] | 421 | |
Clemens Buchacher | 16ed2f4 | 2008-11-05 21:55:54 +0100 | [diff] [blame] | 422 | if (ref->peer_ref) |
| 423 | hashcpy(ref->new_sha1, ref->peer_ref->new_sha1); |
Daniel Barkalow | 64fcef2 | 2009-03-08 21:06:07 -0400 | [diff] [blame] | 424 | else if (!args->send_mirror) |
Clemens Buchacher | 16ed2f4 | 2008-11-05 21:55:54 +0100 | [diff] [blame] | 425 | continue; |
Junio C Hamano | d4f694b | 2006-11-24 00:26:49 -0800 | [diff] [blame] | 426 | |
Clemens Buchacher | 16ed2f4 | 2008-11-05 21:55:54 +0100 | [diff] [blame] | 427 | ref->deletion = is_null_sha1(ref->new_sha1); |
Jeff King | 8736a84 | 2007-11-17 07:54:27 -0500 | [diff] [blame] | 428 | if (ref->deletion && !allow_deleting_refs) { |
| 429 | ref->status = REF_STATUS_REJECT_NODELETE; |
Junio C Hamano | d4f694b | 2006-11-24 00:26:49 -0800 | [diff] [blame] | 430 | continue; |
| 431 | } |
Jeff King | 8736a84 | 2007-11-17 07:54:27 -0500 | [diff] [blame] | 432 | if (!ref->deletion && |
Clemens Buchacher | 16ed2f4 | 2008-11-05 21:55:54 +0100 | [diff] [blame] | 433 | !hashcmp(ref->old_sha1, ref->new_sha1)) { |
Jeff King | 8736a84 | 2007-11-17 07:54:27 -0500 | [diff] [blame] | 434 | ref->status = REF_STATUS_UPTODATE; |
Junio C Hamano | 37fde87 | 2005-08-05 00:47:56 -0700 | [diff] [blame] | 435 | continue; |
| 436 | } |
| 437 | |
| 438 | /* This part determines what can overwrite what. |
| 439 | * The rules are: |
| 440 | * |
Junio C Hamano | ff27adf | 2005-08-24 00:40:14 -0700 | [diff] [blame] | 441 | * (0) you can always use --force or +A:B notation to |
| 442 | * selectively force individual ref pairs. |
Junio C Hamano | 37fde87 | 2005-08-05 00:47:56 -0700 | [diff] [blame] | 443 | * |
| 444 | * (1) if the old thing does not exist, it is OK. |
| 445 | * |
| 446 | * (2) if you do not have the old thing, you are not allowed |
| 447 | * to overwrite it; you would not know what you are losing |
| 448 | * otherwise. |
| 449 | * |
| 450 | * (3) if both new and old are commit-ish, and new is a |
| 451 | * descendant of old, it is OK. |
Junio C Hamano | d4f694b | 2006-11-24 00:26:49 -0800 | [diff] [blame] | 452 | * |
| 453 | * (4) regardless of all of the above, removing :B is |
| 454 | * always allowed. |
Junio C Hamano | 37fde87 | 2005-08-05 00:47:56 -0700 | [diff] [blame] | 455 | */ |
| 456 | |
Jeff King | 8736a84 | 2007-11-17 07:54:27 -0500 | [diff] [blame] | 457 | ref->nonfastforward = |
| 458 | !ref->deletion && |
Junio C Hamano | 4b4ee90 | 2006-12-31 00:59:53 -0800 | [diff] [blame] | 459 | !is_null_sha1(ref->old_sha1) && |
Jeff King | 8736a84 | 2007-11-17 07:54:27 -0500 | [diff] [blame] | 460 | (!has_sha1_file(ref->old_sha1) |
Clemens Buchacher | 16ed2f4 | 2008-11-05 21:55:54 +0100 | [diff] [blame] | 461 | || !ref_newer(ref->new_sha1, ref->old_sha1)); |
Jeff King | 8736a84 | 2007-11-17 07:54:27 -0500 | [diff] [blame] | 462 | |
Daniel Barkalow | 64fcef2 | 2009-03-08 21:06:07 -0400 | [diff] [blame] | 463 | if (ref->nonfastforward && !ref->force && !args->force_update) { |
Jeff King | 8736a84 | 2007-11-17 07:54:27 -0500 | [diff] [blame] | 464 | ref->status = REF_STATUS_REJECT_NONFASTFORWARD; |
| 465 | continue; |
Junio C Hamano | f88395a | 2005-08-03 16:35:29 -0700 | [diff] [blame] | 466 | } |
Jeff King | 8736a84 | 2007-11-17 07:54:27 -0500 | [diff] [blame] | 467 | |
Jeff King | 8736a84 | 2007-11-17 07:54:27 -0500 | [diff] [blame] | 468 | if (!ref->deletion) |
Junio C Hamano | d4f694b | 2006-11-24 00:26:49 -0800 | [diff] [blame] | 469 | new_refs++; |
Junio C Hamano | cfee10a | 2005-12-25 23:18:37 -0800 | [diff] [blame] | 470 | |
Shawn O. Pearce | 0c499ea | 2010-02-05 12:57:39 -0800 | [diff] [blame] | 471 | if (args->dry_run) { |
| 472 | ref->status = REF_STATUS_OK; |
| 473 | } else { |
Jeff King | 8736a84 | 2007-11-17 07:54:27 -0500 | [diff] [blame] | 474 | char *old_hex = sha1_to_hex(ref->old_sha1); |
| 475 | char *new_hex = sha1_to_hex(ref->new_sha1); |
| 476 | |
Shawn O. Pearce | 0c499ea | 2010-02-05 12:57:39 -0800 | [diff] [blame] | 477 | if (!cmds_sent && (status_report || use_sideband)) { |
| 478 | packet_buf_write(&req_buf, "%s %s %s%c%s%s", |
Brian Ewins | a63103a | 2007-10-11 20:32:26 +0100 | [diff] [blame] | 479 | old_hex, new_hex, ref->name, 0, |
Shawn O. Pearce | 0c499ea | 2010-02-05 12:57:39 -0800 | [diff] [blame] | 480 | status_report ? " report-status" : "", |
| 481 | use_sideband ? " side-band-64k" : ""); |
Brian Ewins | a63103a | 2007-10-11 20:32:26 +0100 | [diff] [blame] | 482 | } |
| 483 | else |
Shawn O. Pearce | de1a2fd | 2009-10-30 17:47:41 -0700 | [diff] [blame] | 484 | packet_buf_write(&req_buf, "%s %s %s", |
Brian Ewins | a63103a | 2007-10-11 20:32:26 +0100 | [diff] [blame] | 485 | old_hex, new_hex, ref->name); |
Shawn O. Pearce | 0c499ea | 2010-02-05 12:57:39 -0800 | [diff] [blame] | 486 | ref->status = status_report ? |
| 487 | REF_STATUS_EXPECTING_REPORT : |
| 488 | REF_STATUS_OK; |
| 489 | cmds_sent++; |
Junio C Hamano | cfee10a | 2005-12-25 23:18:37 -0800 | [diff] [blame] | 490 | } |
Linus Torvalds | 7f8e982 | 2005-06-29 22:50:48 -0700 | [diff] [blame] | 491 | } |
Junio C Hamano | f88395a | 2005-08-03 16:35:29 -0700 | [diff] [blame] | 492 | |
Shawn O. Pearce | de1a2fd | 2009-10-30 17:47:41 -0700 | [diff] [blame] | 493 | if (args->stateless_rpc) { |
Shawn O. Pearce | 0c499ea | 2010-02-05 12:57:39 -0800 | [diff] [blame] | 494 | if (!args->dry_run && cmds_sent) { |
Shawn O. Pearce | de1a2fd | 2009-10-30 17:47:41 -0700 | [diff] [blame] | 495 | packet_buf_flush(&req_buf); |
| 496 | send_sideband(out, -1, req_buf.buf, req_buf.len, LARGE_PACKET_MAX); |
| 497 | } |
| 498 | } else { |
| 499 | safe_write(out, req_buf.buf, req_buf.len); |
| 500 | packet_flush(out); |
| 501 | } |
| 502 | strbuf_release(&req_buf); |
| 503 | |
Shawn O. Pearce | 0c499ea | 2010-02-05 12:57:39 -0800 | [diff] [blame] | 504 | if (use_sideband && cmds_sent) { |
| 505 | memset(&demux, 0, sizeof(demux)); |
| 506 | demux.proc = sideband_demux; |
| 507 | demux.data = fd; |
| 508 | demux.out = -1; |
| 509 | if (start_async(&demux)) |
| 510 | die("receive-pack: unable to fork off sideband demultiplexer"); |
| 511 | in = demux.out; |
| 512 | } |
| 513 | |
| 514 | if (new_refs && cmds_sent) { |
Daniel Barkalow | 64fcef2 | 2009-03-08 21:06:07 -0400 | [diff] [blame] | 515 | if (pack_objects(out, remote_refs, extra_have, args) < 0) { |
| 516 | for (ref = remote_refs; ref; ref = ref->next) |
| 517 | ref->status = REF_STATUS_NONE; |
Shawn O. Pearce | 0c499ea | 2010-02-05 12:57:39 -0800 | [diff] [blame] | 518 | if (use_sideband) |
| 519 | finish_async(&demux); |
Jeff King | 8736a84 | 2007-11-17 07:54:27 -0500 | [diff] [blame] | 520 | return -1; |
Daniel Barkalow | 64fcef2 | 2009-03-08 21:06:07 -0400 | [diff] [blame] | 521 | } |
Jeff King | 8736a84 | 2007-11-17 07:54:27 -0500 | [diff] [blame] | 522 | } |
Shawn O. Pearce | 0c499ea | 2010-02-05 12:57:39 -0800 | [diff] [blame] | 523 | if (args->stateless_rpc && cmds_sent) |
Shawn O. Pearce | de1a2fd | 2009-10-30 17:47:41 -0700 | [diff] [blame] | 524 | packet_flush(out); |
Junio C Hamano | cfee10a | 2005-12-25 23:18:37 -0800 | [diff] [blame] | 525 | |
Shawn O. Pearce | 0c499ea | 2010-02-05 12:57:39 -0800 | [diff] [blame] | 526 | if (status_report && cmds_sent) |
Jeff King | ca74c45 | 2007-11-17 07:56:03 -0500 | [diff] [blame] | 527 | ret = receive_status(in, remote_refs); |
Jeff King | ca74c45 | 2007-11-17 07:56:03 -0500 | [diff] [blame] | 528 | else |
| 529 | ret = 0; |
Shawn O. Pearce | de1a2fd | 2009-10-30 17:47:41 -0700 | [diff] [blame] | 530 | if (args->stateless_rpc) |
| 531 | packet_flush(out); |
Jeff King | ca74c45 | 2007-11-17 07:56:03 -0500 | [diff] [blame] | 532 | |
Shawn O. Pearce | 0c499ea | 2010-02-05 12:57:39 -0800 | [diff] [blame] | 533 | if (use_sideband && cmds_sent) { |
| 534 | if (finish_async(&demux)) { |
| 535 | error("error in sideband demultiplexer"); |
| 536 | ret = -1; |
| 537 | } |
| 538 | close(demux.out); |
| 539 | } |
| 540 | |
Jeff King | ca74c45 | 2007-11-17 07:56:03 -0500 | [diff] [blame] | 541 | if (ret < 0) |
| 542 | return ret; |
Jeff King | 8736a84 | 2007-11-17 07:54:27 -0500 | [diff] [blame] | 543 | for (ref = remote_refs; ref; ref = ref->next) { |
| 544 | switch (ref->status) { |
| 545 | case REF_STATUS_NONE: |
| 546 | case REF_STATUS_UPTODATE: |
| 547 | case REF_STATUS_OK: |
| 548 | break; |
| 549 | default: |
| 550 | return -1; |
| 551 | } |
| 552 | } |
| 553 | return 0; |
Linus Torvalds | 6122147 | 2005-06-29 19:09:05 -0700 | [diff] [blame] | 554 | } |
| 555 | |
Daniel Barkalow | 4577370 | 2007-10-29 21:05:40 -0400 | [diff] [blame] | 556 | static void verify_remote_names(int nr_heads, const char **heads) |
Junio C Hamano | 37adac7 | 2006-12-13 10:30:11 -0800 | [diff] [blame] | 557 | { |
| 558 | int i; |
| 559 | |
| 560 | for (i = 0; i < nr_heads; i++) { |
Paolo Bonzini | a83619d | 2008-04-28 11:32:12 -0400 | [diff] [blame] | 561 | const char *local = heads[i]; |
Junio C Hamano | 46220ca | 2008-03-20 23:34:37 -0700 | [diff] [blame] | 562 | const char *remote = strrchr(heads[i], ':'); |
Junio C Hamano | 37adac7 | 2006-12-13 10:30:11 -0800 | [diff] [blame] | 563 | |
Paolo Bonzini | a83619d | 2008-04-28 11:32:12 -0400 | [diff] [blame] | 564 | if (*local == '+') |
| 565 | local++; |
| 566 | |
| 567 | /* A matching refspec is okay. */ |
| 568 | if (remote == local && remote[1] == '\0') |
| 569 | continue; |
| 570 | |
| 571 | remote = remote ? (remote + 1) : local; |
Junio C Hamano | 37adac7 | 2006-12-13 10:30:11 -0800 | [diff] [blame] | 572 | switch (check_ref_format(remote)) { |
| 573 | case 0: /* ok */ |
Junio C Hamano | 257f302 | 2008-01-02 11:14:40 -0800 | [diff] [blame] | 574 | case CHECK_REF_FORMAT_ONELEVEL: |
| 575 | /* ok but a single level -- that is fine for |
| 576 | * a match pattern. |
| 577 | */ |
| 578 | case CHECK_REF_FORMAT_WILDCARD: |
| 579 | /* ok but ends with a pattern-match character */ |
Junio C Hamano | 37adac7 | 2006-12-13 10:30:11 -0800 | [diff] [blame] | 580 | continue; |
| 581 | } |
| 582 | die("remote part of refspec is not a valid name in %s", |
| 583 | heads[i]); |
| 584 | } |
| 585 | } |
Junio C Hamano | f88395a | 2005-08-03 16:35:29 -0700 | [diff] [blame] | 586 | |
Daniel Barkalow | 96249c0 | 2007-10-29 22:03:39 -0400 | [diff] [blame] | 587 | int cmd_send_pack(int argc, const char **argv, const char *prefix) |
Linus Torvalds | 6122147 | 2005-06-29 19:09:05 -0700 | [diff] [blame] | 588 | { |
Daniel Barkalow | 64fcef2 | 2009-03-08 21:06:07 -0400 | [diff] [blame] | 589 | int i, nr_refspecs = 0; |
| 590 | const char **refspecs = NULL; |
Daniel Barkalow | 96249c0 | 2007-10-29 22:03:39 -0400 | [diff] [blame] | 591 | const char *remote_name = NULL; |
Daniel Barkalow | b516968 | 2007-05-15 22:50:19 -0400 | [diff] [blame] | 592 | struct remote *remote = NULL; |
Daniel Barkalow | 96249c0 | 2007-10-29 22:03:39 -0400 | [diff] [blame] | 593 | const char *dest = NULL; |
Daniel Barkalow | 64fcef2 | 2009-03-08 21:06:07 -0400 | [diff] [blame] | 594 | int fd[2]; |
| 595 | struct child_process *conn; |
| 596 | struct extra_have_objects extra_have; |
Clemens Buchacher | 6d2bf96 | 2009-05-31 16:26:48 +0200 | [diff] [blame] | 597 | struct ref *remote_refs, *local_refs; |
Daniel Barkalow | 64fcef2 | 2009-03-08 21:06:07 -0400 | [diff] [blame] | 598 | int ret; |
Shawn O. Pearce | de1a2fd | 2009-10-30 17:47:41 -0700 | [diff] [blame] | 599 | int helper_status = 0; |
Daniel Barkalow | 64fcef2 | 2009-03-08 21:06:07 -0400 | [diff] [blame] | 600 | int send_all = 0; |
| 601 | const char *receivepack = "git-receive-pack"; |
| 602 | int flags; |
Junio C Hamano | 84a9b58 | 2006-03-23 23:41:18 -0800 | [diff] [blame] | 603 | |
Linus Torvalds | 6122147 | 2005-06-29 19:09:05 -0700 | [diff] [blame] | 604 | argv++; |
Linus Torvalds | d089391 | 2005-07-16 13:26:33 -0700 | [diff] [blame] | 605 | for (i = 1; i < argc; i++, argv++) { |
Daniel Barkalow | 96249c0 | 2007-10-29 22:03:39 -0400 | [diff] [blame] | 606 | const char *arg = *argv; |
Linus Torvalds | 6122147 | 2005-06-29 19:09:05 -0700 | [diff] [blame] | 607 | |
| 608 | if (*arg == '-') { |
Junio C Hamano | cc44c76 | 2007-02-20 01:53:29 -0800 | [diff] [blame] | 609 | if (!prefixcmp(arg, "--receive-pack=")) { |
Daniel Barkalow | 64fcef2 | 2009-03-08 21:06:07 -0400 | [diff] [blame] | 610 | receivepack = arg + 15; |
Uwe Kleine-König | d23842f | 2007-01-19 13:49:27 +0100 | [diff] [blame] | 611 | continue; |
| 612 | } |
Junio C Hamano | cc44c76 | 2007-02-20 01:53:29 -0800 | [diff] [blame] | 613 | if (!prefixcmp(arg, "--exec=")) { |
Daniel Barkalow | 64fcef2 | 2009-03-08 21:06:07 -0400 | [diff] [blame] | 614 | receivepack = arg + 7; |
Linus Torvalds | 6122147 | 2005-06-29 19:09:05 -0700 | [diff] [blame] | 615 | continue; |
| 616 | } |
Daniel Barkalow | b516968 | 2007-05-15 22:50:19 -0400 | [diff] [blame] | 617 | if (!prefixcmp(arg, "--remote=")) { |
| 618 | remote_name = arg + 9; |
| 619 | continue; |
| 620 | } |
Linus Torvalds | d089391 | 2005-07-16 13:26:33 -0700 | [diff] [blame] | 621 | if (!strcmp(arg, "--all")) { |
Daniel Barkalow | 64fcef2 | 2009-03-08 21:06:07 -0400 | [diff] [blame] | 622 | send_all = 1; |
Linus Torvalds | d089391 | 2005-07-16 13:26:33 -0700 | [diff] [blame] | 623 | continue; |
| 624 | } |
Brian Ewins | a63103a | 2007-10-11 20:32:26 +0100 | [diff] [blame] | 625 | if (!strcmp(arg, "--dry-run")) { |
Daniel Barkalow | 96249c0 | 2007-10-29 22:03:39 -0400 | [diff] [blame] | 626 | args.dry_run = 1; |
Brian Ewins | a63103a | 2007-10-11 20:32:26 +0100 | [diff] [blame] | 627 | continue; |
| 628 | } |
Andy Whitcroft | 28b9d6e | 2007-11-09 23:32:10 +0000 | [diff] [blame] | 629 | if (!strcmp(arg, "--mirror")) { |
| 630 | args.send_mirror = 1; |
| 631 | continue; |
| 632 | } |
Linus Torvalds | 2a9c3fe | 2005-07-19 07:03:47 -0400 | [diff] [blame] | 633 | if (!strcmp(arg, "--force")) { |
Daniel Barkalow | 96249c0 | 2007-10-29 22:03:39 -0400 | [diff] [blame] | 634 | args.force_update = 1; |
Linus Torvalds | 2a9c3fe | 2005-07-19 07:03:47 -0400 | [diff] [blame] | 635 | continue; |
| 636 | } |
Linus Torvalds | 41f93a2 | 2005-12-20 18:13:02 -0800 | [diff] [blame] | 637 | if (!strcmp(arg, "--verbose")) { |
Daniel Barkalow | 96249c0 | 2007-10-29 22:03:39 -0400 | [diff] [blame] | 638 | args.verbose = 1; |
Linus Torvalds | 41f93a2 | 2005-12-20 18:13:02 -0800 | [diff] [blame] | 639 | continue; |
| 640 | } |
Junio C Hamano | 2245be3 | 2006-02-19 15:03:49 -0800 | [diff] [blame] | 641 | if (!strcmp(arg, "--thin")) { |
Daniel Barkalow | 96249c0 | 2007-10-29 22:03:39 -0400 | [diff] [blame] | 642 | args.use_thin_pack = 1; |
Junio C Hamano | 2245be3 | 2006-02-19 15:03:49 -0800 | [diff] [blame] | 643 | continue; |
| 644 | } |
Shawn O. Pearce | de1a2fd | 2009-10-30 17:47:41 -0700 | [diff] [blame] | 645 | if (!strcmp(arg, "--stateless-rpc")) { |
| 646 | args.stateless_rpc = 1; |
| 647 | continue; |
| 648 | } |
| 649 | if (!strcmp(arg, "--helper-status")) { |
| 650 | helper_status = 1; |
| 651 | continue; |
| 652 | } |
Linus Torvalds | 6122147 | 2005-06-29 19:09:05 -0700 | [diff] [blame] | 653 | usage(send_pack_usage); |
| 654 | } |
Linus Torvalds | d089391 | 2005-07-16 13:26:33 -0700 | [diff] [blame] | 655 | if (!dest) { |
| 656 | dest = arg; |
| 657 | continue; |
| 658 | } |
Daniel Barkalow | 64fcef2 | 2009-03-08 21:06:07 -0400 | [diff] [blame] | 659 | refspecs = (const char **) argv; |
| 660 | nr_refspecs = argc - i; |
Linus Torvalds | 6122147 | 2005-06-29 19:09:05 -0700 | [diff] [blame] | 661 | break; |
| 662 | } |
| 663 | if (!dest) |
| 664 | usage(send_pack_usage); |
Andy Whitcroft | 28b9d6e | 2007-11-09 23:32:10 +0000 | [diff] [blame] | 665 | /* |
| 666 | * --all and --mirror are incompatible; neither makes sense |
| 667 | * with any refspecs. |
| 668 | */ |
Daniel Barkalow | 64fcef2 | 2009-03-08 21:06:07 -0400 | [diff] [blame] | 669 | if ((refspecs && (send_all || args.send_mirror)) || |
| 670 | (send_all && args.send_mirror)) |
Junio C Hamano | 0bc3cdf | 2005-08-02 12:20:27 -0700 | [diff] [blame] | 671 | usage(send_pack_usage); |
Junio C Hamano | 37adac7 | 2006-12-13 10:30:11 -0800 | [diff] [blame] | 672 | |
Daniel Barkalow | b516968 | 2007-05-15 22:50:19 -0400 | [diff] [blame] | 673 | if (remote_name) { |
| 674 | remote = remote_get(remote_name); |
Shawn O. Pearce | 28b91f8 | 2007-09-19 00:49:27 -0400 | [diff] [blame] | 675 | if (!remote_has_url(remote, dest)) { |
Daniel Barkalow | b516968 | 2007-05-15 22:50:19 -0400 | [diff] [blame] | 676 | die("Destination %s is not a uri for %s", |
| 677 | dest, remote_name); |
| 678 | } |
| 679 | } |
| 680 | |
Shawn O. Pearce | de1a2fd | 2009-10-30 17:47:41 -0700 | [diff] [blame] | 681 | if (args.stateless_rpc) { |
| 682 | conn = NULL; |
| 683 | fd[0] = 0; |
| 684 | fd[1] = 1; |
| 685 | } else { |
| 686 | conn = git_connect(fd, dest, receivepack, |
| 687 | args.verbose ? CONNECT_VERBOSE : 0); |
| 688 | } |
Daniel Barkalow | 96249c0 | 2007-10-29 22:03:39 -0400 | [diff] [blame] | 689 | |
Daniel Barkalow | 64fcef2 | 2009-03-08 21:06:07 -0400 | [diff] [blame] | 690 | memset(&extra_have, 0, sizeof(extra_have)); |
Daniel Barkalow | 96249c0 | 2007-10-29 22:03:39 -0400 | [diff] [blame] | 691 | |
Daniel Barkalow | 64fcef2 | 2009-03-08 21:06:07 -0400 | [diff] [blame] | 692 | get_remote_heads(fd[0], &remote_refs, 0, NULL, REF_NORMAL, |
| 693 | &extra_have); |
Daniel Barkalow | 96249c0 | 2007-10-29 22:03:39 -0400 | [diff] [blame] | 694 | |
Daniel Barkalow | 64fcef2 | 2009-03-08 21:06:07 -0400 | [diff] [blame] | 695 | verify_remote_names(nr_refspecs, refspecs); |
Daniel Barkalow | 96249c0 | 2007-10-29 22:03:39 -0400 | [diff] [blame] | 696 | |
Daniel Barkalow | 64fcef2 | 2009-03-08 21:06:07 -0400 | [diff] [blame] | 697 | local_refs = get_local_heads(); |
| 698 | |
| 699 | flags = MATCH_REFS_NONE; |
| 700 | |
| 701 | if (send_all) |
| 702 | flags |= MATCH_REFS_ALL; |
| 703 | if (args.send_mirror) |
| 704 | flags |= MATCH_REFS_MIRROR; |
| 705 | |
| 706 | /* match them up */ |
Clemens Buchacher | 6d2bf96 | 2009-05-31 16:26:48 +0200 | [diff] [blame] | 707 | if (match_refs(local_refs, &remote_refs, nr_refspecs, refspecs, flags)) |
Daniel Barkalow | 64fcef2 | 2009-03-08 21:06:07 -0400 | [diff] [blame] | 708 | return -1; |
Daniel Barkalow | 64fcef2 | 2009-03-08 21:06:07 -0400 | [diff] [blame] | 709 | |
| 710 | ret = send_pack(&args, fd, conn, remote_refs, &extra_have); |
| 711 | |
Shawn O. Pearce | de1a2fd | 2009-10-30 17:47:41 -0700 | [diff] [blame] | 712 | if (helper_status) |
| 713 | print_helper_status(remote_refs); |
| 714 | |
Daniel Barkalow | 64fcef2 | 2009-03-08 21:06:07 -0400 | [diff] [blame] | 715 | close(fd[1]); |
Linus Torvalds | 7f8e982 | 2005-06-29 22:50:48 -0700 | [diff] [blame] | 716 | close(fd[0]); |
Daniel Barkalow | 64fcef2 | 2009-03-08 21:06:07 -0400 | [diff] [blame] | 717 | |
Johannes Sixt | 98158e9 | 2007-10-19 21:47:53 +0200 | [diff] [blame] | 718 | ret |= finish_connect(conn); |
Daniel Barkalow | 64fcef2 | 2009-03-08 21:06:07 -0400 | [diff] [blame] | 719 | |
Shawn O. Pearce | de1a2fd | 2009-10-30 17:47:41 -0700 | [diff] [blame] | 720 | if (!helper_status) |
| 721 | print_push_status(dest, remote_refs); |
Daniel Barkalow | 64fcef2 | 2009-03-08 21:06:07 -0400 | [diff] [blame] | 722 | |
| 723 | if (!args.dry_run && remote) { |
| 724 | struct ref *ref; |
| 725 | for (ref = remote_refs; ref; ref = ref->next) |
| 726 | update_tracking_ref(remote, ref); |
| 727 | } |
| 728 | |
| 729 | if (!ret && !refs_pushed(remote_refs)) |
| 730 | fprintf(stderr, "Everything up-to-date\n"); |
| 731 | |
| 732 | return ret; |
Linus Torvalds | 6122147 | 2005-06-29 19:09:05 -0700 | [diff] [blame] | 733 | } |