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.

506 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)
  223. {
  224. struct child_process pack_objects = CHILD_PROCESS_INIT;
  225. int i;
  226. argv_array_pushl(&pack_objects.args,
  227. "pack-objects", "--all-progress-implied",
  228. "--stdout", "--thin", "--delta-base-offset",
  229. NULL);
  230. pack_objects.in = -1;
  231. pack_objects.out = bundle_fd;
  232. pack_objects.git_cmd = 1;
  233. /*
  234. * start_command() will close our descriptor if it's >1. Duplicate it
  235. * to avoid surprising the caller.
  236. */
  237. if (pack_objects.out > 1) {
  238. pack_objects.out = dup(pack_objects.out);
  239. if (pack_objects.out < 0) {
  240. error_errno(_("unable to dup bundle descriptor"));
  241. child_process_clear(&pack_objects);
  242. return -1;
  243. }
  244. }
  245. if (start_command(&pack_objects))
  246. return error(_("Could not spawn pack-objects"));
  247. for (i = 0; i < revs->pending.nr; i++) {
  248. struct object *object = revs->pending.objects[i].item;
  249. if (object->flags & UNINTERESTING)
  250. write_or_die(pack_objects.in, "^", 1);
  251. write_or_die(pack_objects.in, oid_to_hex(&object->oid), the_hash_algo->hexsz);
  252. write_or_die(pack_objects.in, "\n", 1);
  253. }
  254. close(pack_objects.in);
  255. if (finish_command(&pack_objects))
  256. return error(_("pack-objects died"));
  257. return 0;
  258. }
  259. static int compute_and_write_prerequisites(int bundle_fd,
  260. struct rev_info *revs,
  261. int argc, const char **argv)
  262. {
  263. struct child_process rls = CHILD_PROCESS_INIT;
  264. struct strbuf buf = STRBUF_INIT;
  265. FILE *rls_fout;
  266. int i;
  267. argv_array_pushl(&rls.args,
  268. "rev-list", "--boundary", "--pretty=oneline",
  269. NULL);
  270. for (i = 1; i < argc; i++)
  271. argv_array_push(&rls.args, argv[i]);
  272. rls.out = -1;
  273. rls.git_cmd = 1;
  274. if (start_command(&rls))
  275. return -1;
  276. rls_fout = xfdopen(rls.out, "r");
  277. while (strbuf_getwholeline(&buf, rls_fout, '\n') != EOF) {
  278. struct object_id oid;
  279. if (buf.len > 0 && buf.buf[0] == '-') {
  280. write_or_die(bundle_fd, buf.buf, buf.len);
  281. if (!get_oid_hex(buf.buf + 1, &oid)) {
  282. struct object *object = parse_object_or_die(&oid,
  283. buf.buf);
  284. object->flags |= UNINTERESTING;
  285. add_pending_object(revs, object, buf.buf);
  286. }
  287. } else if (!get_oid_hex(buf.buf, &oid)) {
  288. struct object *object = parse_object_or_die(&oid,
  289. buf.buf);
  290. object->flags |= SHOWN;
  291. }
  292. }
  293. strbuf_release(&buf);
  294. fclose(rls_fout);
  295. if (finish_command(&rls))
  296. return error(_("rev-list died"));
  297. return 0;
  298. }
  299. /*
  300. * Write out bundle refs based on the tips already
  301. * parsed into revs.pending. As a side effect, may
  302. * manipulate revs.pending to include additional
  303. * necessary objects (like tags).
  304. *
  305. * Returns the number of refs written, or negative
  306. * on error.
  307. */
  308. static int write_bundle_refs(int bundle_fd, struct rev_info *revs)
  309. {
  310. int i;
  311. int ref_count = 0;
  312. for (i = 0; i < revs->pending.nr; i++) {
  313. struct object_array_entry *e = revs->pending.objects + i;
  314. struct object_id oid;
  315. char *ref;
  316. const char *display_ref;
  317. int flag;
  318. if (e->item->flags & UNINTERESTING)
  319. continue;
  320. if (dwim_ref(e->name, strlen(e->name), &oid, &ref) != 1)
  321. goto skip_write_ref;
  322. if (read_ref_full(e->name, RESOLVE_REF_READING, &oid, &flag))
  323. flag = 0;
  324. display_ref = (flag & REF_ISSYMREF) ? e->name : ref;
  325. if (e->item->type == OBJ_TAG &&
  326. !is_tag_in_date_range(e->item, revs)) {
  327. e->item->flags |= UNINTERESTING;
  328. goto skip_write_ref;
  329. }
  330. /*
  331. * Make sure the refs we wrote out is correct; --max-count and
  332. * other limiting options could have prevented all the tips
  333. * from getting output.
  334. *
  335. * Non commit objects such as tags and blobs do not have
  336. * this issue as they are not affected by those extra
  337. * constraints.
  338. */
  339. if (!(e->item->flags & SHOWN) && e->item->type == OBJ_COMMIT) {
  340. warning(_("ref '%s' is excluded by the rev-list options"),
  341. e->name);
  342. goto skip_write_ref;
  343. }
  344. /*
  345. * If you run "git bundle create bndl v1.0..v2.0", the
  346. * name of the positive ref is "v2.0" but that is the
  347. * commit that is referenced by the tag, and not the tag
  348. * itself.
  349. */
  350. if (!oideq(&oid, &e->item->oid)) {
  351. /*
  352. * Is this the positive end of a range expressed
  353. * in terms of a tag (e.g. v2.0 from the range
  354. * "v1.0..v2.0")?
  355. */
  356. struct commit *one = lookup_commit_reference(revs->repo, &oid);
  357. struct object *obj;
  358. if (e->item == &(one->object)) {
  359. /*
  360. * Need to include e->name as an
  361. * independent ref to the pack-objects
  362. * input, so that the tag is included
  363. * in the output; otherwise we would
  364. * end up triggering "empty bundle"
  365. * error.
  366. */
  367. obj = parse_object_or_die(&oid, e->name);
  368. obj->flags |= SHOWN;
  369. add_pending_object(revs, obj, e->name);
  370. }
  371. goto skip_write_ref;
  372. }
  373. ref_count++;
  374. write_or_die(bundle_fd, oid_to_hex(&e->item->oid), the_hash_algo->hexsz);
  375. write_or_die(bundle_fd, " ", 1);
  376. write_or_die(bundle_fd, display_ref, strlen(display_ref));
  377. write_or_die(bundle_fd, "\n", 1);
  378. skip_write_ref:
  379. free(ref);
  380. }
  381. /* end header */
  382. write_or_die(bundle_fd, "\n", 1);
  383. return ref_count;
  384. }
  385. int create_bundle(struct repository *r, const char *path,
  386. int argc, const char **argv)
  387. {
  388. struct lock_file lock = LOCK_INIT;
  389. int bundle_fd = -1;
  390. int bundle_to_stdout;
  391. int ref_count = 0;
  392. struct rev_info revs;
  393. bundle_to_stdout = !strcmp(path, "-");
  394. if (bundle_to_stdout)
  395. bundle_fd = 1;
  396. else
  397. bundle_fd = hold_lock_file_for_update(&lock, path,
  398. LOCK_DIE_ON_ERROR);
  399. /* write signature */
  400. write_or_die(bundle_fd, bundle_signature, strlen(bundle_signature));
  401. /* init revs to list objects for pack-objects later */
  402. save_commit_buffer = 0;
  403. repo_init_revisions(r, &revs, NULL);
  404. /* write prerequisites */
  405. if (compute_and_write_prerequisites(bundle_fd, &revs, argc, argv))
  406. goto err;
  407. argc = setup_revisions(argc, argv, &revs, NULL);
  408. if (argc > 1) {
  409. error(_("unrecognized argument: %s"), argv[1]);
  410. goto err;
  411. }
  412. object_array_remove_duplicates(&revs.pending);
  413. ref_count = write_bundle_refs(bundle_fd, &revs);
  414. if (!ref_count)
  415. die(_("Refusing to create empty bundle."));
  416. else if (ref_count < 0)
  417. goto err;
  418. /* write pack */
  419. if (write_pack_data(bundle_fd, &revs))
  420. goto err;
  421. if (!bundle_to_stdout) {
  422. if (commit_lock_file(&lock))
  423. die_errno(_("cannot create '%s'"), path);
  424. }
  425. return 0;
  426. err:
  427. rollback_lock_file(&lock);
  428. return -1;
  429. }
  430. int unbundle(struct repository *r, struct bundle_header *header,
  431. int bundle_fd, int flags)
  432. {
  433. const char *argv_index_pack[] = {"index-pack",
  434. "--fix-thin", "--stdin", NULL, NULL};
  435. struct child_process ip = CHILD_PROCESS_INIT;
  436. if (flags & BUNDLE_VERBOSE)
  437. argv_index_pack[3] = "-v";
  438. if (verify_bundle(r, header, 0))
  439. return -1;
  440. ip.argv = argv_index_pack;
  441. ip.in = bundle_fd;
  442. ip.no_stdout = 1;
  443. ip.git_cmd = 1;
  444. if (run_command(&ip))
  445. return error(_("index-pack died"));
  446. return 0;
  447. }