This is the client side of upload-narrow-base. It sends two commits, a narrow prefix, receives a pack and unpacks it. Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@xxxxxxxxx> --- Makefile | 1 + builtin.h | 1 + builtin/fetch-narrow-base.c | 89 +++++++++++++++++++++++++++++++++++++++++++ git.c | 1 + narrow-tree.h | 4 ++ 5 files changed, 96 insertions(+), 0 deletions(-) create mode 100644 builtin/fetch-narrow-base.c diff --git a/Makefile b/Makefile index 7b33a0e..a10eb00 100644 --- a/Makefile +++ b/Makefile @@ -676,6 +676,7 @@ BUILTIN_OBJS += builtin/diff-index.o BUILTIN_OBJS += builtin/diff-tree.o BUILTIN_OBJS += builtin/diff.o BUILTIN_OBJS += builtin/fast-export.o +BUILTIN_OBJS += builtin/fetch-narrow-base.o BUILTIN_OBJS += builtin/fetch-pack.o BUILTIN_OBJS += builtin/fetch.o BUILTIN_OBJS += builtin/fmt-merge-msg.o diff --git a/builtin.h b/builtin.h index 0383328..9eefa0f 100644 --- a/builtin.h +++ b/builtin.h @@ -66,6 +66,7 @@ extern int cmd_diff(int argc, const char **argv, const char *prefix); extern int cmd_diff_tree(int argc, const char **argv, const char *prefix); extern int cmd_fast_export(int argc, const char **argv, const char *prefix); extern int cmd_fetch(int argc, const char **argv, const char *prefix); +extern int cmd_fetch_narrow_base(int argc, const char **argv, const char *prefix); extern int cmd_fetch_pack(int argc, const char **argv, const char *prefix); extern int cmd_fmt_merge_msg(int argc, const char **argv, const char *prefix); extern int cmd_for_each_ref(int argc, const char **argv, const char *prefix); diff --git a/builtin/fetch-narrow-base.c b/builtin/fetch-narrow-base.c new file mode 100644 index 0000000..0162ad0 --- /dev/null +++ b/builtin/fetch-narrow-base.c @@ -0,0 +1,89 @@ +#include "cache.h" +#include "builtin.h" +#include "commit.h" +#include "pkt-line.h" +#include "transport.h" +#include "sideband.h" +#include "run-command.h" +#include "parse-options.h" + +int fetch_narrow_base(const unsigned char *c1, + const unsigned char *c2, + unsigned char *newsha1, + const char *narrow_prefix, + const char *remote, + const char *exec) +{ + char buf[LARGE_PACKET_MAX]; + int fd[2], len; + struct transport *transport; + struct remote *_remote; + const char *argv[] = { "unpack-objects", "-q", NULL }; + struct child_process cmd; + + _remote = remote_get(remote); + if (!_remote->url[0]) + die("narrow-base: Remote with no URL"); + transport = transport_get(_remote, _remote->url[0]); + if (!exec) + exec = "git-upload-narrow-base"; + transport_connect(transport, "git-upload-narrow-base", exec, fd); + + packet_write(fd[1], "narrow-tree %s\n", narrow_prefix); + packet_write(fd[1], "parent %s\n", sha1_to_hex(c1)); + packet_write(fd[1], "parent %s\n", sha1_to_hex(c2)); + packet_flush(fd[1]); + + len = packet_read_line(fd[0], buf, sizeof(buf)); + if (!len) + die("narrow-base: expected ACK/NAK, got EOF"); + if (buf[len-1] == '\n') + buf[--len] = 0; + if (prefixcmp(buf, "ACK ")) + die("narrow-base: protocol error"); + + get_sha1_hex(buf+4, newsha1); + + memset(&cmd, 0, sizeof(cmd)); + cmd.argv = argv; + cmd.in = fd[0]; + cmd.git_cmd = 1; + + if (run_command(&cmd)) + die("unable to run %s", argv[0]); + + return transport_disconnect(transport); +} + +int cmd_fetch_narrow_base(int argc, const char **argv, const char *prefix) +{ + unsigned char c1[20], c2[20], sha1[20]; + const char *remote; + const char *exec; + const char *narrow_prefix = get_narrow_prefix(); + struct option options[] = { + OPT_STRING(0, "remote", &remote, "remote", "remote host"), + OPT_STRING(0, "upload-narrow-base", &exec, "path", "path to upload-narrow-base"), + OPT_STRING(0, "narrow-tree", &narrow_prefix, "narrow prefix", "narrow prefix"), + OPT_END() + }; + const char *usage[] = { "git narrow-base [options] parent1 parent2", NULL }; + + argc = parse_options(argc, argv, prefix, options, usage, 0); + + if (argc != 2) + die("Insufficient arguments"); + + if (get_sha1(argv[0], c1) || + get_sha1(argv[1], c2) || + !lookup_commit_reference(c1) || + !lookup_commit_reference(c2)) + return 1; + + if (!fetch_narrow_base(c1, c2, sha1, narrow_prefix, remote, exec)) { + printf("%s\n", sha1_to_hex(sha1)); + return 0; + } + + return 1; +} diff --git a/git.c b/git.c index edb379f..f4370b1 100644 --- a/git.c +++ b/git.c @@ -322,6 +322,7 @@ static void handle_internal_command(int argc, const char **argv) { "diff-tree", cmd_diff_tree, RUN_SETUP }, { "fast-export", cmd_fast_export, RUN_SETUP }, { "fetch", cmd_fetch, RUN_SETUP }, + { "fetch-narrow-base", cmd_fetch_narrow_base, RUN_SETUP }, { "fetch-pack", cmd_fetch_pack, RUN_SETUP }, { "fmt-merge-msg", cmd_fmt_merge_msg, RUN_SETUP }, { "for-each-ref", cmd_for_each_ref, RUN_SETUP }, diff --git a/narrow-tree.h b/narrow-tree.h index 78d6f39..614d677 100644 --- a/narrow-tree.h +++ b/narrow-tree.h @@ -3,3 +3,7 @@ extern int join_narrow_tree(const unsigned char *base, unsigned char *newsha1, const unsigned char *subtree_sha1, const char *prefix); int same_narrow_base(const unsigned char *t1, const unsigned char *t2, const char *prefix); int oldest_narrow_base(const unsigned char *sha1, unsigned char *newsha1); +int fetch_narrow_base(const unsigned char *c1, const unsigned char *c2, + unsigned char *newsha1, + const char *narrow_prefix, + const char *remote, const char *exec); -- 1.7.1.rc1.69.g24c2f7 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html