summaryrefslogtreecommitdiff
path: root/upload-pack.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2005-07-04 23:35:13 (GMT)
committerLinus Torvalds <torvalds@g5.osdl.org>2005-07-04 23:35:13 (GMT)
commit75bfc6c232689ae06aba6a7d4aa15ac2791d9a11 (patch)
tree5cbe1763905b2fa0ec6281c8b1003149a1eb72c0 /upload-pack.c
parentfb9040cc83540fff9d05c8056433a4aa05b8a7c2 (diff)
downloadgit-75bfc6c232689ae06aba6a7d4aa15ac2791d9a11.zip
git-75bfc6c232689ae06aba6a7d4aa15ac2791d9a11.tar.gz
git-75bfc6c232689ae06aba6a7d4aa15ac2791d9a11.tar.bz2
Make git-fetch-pack actually do all the unpacking etc.
It returns the result SHA1 on stdout, so you can do remote=$(git-fetch-pack host:dir branchname) and it will unpack the objects and "remote" will be the SHA1 name of the branch on the other side. You can then save that off, or merge it, or whatever.
Diffstat (limited to 'upload-pack.c')
-rw-r--r--upload-pack.c63
1 files changed, 52 insertions, 11 deletions
diff --git a/upload-pack.c b/upload-pack.c
index b454c9e..d35c068 100644
--- a/upload-pack.c
+++ b/upload-pack.c
@@ -10,16 +10,57 @@ static int nr_has = 0, nr_needs = 0;
static unsigned char has_sha1[MAX_HAS][20];
static unsigned char needs_sha1[MAX_NEEDS][20];
+static int strip(char *line, int len)
+{
+ if (len && line[len-1] == '\n')
+ line[--len] = 0;
+ return len;
+}
+
static void create_pack_file(void)
{
- /*
- * Here, we should do
- *
- * git-rev-list --objects needs_sha1 --not has_sha1 |
- * git-pack-objects --stdout
- *
- * but we don't.
- */
+ int fd[2];
+ pid_t pid;
+
+ if (pipe(fd) < 0)
+ die("git-upload-pack: unable to create pipe");
+ pid = fork();
+ if (pid < 0)
+ die("git-upload-pack: unable to fork git-rev-list");
+
+ if (!pid) {
+ int i;
+ int args = nr_has + nr_needs + 5;
+ char **argv = xmalloc(args * sizeof(char *));
+ char *buf = xmalloc(args * 45);
+ char **p = argv;
+
+ dup2(fd[1], 1);
+ close(0);
+ close(fd[0]);
+ close(fd[1]);
+ *p++ = "git-rev-list";
+ *p++ = "--objects";
+ for (i = 0; i < nr_needs; i++) {
+ *p++ = buf;
+ memcpy(buf, sha1_to_hex(needs_sha1[i]), 41);
+ buf += 41;
+ }
+ for (i = 0; i < nr_has; i++) {
+ *p++ = buf;
+ *buf++ = '^';
+ memcpy(buf, sha1_to_hex(has_sha1[i]), 41);
+ buf += 41;
+ }
+ *p++ = NULL;
+ execvp("git-rev-list", argv);
+ die("git-upload-pack: unable to exec git-rev-list");
+ }
+ dup2(fd[0], 0);
+ close(fd[0]);
+ close(fd[1]);
+ execlp("git-pack-objects", "git-pack-objects", "--stdout", NULL);
+ die("git-upload-pack: unable to exec git-pack-objects");
}
static int got_sha1(char *hex, unsigned char *sha1)
@@ -50,8 +91,7 @@ static int get_common_commits(void)
packet_write(1, "NAK\n");
continue;
}
- if (line[len-1] == '\n')
- line[--len] = 0;
+ len = strip(line, len);
if (!strncmp(line, "have ", 5)) {
if (got_sha1(line+5, sha1)) {
packet_write(1, "ACK %s\n", sha1_to_hex(sha1));
@@ -69,7 +109,8 @@ static int get_common_commits(void)
for (;;) {
len = packet_read_line(0, line, sizeof(line));
if (!len)
- break;
+ continue;
+ len = strip(line, len);
if (!strncmp(line, "have ", 5)) {
got_sha1(line+5, sha1);
continue;