* How to clone-pack the HEAD?
@ 2005-12-15 0:44 Petr Baudis
2005-12-15 1:20 ` Junio C Hamano
0 siblings, 1 reply; 10+ messages in thread
From: Petr Baudis @ 2005-12-15 0:44 UTC (permalink / raw)
To: junkio; +Cc: git
Hello,
I'd like to make cg-clone use git-clone-pack instead of git-fetch-pack
so that it gets actually usable on large repositories, but I'm hitting
problems:
(i) git-clone-pack url HEAD doesn't work
If .git/HEAD already exists, it will panick because of the
write_one_ref()'s O_CREAT|O_EXCL. If .git/HEAD doesn't exist,
git-clone-pack refuses to do anything since it doesn't run
with valid GIT repository.
(ii) git-clone-pack has hardcoded assumptions about refs/heads/master
The problem is, git-clone-pack doesn't seem to care about what
ref does HEAD point to at the remote side, it just starts to
panic and do weird things if it isn't master, which seems
"really really wrong". Also, because git-clone-pack ... HEAD
doesn't work, I think I have no way to clone the actual HEAD
ref of the remote repository.
Overally, I think what I really need is git-fetch-pack (with it
outputting the ref info which I can write on my own, DTRT'ing from
the Cogito POV), just with the option not to unpack the pack.
I'd be very happy if fixing this would be possible before 1.0 so that
I can fix Cogito's fetching over git and ssh ASAP - git-clone-pack's
architecture seems to be way too much hardcoded to carry over head names
to the cloned repository (which is fine for the GIT porcelainish, but
not for Cogito philosophy).
PS: Sorry if this mail is a bit incoherent - I'm already falling
asleep over the keyboard, but I don't want to see GIT 1.0 fly by during
the night. ;-) BTW, Junio, do you have any timeline (more precise than
"in the coming week(s)") for the release, or are you just waiting for
"n days without big problem" or something like that?
Thanks,
--
Petr "Pasky" Baudis
Stuff: http://pasky.or.cz/
VI has two modes: the one in which it beeps and the one in which
it doesn't.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: How to clone-pack the HEAD?
2005-12-15 0:44 How to clone-pack the HEAD? Petr Baudis
@ 2005-12-15 1:20 ` Junio C Hamano
2005-12-15 1:32 ` Petr Baudis
0 siblings, 1 reply; 10+ messages in thread
From: Junio C Hamano @ 2005-12-15 1:20 UTC (permalink / raw)
To: Petr Baudis; +Cc: git
Petr Baudis <pasky@ucw.cz> writes:
> (i) git-clone-pack url HEAD doesn't work
"clone-pack url branchname" might work, but the thing is, nobody
uses clone-pack with explicit heads arguments so if HEAD does
not work I am not surprised at all.
> (ii) git-clone-pack has hardcoded assumptions about refs/heads/master
I've read that part of the code twice in the past, but my
recollection is it tries hard to "guess" where HEAD points at
(because the remote side does not tell us, other than which
commit object HEAD points at). When more than two branch heads
point at the same commit as HEAD records, it gives preference to
"master" branch while guessing, but otherwise there is nothing
special about the "master" branch.
The problem is, clone-pack is about cloning and not fetching. I
am not claiming it is the right design decision --- after all,
it was the oldest of the git native protocol driver suite ---
but just stating where it stands with all the history behind its
(and git-fetch-pack's) evolution.
I think extending git-fetch-pack to optionally keep things
packed would be somewhat painful but the right approach. Less
painful and readily doable would be to run clone-pack as is, and
reorganize the result of "copy of the remote" yourself. That
would be a straightforward thing to do if you are using it for
the initial cloning.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: How to clone-pack the HEAD?
2005-12-15 1:20 ` Junio C Hamano
@ 2005-12-15 1:32 ` Petr Baudis
2005-12-15 1:45 ` Junio C Hamano
0 siblings, 1 reply; 10+ messages in thread
From: Petr Baudis @ 2005-12-15 1:32 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
Dear diary, on Thu, Dec 15, 2005 at 02:20:28AM CET, I got a letter
where Junio C Hamano <junkio@cox.net> said that...
> Petr Baudis <pasky@ucw.cz> writes:
>
> > (i) git-clone-pack url HEAD doesn't work
>
> "clone-pack url branchname" might work, but the thing is, nobody
> uses clone-pack with explicit heads arguments so if HEAD does
> not work I am not surprised at all.
..snip..
> I think extending git-fetch-pack to optionally keep things
> packed would be somewhat painful but the right approach. Less
> painful and readily doable would be to run clone-pack as is, and
> reorganize the result of "copy of the remote" yourself. That
> would be a straightforward thing to do if you are using it for
> the initial cloning.
Except that I cannot do the guessing git-clone-pack does (without
fetching all the branches) - so I guess I'll make a patch tomorrow which
fixes git-clone-pack ... HEAD (probably by checking in write_one_ref()
whether it is looking at a symlink and following it first if that's the
case) and then in Cogito do
git-symbolic-ref HEAD refs/heads/origin
before git-clone-pack (and repoint HEAD back after it's over). That
should do exactly what I need it to, I think.
--
Petr "Pasky" Baudis
Stuff: http://pasky.or.cz/
VI has two modes: the one in which it beeps and the one in which
it doesn't.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: How to clone-pack the HEAD?
2005-12-15 1:32 ` Petr Baudis
@ 2005-12-15 1:45 ` Junio C Hamano
2005-12-15 1:53 ` Junio C Hamano
2005-12-15 1:59 ` Petr Baudis
0 siblings, 2 replies; 10+ messages in thread
From: Junio C Hamano @ 2005-12-15 1:45 UTC (permalink / raw)
To: Petr Baudis; +Cc: git
Petr Baudis <pasky@suse.cz> writes:
> Except that I cannot do the guessing git-clone-pack does (without
> fetching all the branches)
Exactly my point. If you are not getting all the branches, you
are not cloning but doing something else.
Extending git-fetch-pack would be the right approach if that is
what you are trying to do.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: How to clone-pack the HEAD?
2005-12-15 1:45 ` Junio C Hamano
@ 2005-12-15 1:53 ` Junio C Hamano
2005-12-15 5:29 ` Junio C Hamano
2005-12-15 1:59 ` Petr Baudis
1 sibling, 1 reply; 10+ messages in thread
From: Junio C Hamano @ 2005-12-15 1:53 UTC (permalink / raw)
To: git
Junio C Hamano <junkio@cox.net> writes:
> Petr Baudis <pasky@suse.cz> writes:
>
>> Except that I cannot do the guessing git-clone-pack does (without
>> fetching all the branches)
>
> Exactly my point. If you are not getting all the branches, you
> are not cloning but doing something else.
Not really. I take this back. What you want to do I did not
understand well enough.
HEAD is kinda special. A hack I can think of is to do ls-remote
first and do the guess clone-pack does for full clone case, and
then give a specific branch name to clone. That might work.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: How to clone-pack the HEAD?
2005-12-15 1:45 ` Junio C Hamano
2005-12-15 1:53 ` Junio C Hamano
@ 2005-12-15 1:59 ` Petr Baudis
1 sibling, 0 replies; 10+ messages in thread
From: Petr Baudis @ 2005-12-15 1:59 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
Dear diary, on Thu, Dec 15, 2005 at 02:45:32AM CET, I got a letter
where Junio C Hamano <junkio@cox.net> said that...
> Petr Baudis <pasky@suse.cz> writes:
>
> > Except that I cannot do the guessing git-clone-pack does (without
> > fetching all the branches)
>
> Exactly my point. If you are not getting all the branches, you
> are not cloning but doing something else.
Ah, play with the words. Sure I'm cloning - however I'm not cloning
a repository but a branch. In Cogito world, that's the only thing that
makes sense to clone, in GIT world it's more complicated (you don't
always clone the whole repository there either, since git-clone-pack
lets you narrow down the refs).
> Extending git-fetch-pack would be the right approach if that is
> what you are trying to do.
I'll then try to extend git-fetch-pack instead. I'll send some fix for
git-clone-pack anyway, though. ;-)
--
Petr "Pasky" Baudis
Stuff: http://pasky.or.cz/
VI has two modes: the one in which it beeps and the one in which
it doesn't.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: How to clone-pack the HEAD?
2005-12-15 1:53 ` Junio C Hamano
@ 2005-12-15 5:29 ` Junio C Hamano
2005-12-15 6:21 ` Junio C Hamano
2005-12-18 0:38 ` Petr Baudis
0 siblings, 2 replies; 10+ messages in thread
From: Junio C Hamano @ 2005-12-15 5:29 UTC (permalink / raw)
To: Petr Baudis; +Cc: git
Junio C Hamano <junkio@cox.net> writes:
> Not really. I take this back. What you want to do I did not
> understand well enough.
>
> HEAD is kinda special. A hack I can think of is to do ls-remote
> first and do the guess clone-pack does for full clone case, and
> then give a specific branch name to clone. That might work.
... and another way would be to do this; I'll put this (with
fixes if there is some needed) in "master" tonight.
Also I might want to give --keep option to fetch-pack as well;
clone-pack has some static functions that we can extract out to
a common file to link to both.
-- >8 --
Subject: [PATCH] clone-pack: make it usable for partial branch cloning.
clone-pack had some logic to accept subset of remote refs from
the command line and clone from there. However, it was never
used in practice and its problems were not found out so far.
This commit changes the command to output the object names of
refs to the standard output instead of making a clone of the
remote repository when explicit <head> parameters are given; the
output format is the same as fetch-pack.
The traditional behaviour of cloning the whole repository by
giving no explicit <head> parameters stays the same.
Signed-off-by: Junio C Hamano <junkio@cox.net>
---
Documentation/git-clone-pack.txt | 6 +++++-
clone-pack.c | 13 +++++++++++--
2 files changed, 16 insertions(+), 3 deletions(-)
31ec6abf887ec95642cbe82fe61076e975494ab0
diff --git a/Documentation/git-clone-pack.txt b/Documentation/git-clone-pack.txt
index cfc7b62..39906fc 100644
--- a/Documentation/git-clone-pack.txt
+++ b/Documentation/git-clone-pack.txt
@@ -43,7 +43,11 @@ OPTIONS
The heads to update. This is relative to $GIT_DIR
(e.g. "HEAD", "refs/heads/master"). When unspecified,
all heads are updated to match the remote repository.
-
++
+Usually all the refs from existing repository are stored
+under the same name in the new repository. Giving explicit
+<head> arguments instead writes the object names and refs to
+the standard output, just like get-fetch-pack does.
Author
------
diff --git a/clone-pack.c b/clone-pack.c
index a99a95c..b5ce5d3 100644
--- a/clone-pack.c
+++ b/clone-pack.c
@@ -259,8 +259,17 @@ static int clone_pack(int fd[2], int nr_
status = clone_without_unpack(fd);
- if (!status)
- write_refs(refs);
+ if (!status) {
+ if (nr_match == 0)
+ write_refs(refs);
+ else
+ while (refs) {
+ printf("%s %s\n",
+ sha1_to_hex(refs->old_sha1),
+ refs->name);
+ refs = refs->next;
+ }
+ }
return status;
}
--
0.99.9n
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: How to clone-pack the HEAD?
2005-12-15 5:29 ` Junio C Hamano
@ 2005-12-15 6:21 ` Junio C Hamano
2005-12-18 0:53 ` Petr Baudis
2005-12-18 0:38 ` Petr Baudis
1 sibling, 1 reply; 10+ messages in thread
From: Junio C Hamano @ 2005-12-15 6:21 UTC (permalink / raw)
To: Petr Baudis; +Cc: git
Junio C Hamano <junkio@cox.net> writes:
> Also I might want to give --keep option to fetch-pack as well;
> clone-pack has some static functions that we can extract out to
> a common file to link to both.
And this is the second installment, on top of the previous one.
I am a bit reluctant about this one only because of its size,
but I suspect it may be much easier to use for your purpose.
I'll keep this in the proposed updates branch for now (the other
one goes to master tonight), so if you like this one, please
holler, test out and ack.
-- >8 --
Subject: [PATCH] fetch-pack: -k option to keep downloaded pack.
Split out the functions that deal with the socketpair after
finishing git protocol handshake to receive the packed data into
a separate file, and use it in fetch-pack to keep/explode the
received pack data. We earlier had something like that on
clone-pack side once, but the list discussion resulted in the
decision that it makes sense to always keep the pack for
clone-pack, so unpacking option is not enabled on the clone-pack
side, but we later still could do so easily if we wanted to with
this change.
Signed-off-by: Junio C Hamano <junkio@cox.net>
---
Documentation/git-fetch-pack.txt | 7 +-
Makefile | 1
cache.h | 5 +
clone-pack.c | 136 ------------------------------
fetch-clone.c | 172 ++++++++++++++++++++++++++++++++++++++
fetch-pack.c | 58 +++++--------
6 files changed, 206 insertions(+), 173 deletions(-)
create mode 100644 fetch-clone.c
32cf3b780b1cf77cf2fa7042d31dfe969ad0b9b9
diff --git a/Documentation/git-fetch-pack.txt b/Documentation/git-fetch-pack.txt
index ea6faab..b507e9b 100644
--- a/Documentation/git-fetch-pack.txt
+++ b/Documentation/git-fetch-pack.txt
@@ -8,7 +8,7 @@ git-fetch-pack - Receive missing objects
SYNOPSIS
--------
-git-fetch-pack [-q] [--exec=<git-upload-pack>] [<host>:]<directory> [<refs>...]
+git-fetch-pack [-q] [-k] [--exec=<git-upload-pack>] [<host>:]<directory> [<refs>...]
DESCRIPTION
-----------
@@ -29,6 +29,11 @@ OPTIONS
Pass '-q' flag to 'git-unpack-objects'; this makes the
cloning process less verbose.
+-k::
+ Do not invoke 'git-unpack-objects' on received data, but
+ create a single packfile out of it instead, and store it
+ in the object database.
+
--exec=<git-upload-pack>::
Use this to specify the path to 'git-upload-pack' on the
remote side, if is not found on your $PATH.
diff --git a/Makefile b/Makefile
index d494ad4..9fd2ed3 100644
--- a/Makefile
+++ b/Makefile
@@ -175,6 +175,7 @@ LIB_OBJS = \
quote.o read-cache.o refs.o run-command.o \
server-info.o setup.o sha1_file.o sha1_name.o strbuf.o \
tag.o tree.o usage.o config.o environment.o ctype.o copy.o \
+ fetch-clone.o \
$(DIFF_OBJS)
LIBS = $(LIB_FILE)
diff --git a/cache.h b/cache.h
index c78d8ae..cb87bec 100644
--- a/cache.h
+++ b/cache.h
@@ -338,4 +338,9 @@ extern char git_default_name[MAX_GITNAME
extern char git_commit_encoding[MAX_ENCODING_LENGTH];
extern int copy_fd(int ifd, int ofd);
+
+/* Finish off pack transfer receiving end */
+extern int receive_unpack_pack(int fd[2], const char *me, int quiet);
+extern int receive_keep_pack(int fd[2], const char *me);
+
#endif /* CACHE_H */
diff --git a/clone-pack.c b/clone-pack.c
index b5ce5d3..03dbc2e 100644
--- a/clone-pack.c
+++ b/clone-pack.c
@@ -1,7 +1,6 @@
#include "cache.h"
#include "refs.h"
#include "pkt-line.h"
-#include <sys/wait.h>
static const char clone_pack_usage[] =
"git-clone-pack [--exec=<git-upload-pack>] [<host>:]<directory> [<heads>]*";
@@ -112,139 +111,6 @@ static void write_refs(struct ref *ref)
free(head_path);
}
-static int finish_pack(const char *pack_tmp_name)
-{
- int pipe_fd[2];
- pid_t pid;
- char idx[PATH_MAX];
- char final[PATH_MAX];
- char hash[41];
- unsigned char sha1[20];
- char *cp;
- int err = 0;
-
- if (pipe(pipe_fd) < 0)
- die("git-clone-pack: unable to set up pipe");
-
- strcpy(idx, pack_tmp_name); /* ".git/objects/pack-XXXXXX" */
- cp = strrchr(idx, '/');
- memcpy(cp, "/pidx", 5);
-
- pid = fork();
- if (pid < 0)
- die("git-clone-pack: unable to fork off git-index-pack");
- if (!pid) {
- close(0);
- dup2(pipe_fd[1], 1);
- close(pipe_fd[0]);
- close(pipe_fd[1]);
- execlp("git-index-pack","git-index-pack",
- "-o", idx, pack_tmp_name, NULL);
- error("cannot exec git-index-pack <%s> <%s>",
- idx, pack_tmp_name);
- exit(1);
- }
- close(pipe_fd[1]);
- if (read(pipe_fd[0], hash, 40) != 40) {
- error("git-clone-pack: unable to read from git-index-pack");
- err = 1;
- }
- close(pipe_fd[0]);
-
- for (;;) {
- int status, code;
- int retval = waitpid(pid, &status, 0);
-
- if (retval < 0) {
- if (errno == EINTR)
- continue;
- error("waitpid failed (%s)", strerror(retval));
- goto error_die;
- }
- if (WIFSIGNALED(status)) {
- int sig = WTERMSIG(status);
- error("git-index-pack died of signal %d", sig);
- goto error_die;
- }
- if (!WIFEXITED(status)) {
- error("git-index-pack died of unnatural causes %d",
- status);
- goto error_die;
- }
- code = WEXITSTATUS(status);
- if (code) {
- error("git-index-pack died with error code %d", code);
- goto error_die;
- }
- if (err)
- goto error_die;
- break;
- }
- hash[40] = 0;
- if (get_sha1_hex(hash, sha1)) {
- error("git-index-pack reported nonsense '%s'", hash);
- goto error_die;
- }
- /* Now we have pack in pack_tmp_name[], and
- * idx in idx[]; rename them to their final names.
- */
- snprintf(final, sizeof(final),
- "%s/pack/pack-%s.pack", get_object_directory(), hash);
- move_temp_to_file(pack_tmp_name, final);
- chmod(final, 0444);
- snprintf(final, sizeof(final),
- "%s/pack/pack-%s.idx", get_object_directory(), hash);
- move_temp_to_file(idx, final);
- chmod(final, 0444);
- return 0;
-
- error_die:
- unlink(idx);
- unlink(pack_tmp_name);
- exit(1);
-}
-
-static int clone_without_unpack(int fd[2])
-{
- char tmpfile[PATH_MAX];
- int ofd, ifd;
-
- ifd = fd[0];
- snprintf(tmpfile, sizeof(tmpfile),
- "%s/pack/tmp-XXXXXX", get_object_directory());
- ofd = mkstemp(tmpfile);
- if (ofd < 0)
- return error("unable to create temporary file %s", tmpfile);
-
- while (1) {
- char buf[8192];
- ssize_t sz, wsz, pos;
- sz = read(ifd, buf, sizeof(buf));
- if (sz == 0)
- break;
- if (sz < 0) {
- error("error reading pack (%s)", strerror(errno));
- close(ofd);
- unlink(tmpfile);
- return -1;
- }
- pos = 0;
- while (pos < sz) {
- wsz = write(ofd, buf + pos, sz - pos);
- if (wsz < 0) {
- error("error writing pack (%s)",
- strerror(errno));
- close(ofd);
- unlink(tmpfile);
- return -1;
- }
- pos += wsz;
- }
- }
- close(ofd);
- return finish_pack(tmpfile);
-}
-
static int clone_pack(int fd[2], int nr_match, char **match)
{
struct ref *refs;
@@ -257,7 +123,7 @@ static int clone_pack(int fd[2], int nr_
}
clone_handshake(fd, refs);
- status = clone_without_unpack(fd);
+ status = receive_keep_pack(fd, "git-clone-pack");
if (!status) {
if (nr_match == 0)
diff --git a/fetch-clone.c b/fetch-clone.c
new file mode 100644
index 0000000..2b2aa15
--- /dev/null
+++ b/fetch-clone.c
@@ -0,0 +1,172 @@
+#include "cache.h"
+#include <sys/wait.h>
+
+static int finish_pack(const char *pack_tmp_name, const char *me)
+{
+ int pipe_fd[2];
+ pid_t pid;
+ char idx[PATH_MAX];
+ char final[PATH_MAX];
+ char hash[41];
+ unsigned char sha1[20];
+ char *cp;
+ int err = 0;
+
+ if (pipe(pipe_fd) < 0)
+ die("%s: unable to set up pipe", me);
+
+ strcpy(idx, pack_tmp_name); /* ".git/objects/pack-XXXXXX" */
+ cp = strrchr(idx, '/');
+ memcpy(cp, "/pidx", 5);
+
+ pid = fork();
+ if (pid < 0)
+ die("git-clone-pack: unable to fork off git-index-pack");
+ if (!pid) {
+ close(0);
+ dup2(pipe_fd[1], 1);
+ close(pipe_fd[0]);
+ close(pipe_fd[1]);
+ execlp("git-index-pack","git-index-pack",
+ "-o", idx, pack_tmp_name, NULL);
+ error("cannot exec git-index-pack <%s> <%s>",
+ idx, pack_tmp_name);
+ exit(1);
+ }
+ close(pipe_fd[1]);
+ if (read(pipe_fd[0], hash, 40) != 40) {
+ error("%s: unable to read from git-index-pack", me);
+ err = 1;
+ }
+ close(pipe_fd[0]);
+
+ for (;;) {
+ int status, code;
+ int retval = waitpid(pid, &status, 0);
+
+ if (retval < 0) {
+ if (errno == EINTR)
+ continue;
+ error("waitpid failed (%s)", strerror(retval));
+ goto error_die;
+ }
+ if (WIFSIGNALED(status)) {
+ int sig = WTERMSIG(status);
+ error("git-index-pack died of signal %d", sig);
+ goto error_die;
+ }
+ if (!WIFEXITED(status)) {
+ error("git-index-pack died of unnatural causes %d",
+ status);
+ goto error_die;
+ }
+ code = WEXITSTATUS(status);
+ if (code) {
+ error("git-index-pack died with error code %d", code);
+ goto error_die;
+ }
+ if (err)
+ goto error_die;
+ break;
+ }
+ hash[40] = 0;
+ if (get_sha1_hex(hash, sha1)) {
+ error("git-index-pack reported nonsense '%s'", hash);
+ goto error_die;
+ }
+ /* Now we have pack in pack_tmp_name[], and
+ * idx in idx[]; rename them to their final names.
+ */
+ snprintf(final, sizeof(final),
+ "%s/pack/pack-%s.pack", get_object_directory(), hash);
+ move_temp_to_file(pack_tmp_name, final);
+ chmod(final, 0444);
+ snprintf(final, sizeof(final),
+ "%s/pack/pack-%s.idx", get_object_directory(), hash);
+ move_temp_to_file(idx, final);
+ chmod(final, 0444);
+ return 0;
+
+ error_die:
+ unlink(idx);
+ unlink(pack_tmp_name);
+ exit(1);
+}
+
+int receive_unpack_pack(int fd[2], const char *me, int quiet)
+{
+ int status;
+ pid_t pid;
+
+ pid = fork();
+ if (pid < 0)
+ die("%s: unable to fork off git-unpack-objects", me);
+ if (!pid) {
+ dup2(fd[0], 0);
+ close(fd[0]);
+ close(fd[1]);
+ execlp("git-unpack-objects", "git-unpack-objects",
+ quiet ? "-q" : NULL, NULL);
+ die("git-unpack-objects exec failed");
+ }
+ close(fd[0]);
+ close(fd[1]);
+ while (waitpid(pid, &status, 0) < 0) {
+ if (errno != EINTR)
+ die("waiting for git-unpack-objects: %s",
+ strerror(errno));
+ }
+ if (WIFEXITED(status)) {
+ int code = WEXITSTATUS(status);
+ if (code)
+ die("git-unpack-objects died with error code %d",
+ code);
+ return 0;
+ }
+ if (WIFSIGNALED(status)) {
+ int sig = WTERMSIG(status);
+ die("git-unpack-objects died of signal %d", sig);
+ }
+ die("git-unpack-objects died of unnatural causes %d", status);
+}
+
+int receive_keep_pack(int fd[2], const char *me)
+{
+ char tmpfile[PATH_MAX];
+ int ofd, ifd;
+
+ ifd = fd[0];
+ snprintf(tmpfile, sizeof(tmpfile),
+ "%s/pack/tmp-XXXXXX", get_object_directory());
+ ofd = mkstemp(tmpfile);
+ if (ofd < 0)
+ return error("unable to create temporary file %s", tmpfile);
+
+ while (1) {
+ char buf[8192];
+ ssize_t sz, wsz, pos;
+ sz = read(ifd, buf, sizeof(buf));
+ if (sz == 0)
+ break;
+ if (sz < 0) {
+ error("error reading pack (%s)", strerror(errno));
+ close(ofd);
+ unlink(tmpfile);
+ return -1;
+ }
+ pos = 0;
+ while (pos < sz) {
+ wsz = write(ofd, buf + pos, sz - pos);
+ if (wsz < 0) {
+ error("error writing pack (%s)",
+ strerror(errno));
+ close(ofd);
+ unlink(tmpfile);
+ return -1;
+ }
+ pos += wsz;
+ }
+ }
+ close(ofd);
+ return finish_pack(tmpfile, me);
+}
diff --git a/fetch-pack.c b/fetch-pack.c
index 58ba209..2528053 100644
--- a/fetch-pack.c
+++ b/fetch-pack.c
@@ -3,13 +3,12 @@
#include "pkt-line.h"
#include "commit.h"
#include "tag.h"
-#include <time.h>
-#include <sys/wait.h>
+static int keep_pack;
static int quiet;
static int verbose;
static const char fetch_pack_usage[] =
-"git-fetch-pack [-q] [-v] [--exec=upload-pack] [host:]directory <refs>...";
+"git-fetch-pack [-q] [-v] [-k] [--exec=upload-pack] [host:]directory <refs>...";
static const char *exec = "git-upload-pack";
#define COMPLETE (1U << 0)
@@ -363,7 +362,6 @@ static int fetch_pack(int fd[2], int nr_
struct ref *ref;
unsigned char sha1[20];
int status;
- pid_t pid;
get_remote_heads(fd[0], &ref, 0, NULL, 0);
if (server_supports("multi_ack")) {
@@ -381,40 +379,22 @@ static int fetch_pack(int fd[2], int nr_
}
if (find_common(fd, sha1, ref) < 0)
fprintf(stderr, "warning: no common commits\n");
- pid = fork();
- if (pid < 0)
- die("git-fetch-pack: unable to fork off git-unpack-objects");
- if (!pid) {
- dup2(fd[0], 0);
- close(fd[0]);
- close(fd[1]);
- execlp("git-unpack-objects", "git-unpack-objects",
- quiet ? "-q" : NULL, NULL);
- die("git-unpack-objects exec failed");
- }
- close(fd[0]);
- close(fd[1]);
- while (waitpid(pid, &status, 0) < 0) {
- if (errno != EINTR)
- die("waiting for git-unpack-objects: %s", strerror(errno));
- }
- if (WIFEXITED(status)) {
- int code = WEXITSTATUS(status);
- if (code)
- die("git-unpack-objects died with error code %d", code);
-all_done:
- while (ref) {
- printf("%s %s\n",
- sha1_to_hex(ref->old_sha1), ref->name);
- ref = ref->next;
- }
- return 0;
- }
- if (WIFSIGNALED(status)) {
- int sig = WTERMSIG(status);
- die("git-unpack-objects died of signal %d", sig);
+
+ if (keep_pack)
+ status = receive_keep_pack(fd, "git-fetch-pack");
+ else
+ status = receive_unpack_pack(fd, "git-fetch-pack", quiet);
+
+ if (status)
+ die("git-fetch-pack: fetch failed.");
+
+ all_done:
+ while (ref) {
+ printf("%s %s\n",
+ sha1_to_hex(ref->old_sha1), ref->name);
+ ref = ref->next;
}
- die("Sherlock Holmes! git-unpack-objects died of unnatural causes %d!", status);
+ return 0;
}
int main(int argc, char **argv)
@@ -440,6 +420,10 @@ int main(int argc, char **argv)
quiet = 1;
continue;
}
+ if (!strcmp("-k", arg)) {
+ keep_pack = 1;
+ continue;
+ }
if (!strcmp("-v", arg)) {
verbose = 1;
continue;
--
0.99.9n
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: How to clone-pack the HEAD?
2005-12-15 5:29 ` Junio C Hamano
2005-12-15 6:21 ` Junio C Hamano
@ 2005-12-18 0:38 ` Petr Baudis
1 sibling, 0 replies; 10+ messages in thread
From: Petr Baudis @ 2005-12-18 0:38 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
Dear diary, on Thu, Dec 15, 2005 at 06:29:10AM CET, I got a letter
where Junio C Hamano <junkio@cox.net> said that...
> Junio C Hamano <junkio@cox.net> writes:
>
> > Not really. I take this back. What you want to do I did not
> > understand well enough.
> >
> > HEAD is kinda special. A hack I can think of is to do ls-remote
> > first and do the guess clone-pack does for full clone case, and
> > then give a specific branch name to clone. That might work.
>
> ... and another way would be to do this; I'll put this (with
> fixes if there is some needed) in "master" tonight.
Thanks! This makes it work very nicely and exactly the way I want, even
giving git-fetch-pack-compatible output so I can seamlessly switch
between the two commands. Very nice!
--
Petr "Pasky" Baudis
Stuff: http://pasky.or.cz/
VI has two modes: the one in which it beeps and the one in which
it doesn't.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: How to clone-pack the HEAD?
2005-12-15 6:21 ` Junio C Hamano
@ 2005-12-18 0:53 ` Petr Baudis
0 siblings, 0 replies; 10+ messages in thread
From: Petr Baudis @ 2005-12-18 0:53 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
Dear diary, on Thu, Dec 15, 2005 at 07:21:23AM CET, I got a letter
where Junio C Hamano <junkio@cox.net> said that...
> Junio C Hamano <junkio@cox.net> writes:
>
> > Also I might want to give --keep option to fetch-pack as well;
> > clone-pack has some static functions that we can extract out to
> > a common file to link to both.
>
> And this is the second installment, on top of the previous one.
> I am a bit reluctant about this one only because of its size,
> but I suspect it may be much easier to use for your purpose.
>
> I'll keep this in the proposed updates branch for now (the other
> one goes to master tonight), so if you like this one, please
> holler, test out and ack.
Well, I like this one, but you don't need to put this to master just for
me, I'm perfectly fine with the git-clone-pack fix - both commands are
now equally simple for me to use in Cogito. (And both seem to work fine
after some basic testing.)
But you are right that git-clone-pack is basically made obsolete by this
patch, and I tend to like that fact - that's why I have slight
preference to this patch anyway, despite its size (and it's mostly
common code being moved around anyway). It's probably too late to remove
git-clone-pack altogether, but you might at least deprecate it and print
a warning when it's being ran (or at least please print a warning when
it's being ran in a repository which is already populated, which is very
likely a driver error, and I've actually made it just a minute ago ;).
--
Petr "Pasky" Baudis
Stuff: http://pasky.or.cz/
VI has two modes: the one in which it beeps and the one in which
it doesn't.
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2005-12-18 0:53 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-12-15 0:44 How to clone-pack the HEAD? Petr Baudis
2005-12-15 1:20 ` Junio C Hamano
2005-12-15 1:32 ` Petr Baudis
2005-12-15 1:45 ` Junio C Hamano
2005-12-15 1:53 ` Junio C Hamano
2005-12-15 5:29 ` Junio C Hamano
2005-12-15 6:21 ` Junio C Hamano
2005-12-18 0:53 ` Petr Baudis
2005-12-18 0:38 ` Petr Baudis
2005-12-15 1:59 ` Petr Baudis
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).