* Re: [PATCH] Changed timestamp behavior of options -c/-C/--amend
From: Erick Mattos @ 2009-10-30 22:30 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <7v8wesh61b.fsf@alter.siamese.dyndns.org>
2009/10/30 Junio C Hamano <gitster@pobox.com>:
> Erick Mattos <erick.mattos@gmail.com> writes:
>
>> 2009/10/30 Junio C Hamano <gitster@pobox.com>:
>>
>>>(besides, you write logs as if you are making
>>> an order to the codebase to "do this!").
>>
>> Not a chance! Just trying to help.
>
> Sorry, you misunderstood me. What I meant was:
>
> It is customery for us to write our log messages as if the author of
> the patch is giving an order, iow, in imperative mood. Your "Changed
> blah" violates that style.
>
I got it in the opposite way. :-D
So one should give an "order"!... :-1
^ permalink raw reply
* Re: [PATCH] Changed timestamp behavior of options -c/-C/--amend
From: Junio C Hamano @ 2009-10-30 22:33 UTC (permalink / raw)
To: Erick Mattos; +Cc: Junio C Hamano, git
In-Reply-To: <55bacdd30910301520h2678d0c2hd8478716d8ce4a17@mail.gmail.com>
Erick Mattos <erick.mattos@gmail.com> writes:
> 2009/10/30 Junio C Hamano <gitster@pobox.com>:
>> Junio C Hamano <gitster@pobox.com> writes:
>>
>>> ...
>>> I agree that the issue the patch addresses is worth improving, and I think
>>> it is sensible to default to reuse the timestamp for -C and not to reuse
>>> for --amend. I am not sure about -c myself, but it probably shouldn't
>>> reuse the timestamp by default.
>>
>> So after realizing that this was about "author" timestamp, I am rescinding
>> this comment about the change of the default for -c and --amend.
>
> Actually I am only changing the default for -c and I see it useful.
> At least with me I normally use -c only to use messages of commits as
> template.
I do that from time to time as well. As I said in a different message, it
may make the default more intutitive if we give new timestamp when the
author is the same as the committer when doing "-c". You are creating
your own commit in that case.
^ permalink raw reply
* Re: [PATCH 3/8] Teach git var about GIT_EDITOR
From: Jonathan Nieder @ 2009-10-30 22:47 UTC (permalink / raw)
To: Johannes Sixt; +Cc: Junio C Hamano, Ben Walton, David Roundy, GIT List
In-Reply-To: <4AEB51C6.7060204@kdbg.org>
Johannes Sixt wrote:
> Jonathan Nieder schrieb:
>> From: Johannes Sixt <j.sixt@viscovery.net>
[...]
> Thanks for cleaning up behind me. I don't mind if you take
> authorship, but if you do keep my name, please make it:
>
> From: Johannes Sixt <j6t@kdbg.org>
Thanks for the catch.
>>+ error(
>> "No editor specified in GIT_EDITOR, core.editor, VISUAL,\n"
>> "or EDITOR. Tried to fall back to vi but terminal is dumb.\n"
>> "Please set one of these variables to an appropriate\n"
>> "editor or run again with options that will not cause an\n"
>> "editor to be invoked (e.g., -m or -F for git commit).");
>>+ return NULL;
>>+ }
>
> I somehow dislike that this huge error message is in git_editor().
Makes sense.
I am a bit uncomfortable with this error in general. It makes some
sense to refuse to use $VISUAL and fall back to $EDITOR if TERM=dumb,
since without this the distinction between VISUAL and EDITOR is not
very useful. But wouldn’t that check be equally useful if GIT_EDITOR
or core.editor is set to vi? Ideally, vi itself would check TERM and
error out, and git would only need to report and handle the exit.
Unfortunately, at least vim is happy to assume a terminal supports
ANSI sequences even if TERM=dumb (e.g., when running from a text
editor like Acme). Unless VISUAL, GIT_EDITOR, and core.editor are
unset, nobody gets the benefit of this check.
Should git error out rather than run $VISUAL when TERM=dumb? How
about $GIT_EDITOR?
The advice about options to avoid invoking an editor is not very
helpful except with 'git commit', so probably only 'git commit' should
print that message.
> The return value, NULL, should be indication enough for the callers
> to handle the situation suitable.
Good idea.
> In particular, launch_editor()
> wants to write this big warning, but 'git var -l' can avoid the
> error message and write only a short notice:
>
> GIT_EDITOR=terminal is dumb, but VISUAL and EDITOR unset
Maybe 'git var -l' should omit GIT_EDITOR in this situation.
Thanks for the comments,
Jonathan
^ permalink raw reply
* Re: [PATCH 3/8] Teach git var about GIT_EDITOR
From: Junio C Hamano @ 2009-10-30 22:43 UTC (permalink / raw)
To: Jonathan Nieder
Cc: Johannes Sixt, Junio C Hamano, Ben Walton, David Roundy, GIT List
In-Reply-To: <20091030224737.GA16565@progeny.tock>
Jonathan Nieder <jrnieder@gmail.com> writes:
> I am a bit uncomfortable with this error in general. It makes some
> sense to refuse to use $VISUAL and fall back to $EDITOR if TERM=dumb,
> since without this the distinction between VISUAL and EDITOR is not
> very useful.
More importantly, that is what people traditionally expected from VISUAL
and EDITOR and we do that only to follow suit.
There is no such tradition for GIT_EDITOR nor core.editor and switching
behaviour based on the name of editor ("vi"? "vim"?...) does not feel
quite right.
^ permalink raw reply
* Re: [RFC PATCH v4 26/26] test smart http fetch and push
From: Shawn O. Pearce @ 2009-10-30 22:59 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <7vljish69m.fsf@alter.siamese.dyndns.org>
Junio C Hamano <gitster@pobox.com> wrote:
> "Shawn O. Pearce" <spearce@spearce.org> writes:
> > Junio C Hamano <gitster@pobox.com> wrote:
> >> "Shawn O. Pearce" <spearce@spearce.org> writes:
> >>
> >> > + sed -e "
> >> > + s/
> >> > //
> >>
> >> This chomped line is so unlike you---what happened?
>
> What I meant was the patch corruption. I couldn't tell what you were
> trying to filter with the first substitution you are giving to sed.
Oh, that. Its a literal CR on the search side, nothing on the
replace side.
--
Shawn.
^ permalink raw reply
* Re: [PATCH 8/8] Provide a build time default-pager setting
From: Junio C Hamano @ 2009-10-30 22:59 UTC (permalink / raw)
To: Jonathan Nieder
Cc: Junio C Hamano, Ben Walton, Johannes Sixt, David Roundy, GIT List
In-Reply-To: <20091030103925.GI1610@progeny.tock>
I'll queue these for now probably on 'pu', but with the comments we saw on
the list expect them to be followed up with replacement patches.
Thanks.
^ permalink raw reply
* Re: [PATCH] Changed timestamp behavior of options -c/-C/--amend
From: Erick Mattos @ 2009-10-30 23:12 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <7v4opgh5qr.fsf@alter.siamese.dyndns.org>
2009/10/30 Junio C Hamano <gitster@pobox.com>:
> Erick Mattos <erick.mattos@gmail.com> writes:
>
>> 2009/10/30 Junio C Hamano <gitster@pobox.com>:
>>> Junio C Hamano <gitster@pobox.com> writes:
>>>
>>>> ...
>>>> I agree that the issue the patch addresses is worth improving, and I think
>>>> it is sensible to default to reuse the timestamp for -C and not to reuse
>>>> for --amend. I am not sure about -c myself, but it probably shouldn't
>>>> reuse the timestamp by default.
>>>
>>> So after realizing that this was about "author" timestamp, I am rescinding
>>> this comment about the change of the default for -c and --amend.
>>
>> Actually I am only changing the default for -c and I see it useful.
>> At least with me I normally use -c only to use messages of commits as
>> template.
>
> I do that from time to time as well. As I said in a different message, it
> may make the default more intutitive if we give new timestamp when the
> author is the same as the committer when doing "-c". You are creating
> your own commit in that case.
>
I don't see a use for comparing the author and committer because I can
use as template my own commits or others'.
Let's clarify the subject:
In my point-of-view -c option is mainly used for templating commit messages.
In that case -c has a different default from -C and --amend options
thus creating a need for two new options: --reuse-timestamp and
--no-reuse-timestamp.
As I see by your messages you do prefer to have all those options set
up for reusing timestamp as default.
In that case we just need one new option: --no-reuse-timestamp (or
--recreate-timestamp or whatever).
So now It is a matter of decision only and you are the guy.
What should be for all?
^ permalink raw reply
* Re: [RFC PATCH v4 11/26] Move WebDAV HTTP push under remote-curl
From: Tay Ray Chuan @ 2009-10-30 23:20 UTC (permalink / raw)
To: Clemens Buchacher; +Cc: git, Shawn O. Pearce, Daniel Barkalow, Mike Hommey
In-Reply-To: <20091030190655.GA7442@localhost>
Hi,
On Sat, Oct 31, 2009 at 3:06 AM, Clemens Buchacher <drizzd@aon.at> wrote:
> How can the changed result of one test suddenly make another test redundant?
> The two are testing different things.
>[snip]
> No, 'git update-ref' correctly reverts the earlier push, so we can push again
> and 'git update-server-info' is therefore necessary for the test to work
> independently of its predecessors result.
I said "redundant" because in the first push, we've already 1) updated
/refs/heads/master (which is what the 'git update-ref' here does) and
2) updated /info/refs (which is what the 'git update-server-info' does
and 3) pushed changes. To me, the "unpacked refs" test reads as a
trivial test of http-push's ability to update /refs/heads/master and
/info/refs (something we've already done in the first "packed refs"
test), rather than its pushing per se. Is it your intention to keep
the "unpacked refs" test due to the former?
--
Cheers,
Ray Chuan
^ permalink raw reply
* Re: finding the merge of two or more commits
From: Jakub Narebski @ 2009-10-30 23:38 UTC (permalink / raw)
To: E R; +Cc: git
In-Reply-To: <3a69fa7c0910291412l439f7f61vd3b55a77cd7e10b5@mail.gmail.com>
E R <pc88mxer@gmail.com> writes:
> Given two commits c1 and c2, is it possible to ask git if there are
> any commits in the repository that were created by either a sequence
> of commands like:
>
> git checkout c1
> git merge c2
>
> or:
>
> git checkout c2
> git merge c1
>
> with any required conflict resolution?
>
> That is, I don't want to merge c1 and c2 myself, but I want to know if
> someone else has merged c1 and c2, performed any conflict resolution
> and committed the result.
I assume that commits c1 and c2 are not one ancestor of the other (are
not in fast-forward relation).
Translating your question into question about DAG of revisions, you
want to check if there is branch for which both c1 and c2 are
reachable from:
c1sha=$(git rev-parse c1)
c2sha=$(git rev-parse c2)
git for-each-ref --format="%(refname)" refs/heads/ |
while read refname
do
b1=$(git merge-base c1 $refname)
b2=$(git merge-base c2 $refname)
if [ "$b1" = "$c1sha" -a "$b2" = "$c2sha" ]
then
print ${refname#refs/heads/}
fi
done
Instead of comparing git-merge-base with SHA-1 of c1 and c2
respoectively, you can count commits:
git for-each-ref --format="%(refname)" refs/heads/ |
while read refname
do
count1=$(git rev-list c1..$refname | wc -l)
count2=$(git rev-list c2..$refname | wc -l)
if [ "$count1" > 0 -a "$count2" > 0 ]
then
print ${refname#refs/heads/}
fi
done
Not tested!
--
Jakub Narebski
Poland
ShadeHawk on #git
^ permalink raw reply
* Re: [PATCH 3/8] Teach git var about GIT_EDITOR
From: Jonathan Nieder @ 2009-10-31 0:01 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Johannes Sixt, Ben Walton, David Roundy, GIT List
In-Reply-To: <7vvdhwfqon.fsf@alter.siamese.dyndns.org>
Junio C Hamano wrote:
> Jonathan Nieder <jrnieder@gmail.com> writes:
>
>> I am a bit uncomfortable with this error in general. It makes some
>> sense to refuse to use $VISUAL and fall back to $EDITOR if TERM=dumb,
>> since without this the distinction between VISUAL and EDITOR is not
>> very useful.
>
> More importantly, that is what people traditionally expected from VISUAL
> and EDITOR and we do that only to follow suit.
Unfortunately, we don’t do that: we currently still use $VISUAL if
TERM=dumb and just refuse to fall back to vi in that case. I’ll add a
patch to fix this.
> There is no such tradition for GIT_EDITOR nor core.editor
Makes sense.
Jonathan
^ permalink raw reply
* Re: [RFC PATCH v4 14/26] Add stateless RPC options to upload-pack, receive-pack
From: Shawn O. Pearce @ 2009-10-30 23:59 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <7vtyxi53sh.fsf@alter.siamese.dyndns.org>
Junio C Hamano <gitster@pobox.com> wrote:
> I think that is probably too much complexity for too little gain. I think
> detecting stale request and having requestor retry would be sufficient,
> and validating the want lines as we already do would give the same level
> of assurance as "check against the hash of first phase response" I
> outlined above, and would be much simpler thus more robust.
Ack.
I think what we want here is to just add an "ERR invalid want"
message just before disconnecting when the client gives us a SHA-1
which we don't point to directly. Client implementations can choose
how to handle this error. They could retry from the beginning,
or they could abort.
--
Shawn.
^ permalink raw reply
* Re: [RFC PATCH v4 11/26] Move WebDAV HTTP push under remote-curl
From: Shawn O. Pearce @ 2009-10-31 0:09 UTC (permalink / raw)
To: Tay Ray Chuan; +Cc: git, Clemens Buchacher, Daniel Barkalow, Mike Hommey
In-Reply-To: <be6fef0d0910300802t44801cb9n7a129905725f5c56@mail.gmail.com>
Tay Ray Chuan <rctay89@gmail.com> wrote:
> On Thu, Oct 29, 2009 at 8:00 AM, Shawn O. Pearce <spearce@spearce.org> wrote:
> > ?update http tests according to remote-curl capabilities
>
> it would be great if you could mention the $ORIG_HEAD bit:
>
> o Use a variable ($ORIG_HEAD) instead of full SHA-1 name.
Thanks, added.
--
Shawn.
^ permalink raw reply
* Re: [PATCH] Changed timestamp behavior of options -c/-C/--amend
From: Junio C Hamano @ 2009-10-31 0:10 UTC (permalink / raw)
To: Erick Mattos; +Cc: git
In-Reply-To: <55bacdd30910301612xabe2071i1319d920191f080f@mail.gmail.com>
Erick Mattos <erick.mattos@gmail.com> writes:
> I don't see a use for comparing the author and committer because I can
> use as template my own commits or others'.
You _can_ use whichever irrelevant commit as a template, but "you _can_"
is different from what it means, and what is and what is not _sensible_.
You may be rewriting somebody else's patch (e.g. fixing up a typo in the
message, or changing the implementation, or both). If you are going to
keep the authorship, you are saying that "it is still _his_ code, not
mine". In such a case, it never makes sense to change the timestamp, if
that author is somebody other than you. After all that other guy may not
even be aware of what you are doing when you make this commit; he may be
in bed sound asleep in a different timezone.
In another scenario, if your fix-up is very significant, even if you
started from somebody else's patch, you may want to say "now this is my
patch, the original author may have given me some inspiration, but the
changes in this commit, including all the bugs, are mine". The same
applies if you looked at the problem description of somebody' patch, and
did your own solution without using anything from his commit.
At that point, you would want the resulting commit to say it was written
by you at this moment. You do not want to see -c/-C/--amend to retain any
part of the authorship (not just timestamp) from the original commit.
Side note. You may be fixing your own patch, in which case you may or
may not consider your change significant, but at the time of either
old timestamp or current time, you were working on this change, so
using the current timestamp instead of using the old one is not a big
deal, and that is why I think committer==author may be a good
heuristic when deciding to touch or not touch the timestamp.
But in general I do not like such dwim that depends on who you are (it
makes it harder to explain, even if the end result may be useful in
practice), so I'd rather not to see such a code for this topic if we
can avoid it.
In short, I do not think it makes sense to change only the timestamp while
keeping the author. The issue is not "timestamp behaviour" with "use new
timestamp" option, but rather is an ability to declare "Now this is a
commit made _by me_ and _now_; iow, I take authorship for this change",
even when you reuse the commit log message from somewhere else.
So what is needed is an option to tell -c/-C/--amend to reuse _only_ the
message but no authorship information from the original commit, I think.
^ permalink raw reply
* Re: [RFC PATCH v4 26/26] test smart http fetch and push
From: Shawn O. Pearce @ 2009-10-31 0:13 UTC (permalink / raw)
To: Tay Ray Chuan; +Cc: git, Clemens Buchacher
In-Reply-To: <be6fef0d0910300910x5e8bc552k4f020ca8bb890352@mail.gmail.com>
Tay Ray Chuan <rctay89@gmail.com> wrote:
>
> Having "/git/" reside as a subdirectory in "/" where WebDAV is enabled
> may be confusing to readers. I think we should use "/smart/" for the
> CGI map, and consequently, use "/dumb/" for WebDAV repositories,
> rather than the root "/" that it is occupying.
Yup, great idea. Patch added to switch to /dumb/ for WebDAV,
and changed to use /smart/ for this patch.
> Mention of "packed refs" should be removed from the description, and
> the 'unpacked refs' test, irrelevant in this context, should be
> removed too. The assumptions these tests are based on is relevant to
> t5540, but not in t5541. My explanation follows.
Yup, you are right, thanks. Fixed.
--
Shawn.
^ permalink raw reply
* [PATCH v5 03/28] pkt-line: Make packet_read_line easier to debug
From: Shawn O. Pearce @ 2009-10-31 0:47 UTC (permalink / raw)
To: git
In-Reply-To: <1256950067-27938-1-git-send-email-spearce@spearce.org>
When there is an error parsing the 4 byte length component we now
display it as part of the die message, this may hint as to what
data was misunderstood by the application.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
---
pkt-line.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/pkt-line.c b/pkt-line.c
index bd603f8..295ba2b 100644
--- a/pkt-line.c
+++ b/pkt-line.c
@@ -129,7 +129,7 @@ int packet_read_line(int fd, char *buffer, unsigned size)
safe_read(fd, linelen, 4);
len = packet_length(linelen);
if (len < 0)
- die("protocol error: bad line length character");
+ die("protocol error: bad line length character: %.4s", linelen);
if (!len)
return 0;
len -= 4;
--
1.6.5.2.181.gd6f41
^ permalink raw reply related
* [PATCH v5 00/28] Return of smart HTTP
From: Shawn O. Pearce @ 2009-10-31 0:47 UTC (permalink / raw)
To: git
Hopefully the final spin of the smart HTTP series. I think we are
down to bike shedding, which I take it means folks are otherwise
reasonably happy with the code.
Because the series is so large I'll send an inter-diff relative to
v4 after this cover letter.
Clemens Buchacher (2):
remote-helpers: return successfully if everything up-to-date
set httpd port before sourcing lib-httpd
Mark Lodato (5):
http-backend: add GIT_PROJECT_ROOT environment var
http-backend: reword some documentation
http-backend: use mod_alias instead of mod_rewrite
http-backend: add example for gitweb on same URL
http-backend: more explict LocationMatch
Shawn O. Pearce (19):
pkt-line: Add strbuf based functions
pkt-line: Make packet_read_line easier to debug
fetch-pack: Use a strbuf to compose the want list
Move "get_ack()" back to fetch-pack
Add multi_ack_detailed capability to fetch-pack/upload-pack
remote-curl: Refactor walker initialization
fetch: Allow transport -v -v -v to set verbosity to 3
remote-helpers: Fetch more than one ref in a batch
remote-helpers: Support custom transport options
Move WebDAV HTTP push under remote-curl
Git-aware CGI to provide dumb HTTP transport
Add stateless RPC options to upload-pack, receive-pack
Smart fetch and push over HTTP: server side
Discover refs via smart HTTP server when available
Smart push over HTTP: client side
Smart fetch over HTTP: client side
Smart HTTP fetch: gzip requests
http tests: use /dumb/ URL prefix
test smart http fetch and push
Tay Ray Chuan (2):
http-push: fix check condition on http.c::finish_http_pack_request()
t5540-http-push: remove redundant fetches
.gitignore | 1 +
Documentation/config.txt | 8 +
Documentation/git-http-backend.txt | 170 ++++++++
Documentation/git-remote-helpers.txt | 85 ++++-
Makefile | 1 +
builtin-fetch-pack.c | 210 ++++++++--
builtin-fetch.c | 2 +-
builtin-receive-pack.c | 26 +-
builtin-send-pack.c | 116 +++++-
cache.h | 1 -
commit.c | 10 +-
commit.h | 2 +-
connect.c | 21 -
fetch-pack.h | 3 +-
http-backend.c | 627 ++++++++++++++++++++++++++++
http-push.c | 31 ++-
http.c | 13 +-
http.h | 2 +
pkt-line.c | 84 ++++-
pkt-line.h | 4 +
remote-curl.c | 759 ++++++++++++++++++++++++++++++++--
send-pack.h | 3 +-
sideband.c | 11 +-
t/lib-httpd/apache.conf | 24 +-
t/t5540-http-push.sh | 35 +-
t/t5541-http-push.sh | 92 ++++
t/t5550-http-fetch.sh | 12 +-
t/t5551-http-fetch.sh | 102 +++++
transport-helper.c | 264 +++++++++++-
transport.c | 32 +--
transport.h | 2 +-
upload-pack.c | 71 +++-
32 files changed, 2589 insertions(+), 235 deletions(-)
create mode 100644 Documentation/git-http-backend.txt
create mode 100644 http-backend.c
create mode 100755 t/t5541-http-push.sh
create mode 100755 t/t5551-http-fetch.sh
^ permalink raw reply
* [PATCH v5 02/28] pkt-line: Add strbuf based functions
From: Shawn O. Pearce @ 2009-10-31 0:47 UTC (permalink / raw)
To: git
In-Reply-To: <1256950067-27938-1-git-send-email-spearce@spearce.org>
These routines help to work with pkt-line values inside of a strbuf,
permitting simple formatting of buffered network messages.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
---
pkt-line.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++++++--------
pkt-line.h | 4 +++
2 files changed, 76 insertions(+), 12 deletions(-)
diff --git a/pkt-line.c b/pkt-line.c
index b691abe..bd603f8 100644
--- a/pkt-line.c
+++ b/pkt-line.c
@@ -42,17 +42,19 @@ void packet_flush(int fd)
safe_write(fd, "0000", 4);
}
+void packet_buf_flush(struct strbuf *buf)
+{
+ strbuf_add(buf, "0000", 4);
+}
+
#define hex(a) (hexchar[(a) & 15])
-void packet_write(int fd, const char *fmt, ...)
+static char buffer[1000];
+static unsigned format_packet(const char *fmt, va_list args)
{
- static char buffer[1000];
static char hexchar[] = "0123456789abcdef";
- va_list args;
unsigned n;
- va_start(args, fmt);
n = vsnprintf(buffer + 4, sizeof(buffer) - 4, fmt, args);
- va_end(args);
if (n >= sizeof(buffer)-4)
die("protocol error: impossibly long line");
n += 4;
@@ -60,9 +62,31 @@ void packet_write(int fd, const char *fmt, ...)
buffer[1] = hex(n >> 8);
buffer[2] = hex(n >> 4);
buffer[3] = hex(n);
+ return n;
+}
+
+void packet_write(int fd, const char *fmt, ...)
+{
+ va_list args;
+ unsigned n;
+
+ va_start(args, fmt);
+ n = format_packet(fmt, args);
+ va_end(args);
safe_write(fd, buffer, n);
}
+void packet_buf_write(struct strbuf *buf, const char *fmt, ...)
+{
+ va_list args;
+ unsigned n;
+
+ va_start(args, fmt);
+ n = format_packet(fmt, args);
+ va_end(args);
+ strbuf_add(buf, buffer, n);
+}
+
static void safe_read(int fd, void *buffer, unsigned size)
{
ssize_t ret = read_in_full(fd, buffer, size);
@@ -72,15 +96,11 @@ static void safe_read(int fd, void *buffer, unsigned size)
die("The remote end hung up unexpectedly");
}
-int packet_read_line(int fd, char *buffer, unsigned size)
+static int packet_length(const char *linelen)
{
int n;
- unsigned len;
- char linelen[4];
-
- safe_read(fd, linelen, 4);
+ int len = 0;
- len = 0;
for (n = 0; n < 4; n++) {
unsigned char c = linelen[n];
len <<= 4;
@@ -96,8 +116,20 @@ int packet_read_line(int fd, char *buffer, unsigned size)
len += c - 'A' + 10;
continue;
}
- die("protocol error: bad line length character");
+ return -1;
}
+ return len;
+}
+
+int packet_read_line(int fd, char *buffer, unsigned size)
+{
+ int len;
+ char linelen[4];
+
+ safe_read(fd, linelen, 4);
+ len = packet_length(linelen);
+ if (len < 0)
+ die("protocol error: bad line length character");
if (!len)
return 0;
len -= 4;
@@ -107,3 +139,31 @@ int packet_read_line(int fd, char *buffer, unsigned size)
buffer[len] = 0;
return len;
}
+
+int packet_get_line(struct strbuf *out,
+ char **src_buf, size_t *src_len)
+{
+ int len;
+
+ if (*src_len < 4)
+ return -1;
+ len = packet_length(*src_buf);
+ if (len < 0)
+ return -1;
+ if (!len) {
+ *src_buf += 4;
+ *src_len -= 4;
+ return 0;
+ }
+ if (*src_len < len)
+ return -2;
+
+ *src_buf += 4;
+ *src_len -= 4;
+ len -= 4;
+
+ strbuf_add(out, *src_buf, len);
+ *src_buf += len;
+ *src_len -= len;
+ return len;
+}
diff --git a/pkt-line.h b/pkt-line.h
index 9df653f..1e5dcfe 100644
--- a/pkt-line.h
+++ b/pkt-line.h
@@ -2,14 +2,18 @@
#define PKTLINE_H
#include "git-compat-util.h"
+#include "strbuf.h"
/*
* Silly packetized line writing interface
*/
void packet_flush(int fd);
void packet_write(int fd, const char *fmt, ...) __attribute__((format (printf, 2, 3)));
+void packet_buf_flush(struct strbuf *buf);
+void packet_buf_write(struct strbuf *buf, const char *fmt, ...) __attribute__((format (printf, 2, 3)));
int packet_read_line(int fd, char *buffer, unsigned size);
+int packet_get_line(struct strbuf *out, char **src_buf, size_t *src_len);
ssize_t safe_write(int, const void *, ssize_t);
#endif
--
1.6.5.2.181.gd6f41
^ permalink raw reply related
* [PATCH v5 00/28] interdiff to v4
From: Shawn O. Pearce @ 2009-10-31 0:47 UTC (permalink / raw)
To: git
In-Reply-To: <1256950067-27938-1-git-send-email-spearce@spearce.org>
diff --git a/pkt-line.c b/pkt-line.c
index 893dd3c..295ba2b 100644
--- a/pkt-line.c
+++ b/pkt-line.c
@@ -124,14 +124,12 @@ static int packet_length(const char *linelen)
int packet_read_line(int fd, char *buffer, unsigned size)
{
int len;
- char linelen[5];
+ char linelen[4];
safe_read(fd, linelen, 4);
len = packet_length(linelen);
- if (len < 0) {
- linelen[4] = '\0';
- die("protocol error: bad line length character: %s", linelen);
- }
+ if (len < 0)
+ die("protocol error: bad line length character: %.4s", linelen);
if (!len)
return 0;
len -= 4;
diff --git a/t/lib-httpd/apache.conf b/t/lib-httpd/apache.conf
index 2098ce0..0fe3fd0 100644
--- a/t/lib-httpd/apache.conf
+++ b/t/lib-httpd/apache.conf
@@ -8,20 +8,22 @@ ErrorLog error.log
<IfModule !mod_log_config.c>
LoadModule log_config_module modules/mod_log_config.so
</IfModule>
-<IfModule !mod_cgi.c>
- LoadModule cgi_module modules/mod_cgi.so
-</IfModule>
<IfModule !mod_alias.c>
LoadModule alias_module modules/mod_alias.so
</IfModule>
+<IfModule !mod_cgi.c>
+ LoadModule cgi_module modules/mod_cgi.so
+</IfModule>
<IfModule !mod_env.c>
LoadModule env_module modules/mod_env.so
</IfModule>
-<Location /git/>
+Alias /dumb/ www/
+
+<Location /smart/>
SetEnv GIT_EXEC_PATH ${GIT_EXEC_PATH}
</Location>
-ScriptAlias /git/ ${GIT_EXEC_PATH}/git-http-backend/
+ScriptAlias /smart/ ${GIT_EXEC_PATH}/git-http-backend/
<Directory ${GIT_EXEC_PATH}>
Options None
</Directory>
@@ -46,7 +48,7 @@ SSLEngine On
LoadModule dav_fs_module modules/mod_dav_fs.so
DAVLockDB DAVLock
- <Location />
+ <Location /dumb/>
Dav on
</Location>
</IfDefine>
diff --git a/t/t5540-http-push.sh b/t/t5540-http-push.sh
index 5c0f4d7..bb18f8b 100755
--- a/t/t5540-http-push.sh
+++ b/t/t5540-http-push.sh
@@ -9,17 +9,16 @@ This test runs various sanity checks on http-push.'
. ./test-lib.sh
-ROOT_PATH="$PWD"
-LIB_HTTPD_DAV=t
-LIB_HTTPD_PORT=${LIB_HTTPD_PORT-'5540'}
-
if git http-push > /dev/null 2>&1 || [ $? -eq 128 ]
then
say "skipping test, USE_CURL_MULTI is not defined"
test_done
fi
+LIB_HTTPD_DAV=t
+LIB_HTTPD_PORT=${LIB_HTTPD_PORT-'5540'}
. "$TEST_DIRECTORY"/lib-httpd.sh
+ROOT_PATH="$PWD"
start_httpd
test_expect_success 'setup remote repository' '
@@ -43,7 +42,7 @@ test_expect_success 'setup remote repository' '
test_expect_success 'clone remote repository' '
cd "$ROOT_PATH" &&
- git clone $HTTPD_URL/test_repo.git test_repo_clone
+ git clone $HTTPD_URL/dumb/test_repo.git test_repo_clone
'
test_expect_success 'push to remote repository with packed refs' '
@@ -76,7 +75,7 @@ test_expect_success 'http-push fetches unpacked objects' '
cp -R "$HTTPD_DOCUMENT_ROOT_PATH"/test_repo.git \
"$HTTPD_DOCUMENT_ROOT_PATH"/test_repo_unpacked.git &&
- git clone $HTTPD_URL/test_repo_unpacked.git \
+ git clone $HTTPD_URL/dumb/test_repo_unpacked.git \
"$ROOT_PATH"/fetch_unpacked &&
# By reset, we force git to retrieve the object
@@ -85,14 +84,14 @@ test_expect_success 'http-push fetches unpacked objects' '
git remote rm origin &&
git reflog expire --expire=0 --all &&
git prune &&
- git push -f -v $HTTPD_URL/test_repo_unpacked.git master)
+ git push -f -v $HTTPD_URL/dumb/test_repo_unpacked.git master)
'
test_expect_success 'http-push fetches packed objects' '
cp -R "$HTTPD_DOCUMENT_ROOT_PATH"/test_repo.git \
"$HTTPD_DOCUMENT_ROOT_PATH"/test_repo_packed.git &&
- git clone $HTTPD_URL/test_repo_packed.git \
+ git clone $HTTPD_URL/dumb/test_repo_packed.git \
"$ROOT_PATH"/test_repo_clone_packed &&
(cd "$HTTPD_DOCUMENT_ROOT_PATH"/test_repo_packed.git &&
@@ -105,7 +104,7 @@ test_expect_success 'http-push fetches packed objects' '
git remote rm origin &&
git reflog expire --expire=0 --all &&
git prune &&
- git push -f -v $HTTPD_URL/test_repo_packed.git master)
+ git push -f -v $HTTPD_URL/dumb/test_repo_packed.git master)
'
test_expect_success 'create and delete remote branch' '
diff --git a/t/t5541-http-push.sh b/t/t5541-http-push.sh
index 690c466..2a58d0c 100755
--- a/t/t5541-http-push.sh
+++ b/t/t5541-http-push.sh
@@ -12,7 +12,7 @@ if test -n "$NO_CURL"; then
fi
ROOT_PATH="$PWD"
-LIB_HTTPD_PORT=${LIB_HTTPD_PORT-'5550'}
+LIB_HTTPD_PORT=${LIB_HTTPD_PORT-'5541'}
. "$TEST_DIRECTORY"/lib-httpd.sh
start_httpd
@@ -36,10 +36,10 @@ test_expect_success 'setup remote repository' '
test_expect_success 'clone remote repository' '
cd "$ROOT_PATH" &&
- git clone $HTTPD_URL/git/test_repo.git test_repo_clone
+ git clone $HTTPD_URL/smart/test_repo.git test_repo_clone
'
-test_expect_success 'push to remote repository with packed refs' '
+test_expect_success 'push to remote repository' '
cd "$ROOT_PATH"/test_repo_clone &&
: >path2 &&
git add path2 &&
@@ -55,15 +55,6 @@ test_expect_success 'push already up-to-date' '
git push
'
-test_expect_success 'push to remote repository with unpacked refs' '
- (cd "$HTTPD_DOCUMENT_ROOT_PATH"/test_repo.git &&
- rm packed-refs &&
- git update-ref refs/heads/master $ORIG_HEAD) &&
- git push &&
- (cd "$HTTPD_DOCUMENT_ROOT_PATH"/test_repo.git &&
- test $HEAD = $(git rev-parse --verify HEAD))
-'
-
test_expect_success 'create and delete remote branch' '
cd "$ROOT_PATH"/test_repo_clone &&
git checkout -b dev &&
@@ -77,17 +68,15 @@ test_expect_success 'create and delete remote branch' '
'
cat >exp <<EOF
-GET /git/test_repo.git/info/refs?service=git-upload-pack HTTP/1.1 200
-POST /git/test_repo.git/git-upload-pack HTTP/1.1 200
-GET /git/test_repo.git/info/refs?service=git-receive-pack HTTP/1.1 200
-POST /git/test_repo.git/git-receive-pack HTTP/1.1 200
-GET /git/test_repo.git/info/refs?service=git-receive-pack HTTP/1.1 200
-GET /git/test_repo.git/info/refs?service=git-receive-pack HTTP/1.1 200
-POST /git/test_repo.git/git-receive-pack HTTP/1.1 200
-GET /git/test_repo.git/info/refs?service=git-receive-pack HTTP/1.1 200
-POST /git/test_repo.git/git-receive-pack HTTP/1.1 200
-GET /git/test_repo.git/info/refs?service=git-receive-pack HTTP/1.1 200
-POST /git/test_repo.git/git-receive-pack HTTP/1.1 200
+GET /smart/test_repo.git/info/refs?service=git-upload-pack HTTP/1.1 200
+POST /smart/test_repo.git/git-upload-pack HTTP/1.1 200
+GET /smart/test_repo.git/info/refs?service=git-receive-pack HTTP/1.1 200
+POST /smart/test_repo.git/git-receive-pack HTTP/1.1 200
+GET /smart/test_repo.git/info/refs?service=git-receive-pack HTTP/1.1 200
+GET /smart/test_repo.git/info/refs?service=git-receive-pack HTTP/1.1 200
+POST /smart/test_repo.git/git-receive-pack HTTP/1.1 200
+GET /smart/test_repo.git/info/refs?service=git-receive-pack HTTP/1.1 200
+POST /smart/test_repo.git/git-receive-pack HTTP/1.1 200
EOF
test_expect_success 'used receive-pack service' '
sed -e "
diff --git a/t/t5550-http-fetch.sh b/t/t5550-http-fetch.sh
index 8d6443f..8cfce96 100755
--- a/t/t5550-http-fetch.sh
+++ b/t/t5550-http-fetch.sh
@@ -30,7 +30,7 @@ test_expect_success 'create http-accessible bare repository' '
'
test_expect_success 'clone http repository' '
- git clone $HTTPD_URL/repo.git clone &&
+ git clone $HTTPD_URL/dumb/repo.git clone &&
test_cmp file clone/file
'
@@ -58,7 +58,7 @@ test_expect_success 'fetch packed objects' '
cd "$HTTPD_DOCUMENT_ROOT_PATH"/repo_pack.git &&
git --bare repack &&
git --bare prune-packed &&
- git clone $HTTPD_URL/repo_pack.git
+ git clone $HTTPD_URL/dumb/repo_pack.git
'
test_expect_success 'did not use upload-pack service' '
diff --git a/t/t5551-http-fetch.sh b/t/t5551-http-fetch.sh
index afddc2c..eb0c039 100755
--- a/t/t5551-http-fetch.sh
+++ b/t/t5551-http-fetch.sh
@@ -8,7 +8,7 @@ if test -n "$NO_CURL"; then
test_done
fi
-LIB_HTTPD_PORT=${LIB_HTTPD_PORT-'5550'}
+LIB_HTTPD_PORT=${LIB_HTTPD_PORT-'5551'}
. "$TEST_DIRECTORY"/lib-httpd.sh
start_httpd
@@ -28,19 +28,21 @@ test_expect_success 'create http-accessible bare repository' '
'
cat >exp <<EOF
-> GET /git/repo.git/info/refs?service=git-upload-pack HTTP/1.1
-Accept: */*
-Pragma: no-cache
+> GET /smart/repo.git/info/refs?service=git-upload-pack HTTP/1.1
+> Accept: */*
+> Pragma: no-cache
+
< HTTP/1.1 200 OK
< Pragma: no-cache
< Cache-Control: no-cache, max-age=0, must-revalidate
< Content-Type: application/x-git-upload-pack-advertisement
<
-> POST /git/repo.git/git-upload-pack HTTP/1.1
-Accept-Encoding: deflate, gzip
-Content-Type: application/x-git-upload-pack-request
-Accept: application/x-git-upload-pack-response
-Content-Length: xxxx
+> POST /smart/repo.git/git-upload-pack HTTP/1.1
+> Accept-Encoding: deflate, gzip
+> Content-Type: application/x-git-upload-pack-request
+> Accept: application/x-git-upload-pack-response
+> Content-Length: xxx
+
< HTTP/1.1 200 OK
< Pragma: no-cache
< Cache-Control: no-cache, max-age=0, must-revalidate
@@ -48,13 +50,26 @@ Content-Length: xxxx
<
EOF
test_expect_success 'clone http repository' '
- GIT_CURL_VERBOSE=1 git clone $HTTPD_URL/git/repo.git clone 2>err &&
+ GIT_CURL_VERBOSE=1 git clone --quiet $HTTPD_URL/smart/repo.git clone 2>err &&
test_cmp file clone/file &&
- egrep "^([<>]|Pragma|Accept|Content-|Transfer-)" err |
- egrep -v "^< (Server|Expires|Date|Content-Length:|Transfer-Encoding: chunked)" |
+ tr '\''\015'\'' Q <err |
sed -e "
- s/
//
- s/^Content-Length: .*$/Content-Length: xxxx/
+ s/Q\$//
+ /^[*] /d
+
+ /^[^><]/{
+ s/^/> /
+ }
+
+ /^> User-Agent: /d
+ /^> Host: /d
+ s/^> Content-Length: .*/> Content-Length: xxx/
+
+ /^< Server: /d
+ /^< Expires: /d
+ /^< Date: /d
+ /^< Content-Length: /d
+ /^< Transfer-Encoding: /d
" >act &&
test_cmp exp act
'
@@ -68,10 +83,10 @@ test_expect_success 'fetch changes via http' '
'
cat >exp <<EOF
-GET /git/repo.git/info/refs?service=git-upload-pack HTTP/1.1 200
-POST /git/repo.git/git-upload-pack HTTP/1.1 200
-GET /git/repo.git/info/refs?service=git-upload-pack HTTP/1.1 200
-POST /git/repo.git/git-upload-pack HTTP/1.1 200
+GET /smart/repo.git/info/refs?service=git-upload-pack HTTP/1.1 200
+POST /smart/repo.git/git-upload-pack HTTP/1.1 200
+GET /smart/repo.git/info/refs?service=git-upload-pack HTTP/1.1 200
+POST /smart/repo.git/git-upload-pack HTTP/1.1 200
EOF
test_expect_success 'used upload-pack service' '
sed -e "
^ permalink raw reply related
* [PATCH v5 01/28] http-push: fix check condition on http.c::finish_http_pack_request()
From: Shawn O. Pearce @ 2009-10-31 0:47 UTC (permalink / raw)
To: git; +Cc: Tay Ray Chuan
In-Reply-To: <1256950067-27938-1-git-send-email-spearce@spearce.org>
From: Tay Ray Chuan <rctay89@gmail.com>
Check that http.c::finish_http_pack_request() returns 0 (for success).
Signed-off-by: Tay Ray Chuan <rctay89@gmail.com>
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
---
http-push.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/http-push.c b/http-push.c
index 00e83dc..cc5d4b8 100644
--- a/http-push.c
+++ b/http-push.c
@@ -604,7 +604,7 @@ static void finish_request(struct transfer_request *request)
preq = (struct http_pack_request *)request->userData;
if (preq) {
- if (finish_http_pack_request(preq) > 0)
+ if (finish_http_pack_request(preq) == 0)
fail = 0;
release_http_pack_request(preq);
}
--
1.6.5.2.181.gd6f41
^ permalink raw reply related
* [PATCH v5 04/28] fetch-pack: Use a strbuf to compose the want list
From: Shawn O. Pearce @ 2009-10-31 0:47 UTC (permalink / raw)
To: git
In-Reply-To: <1256950067-27938-1-git-send-email-spearce@spearce.org>
This change is being offered as a refactoring to make later
commits in the smart HTTP series easier.
By changing the enabled capabilities to be formatted in a strbuf
it is easier to add a new capability to the set of supported
capabilities.
By formatting the want portion of the request into a strbuf and
writing it as a whole block we can later decide to hold onto
the req_buf (instead of releasing it) to recycle in stateless
communications.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
---
builtin-fetch-pack.c | 52 ++++++++++++++++++++++++++++++++-----------------
commit.c | 10 +++-----
commit.h | 2 +-
3 files changed, 39 insertions(+), 25 deletions(-)
diff --git a/builtin-fetch-pack.c b/builtin-fetch-pack.c
index 629735f..783c2b0 100644
--- a/builtin-fetch-pack.c
+++ b/builtin-fetch-pack.c
@@ -165,6 +165,7 @@ static int find_common(int fd[2], unsigned char *result_sha1,
const unsigned char *sha1;
unsigned in_vain = 0;
int got_continue = 0;
+ struct strbuf req_buf = STRBUF_INIT;
if (marked)
for_each_ref(clear_marks, NULL);
@@ -175,6 +176,7 @@ static int find_common(int fd[2], unsigned char *result_sha1,
fetching = 0;
for ( ; refs ; refs = refs->next) {
unsigned char *remote = refs->old_sha1;
+ const char *remote_hex;
struct object *o;
/*
@@ -192,27 +194,36 @@ static int find_common(int fd[2], unsigned char *result_sha1,
continue;
}
- if (!fetching)
- packet_write(fd[1], "want %s%s%s%s%s%s%s%s\n",
- sha1_to_hex(remote),
- (multi_ack ? " multi_ack" : ""),
- (use_sideband == 2 ? " side-band-64k" : ""),
- (use_sideband == 1 ? " side-band" : ""),
- (args.use_thin_pack ? " thin-pack" : ""),
- (args.no_progress ? " no-progress" : ""),
- (args.include_tag ? " include-tag" : ""),
- (prefer_ofs_delta ? " ofs-delta" : ""));
- else
- packet_write(fd[1], "want %s\n", sha1_to_hex(remote));
+ remote_hex = sha1_to_hex(remote);
+ if (!fetching) {
+ struct strbuf c = STRBUF_INIT;
+ if (multi_ack) strbuf_addstr(&c, " multi_ack");
+ if (use_sideband == 2) strbuf_addstr(&c, " side-band-64k");
+ if (use_sideband == 1) strbuf_addstr(&c, " side-band");
+ if (args.use_thin_pack) strbuf_addstr(&c, " thin-pack");
+ if (args.no_progress) strbuf_addstr(&c, " no-progress");
+ if (args.include_tag) strbuf_addstr(&c, " include-tag");
+ if (prefer_ofs_delta) strbuf_addstr(&c, " ofs-delta");
+ packet_buf_write(&req_buf, "want %s%s\n", remote_hex, c.buf);
+ strbuf_release(&c);
+ } else
+ packet_buf_write(&req_buf, "want %s\n", remote_hex);
fetching++;
}
+
+ if (!fetching) {
+ strbuf_release(&req_buf);
+ packet_flush(fd[1]);
+ return 1;
+ }
+
if (is_repository_shallow())
- write_shallow_commits(fd[1], 1);
+ write_shallow_commits(&req_buf, 1);
if (args.depth > 0)
- packet_write(fd[1], "deepen %d", args.depth);
- packet_flush(fd[1]);
- if (!fetching)
- return 1;
+ packet_buf_write(&req_buf, "deepen %d", args.depth);
+ packet_buf_flush(&req_buf);
+
+ safe_write(fd[1], req_buf.buf, req_buf.len);
if (args.depth > 0) {
char line[1024];
@@ -296,6 +307,8 @@ done:
multi_ack = 0;
flushes++;
}
+ strbuf_release(&req_buf);
+
while (flushes || multi_ack) {
int ack = get_ack(fd[0], result_sha1);
if (ack) {
@@ -809,6 +822,7 @@ struct ref *fetch_pack(struct fetch_pack_args *my_args,
if (args.depth > 0) {
struct cache_time mtime;
+ struct strbuf sb = STRBUF_INIT;
char *shallow = git_path("shallow");
int fd;
@@ -826,12 +840,14 @@ struct ref *fetch_pack(struct fetch_pack_args *my_args,
fd = hold_lock_file_for_update(&lock, shallow,
LOCK_DIE_ON_ERROR);
- if (!write_shallow_commits(fd, 0)) {
+ if (!write_shallow_commits(&sb, 0)
+ || write_in_full(fd, sb.buf, sb.len) != sb.len) {
unlink_or_warn(shallow);
rollback_lock_file(&lock);
} else {
commit_lock_file(&lock);
}
+ strbuf_release(&sb);
}
reprepare_packed_git();
diff --git a/commit.c b/commit.c
index fedbd5e..471efb0 100644
--- a/commit.c
+++ b/commit.c
@@ -199,7 +199,7 @@ struct commit_graft *lookup_commit_graft(const unsigned char *sha1)
return commit_graft[pos];
}
-int write_shallow_commits(int fd, int use_pack_protocol)
+int write_shallow_commits(struct strbuf *out, int use_pack_protocol)
{
int i, count = 0;
for (i = 0; i < commit_graft_nr; i++)
@@ -208,12 +208,10 @@ int write_shallow_commits(int fd, int use_pack_protocol)
sha1_to_hex(commit_graft[i]->sha1);
count++;
if (use_pack_protocol)
- packet_write(fd, "shallow %s", hex);
+ packet_buf_write(out, "shallow %s", hex);
else {
- if (write_in_full(fd, hex, 40) != 40)
- break;
- if (write_str_in_full(fd, "\n") != 1)
- break;
+ strbuf_addstr(out, hex);
+ strbuf_addch(out, '\n');
}
}
return count;
diff --git a/commit.h b/commit.h
index f4fc5c5..817c75c 100644
--- a/commit.h
+++ b/commit.h
@@ -131,7 +131,7 @@ extern struct commit_list *get_octopus_merge_bases(struct commit_list *in);
extern int register_shallow(const unsigned char *sha1);
extern int unregister_shallow(const unsigned char *sha1);
-extern int write_shallow_commits(int fd, int use_pack_protocol);
+extern int write_shallow_commits(struct strbuf *out, int use_pack_protocol);
extern int is_repository_shallow(void);
extern struct commit_list *get_shallow_commits(struct object_array *heads,
int depth, int shallow_flag, int not_shallow_flag);
--
1.6.5.2.181.gd6f41
^ permalink raw reply related
* [PATCH v5 07/28] remote-curl: Refactor walker initialization
From: Shawn O. Pearce @ 2009-10-31 0:47 UTC (permalink / raw)
To: git; +Cc: Daniel Barkalow
In-Reply-To: <1256950067-27938-1-git-send-email-spearce@spearce.org>
We will need the walker, url and remote in other functions as the
code grows larger to support smart HTTP. Extract this out into a
set of globals we can easily reference once configured.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
CC: Daniel Barkalow <barkalow@iabervon.org>
---
remote-curl.c | 24 ++++++++++++++----------
1 files changed, 14 insertions(+), 10 deletions(-)
diff --git a/remote-curl.c b/remote-curl.c
index 2faf1c6..478f3ea 100644
--- a/remote-curl.c
+++ b/remote-curl.c
@@ -5,7 +5,17 @@
#include "http.h"
#include "exec_cmd.h"
-static struct ref *get_refs(struct walker *walker, const char *url)
+static struct remote *remote;
+static const char *url;
+static struct walker *walker;
+
+static void init_walker(void)
+{
+ if (!walker)
+ walker = get_http_walker(url, remote);
+}
+
+static struct ref *get_refs(void)
{
struct strbuf buffer = STRBUF_INIT;
char *data, *start, *mid;
@@ -21,6 +31,7 @@ static struct ref *get_refs(struct walker *walker, const char *url)
refs_url = xmalloc(strlen(url) + 11);
sprintf(refs_url, "%s/info/refs", url);
+ init_walker();
http_ret = http_get_strbuf(refs_url, &buffer, HTTP_NO_CACHE);
switch (http_ret) {
case HTTP_OK:
@@ -78,10 +89,7 @@ static struct ref *get_refs(struct walker *walker, const char *url)
int main(int argc, const char **argv)
{
- struct remote *remote;
struct strbuf buf = STRBUF_INIT;
- const char *url;
- struct walker *walker = NULL;
git_extract_argv0_path(argv[0]);
setup_git_directory();
@@ -103,8 +111,7 @@ int main(int argc, const char **argv)
break;
if (!prefixcmp(buf.buf, "fetch ")) {
char *obj = buf.buf + strlen("fetch ");
- if (!walker)
- walker = get_http_walker(url, remote);
+ init_walker();
walker->get_all = 1;
walker->get_tree = 1;
walker->get_history = 1;
@@ -115,11 +122,8 @@ int main(int argc, const char **argv)
printf("\n");
fflush(stdout);
} else if (!strcmp(buf.buf, "list")) {
- struct ref *refs;
+ struct ref *refs = get_refs();
struct ref *posn;
- if (!walker)
- walker = get_http_walker(url, remote);
- refs = get_refs(walker, url);
for (posn = refs; posn; posn = posn->next) {
if (posn->symref)
printf("@%s %s\n", posn->symref, posn->name);
--
1.6.5.2.181.gd6f41
^ permalink raw reply related
* [PATCH v5 06/28] Add multi_ack_detailed capability to fetch-pack/upload-pack
From: Shawn O. Pearce @ 2009-10-31 0:47 UTC (permalink / raw)
To: git
In-Reply-To: <1256950067-27938-1-git-send-email-spearce@spearce.org>
When multi_ack_detailed is enabled the ACK continue messages returned
by the remote upload-pack are broken out to describe the different
states within the peer. This permits the client to better understand
the server's in-memory state.
The fetch-pack/upload-pack protocol now looks like:
NAK
---------------------------------
Always sent in response to "done" if there was no common base
selected from the "have" lines (or no have lines were sent).
* no multi_ack or multi_ack_detailed:
Sent when the client has sent a pkt-line flush ("0000") and
the server has not yet found a common base object.
* either multi_ack or multi_ack_detailed:
Always sent in response to a pkt-line flush.
ACK %s
-----------------------------------
* no multi_ack or multi_ack_detailed:
Sent in response to "have" when the object exists on the remote
side and is therefore an object in common between the peers.
The argument is the SHA-1 of the common object.
* either multi_ack or multi_ack_detailed:
Sent in response to "done" if there are common objects.
The argument is the last SHA-1 determined to be common.
ACK %s continue
-----------------------------------
* multi_ack only:
Sent in response to "have".
The remote side wants the client to consider this object as
common, and immediately stop transmitting additional "have"
lines for objects that are reachable from it. The reason
the client should stop is not given, but is one of the two
cases below available under multi_ack_detailed.
ACK %s common
-----------------------------------
* multi_ack_detailed only:
Sent in response to "have". Both sides have this object.
Like with "ACK %s continue" above the client should stop
sending have lines reachable for objects from the argument.
ACK %s ready
-----------------------------------
* multi_ack_detailed only:
Sent in response to "have".
The client should stop transmitting objects which are reachable
from the argument, and send "done" soon to get the objects.
If the remote side has the specified object, it should
first send an "ACK %s common" message prior to sending
"ACK %s ready".
Clients may still submit additional "have" lines if there are
more side branches for the client to explore that might be added
to the common set and reduce the number of objects to transfer.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
---
builtin-fetch-pack.c | 41 ++++++++++++++++++++++++++++++++---------
upload-pack.c | 31 ++++++++++++++++++-------------
2 files changed, 50 insertions(+), 22 deletions(-)
diff --git a/builtin-fetch-pack.c b/builtin-fetch-pack.c
index 7c09d46..615f549 100644
--- a/builtin-fetch-pack.c
+++ b/builtin-fetch-pack.c
@@ -157,7 +157,15 @@ static const unsigned char *get_rev(void)
return commit->object.sha1;
}
-static int get_ack(int fd, unsigned char *result_sha1)
+enum ack_type {
+ NAK = 0,
+ ACK,
+ ACK_continue,
+ ACK_common,
+ ACK_ready
+};
+
+static enum ack_type get_ack(int fd, unsigned char *result_sha1)
{
static char line[1000];
int len = packet_read_line(fd, line, sizeof(line));
@@ -167,12 +175,16 @@ static int get_ack(int fd, unsigned char *result_sha1)
if (line[len-1] == '\n')
line[--len] = 0;
if (!strcmp(line, "NAK"))
- return 0;
+ return NAK;
if (!prefixcmp(line, "ACK ")) {
if (!get_sha1_hex(line+4, result_sha1)) {
if (strstr(line+45, "continue"))
- return 2;
- return 1;
+ return ACK_continue;
+ if (strstr(line+45, "common"))
+ return ACK_common;
+ if (strstr(line+45, "ready"))
+ return ACK_ready;
+ return ACK;
}
}
die("git fetch_pack: expected ACK/NAK, got '%s'", line);
@@ -218,7 +230,8 @@ static int find_common(int fd[2], unsigned char *result_sha1,
remote_hex = sha1_to_hex(remote);
if (!fetching) {
struct strbuf c = STRBUF_INIT;
- if (multi_ack) strbuf_addstr(&c, " multi_ack");
+ if (multi_ack == 2) strbuf_addstr(&c, " multi_ack_detailed");
+ if (multi_ack == 1) strbuf_addstr(&c, " multi_ack");
if (use_sideband == 2) strbuf_addstr(&c, " side-band-64k");
if (use_sideband == 1) strbuf_addstr(&c, " side-band");
if (args.use_thin_pack) strbuf_addstr(&c, " thin-pack");
@@ -298,18 +311,23 @@ static int find_common(int fd[2], unsigned char *result_sha1,
if (args.verbose && ack)
fprintf(stderr, "got ack %d %s\n", ack,
sha1_to_hex(result_sha1));
- if (ack == 1) {
+ switch (ack) {
+ case ACK:
flushes = 0;
multi_ack = 0;
retval = 0;
goto done;
- } else if (ack == 2) {
+ case ACK_common:
+ case ACK_ready:
+ case ACK_continue: {
struct commit *commit =
lookup_commit(result_sha1);
mark_common(commit, 0, 1);
retval = 0;
in_vain = 0;
got_continue = 1;
+ break;
+ }
}
} while (ack);
flushes--;
@@ -336,7 +354,7 @@ done:
if (args.verbose)
fprintf(stderr, "got ack (%d) %s\n", ack,
sha1_to_hex(result_sha1));
- if (ack == 1)
+ if (ack == ACK)
return 0;
multi_ack = 1;
continue;
@@ -618,7 +636,12 @@ static struct ref *do_fetch_pack(int fd[2],
if (is_repository_shallow() && !server_supports("shallow"))
die("Server does not support shallow clients");
- if (server_supports("multi_ack")) {
+ if (server_supports("multi_ack_detailed")) {
+ if (args.verbose)
+ fprintf(stderr, "Server supports multi_ack_detailed\n");
+ multi_ack = 2;
+ }
+ else if (server_supports("multi_ack")) {
if (args.verbose)
fprintf(stderr, "Server supports multi_ack\n");
multi_ack = 1;
diff --git a/upload-pack.c b/upload-pack.c
index 38ddac2..f1dc3a3 100644
--- a/upload-pack.c
+++ b/upload-pack.c
@@ -498,7 +498,7 @@ static int get_common_commits(void)
{
static char line[1000];
unsigned char sha1[20];
- char hex[41], last_hex[41];
+ char last_hex[41];
save_commit_buffer = 0;
@@ -515,19 +515,22 @@ static int get_common_commits(void)
if (!prefixcmp(line, "have ")) {
switch (got_sha1(line+5, sha1)) {
case -1: /* they have what we do not */
- if (multi_ack && ok_to_give_up())
- packet_write(1, "ACK %s continue\n",
- sha1_to_hex(sha1));
+ if (multi_ack && ok_to_give_up()) {
+ const char *hex = sha1_to_hex(sha1);
+ if (multi_ack == 2)
+ packet_write(1, "ACK %s ready\n", hex);
+ else
+ packet_write(1, "ACK %s continue\n", hex);
+ }
break;
default:
- memcpy(hex, sha1_to_hex(sha1), 41);
- if (multi_ack) {
- const char *msg = "ACK %s continue\n";
- packet_write(1, msg, hex);
- memcpy(last_hex, hex, 41);
- }
+ memcpy(last_hex, sha1_to_hex(sha1), 41);
+ if (multi_ack == 2)
+ packet_write(1, "ACK %s common\n", last_hex);
+ else if (multi_ack)
+ packet_write(1, "ACK %s continue\n", last_hex);
else if (have_obj.nr == 1)
- packet_write(1, "ACK %s\n", hex);
+ packet_write(1, "ACK %s\n", last_hex);
break;
}
continue;
@@ -587,7 +590,9 @@ static void receive_needs(void)
get_sha1_hex(line+5, sha1_buf))
die("git upload-pack: protocol error, "
"expected to get sha, not '%s'", line);
- if (strstr(line+45, "multi_ack"))
+ if (strstr(line+45, "multi_ack_detailed"))
+ multi_ack = 2;
+ else if (strstr(line+45, "multi_ack"))
multi_ack = 1;
if (strstr(line+45, "thin-pack"))
use_thin_pack = 1;
@@ -681,7 +686,7 @@ static int send_ref(const char *refname, const unsigned char *sha1, int flag, vo
{
static const char *capabilities = "multi_ack thin-pack side-band"
" side-band-64k ofs-delta shallow no-progress"
- " include-tag";
+ " include-tag multi_ack_detailed";
struct object *o = parse_object(sha1);
if (!o)
--
1.6.5.2.181.gd6f41
^ permalink raw reply related
* [PATCH v5 08/28] fetch: Allow transport -v -v -v to set verbosity to 3
From: Shawn O. Pearce @ 2009-10-31 0:47 UTC (permalink / raw)
To: git; +Cc: Daniel Barkalow
In-Reply-To: <1256950067-27938-1-git-send-email-spearce@spearce.org>
Helpers might want a higher level of verbosity than just +1 (the
porcelain default setting) and +2 (-v -v). Expand the field to
allow verbosity in the range -1..3.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
CC: Daniel Barkalow <barkalow@iabervon.org>
---
builtin-fetch.c | 2 +-
transport.h | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/builtin-fetch.c b/builtin-fetch.c
index cb48c57..52a9a42 100644
--- a/builtin-fetch.c
+++ b/builtin-fetch.c
@@ -665,7 +665,7 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
transport = transport_get(remote, remote->url[0]);
if (verbosity >= 2)
- transport->verbose = 1;
+ transport->verbose = verbosity <= 3 ? verbosity : 3;
if (verbosity < 0)
transport->verbose = -1;
if (upload_pack)
diff --git a/transport.h b/transport.h
index c14da6f..e4e6177 100644
--- a/transport.h
+++ b/transport.h
@@ -25,7 +25,7 @@ struct transport {
int (*disconnect)(struct transport *connection);
char *pack_lockfile;
- signed verbose : 2;
+ signed verbose : 3;
/* Force progress even if the output is not a tty */
unsigned progress : 1;
};
--
1.6.5.2.181.gd6f41
^ permalink raw reply related
* [PATCH v5 05/28] Move "get_ack()" back to fetch-pack
From: Shawn O. Pearce @ 2009-10-31 0:47 UTC (permalink / raw)
To: git
In-Reply-To: <1256950067-27938-1-git-send-email-spearce@spearce.org>
In 41cb7488 Linus moved this function to connect.c for reuse inside
of the git-clone-pack command. That was 2005, but in 2006 Junio
retired git-clone-pack in commit efc7fa53. Since then the only
caller has been fetch-pack. Since this ACK/NAK exchange is only
used by the fetch-pack/upload-pack protocol we should move it back
to be a private detail of fetch-pack.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
---
builtin-fetch-pack.c | 21 +++++++++++++++++++++
cache.h | 1 -
connect.c | 21 ---------------------
3 files changed, 21 insertions(+), 22 deletions(-)
diff --git a/builtin-fetch-pack.c b/builtin-fetch-pack.c
index 783c2b0..7c09d46 100644
--- a/builtin-fetch-pack.c
+++ b/builtin-fetch-pack.c
@@ -157,6 +157,27 @@ static const unsigned char *get_rev(void)
return commit->object.sha1;
}
+static int get_ack(int fd, unsigned char *result_sha1)
+{
+ static char line[1000];
+ int len = packet_read_line(fd, line, sizeof(line));
+
+ if (!len)
+ die("git fetch-pack: expected ACK/NAK, got EOF");
+ if (line[len-1] == '\n')
+ line[--len] = 0;
+ if (!strcmp(line, "NAK"))
+ return 0;
+ if (!prefixcmp(line, "ACK ")) {
+ if (!get_sha1_hex(line+4, result_sha1)) {
+ if (strstr(line+45, "continue"))
+ return 2;
+ return 1;
+ }
+ }
+ die("git fetch_pack: expected ACK/NAK, got '%s'", line);
+}
+
static int find_common(int fd[2], unsigned char *result_sha1,
struct ref *refs)
{
diff --git a/cache.h b/cache.h
index a5eeead..4e283be 100644
--- a/cache.h
+++ b/cache.h
@@ -856,7 +856,6 @@ extern struct ref *find_ref_by_name(const struct ref *list, const char *name);
extern struct child_process *git_connect(int fd[2], const char *url, const char *prog, int flags);
extern int finish_connect(struct child_process *conn);
extern int path_match(const char *path, int nr, char **match);
-extern int get_ack(int fd, unsigned char *result_sha1);
struct extra_have_objects {
int nr, alloc;
unsigned char (*array)[20];
diff --git a/connect.c b/connect.c
index 7945e38..839a103 100644
--- a/connect.c
+++ b/connect.c
@@ -107,27 +107,6 @@ int server_supports(const char *feature)
strstr(server_capabilities, feature) != NULL;
}
-int get_ack(int fd, unsigned char *result_sha1)
-{
- static char line[1000];
- int len = packet_read_line(fd, line, sizeof(line));
-
- if (!len)
- die("git fetch-pack: expected ACK/NAK, got EOF");
- if (line[len-1] == '\n')
- line[--len] = 0;
- if (!strcmp(line, "NAK"))
- return 0;
- if (!prefixcmp(line, "ACK ")) {
- if (!get_sha1_hex(line+4, result_sha1)) {
- if (strstr(line+45, "continue"))
- return 2;
- return 1;
- }
- }
- die("git fetch_pack: expected ACK/NAK, got '%s'", line);
-}
-
int path_match(const char *path, int nr, char **match)
{
int i;
--
1.6.5.2.181.gd6f41
^ permalink raw reply related
* [PATCH v5 09/28] remote-helpers: Fetch more than one ref in a batch
From: Shawn O. Pearce @ 2009-10-31 0:47 UTC (permalink / raw)
To: git; +Cc: Daniel Barkalow
In-Reply-To: <1256950067-27938-1-git-send-email-spearce@spearce.org>
Some network protocols (e.g. native git://) are able to fetch more
than one ref at a time and reduce the overall transfer cost by
combining the requests into a single exchange. Instead of feeding
each fetch request one at a time to the helper, feed all of them
at once so the helper can decide whether or not it should batch them.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
CC: Daniel Barkalow <barkalow@iabervon.org>
---
Documentation/git-remote-helpers.txt | 14 ++++--
remote-curl.c | 88 +++++++++++++++++++++++++++++----
transport-helper.c | 39 +++++++++++----
3 files changed, 115 insertions(+), 26 deletions(-)
diff --git a/Documentation/git-remote-helpers.txt b/Documentation/git-remote-helpers.txt
index 173ee23..e44d821 100644
--- a/Documentation/git-remote-helpers.txt
+++ b/Documentation/git-remote-helpers.txt
@@ -36,10 +36,16 @@ Commands are given by the caller on the helper's standard input, one per line.
complete list, outputs a blank line.
'fetch' <sha1> <name>::
- Fetches the given object, writing the necessary objects to the
- database. Outputs a blank line when the fetch is
- complete. Only objects which were reported in the ref list
- with a sha1 may be fetched this way.
+ Fetches the given object, writing the necessary objects
+ to the database. Fetch commands are sent in a batch, one
+ per line, and the batch is terminated with a blank line.
+ Outputs a single blank line when all fetch commands in the
+ same batch are complete. Only objects which were reported
+ in the ref list with a sha1 may be fetched this way.
++
+Optionally may output a 'lock <file>' line indicating a file under
+GIT_DIR/objects/pack which is keeping a pack until refs can be
+suitably updated.
+
Supported if the helper has the "fetch" capability.
diff --git a/remote-curl.c b/remote-curl.c
index 478f3ea..22cd5c5 100644
--- a/remote-curl.c
+++ b/remote-curl.c
@@ -87,6 +87,81 @@ static struct ref *get_refs(void)
return refs;
}
+static int fetch_dumb(int nr_heads, struct ref **to_fetch)
+{
+ char **targets = xmalloc(nr_heads * sizeof(char*));
+ int ret, i;
+
+ for (i = 0; i < nr_heads; i++)
+ targets[i] = xstrdup(sha1_to_hex(to_fetch[i]->old_sha1));
+
+ init_walker();
+ walker->get_all = 1;
+ walker->get_tree = 1;
+ walker->get_history = 1;
+ walker->get_verbosely = 0;
+ walker->get_recover = 0;
+ ret = walker_fetch(walker, nr_heads, targets, NULL, NULL);
+
+ for (i = 0; i < nr_heads; i++)
+ free(targets[i]);
+ free(targets);
+
+ return ret ? error("Fetch failed.") : 0;
+}
+
+static void parse_fetch(struct strbuf *buf)
+{
+ struct ref **to_fetch = NULL;
+ struct ref *list_head = NULL;
+ struct ref **list = &list_head;
+ int alloc_heads = 0, nr_heads = 0;
+
+ do {
+ if (!prefixcmp(buf->buf, "fetch ")) {
+ char *p = buf->buf + strlen("fetch ");
+ char *name;
+ struct ref *ref;
+ unsigned char old_sha1[20];
+
+ if (strlen(p) < 40 || get_sha1_hex(p, old_sha1))
+ die("protocol error: expected sha/ref, got %s'", p);
+ if (p[40] == ' ')
+ name = p + 41;
+ else if (!p[40])
+ name = "";
+ else
+ die("protocol error: expected sha/ref, got %s'", p);
+
+ ref = alloc_ref(name);
+ hashcpy(ref->old_sha1, old_sha1);
+
+ *list = ref;
+ list = &ref->next;
+
+ ALLOC_GROW(to_fetch, nr_heads + 1, alloc_heads);
+ to_fetch[nr_heads++] = ref;
+ }
+ else
+ die("http transport does not support %s", buf->buf);
+
+ strbuf_reset(buf);
+ if (strbuf_getline(buf, stdin, '\n') == EOF)
+ return;
+ if (!*buf->buf)
+ break;
+ } while (1);
+
+ if (fetch_dumb(nr_heads, to_fetch))
+ exit(128); /* error already reported */
+ free_refs(list_head);
+ free(to_fetch);
+
+ printf("\n");
+ fflush(stdout);
+ strbuf_reset(buf);
+}
+
int main(int argc, const char **argv)
{
struct strbuf buf = STRBUF_INIT;
@@ -110,17 +185,8 @@ int main(int argc, const char **argv)
if (strbuf_getline(&buf, stdin, '\n') == EOF)
break;
if (!prefixcmp(buf.buf, "fetch ")) {
- char *obj = buf.buf + strlen("fetch ");
- init_walker();
- walker->get_all = 1;
- walker->get_tree = 1;
- walker->get_history = 1;
- walker->get_verbosely = 0;
- walker->get_recover = 0;
- if (walker_fetch(walker, 1, &obj, NULL, NULL))
- die("Fetch failed.");
- printf("\n");
- fflush(stdout);
+ parse_fetch(&buf);
+
} else if (!strcmp(buf.buf, "list")) {
struct ref *refs = get_refs();
struct ref *posn;
diff --git a/transport-helper.c b/transport-helper.c
index f57e84c..9de3408 100644
--- a/transport-helper.c
+++ b/transport-helper.c
@@ -10,6 +10,7 @@ struct helper_data
{
const char *name;
struct child_process *helper;
+ FILE *out;
unsigned fetch : 1;
};
@@ -18,7 +19,6 @@ static struct child_process *get_helper(struct transport *transport)
struct helper_data *data = transport->data;
struct strbuf buf = STRBUF_INIT;
struct child_process *helper;
- FILE *file;
if (data->helper)
return data->helper;
@@ -39,9 +39,9 @@ static struct child_process *get_helper(struct transport *transport)
write_str_in_full(helper->in, "capabilities\n");
- file = xfdopen(helper->out, "r");
+ data->out = xfdopen(helper->out, "r");
while (1) {
- if (strbuf_getline(&buf, file, '\n') == EOF)
+ if (strbuf_getline(&buf, data->out, '\n') == EOF)
exit(128); /* child died, message supplied already */
if (!*buf.buf)
@@ -58,6 +58,7 @@ static int disconnect_helper(struct transport *transport)
if (data->helper) {
write_str_in_full(data->helper->in, "\n");
close(data->helper->in);
+ fclose(data->out);
finish_command(data->helper);
free((char *)data->helper->argv[0]);
free(data->helper->argv);
@@ -70,8 +71,7 @@ static int disconnect_helper(struct transport *transport)
static int fetch_with_fetch(struct transport *transport,
int nr_heads, const struct ref **to_fetch)
{
- struct child_process *helper = get_helper(transport);
- FILE *file = xfdopen(helper->out, "r");
+ struct helper_data *data = transport->data;
int i;
struct strbuf buf = STRBUF_INIT;
@@ -82,12 +82,30 @@ static int fetch_with_fetch(struct transport *transport,
strbuf_addf(&buf, "fetch %s %s\n",
sha1_to_hex(posn->old_sha1), posn->name);
- write_in_full(helper->in, buf.buf, buf.len);
- strbuf_reset(&buf);
+ }
- if (strbuf_getline(&buf, file, '\n') == EOF)
+ strbuf_addch(&buf, '\n');
+ if (write_in_full(data->helper->in, buf.buf, buf.len) != buf.len)
+ die_errno("cannot send fetch to %s", data->name);
+
+ while (1) {
+ strbuf_reset(&buf);
+ if (strbuf_getline(&buf, data->out, '\n') == EOF)
exit(128); /* child died, message supplied already */
+
+ if (!prefixcmp(buf.buf, "lock ")) {
+ const char *name = buf.buf + 5;
+ if (transport->pack_lockfile)
+ warning("%s also locked %s", data->name, name);
+ else
+ transport->pack_lockfile = xstrdup(name);
+ }
+ else if (!buf.len)
+ break;
+ else
+ warning("%s unexpectedly said: '%s'", data->name, buf.buf);
}
+ strbuf_release(&buf);
return 0;
}
@@ -113,21 +131,20 @@ static int fetch(struct transport *transport,
static struct ref *get_refs_list(struct transport *transport, int for_push)
{
+ struct helper_data *data = transport->data;
struct child_process *helper;
struct ref *ret = NULL;
struct ref **tail = &ret;
struct ref *posn;
struct strbuf buf = STRBUF_INIT;
- FILE *file;
helper = get_helper(transport);
write_str_in_full(helper->in, "list\n");
- file = xfdopen(helper->out, "r");
while (1) {
char *eov, *eon;
- if (strbuf_getline(&buf, file, '\n') == EOF)
+ if (strbuf_getline(&buf, data->out, '\n') == EOF)
exit(128); /* child died, message supplied already */
if (!*buf.buf)
--
1.6.5.2.181.gd6f41
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox