Stephen Boyd | c2e86ad | 2011-03-22 00:51:05 -0700 | [diff] [blame] | 1 | #include "builtin.h" |
Linus Torvalds | def88e9 | 2005-07-04 13:26:53 -0700 | [diff] [blame] | 2 | #include "pkt-line.h" |
Daniel Barkalow | 2d4177c | 2007-09-10 23:03:00 -0400 | [diff] [blame] | 3 | #include "fetch-pack.h" |
Junio C Hamano | 47a5918 | 2013-07-08 13:56:53 -0700 | [diff] [blame] | 4 | #include "remote.h" |
| 5 | #include "connect.h" |
Nguyễn Thái Ngọc Duy | 1609488 | 2013-12-05 20:02:50 +0700 | [diff] [blame] | 6 | #include "sha1-array.h" |
Shawn O. Pearce | fa74052 | 2007-09-19 00:49:35 -0400 | [diff] [blame] | 7 | |
Junio C Hamano | 33b8303 | 2005-08-12 02:08:29 -0700 | [diff] [blame] | 8 | static const char fetch_pack_usage[] = |
Alex Henrie | 9c9b4f2 | 2015-01-13 00:44:47 -0700 | [diff] [blame] | 9 | "git fetch-pack [--all] [--stdin] [--quiet | -q] [--keep | -k] [--thin] " |
Ivan Todoroski | 078b895 | 2012-04-02 17:13:48 +0200 | [diff] [blame] | 10 | "[--include-tag] [--upload-pack=<git-upload-pack>] [--depth=<n>] " |
Torsten Bögershausen | 5610b7c | 2013-11-28 20:49:17 +0100 | [diff] [blame] | 11 | "[--no-progress] [--diag-url] [-v] [<host>:]<directory> [<refs>...]"; |
Linus Torvalds | def88e9 | 2005-07-04 13:26:53 -0700 | [diff] [blame] | 12 | |
Junio C Hamano | f2db854 | 2013-01-29 14:02:15 -0800 | [diff] [blame] | 13 | static void add_sought_entry_mem(struct ref ***sought, int *nr, int *alloc, |
| 14 | const char *name, int namelen) |
| 15 | { |
| 16 | struct ref *ref = xcalloc(1, sizeof(*ref) + namelen + 1); |
brian m. carlson | 854ecb9 | 2015-11-10 02:22:21 +0000 | [diff] [blame^] | 17 | struct object_id oid; |
| 18 | const int chunksz = GIT_SHA1_HEXSZ + 1; |
Nguyễn Thái Ngọc Duy | 58f2ed0 | 2013-12-05 20:02:49 +0700 | [diff] [blame] | 19 | |
brian m. carlson | 854ecb9 | 2015-11-10 02:22:21 +0000 | [diff] [blame^] | 20 | if (namelen > chunksz && name[chunksz - 1] == ' ' && |
| 21 | !get_oid_hex(name, &oid)) { |
| 22 | oidcpy(&ref->old_oid, &oid); |
| 23 | name += chunksz; |
| 24 | namelen -= chunksz; |
Nguyễn Thái Ngọc Duy | 58f2ed0 | 2013-12-05 20:02:49 +0700 | [diff] [blame] | 25 | } |
Junio C Hamano | f2db854 | 2013-01-29 14:02:15 -0800 | [diff] [blame] | 26 | |
| 27 | memcpy(ref->name, name, namelen); |
| 28 | ref->name[namelen] = '\0'; |
| 29 | (*nr)++; |
| 30 | ALLOC_GROW(*sought, *nr, *alloc); |
| 31 | (*sought)[*nr - 1] = ref; |
| 32 | } |
| 33 | |
| 34 | static void add_sought_entry(struct ref ***sought, int *nr, int *alloc, |
| 35 | const char *string) |
| 36 | { |
| 37 | add_sought_entry_mem(sought, nr, alloc, string, strlen(string)); |
| 38 | } |
| 39 | |
Daniel Barkalow | 2d4177c | 2007-09-10 23:03:00 -0400 | [diff] [blame] | 40 | int cmd_fetch_pack(int argc, const char **argv, const char *prefix) |
Linus Torvalds | def88e9 | 2005-07-04 13:26:53 -0700 | [diff] [blame] | 41 | { |
Michael Haggerty | 57e6fc69 | 2012-05-21 09:59:59 +0200 | [diff] [blame] | 42 | int i, ret; |
Daniel Barkalow | ba22785 | 2008-02-04 13:26:23 -0500 | [diff] [blame] | 43 | struct ref *ref = NULL; |
Michael Haggerty | 9d19c6e | 2012-05-21 09:59:56 +0200 | [diff] [blame] | 44 | const char *dest = NULL; |
Junio C Hamano | f2db854 | 2013-01-29 14:02:15 -0800 | [diff] [blame] | 45 | struct ref **sought = NULL; |
| 46 | int nr_sought = 0, alloc_sought = 0; |
Daniel Barkalow | ba22785 | 2008-02-04 13:26:23 -0500 | [diff] [blame] | 47 | int fd[2]; |
Shawn O. Pearce | 249b200 | 2009-10-30 17:47:42 -0700 | [diff] [blame] | 48 | char *pack_lockfile = NULL; |
| 49 | char **pack_lockfile_ptr = NULL; |
Daniel Barkalow | ba22785 | 2008-02-04 13:26:23 -0500 | [diff] [blame] | 50 | struct child_process *conn; |
Nguyễn Thái Ngọc Duy | f8eb303 | 2012-10-26 22:53:54 +0700 | [diff] [blame] | 51 | struct fetch_pack_args args; |
Nguyễn Thái Ngọc Duy | 1609488 | 2013-12-05 20:02:50 +0700 | [diff] [blame] | 52 | struct sha1_array shallow = SHA1_ARRAY_INIT; |
Linus Torvalds | def88e9 | 2005-07-04 13:26:53 -0700 | [diff] [blame] | 53 | |
Jeff King | bbc30f9 | 2011-02-24 09:30:19 -0500 | [diff] [blame] | 54 | packet_trace_identity("fetch-pack"); |
| 55 | |
Nguyễn Thái Ngọc Duy | f8eb303 | 2012-10-26 22:53:54 +0700 | [diff] [blame] | 56 | memset(&args, 0, sizeof(args)); |
| 57 | args.uploadpack = "git-upload-pack"; |
| 58 | |
Michael Haggerty | ff22ff9 | 2012-05-21 09:59:58 +0200 | [diff] [blame] | 59 | for (i = 1; i < argc && *argv[i] == '-'; i++) { |
Daniel Barkalow | 2d4177c | 2007-09-10 23:03:00 -0400 | [diff] [blame] | 60 | const char *arg = argv[i]; |
Linus Torvalds | def88e9 | 2005-07-04 13:26:53 -0700 | [diff] [blame] | 61 | |
Christian Couder | 5955654 | 2013-11-30 21:55:40 +0100 | [diff] [blame] | 62 | if (starts_with(arg, "--upload-pack=")) { |
Michael Haggerty | ff22ff9 | 2012-05-21 09:59:58 +0200 | [diff] [blame] | 63 | args.uploadpack = arg + 14; |
| 64 | continue; |
Linus Torvalds | def88e9 | 2005-07-04 13:26:53 -0700 | [diff] [blame] | 65 | } |
Christian Couder | 5955654 | 2013-11-30 21:55:40 +0100 | [diff] [blame] | 66 | if (starts_with(arg, "--exec=")) { |
Michael Haggerty | ff22ff9 | 2012-05-21 09:59:58 +0200 | [diff] [blame] | 67 | args.uploadpack = arg + 7; |
| 68 | continue; |
| 69 | } |
| 70 | if (!strcmp("--quiet", arg) || !strcmp("-q", arg)) { |
| 71 | args.quiet = 1; |
| 72 | continue; |
| 73 | } |
| 74 | if (!strcmp("--keep", arg) || !strcmp("-k", arg)) { |
| 75 | args.lock_pack = args.keep_pack; |
| 76 | args.keep_pack = 1; |
| 77 | continue; |
| 78 | } |
| 79 | if (!strcmp("--thin", arg)) { |
| 80 | args.use_thin_pack = 1; |
| 81 | continue; |
| 82 | } |
| 83 | if (!strcmp("--include-tag", arg)) { |
| 84 | args.include_tag = 1; |
| 85 | continue; |
| 86 | } |
| 87 | if (!strcmp("--all", arg)) { |
| 88 | args.fetch_all = 1; |
| 89 | continue; |
| 90 | } |
| 91 | if (!strcmp("--stdin", arg)) { |
| 92 | args.stdin_refs = 1; |
| 93 | continue; |
| 94 | } |
Torsten Bögershausen | 5610b7c | 2013-11-28 20:49:17 +0100 | [diff] [blame] | 95 | if (!strcmp("--diag-url", arg)) { |
| 96 | args.diag_url = 1; |
| 97 | continue; |
| 98 | } |
Michael Haggerty | ff22ff9 | 2012-05-21 09:59:58 +0200 | [diff] [blame] | 99 | if (!strcmp("-v", arg)) { |
| 100 | args.verbose = 1; |
| 101 | continue; |
| 102 | } |
Christian Couder | 5955654 | 2013-11-30 21:55:40 +0100 | [diff] [blame] | 103 | if (starts_with(arg, "--depth=")) { |
Michael Haggerty | ff22ff9 | 2012-05-21 09:59:58 +0200 | [diff] [blame] | 104 | args.depth = strtol(arg + 8, NULL, 0); |
| 105 | continue; |
| 106 | } |
| 107 | if (!strcmp("--no-progress", arg)) { |
| 108 | args.no_progress = 1; |
| 109 | continue; |
| 110 | } |
| 111 | if (!strcmp("--stateless-rpc", arg)) { |
| 112 | args.stateless_rpc = 1; |
| 113 | continue; |
| 114 | } |
| 115 | if (!strcmp("--lock-pack", arg)) { |
| 116 | args.lock_pack = 1; |
| 117 | pack_lockfile_ptr = &pack_lockfile; |
| 118 | continue; |
| 119 | } |
Nguyễn Thái Ngọc Duy | 9ba3804 | 2013-07-21 15:18:05 +0700 | [diff] [blame] | 120 | if (!strcmp("--check-self-contained-and-connected", arg)) { |
| 121 | args.check_self_contained_and_connected = 1; |
| 122 | continue; |
| 123 | } |
Nguyễn Thái Ngọc Duy | 1609488 | 2013-12-05 20:02:50 +0700 | [diff] [blame] | 124 | if (!strcmp("--cloning", arg)) { |
| 125 | args.cloning = 1; |
| 126 | continue; |
| 127 | } |
| 128 | if (!strcmp("--update-shallow", arg)) { |
| 129 | args.update_shallow = 1; |
| 130 | continue; |
| 131 | } |
Michael Haggerty | ff22ff9 | 2012-05-21 09:59:58 +0200 | [diff] [blame] | 132 | usage(fetch_pack_usage); |
Linus Torvalds | def88e9 | 2005-07-04 13:26:53 -0700 | [diff] [blame] | 133 | } |
Michael Haggerty | 4cc00fc | 2012-05-21 09:59:57 +0200 | [diff] [blame] | 134 | |
| 135 | if (i < argc) |
| 136 | dest = argv[i++]; |
| 137 | else |
Linus Torvalds | def88e9 | 2005-07-04 13:26:53 -0700 | [diff] [blame] | 138 | usage(fetch_pack_usage); |
Daniel Barkalow | 2d4177c | 2007-09-10 23:03:00 -0400 | [diff] [blame] | 139 | |
Michael Haggerty | 57e6fc69 | 2012-05-21 09:59:59 +0200 | [diff] [blame] | 140 | /* |
| 141 | * Copy refs from cmdline to growable list, then append any |
| 142 | * refs from the standard input: |
| 143 | */ |
Michael Haggerty | 57e6fc69 | 2012-05-21 09:59:59 +0200 | [diff] [blame] | 144 | for (; i < argc; i++) |
Junio C Hamano | f2db854 | 2013-01-29 14:02:15 -0800 | [diff] [blame] | 145 | add_sought_entry(&sought, &nr_sought, &alloc_sought, argv[i]); |
Ivan Todoroski | 078b895 | 2012-04-02 17:13:48 +0200 | [diff] [blame] | 146 | if (args.stdin_refs) { |
Ivan Todoroski | 078b895 | 2012-04-02 17:13:48 +0200 | [diff] [blame] | 147 | if (args.stateless_rpc) { |
| 148 | /* in stateless RPC mode we use pkt-line to read |
| 149 | * from stdin, until we get a flush packet |
| 150 | */ |
Ivan Todoroski | 078b895 | 2012-04-02 17:13:48 +0200 | [diff] [blame] | 151 | for (;;) { |
Jeff King | 74543a0 | 2013-02-20 15:02:57 -0500 | [diff] [blame] | 152 | char *line = packet_read_line(0, NULL); |
| 153 | if (!line) |
Ivan Todoroski | 078b895 | 2012-04-02 17:13:48 +0200 | [diff] [blame] | 154 | break; |
Junio C Hamano | e013bda | 2013-04-01 08:59:37 -0700 | [diff] [blame] | 155 | add_sought_entry(&sought, &nr_sought, &alloc_sought, line); |
Ivan Todoroski | 078b895 | 2012-04-02 17:13:48 +0200 | [diff] [blame] | 156 | } |
| 157 | } |
| 158 | else { |
| 159 | /* read from stdin one ref per line, until EOF */ |
| 160 | struct strbuf line = STRBUF_INIT; |
Michael Haggerty | 8bee93d | 2012-09-09 08:19:40 +0200 | [diff] [blame] | 161 | while (strbuf_getline(&line, stdin, '\n') != EOF) |
Junio C Hamano | f2db854 | 2013-01-29 14:02:15 -0800 | [diff] [blame] | 162 | add_sought_entry(&sought, &nr_sought, &alloc_sought, line.buf); |
Ivan Todoroski | 078b895 | 2012-04-02 17:13:48 +0200 | [diff] [blame] | 163 | strbuf_release(&line); |
| 164 | } |
| 165 | } |
| 166 | |
Shawn O. Pearce | 249b200 | 2009-10-30 17:47:42 -0700 | [diff] [blame] | 167 | if (args.stateless_rpc) { |
| 168 | conn = NULL; |
| 169 | fd[0] = 0; |
| 170 | fd[1] = 1; |
Daniel Barkalow | ba22785 | 2008-02-04 13:26:23 -0500 | [diff] [blame] | 171 | } else { |
Torsten Bögershausen | 5610b7c | 2013-11-28 20:49:17 +0100 | [diff] [blame] | 172 | int flags = args.verbose ? CONNECT_VERBOSE : 0; |
| 173 | if (args.diag_url) |
| 174 | flags |= CONNECT_DIAG_URL; |
Michael Haggerty | 9d19c6e | 2012-05-21 09:59:56 +0200 | [diff] [blame] | 175 | conn = git_connect(fd, dest, args.uploadpack, |
Torsten Bögershausen | 5610b7c | 2013-11-28 20:49:17 +0100 | [diff] [blame] | 176 | flags); |
| 177 | if (!conn) |
| 178 | return args.diag_url ? 0 : 1; |
Daniel Barkalow | ba22785 | 2008-02-04 13:26:23 -0500 | [diff] [blame] | 179 | } |
Nguyễn Thái Ngọc Duy | 1609488 | 2013-12-05 20:02:50 +0700 | [diff] [blame] | 180 | get_remote_heads(fd[0], NULL, 0, &ref, 0, NULL, &shallow); |
Shawn O. Pearce | 249b200 | 2009-10-30 17:47:42 -0700 | [diff] [blame] | 181 | |
Nguyễn Thái Ngọc Duy | 1609488 | 2013-12-05 20:02:50 +0700 | [diff] [blame] | 182 | ref = fetch_pack(&args, fd, conn, ref, dest, sought, nr_sought, |
| 183 | &shallow, pack_lockfile_ptr); |
Shawn O. Pearce | 249b200 | 2009-10-30 17:47:42 -0700 | [diff] [blame] | 184 | if (pack_lockfile) { |
| 185 | printf("lock %s\n", pack_lockfile); |
| 186 | fflush(stdout); |
| 187 | } |
Nguyễn Thái Ngọc Duy | 9ba3804 | 2013-07-21 15:18:05 +0700 | [diff] [blame] | 188 | if (args.check_self_contained_and_connected && |
| 189 | args.self_contained_and_connected) { |
| 190 | printf("connectivity-ok\n"); |
| 191 | fflush(stdout); |
| 192 | } |
Shawn O. Pearce | 249b200 | 2009-10-30 17:47:42 -0700 | [diff] [blame] | 193 | close(fd[0]); |
| 194 | close(fd[1]); |
| 195 | if (finish_connect(conn)) |
Michael Haggerty | 7418f1a | 2012-09-09 08:19:46 +0200 | [diff] [blame] | 196 | return 1; |
Junio C Hamano | 9e5d2b4 | 2005-11-06 00:09:59 -0800 | [diff] [blame] | 197 | |
Junio C Hamano | f2db854 | 2013-01-29 14:02:15 -0800 | [diff] [blame] | 198 | ret = !ref; |
Michael Haggerty | b285668 | 2012-09-09 08:19:48 +0200 | [diff] [blame] | 199 | |
| 200 | /* |
| 201 | * If the heads to pull were given, we should have consumed |
| 202 | * all of them by matching the remote. Otherwise, 'git fetch |
| 203 | * remote no-such-ref' would silently succeed without issuing |
| 204 | * an error. |
| 205 | */ |
Junio C Hamano | f2db854 | 2013-01-29 14:02:15 -0800 | [diff] [blame] | 206 | for (i = 0; i < nr_sought; i++) { |
| 207 | if (!sought[i] || sought[i]->matched) |
| 208 | continue; |
| 209 | error("no such remote ref %s", sought[i]->name); |
| 210 | ret = 1; |
| 211 | } |
| 212 | |
Daniel Barkalow | ba22785 | 2008-02-04 13:26:23 -0500 | [diff] [blame] | 213 | while (ref) { |
| 214 | printf("%s %s\n", |
brian m. carlson | f4e54d0 | 2015-11-10 02:22:20 +0000 | [diff] [blame] | 215 | oid_to_hex(&ref->old_oid), ref->name); |
Daniel Barkalow | ba22785 | 2008-02-04 13:26:23 -0500 | [diff] [blame] | 216 | ref = ref->next; |
| 217 | } |
Junio C Hamano | 9e5d2b4 | 2005-11-06 00:09:59 -0800 | [diff] [blame] | 218 | |
Daniel Barkalow | ba22785 | 2008-02-04 13:26:23 -0500 | [diff] [blame] | 219 | return ret; |
| 220 | } |