@matheusbsbs / matheus-bagliano / commits / 73b49a7592
Fork 0

remote-helpers: add support for an export command

Signed-off-by: Junio C Hamano <gitster@pobox.com>

Sverre Rabbelier committed Mar 29, 2010 at 11:48 UTC 73b49a759216bf33cc366eeac113ce00d8c49cc6
1 file changed +120 -12
transport-helper.c
+120 -12
@@ -7,6 +7,7 @@
7 #include "revision.h"
8 #include "quote.h"
9 #include "remote.h"
10 +#include "string-list.h"
11
12 static int debug;
13
@@ -17,6 +18,7 @@ struct helper_data
18 FILE *out;
19 unsigned fetch : 1,
20 import : 1,
21 + export : 1,
22 option : 1,
23 push : 1,
24 connect : 1,
@@ -163,6 +165,8 @@ static struct child_process *get_helper(struct transport *transport)
165 data->push = 1;
166 else if (!strcmp(capname, "import"))
167 data->import = 1;
168 + else if (!strcmp(capname, "export"))
169 + data->export = 1;
170 else if (!data->refspecs && !prefixcmp(capname, "refspec ")) {
171 ALLOC_GROW(refspecs,
172 refspec_nr + 1,
@@ -356,6 +360,33 @@ static int get_importer(struct transport *transport, struct child_process *fasti
360 return start_command(fastimport);
361 }
362
363 +static int get_exporter(struct transport *transport,
364 + struct child_process *fastexport,
365 + const char *export_marks,
366 + const char *import_marks,
367 + struct string_list *revlist_args)
368 +{
369 + struct child_process *helper = get_helper(transport);
370 + int argc = 0, i;
371 + memset(fastexport, 0, sizeof(*fastexport));
372 +
373 + /* we need to duplicate helper->in because we want to use it after
374 + * fastexport is done with it. */
375 + fastexport->out = dup(helper->in);
376 + fastexport->argv = xcalloc(4 + revlist_args->nr, sizeof(*fastexport->argv));
377 + fastexport->argv[argc++] = "fast-export";
378 + if (export_marks)
379 + fastexport->argv[argc++] = export_marks;
380 + if (import_marks)
381 + fastexport->argv[argc++] = import_marks;
382 +
383 + for (i = 0; i < revlist_args->nr; i++)
384 + fastexport->argv[argc++] = revlist_args->items[i].string;
385 +
386 + fastexport->git_cmd = 1;
387 + return start_command(fastexport);
388 +}
389 +
390 static int fetch_with_import(struct transport *transport,
391 int nr_heads, struct ref **to_fetch)
392 {
@@ -523,7 +554,7 @@ static int fetch(struct transport *transport,
554 return -1;
555 }
556
526 -static int push_refs(struct transport *transport,
557 +static int push_refs_with_push(struct transport *transport,
558 struct ref *remote_refs, int flags)
559 {
560 int force_all = flags & TRANSPORT_PUSH_FORCE;
@@ -533,17 +564,6 @@ static int push_refs(struct transport *transport,
564 struct child_process *helper;
565 struct ref *ref;
566
536 - if (process_connect(transport, 1)) {
537 - do_take_over(transport);
538 - return transport->push_refs(transport, remote_refs, flags);
539 - }
540 -
541 - if (!remote_refs) {
542 - fprintf(stderr, "No refs in common and none specified; doing nothing.\n"
543 - "Perhaps you should specify a branch such as 'master'.\n");
544 - return 0;
545 - }
546 -
567 helper = get_helper(transport);
568 if (!data->push)
569 return 1;
@@ -662,6 +682,94 @@ static int push_refs(struct transport *transport,
682 return 0;
683 }
684
685 +static int push_refs_with_export(struct transport *transport,
686 + struct ref *remote_refs, int flags)
687 +{
688 + struct ref *ref;
689 + struct child_process *helper, exporter;
690 + struct helper_data *data = transport->data;
691 + char *export_marks = NULL, *import_marks = NULL;
692 + struct string_list revlist_args = { NULL, 0, 0 };
693 + struct strbuf buf = STRBUF_INIT;
694 +
695 + helper = get_helper(transport);
696 +
697 + write_constant(helper->in, "export\n");
698 +
699 + recvline(data, &buf);
700 + if (debug)
701 + fprintf(stderr, "Debug: Got export_marks '%s'\n", buf.buf);
702 + if (buf.len) {
703 + struct strbuf arg = STRBUF_INIT;
704 + strbuf_addstr(&arg, "--export-marks=");
705 + strbuf_addbuf(&arg, &buf);
706 + export_marks = strbuf_detach(&arg, NULL);
707 + }
708 +
709 + recvline(data, &buf);
710 + if (debug)
711 + fprintf(stderr, "Debug: Got import_marks '%s'\n", buf.buf);
712 + if (buf.len) {
713 + struct strbuf arg = STRBUF_INIT;
714 + strbuf_addstr(&arg, "--import-marks=");
715 + strbuf_addbuf(&arg, &buf);
716 + import_marks = strbuf_detach(&arg, NULL);
717 + }
718 +
719 + strbuf_reset(&buf);
720 +
721 + for (ref = remote_refs; ref; ref = ref->next) {
722 + char *private;
723 + unsigned char sha1[20];
724 +
725 + if (!data->refspecs)
726 + continue;
727 + private = apply_refspecs(data->refspecs, data->refspec_nr, ref->name);
728 + if (private && !get_sha1(private, sha1)) {
729 + strbuf_addf(&buf, "^%s", private);
730 + string_list_append(strbuf_detach(&buf, NULL), &revlist_args);
731 + }
732 +
733 + string_list_append(ref->name, &revlist_args);
734 +
735 + }
736 +
737 + if (get_exporter(transport, &exporter,
738 + export_marks, import_marks, &revlist_args))
739 + die("Couldn't run fast-export");
740 +
741 + data->no_disconnect_req = 1;
742 + finish_command(&exporter);
743 + disconnect_helper(transport);
744 + return 0;
745 +}
746 +
747 +static int push_refs(struct transport *transport,
748 + struct ref *remote_refs, int flags)
749 +{
750 + struct helper_data *data = transport->data;
751 +
752 + if (process_connect(transport, 1)) {
753 + do_take_over(transport);
754 + return transport->push_refs(transport, remote_refs, flags);
755 + }
756 +
757 + if (!remote_refs) {
758 + fprintf(stderr, "No refs in common and none specified; doing nothing.\n"
759 + "Perhaps you should specify a branch such as 'master'.\n");
760 + return 0;
761 + }
762 +
763 + if (data->push)
764 + return push_refs_with_push(transport, remote_refs, flags);
765 +
766 + if (data->export)
767 + return push_refs_with_export(transport, remote_refs, flags);
768 +
769 + return -1;
770 +}
771 +
772 +
773 static int has_attribute(const char *attrs, const char *attr) {
774 int len;
775 if (!attrs)