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" |
Jeff King | ff5effd | 2012-08-03 12:19:16 -0400 | [diff] [blame] | 11 | #include "version.h" |
Linus Torvalds | 6122147 | 2005-06-29 19:09:05 -0700 | [diff] [blame] | 12 | |
Junio C Hamano | 2a24501 | 2005-07-14 00:10:05 -0700 | [diff] [blame] | 13 | static const char send_pack_usage[] = |
Stephan Beyer | 1b1dd23 | 2008-07-13 15:36:15 +0200 | [diff] [blame] | 14 | "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] | 15 | " --all and explicit <ref> specification are mutually exclusive."; |
Daniel Barkalow | 96249c0 | 2007-10-29 22:03:39 -0400 | [diff] [blame] | 16 | |
Brandon Casey | 6828f72 | 2009-03-26 21:37:53 -0500 | [diff] [blame] | 17 | static struct send_pack_args args; |
Linus Torvalds | 6122147 | 2005-06-29 19:09:05 -0700 | [diff] [blame] | 18 | |
Shawn O. Pearce | de1a2fd | 2009-10-30 17:47:41 -0700 | [diff] [blame] | 19 | static 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 Hamano | 75e5c0d | 2013-01-23 13:55:30 -0800 | [diff] [blame] | 47 | 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 Rorvick | dbfeddb | 2012-11-29 19:41:37 -0600 | [diff] [blame] | 57 | case REF_STATUS_REJECT_ALREADY_EXISTS: |
| 58 | res = "error"; |
| 59 | msg = "already exists"; |
| 60 | break; |
| 61 | |
Shawn O. Pearce | de1a2fd | 2009-10-30 17:47:41 -0700 | [diff] [blame] | 62 | 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 Barkalow | 96249c0 | 2007-10-29 22:03:39 -0400 | [diff] [blame] | 87 | int cmd_send_pack(int argc, const char **argv, const char *prefix) |
Linus Torvalds | 6122147 | 2005-06-29 19:09:05 -0700 | [diff] [blame] | 88 | { |
Daniel Barkalow | 64fcef2 | 2009-03-08 21:06:07 -0400 | [diff] [blame] | 89 | int i, nr_refspecs = 0; |
| 90 | const char **refspecs = NULL; |
Daniel Barkalow | 96249c0 | 2007-10-29 22:03:39 -0400 | [diff] [blame] | 91 | const char *remote_name = NULL; |
Daniel Barkalow | b516968 | 2007-05-15 22:50:19 -0400 | [diff] [blame] | 92 | struct remote *remote = NULL; |
Daniel Barkalow | 96249c0 | 2007-10-29 22:03:39 -0400 | [diff] [blame] | 93 | const char *dest = NULL; |
Daniel Barkalow | 64fcef2 | 2009-03-08 21:06:07 -0400 | [diff] [blame] | 94 | int fd[2]; |
| 95 | struct child_process *conn; |
| 96 | struct extra_have_objects extra_have; |
Clemens Buchacher | 6d2bf96 | 2009-05-31 16:26:48 +0200 | [diff] [blame] | 97 | struct ref *remote_refs, *local_refs; |
Daniel Barkalow | 64fcef2 | 2009-03-08 21:06:07 -0400 | [diff] [blame] | 98 | int ret; |
Shawn O. Pearce | de1a2fd | 2009-10-30 17:47:41 -0700 | [diff] [blame] | 99 | int helper_status = 0; |
Daniel Barkalow | 64fcef2 | 2009-03-08 21:06:07 -0400 | [diff] [blame] | 100 | int send_all = 0; |
| 101 | const char *receivepack = "git-receive-pack"; |
| 102 | int flags; |
Chris Rorvick | 10643d4 | 2012-11-29 19:41:33 -0600 | [diff] [blame] | 103 | unsigned int reject_reasons; |
Jeff King | 391b1f2 | 2012-05-01 04:42:24 -0400 | [diff] [blame] | 104 | int progress = -1; |
Junio C Hamano | 84a9b58 | 2006-03-23 23:41:18 -0800 | [diff] [blame] | 105 | |
Linus Torvalds | 6122147 | 2005-06-29 19:09:05 -0700 | [diff] [blame] | 106 | argv++; |
Linus Torvalds | d089391 | 2005-07-16 13:26:33 -0700 | [diff] [blame] | 107 | for (i = 1; i < argc; i++, argv++) { |
Daniel Barkalow | 96249c0 | 2007-10-29 22:03:39 -0400 | [diff] [blame] | 108 | const char *arg = *argv; |
Linus Torvalds | 6122147 | 2005-06-29 19:09:05 -0700 | [diff] [blame] | 109 | |
| 110 | if (*arg == '-') { |
Junio C Hamano | cc44c76 | 2007-02-20 01:53:29 -0800 | [diff] [blame] | 111 | if (!prefixcmp(arg, "--receive-pack=")) { |
Daniel Barkalow | 64fcef2 | 2009-03-08 21:06:07 -0400 | [diff] [blame] | 112 | receivepack = arg + 15; |
Uwe Kleine-König | d23842f | 2007-01-19 13:49:27 +0100 | [diff] [blame] | 113 | continue; |
| 114 | } |
Junio C Hamano | cc44c76 | 2007-02-20 01:53:29 -0800 | [diff] [blame] | 115 | if (!prefixcmp(arg, "--exec=")) { |
Daniel Barkalow | 64fcef2 | 2009-03-08 21:06:07 -0400 | [diff] [blame] | 116 | receivepack = arg + 7; |
Linus Torvalds | 6122147 | 2005-06-29 19:09:05 -0700 | [diff] [blame] | 117 | continue; |
| 118 | } |
Daniel Barkalow | b516968 | 2007-05-15 22:50:19 -0400 | [diff] [blame] | 119 | if (!prefixcmp(arg, "--remote=")) { |
| 120 | remote_name = arg + 9; |
| 121 | continue; |
| 122 | } |
Linus Torvalds | d089391 | 2005-07-16 13:26:33 -0700 | [diff] [blame] | 123 | if (!strcmp(arg, "--all")) { |
Daniel Barkalow | 64fcef2 | 2009-03-08 21:06:07 -0400 | [diff] [blame] | 124 | send_all = 1; |
Linus Torvalds | d089391 | 2005-07-16 13:26:33 -0700 | [diff] [blame] | 125 | continue; |
| 126 | } |
Brian Ewins | a63103a | 2007-10-11 20:32:26 +0100 | [diff] [blame] | 127 | if (!strcmp(arg, "--dry-run")) { |
Daniel Barkalow | 96249c0 | 2007-10-29 22:03:39 -0400 | [diff] [blame] | 128 | args.dry_run = 1; |
Brian Ewins | a63103a | 2007-10-11 20:32:26 +0100 | [diff] [blame] | 129 | continue; |
| 130 | } |
Andy Whitcroft | 28b9d6e | 2007-11-09 23:32:10 +0000 | [diff] [blame] | 131 | if (!strcmp(arg, "--mirror")) { |
| 132 | args.send_mirror = 1; |
| 133 | continue; |
| 134 | } |
Linus Torvalds | 2a9c3fe | 2005-07-19 07:03:47 -0400 | [diff] [blame] | 135 | if (!strcmp(arg, "--force")) { |
Daniel Barkalow | 96249c0 | 2007-10-29 22:03:39 -0400 | [diff] [blame] | 136 | args.force_update = 1; |
Linus Torvalds | 2a9c3fe | 2005-07-19 07:03:47 -0400 | [diff] [blame] | 137 | continue; |
| 138 | } |
Clemens Buchacher | c207e34 | 2012-01-08 22:06:20 +0100 | [diff] [blame] | 139 | if (!strcmp(arg, "--quiet")) { |
| 140 | args.quiet = 1; |
| 141 | continue; |
| 142 | } |
Linus Torvalds | 41f93a2 | 2005-12-20 18:13:02 -0800 | [diff] [blame] | 143 | if (!strcmp(arg, "--verbose")) { |
Daniel Barkalow | 96249c0 | 2007-10-29 22:03:39 -0400 | [diff] [blame] | 144 | args.verbose = 1; |
Linus Torvalds | 41f93a2 | 2005-12-20 18:13:02 -0800 | [diff] [blame] | 145 | continue; |
| 146 | } |
Jeff King | 391b1f2 | 2012-05-01 04:42:24 -0400 | [diff] [blame] | 147 | if (!strcmp(arg, "--progress")) { |
| 148 | progress = 1; |
| 149 | continue; |
| 150 | } |
| 151 | if (!strcmp(arg, "--no-progress")) { |
| 152 | progress = 0; |
| 153 | continue; |
| 154 | } |
Junio C Hamano | 2245be3 | 2006-02-19 15:03:49 -0800 | [diff] [blame] | 155 | if (!strcmp(arg, "--thin")) { |
Daniel Barkalow | 96249c0 | 2007-10-29 22:03:39 -0400 | [diff] [blame] | 156 | args.use_thin_pack = 1; |
Junio C Hamano | 2245be3 | 2006-02-19 15:03:49 -0800 | [diff] [blame] | 157 | continue; |
| 158 | } |
Shawn O. Pearce | de1a2fd | 2009-10-30 17:47:41 -0700 | [diff] [blame] | 159 | 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 Torvalds | 6122147 | 2005-06-29 19:09:05 -0700 | [diff] [blame] | 167 | usage(send_pack_usage); |
| 168 | } |
Linus Torvalds | d089391 | 2005-07-16 13:26:33 -0700 | [diff] [blame] | 169 | if (!dest) { |
| 170 | dest = arg; |
| 171 | continue; |
| 172 | } |
Daniel Barkalow | 64fcef2 | 2009-03-08 21:06:07 -0400 | [diff] [blame] | 173 | refspecs = (const char **) argv; |
| 174 | nr_refspecs = argc - i; |
Linus Torvalds | 6122147 | 2005-06-29 19:09:05 -0700 | [diff] [blame] | 175 | break; |
| 176 | } |
| 177 | if (!dest) |
| 178 | usage(send_pack_usage); |
Andy Whitcroft | 28b9d6e | 2007-11-09 23:32:10 +0000 | [diff] [blame] | 179 | /* |
| 180 | * --all and --mirror are incompatible; neither makes sense |
| 181 | * with any refspecs. |
| 182 | */ |
Daniel Barkalow | 64fcef2 | 2009-03-08 21:06:07 -0400 | [diff] [blame] | 183 | if ((refspecs && (send_all || args.send_mirror)) || |
| 184 | (send_all && args.send_mirror)) |
Junio C Hamano | 0bc3cdf | 2005-08-02 12:20:27 -0700 | [diff] [blame] | 185 | usage(send_pack_usage); |
Junio C Hamano | 37adac7 | 2006-12-13 10:30:11 -0800 | [diff] [blame] | 186 | |
Daniel Barkalow | b516968 | 2007-05-15 22:50:19 -0400 | [diff] [blame] | 187 | if (remote_name) { |
| 188 | remote = remote_get(remote_name); |
Shawn O. Pearce | 28b91f8 | 2007-09-19 00:49:27 -0400 | [diff] [blame] | 189 | if (!remote_has_url(remote, dest)) { |
Daniel Barkalow | b516968 | 2007-05-15 22:50:19 -0400 | [diff] [blame] | 190 | die("Destination %s is not a uri for %s", |
| 191 | dest, remote_name); |
| 192 | } |
| 193 | } |
| 194 | |
Jeff King | 391b1f2 | 2012-05-01 04:42:24 -0400 | [diff] [blame] | 195 | if (progress == -1) |
| 196 | progress = !args.quiet && isatty(2); |
| 197 | args.progress = progress; |
Jeff King | 8d32e60 | 2012-05-01 04:41:42 -0400 | [diff] [blame] | 198 | |
Shawn O. Pearce | de1a2fd | 2009-10-30 17:47:41 -0700 | [diff] [blame] | 199 | if (args.stateless_rpc) { |
| 200 | conn = NULL; |
| 201 | fd[0] = 0; |
| 202 | fd[1] = 1; |
| 203 | } else { |
Junio C Hamano | 5a277f3 | 2011-09-06 11:06:32 -0700 | [diff] [blame] | 204 | conn = git_connect(fd, dest, receivepack, |
Shawn O. Pearce | de1a2fd | 2009-10-30 17:47:41 -0700 | [diff] [blame] | 205 | args.verbose ? CONNECT_VERBOSE : 0); |
| 206 | } |
Daniel Barkalow | 96249c0 | 2007-10-29 22:03:39 -0400 | [diff] [blame] | 207 | |
Daniel Barkalow | 64fcef2 | 2009-03-08 21:06:07 -0400 | [diff] [blame] | 208 | memset(&extra_have, 0, sizeof(extra_have)); |
Daniel Barkalow | 96249c0 | 2007-10-29 22:03:39 -0400 | [diff] [blame] | 209 | |
Jeff King | afe7c5f | 2011-12-12 19:41:37 -0500 | [diff] [blame] | 210 | get_remote_heads(fd[0], &remote_refs, REF_NORMAL, &extra_have); |
Daniel Barkalow | 96249c0 | 2007-10-29 22:03:39 -0400 | [diff] [blame] | 211 | |
Michael Lukashov | f1863d0 | 2010-02-16 23:42:52 +0000 | [diff] [blame] | 212 | transport_verify_remote_names(nr_refspecs, refspecs); |
Daniel Barkalow | 96249c0 | 2007-10-29 22:03:39 -0400 | [diff] [blame] | 213 | |
Daniel Barkalow | 64fcef2 | 2009-03-08 21:06:07 -0400 | [diff] [blame] | 214 | 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 Hamano | 29753cd | 2011-09-09 11:54:58 -0700 | [diff] [blame] | 224 | if (match_push_refs(local_refs, &remote_refs, nr_refspecs, refspecs, flags)) |
Daniel Barkalow | 64fcef2 | 2009-03-08 21:06:07 -0400 | [diff] [blame] | 225 | return -1; |
Daniel Barkalow | 64fcef2 | 2009-03-08 21:06:07 -0400 | [diff] [blame] | 226 | |
Tay Ray Chuan | 20e8b46 | 2010-01-08 10:12:42 +0800 | [diff] [blame] | 227 | set_ref_status_for_push(remote_refs, args.send_mirror, |
| 228 | args.force_update); |
| 229 | |
Daniel Barkalow | 64fcef2 | 2009-03-08 21:06:07 -0400 | [diff] [blame] | 230 | ret = send_pack(&args, fd, conn, remote_refs, &extra_have); |
| 231 | |
Shawn O. Pearce | de1a2fd | 2009-10-30 17:47:41 -0700 | [diff] [blame] | 232 | if (helper_status) |
| 233 | print_helper_status(remote_refs); |
| 234 | |
Daniel Barkalow | 64fcef2 | 2009-03-08 21:06:07 -0400 | [diff] [blame] | 235 | close(fd[1]); |
Linus Torvalds | 7f8e982 | 2005-06-29 22:50:48 -0700 | [diff] [blame] | 236 | close(fd[0]); |
Daniel Barkalow | 64fcef2 | 2009-03-08 21:06:07 -0400 | [diff] [blame] | 237 | |
Johannes Sixt | 98158e9 | 2007-10-19 21:47:53 +0200 | [diff] [blame] | 238 | ret |= finish_connect(conn); |
Daniel Barkalow | 64fcef2 | 2009-03-08 21:06:07 -0400 | [diff] [blame] | 239 | |
Shawn O. Pearce | de1a2fd | 2009-10-30 17:47:41 -0700 | [diff] [blame] | 240 | if (!helper_status) |
Chris Rorvick | 10643d4 | 2012-11-29 19:41:33 -0600 | [diff] [blame] | 241 | transport_print_push_status(dest, remote_refs, args.verbose, 0, &reject_reasons); |
Daniel Barkalow | 64fcef2 | 2009-03-08 21:06:07 -0400 | [diff] [blame] | 242 | |
| 243 | if (!args.dry_run && remote) { |
| 244 | struct ref *ref; |
| 245 | for (ref = remote_refs; ref; ref = ref->next) |
Michael Lukashov | f1863d0 | 2010-02-16 23:42:52 +0000 | [diff] [blame] | 246 | transport_update_tracking_ref(remote, ref, args.verbose); |
Daniel Barkalow | 64fcef2 | 2009-03-08 21:06:07 -0400 | [diff] [blame] | 247 | } |
| 248 | |
Michael Lukashov | f1863d0 | 2010-02-16 23:42:52 +0000 | [diff] [blame] | 249 | if (!ret && !transport_refs_pushed(remote_refs)) |
Daniel Barkalow | 64fcef2 | 2009-03-08 21:06:07 -0400 | [diff] [blame] | 250 | fprintf(stderr, "Everything up-to-date\n"); |
| 251 | |
| 252 | return ret; |
Linus Torvalds | 6122147 | 2005-06-29 19:09:05 -0700 | [diff] [blame] | 253 | } |