THIS IS A TEST INSTANCE ONLY! REPOSITORIES CAN BE DELETED AT ANY TIME!

Git Source Code Mirror - This is a publish-only repository and all pull requests are ignored. Please follow Documentation/SubmittingPatches procedure for any of your improvements.
git
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

507 lines
13KB

  1. #include "cache.h"
  2. #include "lockfile.h"
  3. #include "bundle.h"
  4. #include "object-store.h"
  5. #include "repository.h"
  6. #include "object.h"
  7. #include "commit.h"
  8. #include "diff.h"
  9. #include "revision.h"
  10. #include "list-objects.h"
  11. #include "run-command.h"
  12. #include "refs.h"
  13. #include "argv-array.h"
  14. static const char bundle_signature[] = "# v2 git bundle\n";
  15. static void add_to_ref_list(const struct object_id *oid, const char *name,
  16. struct ref_list *list)
  17. {
  18. ALLOC_GROW(list->list, list->nr + 1, list->alloc);
  19. oidcpy(&list->list[list->nr].oid, oid);
  20. list->list[list->nr].name = xstrdup(name);
  21. list->nr++;
  22. }
  23. static int parse_bundle_header(int fd, struct bundle_header *header,
  24. const char *report_path)
  25. {
  26. struct strbuf buf = STRBUF_INIT;
  27. int status = 0;
  28. /* The bundle header begins with the signature */
  29. if (strbuf_getwholeline_fd(&buf, fd, '\n') ||
  30. strcmp(buf.buf, bundle_signature)) {
  31. if (report_path)
  32. error(_("'%s' does not look like a v2 bundle file"),
  33. report_path);
  34. status = -1;
  35. goto abort;
  36. }
  37. /* The bundle header ends with an empty line */
  38. while (!strbuf_getwholeline_fd(&buf, fd, '\n') &&
  39. buf.len && buf.buf[0] != '\n') {
  40. struct object_id oid;
  41. int is_prereq = 0;
  42. const char *p;
  43. if (*buf.buf == '-') {
  44. is_prereq = 1;
  45. strbuf_remove(&buf, 0, 1);
  46. }
  47. strbuf_rtrim(&buf);
  48. /*
  49. * Tip lines have object name, SP, and refname.
  50. * Prerequisites have object name that is optionally
  51. * followed by SP and subject line.
  52. */
  53. if (parse_oid_hex(buf.buf, &oid, &p) ||
  54. (*p && !isspace(*p)) ||
  55. (!is_prereq && !*p)) {
  56. if (report_path)
  57. error(_("unrecognized header: %s%s (%d)"),
  58. (is_prereq ? "-" : ""), buf.buf, (int)buf.len);
  59. status = -1;
  60. break;
  61. } else {
  62. if (is_prereq)
  63. add_to_ref_list(&oid, "", &header->prerequisites);
  64. else
  65. add_to_ref_list(&oid, p + 1, &header->references);
  66. }
  67. }
  68. abort:
  69. if (status) {
  70. close(fd);
  71. fd = -1;
  72. }
  73. strbuf_release(&buf);
  74. return fd;
  75. }
  76. int read_bundle_header(const char *path, struct bundle_header *header)
  77. {
  78. int fd = open(path, O_RDONLY);
  79. if (fd < 0)
  80. return error(_("could not open '%s'"), path);
  81. return parse_bundle_header(fd, header, path);
  82. }
  83. int is_bundle(const char *path, int quiet)
  84. {
  85. struct bundle_header header;
  86. int fd = open(path, O_RDONLY);
  87. if (fd < 0)
  88. return 0;
  89. memset(&header, 0, sizeof(header));
  90. fd = parse_bundle_header(fd, &header, quiet ? NULL : path);
  91. if (fd >= 0)
  92. close(fd);
  93. return (fd >= 0);
  94. }
  95. static int list_refs(struct ref_list *r, int argc, const char **argv)
  96. {
  97. int i;
  98. for (i = 0; i < r->nr; i++) {
  99. if (argc > 1) {
  100. int j;
  101. for (j = 1; j < argc; j++)
  102. if (!strcmp(r->list[i].name, argv[j]))
  103. break;
  104. if (j == argc)
  105. continue;
  106. }
  107. printf("%s %s\n", oid_to_hex(&r->list[i].oid),
  108. r->list[i].name);
  109. }
  110. return 0;
  111. }
  112. /* Remember to update object flag allocation in object.h */
  113. #define PREREQ_MARK (1u<<16)
  114. int verify_bundle(struct repository *r,
  115. struct bundle_header *header,
  116. int verbose)
  117. {
  118. /*
  119. * Do fast check, then if any prereqs are missing then go line by line
  120. * to be verbose about the errors
  121. */
  122. struct ref_list *p = &header->prerequisites;
  123. struct rev_info revs;
  124. const char *argv[] = {NULL, "--all", NULL};
  125. struct commit *commit;
  126. int i, ret = 0, req_nr;
  127. const char *message = _("Repository lacks these prerequisite commits:");
  128. if (!r || !r->objects || !r->objects->odb)
  129. return error(_("need a repository to verify a bundle"));
  130. repo_init_revisions(r, &revs, NULL);
  131. for (i = 0; i < p->nr; i++) {
  132. struct ref_list_entry *e = p->list + i;
  133. struct object *o = parse_object(r, &e->oid);
  134. if (o) {
  135. o->flags |= PREREQ_MARK;
  136. add_pending_object(&revs, o, e->name);
  137. continue;
  138. }
  139. if (++ret == 1)
  140. error("%s", message);
  141. error("%s %s", oid_to_hex(&e->oid), e->name);
  142. }
  143. if (revs.pending.nr != p->nr)
  144. return ret;
  145. req_nr = revs.pending.nr;
  146. setup_revisions(2, argv, &revs, NULL);
  147. if (prepare_revision_walk(&revs))
  148. die(_("revision walk setup failed"));
  149. i = req_nr;
  150. while (i && (commit = get_revision(&revs)))
  151. if (commit->object.flags & PREREQ_MARK)
  152. i--;
  153. for (i = 0; i < p->nr; i++) {
  154. struct ref_list_entry *e = p->list + i;
  155. struct object *o = parse_object(r, &e->oid);
  156. assert(o); /* otherwise we'd have returned early */
  157. if (o->flags & SHOWN)
  158. continue;
  159. if (++ret == 1)
  160. error("%s", message);
  161. error("%s %s", oid_to_hex(&e->oid), e->name);
  162. }
  163. /* Clean up objects used, as they will be reused. */
  164. for (i = 0; i < p->nr; i++) {
  165. struct ref_list_entry *e = p->list + i;
  166. commit = lookup_commit_reference_gently(r, &e->oid, 1);
  167. if (commit)
  168. clear_commit_marks(commit, ALL_REV_FLAGS);
  169. }
  170. if (verbose) {
  171. struct ref_list *r;
  172. r = &header->references;
  173. printf_ln(Q_("The bundle contains this ref:",
  174. "The bundle contains these %d refs:",
  175. r->nr),
  176. r->nr);
  177. list_refs(r, 0, NULL);
  178. r = &header->prerequisites;
  179. if (!r->nr) {
  180. printf_ln(_("The bundle records a complete history."));
  181. } else {
  182. printf_ln(Q_("The bundle requires this ref:",
  183. "The bundle requires these %d refs:",
  184. r->nr),
  185. r->nr);
  186. list_refs(r, 0, NULL);
  187. }
  188. }
  189. return ret;
  190. }
  191. int list_bundle_refs(struct bundle_header *header, int argc, const char **argv)
  192. {
  193. return list_refs(&header->references, argc, argv);
  194. }
  195. static int is_tag_in_date_range(struct object *tag, struct rev_info *revs)
  196. {
  197. unsigned long size;
  198. enum object_type type;
  199. char *buf = NULL, *line, *lineend;
  200. timestamp_t date;
  201. int result = 1;
  202. if (revs->max_age == -1 && revs->min_age == -1)
  203. goto out;
  204. buf = read_object_file(&tag->oid, &type, &size);
  205. if (!buf)
  206. goto out;
  207. line = memmem(buf, size, "\ntagger ", 8);
  208. if (!line++)
  209. goto out;
  210. lineend = memchr(line, '\n', buf + size - line);
  211. line = memchr(line, '>', lineend ? lineend - line : buf + size - line);
  212. if (!line++)
  213. goto out;
  214. date = parse_timestamp(line, NULL, 10);
  215. result = (revs->max_age == -1 || revs->max_age < date) &&
  216. (revs->min_age == -1 || revs->min_age > date);
  217. out:
  218. free(buf);
  219. return result;
  220. }
  221. /* Write the pack data to bundle_fd */
  222. static int write_pack_data(int bundle_fd, struct rev_info *revs, struct argv_array *pack_options)
  223. {
  224. struct child_process pack_objects = CHILD_PROCESS_INIT;
  225. int i;
  226. argv_array_pushl(&pack_objects.args,
  227. "pack-objects",
  228. "--stdout", "--thin", "--delta-base-offset",
  229. NULL);
  230. argv_array_pushv(&pack_objects.args, pack_options->argv);
  231. pack_objects.in = -1;
  232. pack_objects.out = bundle_fd;
  233. pack_objects.git_cmd = 1;
  234. /*
  235. * start_command() will close our descriptor if it's >1. Duplicate it
  236. * to avoid surprising the caller.
  237. */
  238. if (pack_objects.out > 1) {
  239. pack_objects.out = dup(pack_objects.out);
  240. if (pack_objects.out < 0) {
  241. error_errno(_("unable to dup bundle descriptor"));
  242. child_process_clear(&pack_objects);
  243. return -1;
  244. }
  245. }
  246. if (start_command(&pack_objects))
  247. return error(_("Could not spawn pack-objects"));
  248. for (i = 0; i < revs->pending.nr; i++) {
  249. struct object *object = revs->pending.objects[i].item;
  250. if (object->flags & UNINTERESTING)
  251. write_or_die(pack_objects.in, "^", 1);
  252. write_or_die(pack_objects.in, oid_to_hex(&object->oid), the_hash_algo->hexsz);
  253. write_or_die(pack_objects.in, "\n", 1);
  254. }
  255. close(pack_objects.in);
  256. if (finish_command(&pack_objects))
  257. return error(_("pack-objects died"));
  258. return 0;
  259. }
  260. static int compute_and_write_prerequisites(int bundle_fd,
  261. struct rev_info *revs,
  262. int argc, const char **argv)
  263. {
  264. struct child_process rls = CHILD_PROCESS_INIT;
  265. struct strbuf buf = STRBUF_INIT;
  266. FILE *rls_fout;
  267. int i;
  268. argv_array_pushl(&rls.args,
  269. "rev-list", "--boundary", "--pretty=oneline",
  270. NULL);
  271. for (i = 1; i < argc; i++)
  272. argv_array_push(&rls.args, argv[i]);
  273. rls.out = -1;
  274. rls.git_cmd = 1;
  275. if (start_command(&rls))
  276. return -1;
  277. rls_fout = xfdopen(rls.out, "r");
  278. while (strbuf_getwholeline(&buf, rls_fout, '\n') != EOF) {
  279. struct object_id oid;
  280. if (buf.len > 0 && buf.buf[0] == '-') {
  281. write_or_die(bundle_fd, buf.buf, buf.len);
  282. if (!get_oid_hex(buf.buf + 1, &oid)) {
  283. struct object *object = parse_object_or_die(&oid,
  284. buf.buf);
  285. object->flags |= UNINTERESTING;
  286. add_pending_object(revs, object, buf.buf);
  287. }
  288. } else if (!get_oid_hex(buf.buf, &oid)) {
  289. struct object *object = parse_object_or_die(&oid,
  290. buf.buf);
  291. object->flags |= SHOWN;
  292. }
  293. }
  294. strbuf_release(&buf);
  295. fclose(rls_fout);
  296. if (finish_command(&rls))
  297. return error(_("rev-list died"));
  298. return 0;
  299. }
  300. /*
  301. * Write out bundle refs based on the tips already
  302. * parsed into revs.pending. As a side effect, may
  303. * manipulate revs.pending to include additional
  304. * necessary objects (like tags).
  305. *
  306. * Returns the number of refs written, or negative
  307. * on error.
  308. */
  309. static int write_bundle_refs(int bundle_fd, struct rev_info *revs)
  310. {
  311. int i;
  312. int ref_count = 0;
  313. for (i = 0; i < revs->pending.nr; i++) {
  314. struct object_array_entry *e = revs->pending.objects + i;
  315. struct object_id oid;
  316. char *ref;
  317. const char *display_ref;
  318. int flag;
  319. if (e->item->flags & UNINTERESTING)
  320. continue;
  321. if (dwim_ref(e->name, strlen(e->name), &oid, &ref) != 1)
  322. goto skip_write_ref;
  323. if (read_ref_full(e->name, RESOLVE_REF_READING, &oid, &flag))
  324. flag = 0;
  325. display_ref = (flag & REF_ISSYMREF) ? e->name : ref;
  326. if (e->item->type == OBJ_TAG &&
  327. !is_tag_in_date_range(e->item, revs)) {
  328. e->item->flags |= UNINTERESTING;
  329. goto skip_write_ref;
  330. }
  331. /*
  332. * Make sure the refs we wrote out is correct; --max-count and
  333. * other limiting options could have prevented all the tips
  334. * from getting output.
  335. *
  336. * Non commit objects such as tags and blobs do not have
  337. * this issue as they are not affected by those extra
  338. * constraints.
  339. */
  340. if (!(e->item->flags & SHOWN) && e->item->type == OBJ_COMMIT) {
  341. warning(_("ref '%s' is excluded by the rev-list options"),
  342. e->name);
  343. goto skip_write_ref;
  344. }
  345. /*
  346. * If you run "git bundle create bndl v1.0..v2.0", the
  347. * name of the positive ref is "v2.0" but that is the
  348. * commit that is referenced by the tag, and not the tag
  349. * itself.
  350. */
  351. if (!oideq(&oid, &e->item->oid)) {
  352. /*
  353. * Is this the positive end of a range expressed
  354. * in terms of a tag (e.g. v2.0 from the range
  355. * "v1.0..v2.0")?
  356. */
  357. struct commit *one = lookup_commit_reference(revs->repo, &oid);
  358. struct object *obj;
  359. if (e->item == &(one->object)) {
  360. /*
  361. * Need to include e->name as an
  362. * independent ref to the pack-objects
  363. * input, so that the tag is included
  364. * in the output; otherwise we would
  365. * end up triggering "empty bundle"
  366. * error.
  367. */
  368. obj = parse_object_or_die(&oid, e->name);
  369. obj->flags |= SHOWN;
  370. add_pending_object(revs, obj, e->name);
  371. }
  372. goto skip_write_ref;
  373. }
  374. ref_count++;
  375. write_or_die(bundle_fd, oid_to_hex(&e->item->oid), the_hash_algo->hexsz);
  376. write_or_die(bundle_fd, " ", 1);
  377. write_or_die(bundle_fd, display_ref, strlen(display_ref));
  378. write_or_die(bundle_fd, "\n", 1);
  379. skip_write_ref:
  380. free(ref);
  381. }
  382. /* end header */
  383. write_or_die(bundle_fd, "\n", 1);
  384. return ref_count;
  385. }
  386. int create_bundle(struct repository *r, const char *path,
  387. int argc, const char **argv, struct argv_array *pack_options)
  388. {
  389. struct lock_file lock = LOCK_INIT;
  390. int bundle_fd = -1;
  391. int bundle_to_stdout;
  392. int ref_count = 0;
  393. struct rev_info revs;
  394. bundle_to_stdout = !strcmp(path, "-");
  395. if (bundle_to_stdout)
  396. bundle_fd = 1;
  397. else
  398. bundle_fd = hold_lock_file_for_update(&lock, path,
  399. LOCK_DIE_ON_ERROR);
  400. /* write signature */
  401. write_or_die(bundle_fd, bundle_signature, strlen(bundle_signature));
  402. /* init revs to list objects for pack-objects later */
  403. save_commit_buffer = 0;
  404. repo_init_revisions(r, &revs, NULL);
  405. /* write prerequisites */
  406. if (compute_and_write_prerequisites(bundle_fd, &revs, argc, argv))
  407. goto err;
  408. argc = setup_revisions(argc, argv, &revs, NULL);
  409. if (argc > 1) {
  410. error(_("unrecognized argument: %s"), argv[1]);
  411. goto err;
  412. }
  413. object_array_remove_duplicates(&revs.pending);
  414. ref_count = write_bundle_refs(bundle_fd, &revs);
  415. if (!ref_count)
  416. die(_("Refusing to create empty bundle."));
  417. else if (ref_count < 0)
  418. goto err;
  419. /* write pack */
  420. if (write_pack_data(bundle_fd, &revs, pack_options))
  421. goto err;
  422. if (!bundle_to_stdout) {
  423. if (commit_lock_file(&lock))
  424. die_errno(_("cannot create '%s'"), path);
  425. }
  426. return 0;
  427. err:
  428. rollback_lock_file(&lock);
  429. return -1;
  430. }
  431. int unbundle(struct repository *r, struct bundle_header *header,
  432. int bundle_fd, int flags)
  433. {
  434. const char *argv_index_pack[] = {"index-pack",
  435. "--fix-thin", "--stdin", NULL, NULL};
  436. struct child_process ip = CHILD_PROCESS_INIT;
  437. if (flags & BUNDLE_VERBOSE)
  438. argv_index_pack[3] = "-v";
  439. if (verify_bundle(r, header, 0))
  440. return -1;
  441. ip.argv = argv_index_pack;
  442. ip.in = bundle_fd;
  443. ip.no_stdout = 1;
  444. ip.git_cmd = 1;
  445. if (run_command(&ip))
  446. return error(_("index-pack died"));
  447. return 0;
  448. }