* Re: [RFC] adding support for md5
From: Junio C Hamano @ 2006-08-24 10:34 UTC (permalink / raw)
To: Shawn Pearce; +Cc: git
In-Reply-To: <20060824080807.GG25247@spearce.org>
Shawn Pearce <spearce@spearce.org> writes:
>> Except some minor nits, yes.
>>
>> * I would have preferred two patches, one for "master" and one
>> for the C merge-recursive topic (or at least "next").
>
> Doh. I didn't realize this was something you were interested in
> pulling into master.
Applying them directly to "master" does not have much to do with
this.
Of course, if something is obviously the right thing to do, then
I often apply them straight to "master" (or apply them to
"maint" and pull the result into "master"). In other cases, I
prefer to fork off a new series from the tip of the "master"
into a new topic branch. Then merge that into either "pu" (if I
have suspicion that it is not ready for even testing yet) or
"next", and cook there for a while until it is ready.
While being cooked in "next", what happens is that changes to
that specific topic are applied to the tip of the topic branch,
and then pulled into "next", over and over. Many topic branches
are cooked simultaneously that way. So the development history
of "next" is, eh, messy.
I usually test "next", in other words, multiple topics cooking
together. But when some changes are applied to "master" that
might interfere with an older but still not in "master", I pull
"master" into the topic and test that topic alone in isolation.
That way, when a topic matures, we can be reasonably sure that
it can be pulled into "master" without breaking things.
A single patch on top of "next" depends on all existing topics
that may or may not turn out to be useful. That makes such a
patch less useful than otherwise be.
So if a series affects things in "master" and some other things
still not in "master", a preferred way, from my workflow point
of view, is to have at least two patches: one for "master" and
another for the rest. Then what I would do is to fork one topic
off from "master" and apply the former, pull that into "next"
and cook that. That part of the topic can graduate to "master"
without waiting for other topics in "next".
What happens to the rest is a bit more involved. In the case of
the hashcpy() patch, one thing that only exists in "next" was
merge-recursive.c, but the story would be the same if "next" had
more places that used memcpy(a, b, 20) than "master" in a file
that are common in two branches. Ideally, the remainder will be
broken into pieces and applied as a fixup on top of existing
topics (in this case, C merge-recursive topic) and then merged
into "next". This can be either done by applying the remainder
directly on top of the affected topic, or forking a subtopic off
of the affected topic (the latter is useful if the new series
might turn out to be dud -- the original topic will not be
contaminated by bad changes and can graduate to "master" more
easily).
In any case, I've done a split myself and the parts that can be
applied to "master" is now sitting in gl/cleanup topic and the
remainder is sitting in gl/cleanup-next topic which was forked
off from C merge-recursive topic (you can tell where their tips
are by looking at "gitk next" output) and both are merged into
"next".
^ permalink raw reply
* Re : git-send-email: threaded view issue with Thunderbird
From: moreau francis @ 2006-08-24 9:13 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <7v64gibjox.fsf@assigned-by-dhcp.cox.net>
Junio C Hamano wrote:
> moreau francis <francis_moreau2000@yahoo.fr> writes:
>
>> Hi,
>>
>> Sometimes, actually most of the time, git-send-email _seems_ to not
>> work properly with Thunderbird: for example if I send a patchset made
>> up by 4 single patchs, then Thunderbird show me this patchset 'broken'
>> that is [PATCH 2/4] is not shown as a reply to [PATCH 1/4].
>> ...
>> The strange thing is that all email headers are correct.
>
> Then this is a wrong list perhaps ;-).
>
yeah, that's why I wrote "git-send-email _seems_ to not work properly
with Thunderbird". I actually think it's a Thunderbird issue, I'll
contact them hoping they won't tell me it's a git issue ;)
thanks
Francis
^ permalink raw reply
* Re: git-send-email: threaded view issue with Thunderbird
From: Junio C Hamano @ 2006-08-24 8:52 UTC (permalink / raw)
To: Pierre Habouzit; +Cc: git
In-Reply-To: <200608241043.02731.madcoder@debian.org>
Pierre Habouzit <madcoder@debian.org> writes:
> if it's not too crude, I will consider submit it to the list as a
> possible replacement/competitor for git-send-email.
Please not a revolution but an evolution if possible...
^ permalink raw reply
* Re : git-send-email: threaded view issue with Thunderbird
From: moreau francis @ 2006-08-24 8:52 UTC (permalink / raw)
To: Pierre Habouzit; +Cc: git
In-Reply-To: <200608241043.02731.madcoder@debian.org>
bonjour,
Pierre Habouzit wrote:
> Le jeu 24 août 2006 10:12, moreau francis a écrit :
>> Hi,
>>
>> Sometimes, actually most of the time, git-send-email _seems_ to not
>> work properly with Thunderbird: for example if I send a patchset made
>> up by 4 single patchs, then Thunderbird show me this patchset
>> 'broken' that is [PATCH 2/4] is not shown as a reply to [PATCH 1/4].
>>
>> For example I can see:
>>
>> […]
>>
>> [PATCH 0/7] C cleanup series, mostly nasty shadowing
>>
>> Does anybody have an idea on what's going wrong ?
>
> here the problem is that I manually sent the 0/7 as the initial mail,
> and passed its msg-id into --in-reply-to switch of git-send-email. but
> I did not specified the brackets, and those were not added, meaning
> that the reference was bad formatted.
>
well the problem occur with your [PATCH 2/7] and [PATCH 3/7] too. I don't
think you manually setup the headers for these patches, do you ?
> I don't know where your other problems come from. What I know for sure
> is that I will write my own git-send-email version, with less perl, and
that would be great since I don't speak perl.
Francis
^ permalink raw reply
* Re: git-send-email: threaded view issue with Thunderbird
From: Junio C Hamano @ 2006-08-24 8:51 UTC (permalink / raw)
To: moreau francis; +Cc: git
In-Reply-To: <20060824081228.69110.qmail@web25808.mail.ukl.yahoo.com>
moreau francis <francis_moreau2000@yahoo.fr> writes:
> Hi,
>
> Sometimes, actually most of the time, git-send-email _seems_ to not
> work properly with Thunderbird: for example if I send a patchset made
> up by 4 single patchs, then Thunderbird show me this patchset 'broken'
> that is [PATCH 2/4] is not shown as a reply to [PATCH 1/4].
> ...
> The strange thing is that all email headers are correct.
Then this is a wrong list perhaps ;-).
> I recently notice that someone has sent a patchset using
> git-send-email and I can see it 'broken' as well. The subject of the
> first email of the set is
>
> [PATCH 0/7] C cleanup series, mostly nasty shadowing
>
> Does anybody have an idea on what's going wrong ?
I see that 7+1 series as "broken"; #1 is not a reply to #0.
All others are reply to the previous one which is fine:
Subject: [PATCH 0/7] C cleanup series, mostly nasty shadowing
Message-ID: <200608231238.10963.madcoder@debian.org>
Subject: [PATCH 1/7] avoid to use error that shadows the funct
Message-ID: <11563295562072-git-send-email-madcoder@debian.org>
In-Reply-To: 200608231238.10963.madcoder@debian.org
Subject: [PATCH 2/7] git_dir holds pointers to local strings,
Message-ID: <11563295562422-git-send-email-madcoder@debian.org>
In-Reply-To: <11563295562072-git-send-email-madcoder@debian.org>
Subject: [PATCH 3/7] missing 'static' keywords
Message-ID: <1156329556788-git-send-email-madcoder@debian.org>
In-Reply-To: <11563295562422-git-send-email-madcoder@debian.org>
Subject: [PATCH 4/7] remove ugly shadowing of loop indexes in s
Message-ID: <11563295573215-git-send-email-madcoder@debian.org>
In-Reply-To: <1156329556788-git-send-email-madcoder@debian.org>
Subject: [PATCH 5/7] missing #define DEBUG 0 that made the prep
Message-ID: <11563295573035-git-send-email-madcoder@debian.org>
In-Reply-To: <11563295573215-git-send-email-madcoder@debian.org>
Subject: [PATCH 6/7] use name[len] in switch directly,
Message-ID: <1156329557424-git-send-email-madcoder@debian.org>
In-Reply-To: <11563295573035-git-send-email-madcoder@debian.org>
Subject: [PATCH 7/7] n is in fact unused, and is later shadowed.
Message-ID: <1156329557613-git-send-email-madcoder@debian.org>
In-Reply-To: <1156329557424-git-send-email-madcoder@debian.org>
Because #1 has a bogus In-Reply-To field, #0 and #1 would be
shown at the same level, but #2-7 would be staggered below #1.
^ permalink raw reply
* Re: git-send-email: threaded view issue with Thunderbird
From: Pierre Habouzit @ 2006-08-24 8:42 UTC (permalink / raw)
To: moreau francis; +Cc: git
In-Reply-To: <20060824081228.69110.qmail@web25808.mail.ukl.yahoo.com>
[-- Attachment #1: Type: text/plain, Size: 1353 bytes --]
Le jeu 24 août 2006 10:12, moreau francis a écrit :
> Hi,
>
> Sometimes, actually most of the time, git-send-email _seems_ to not
> work properly with Thunderbird: for example if I send a patchset made
> up by 4 single patchs, then Thunderbird show me this patchset
> 'broken' that is [PATCH 2/4] is not shown as a reply to [PATCH 1/4].
>
> For example I can see:
>
> […]
>
> [PATCH 0/7] C cleanup series, mostly nasty shadowing
>
> Does anybody have an idea on what's going wrong ?
here the problem is that I manually sent the 0/7 as the initial mail,
and passed its msg-id into --in-reply-to switch of git-send-email. but
I did not specified the brackets, and those were not added, meaning
that the reference was bad formatted.
I don't know where your other problems come from. What I know for sure
is that I will write my own git-send-email version, with less perl, and
less broken features, because the two first try I had with
git-send-email were quite inconclusive, doing all *but* what I wanted
them to do.
if it's not too crude, I will consider submit it to the list as a
possible replacement/competitor for git-send-email.
--
·O· Pierre Habouzit
··O madcoder@debian.org
OOO http://www.madism.org
[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply
* git-send-email: threaded view issue with Thunderbird
From: moreau francis @ 2006-08-24 8:12 UTC (permalink / raw)
To: git
Hi,
Sometimes, actually most of the time, git-send-email _seems_ to not
work properly with Thunderbird: for example if I send a patchset made
up by 4 single patchs, then Thunderbird show me this patchset 'broken'
that is [PATCH 2/4] is not shown as a reply to [PATCH 1/4].
For example I can see:
[PATCH 0/4]
[PATCH 1/4]
[PATCH 2/4]
[PATCH 3/4]
[PATCH 4/4]
instead of
[PATCH 0/4]
[PATCH 1/4]
[PATCH 2/4]
[PATCH 3/4]
[PATCH 4/4]
The strange thing is that all email headers are correct.
I recently notice that someone has sent a patchset using
git-send-email and I can see it 'broken' as well. The subject of the
first email of the set is
[PATCH 0/7] C cleanup series, mostly nasty shadowing
Does anybody have an idea on what's going wrong ?
thanks,
Francis
^ permalink raw reply
* Re: [RFC] adding support for md5
From: Shawn Pearce @ 2006-08-24 8:08 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <7vac5ubn57.fsf@assigned-by-dhcp.cox.net>
Junio C Hamano <junkio@cox.net> wrote:
> Shawn Pearce <spearce@spearce.org> writes:
>
> >> > What about all of those memcpy(a, b, 20)'s? :-)
> >>
> >> Surely. If you are inclined to, go wild.
> >
> > Like this? :-)
>
> Except some minor nits, yes.
>
> * I would have preferred two patches, one for "master" and one
> for the C merge-recursive topic (or at least "next").
Doh. I didn't realize this was something you were interested in
pulling into master. Otherwise I would have done this. Next time
I'll try to keep that in mind.
> * You missed a few in "master".
Not surprising since I typically work against and use next.
> * The cast in the second hunk in combine-diff.c was wrong;
> breakage was caught by our testsuite.
OK, that's just flat out stupid of me. I apologize for making you
fix my mistakes. :-)
> I've pushed out a fixed up result in "master" and "next".
Thanks.
--
Shawn.
^ permalink raw reply
* Re: [PATCH] git-daemon: more powerful base-path/user-path settings, using formats.
From: Pierre Habouzit @ 2006-08-24 7:50 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <7vbqqbgf79.fsf@assigned-by-dhcp.cox.net>
[-- Attachment #1: Type: text/plain, Size: 1756 bytes --]
Le jeu 24 août 2006 02:17, Junio C Hamano a écrit :
> Pierre Habouzit <madcoder@debian.org> writes:
> > Allow a form of virtualhosting, when %h format is used.
> >
> > Signed-off-by: Pierre Habouzit <madcoder@debian.org>
> > ---
> >
> > This is intended to be a more flexible solution, that also
> > gives virtual hosting as a bonus. I still see no way to deal with
> > older clients when virtual hosting is used by the admin though,
> > having a "default" hostname won't solve anything at all anyway.
>
> I mildly disagree about the last sentence. Enabling virtual
> hosting does not have to mean all virtual hosts are treated
> equal. It is conceivable that a site hosts the primary,
> "collection of public repositories everybody would want to go
> to" set, with supplemental ones for specific audiences that are
> done via virtual hosting. General public who would want to
> access the primary one can come with older clients that way, and
> only the narrower audiences have to be told to upgrade.
hmm, yes, that's indeed fair. Well, adding a --default-hostname that is
used if no host= is passed is completely obvious and straightforward
and solves that issue.
I also spotted a bug in the git_path_fmt function, I test 'pos' at the
end of the loop, but the overflow test is not done when there is no
format involved, wich could /theorically/ lead to buffer overflow. So
please disregard that issue, I will at least provide a patch that fixes
that.
> Haven't looked at the rest of the patch yet. Will comment
> later.
np, TIA
--
·O· Pierre Habouzit
··O madcoder@debian.org
OOO http://www.madism.org
[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply
* Re: [RFC] adding support for md5
From: Junio C Hamano @ 2006-08-24 7:36 UTC (permalink / raw)
To: Shawn Pearce; +Cc: git
In-Reply-To: <20060823064900.GA26340@spearce.org>
Shawn Pearce <spearce@spearce.org> writes:
>> > What about all of those memcpy(a, b, 20)'s? :-)
>>
>> Surely. If you are inclined to, go wild.
>
> Like this? :-)
Except some minor nits, yes.
* I would have preferred two patches, one for "master" and one
for the C merge-recursive topic (or at least "next").
* You missed a few in "master".
* The cast in the second hunk in combine-diff.c was wrong;
breakage was caught by our testsuite.
I've pushed out a fixed up result in "master" and "next".
^ permalink raw reply
* Re: git cherry-pick feature request
From: Junio C Hamano @ 2006-08-24 7:36 UTC (permalink / raw)
To: Paul Mackerras; +Cc: git
In-Reply-To: <17644.21269.128308.313284@cargo.ozlabs.ibm.com>
Paul Mackerras <paulus@samba.org> writes:
> While I'm asking for features, another one that would be really useful
> for another tool I'm writing is a 3-way diff for a file between the
> working directory, the index, and the current head commit, something
> like what git diff-tree -c does for merges. That is, it would have
> two columns of +/-/space characters, one for the current head and one
> for the index. A '-' would indicate that the line appears in the
> current head or the index but not in the version of the file in the
> working directory. A '+' would indicate that the line appears in the
> working directory version.
The combined diff (-c and --cc) comparison works by comparing a
single post-image (merge result) with multiple pre-images, so I
think it is reasonable to compare the working tree files as the
post-image and cached and HEAD-tree versions as the preimages.
I am not sure how useful this would be though -- I am guessing
that in most people's workflow the index and the HEAD would
exactly match most of the time, since that is the way Linus
encourages (and I follow that myself). So for that extreme use
case, the difference between "diff-index HEAD" and the proposed
command (I am thinking about calling it git-diff-status) would
be that the latter always has two plus or minus signs instead of
one, and lines with a single plus or minus would be an
indication that HEAD and index have drifted. In other words,
the largest benefit of "combined diff" which is to simplify
trivial "The result took this one not that one wholesale"
differences would not be felt.
I have to visualize the result a bit before coding this.
^ permalink raw reply
* Re: git cherry-pick feature request
From: Junio C Hamano @ 2006-08-24 7:29 UTC (permalink / raw)
To: Jeff King; +Cc: Paul Mackerras, git
In-Reply-To: <20060823143551.GA4592@sigio.intra.peff.net>
Jeff King <peff@peff.net> writes:
> On Wed, Aug 23, 2006 at 11:07:33PM +1000, Paul Mackerras wrote:
>
>> While I'm asking for features, another one that would be really useful
>> for another tool I'm writing is a 3-way diff for a file between the
>> working directory, the index, and the current head commit, something
>> like what git diff-tree -c does for merges. That is, it would have
>
> Theoretically I'm working on this, but I haven't really had time to get
> started on it yet this week. If you have patience, I'll get to it. If
> not, then somebody else is welcome to take a crack at it.
It is not entirely related, but I've restarted looking into a
parallel tree walker again and will push something in "pu"
tonight.
It will probably be quite a while until it becomes useful,
though. I suspect your approach of internally running
run_diff_files() and run_diff_index() and consolidating the
result, while it might feel hackish, would be easier at least in
the short term.
^ permalink raw reply
* [PATCH] Refactoring tracing code in "git.c" and "exec_cmd.c".
From: Christian Couder @ 2006-08-24 5:45 UTC (permalink / raw)
To: Junio Hamano; +Cc: git
Some new helper functions in "quote.c" are used for this.
The goal is also to get near the point where we can use
one write(2) call to trace in any open file descriptor.
This is why we put the trace string into one buffer.
Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
---
exec_cmd.c | 10 ++------
git.c | 20 ++++-----------
quote.c | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
quote.h | 3 ++
4 files changed, 88 insertions(+), 23 deletions(-)
diff --git a/exec_cmd.c b/exec_cmd.c
index e30936d..5688e0b 100644
--- a/exec_cmd.c
+++ b/exec_cmd.c
@@ -98,14 +98,8 @@ int execv_git_cmd(const char **argv)
argv[0] = git_command;
if (getenv("GIT_TRACE")) {
- const char **p = argv;
- fputs("trace: exec:", stderr);
- while (*p) {
- fputc(' ', stderr);
- sq_quote_print(stderr, *p);
- ++p;
- }
- putc('\n', stderr);
+ sq_quote_argv_printf(stderr, argv, -1,
+ "trace: exec: ARGV\n");
fflush(stderr);
}
diff --git a/git.c b/git.c
index 930998b..d13b841 100644
--- a/git.c
+++ b/git.c
@@ -180,14 +180,9 @@ static int handle_alias(int *argcp, cons
die("recursive alias: %s", alias_command);
if (getenv("GIT_TRACE")) {
- int i;
- fprintf(stderr, "trace: alias expansion: %s =>",
- alias_command);
- for (i = 0; i < count; ++i) {
- fputc(' ', stderr);
- sq_quote_print(stderr, new_argv[i]);
- }
- fputc('\n', stderr);
+ sq_quote_argv_printf(stderr, new_argv, count,
+ "trace: alias expansion: %s => ARGV\n",
+ alias_command);
fflush(stderr);
}
@@ -292,13 +287,8 @@ static void handle_internal_command(int
if (p->option & USE_PAGER)
setup_pager();
if (getenv("GIT_TRACE")) {
- int i;
- fprintf(stderr, "trace: built-in: git");
- for (i = 0; i < argc; ++i) {
- fputc(' ', stderr);
- sq_quote_print(stderr, argv[i]);
- }
- putc('\n', stderr);
+ sq_quote_argv_printf(stderr, argv, argc,
+ "trace: built-in: git ARGV\n");
fflush(stderr);
}
diff --git a/quote.c b/quote.c
index e220dcc..84d0b7b 100644
--- a/quote.c
+++ b/quote.c
@@ -74,6 +74,84 @@ char *sq_quote(const char *src)
return buf;
}
+char *sq_quote_argv(const char** argv, int count)
+{
+ char *buf, *to;
+ int i;
+ size_t len;
+
+ /* Count argv if needed. */
+ if (count < 0) {
+ char **p = (char **)argv;
+ count = 0;
+ while (*p++) count++;
+ }
+
+ /* Get destination buffer length. */
+ len = count ? count : 1;
+ for (i = 0; i < count; ++i)
+ len += sq_quote_buf(NULL, 0, argv[i]);
+
+ /* Alloc destination buffer. */
+ to = buf = xmalloc(len);
+
+ /* Copy into destination buffer. */
+ for (i = 0; i < count; ++i) {
+ if (i) *to++ = ' ';
+ to += sq_quote_buf(to, len, argv[i]);
+ }
+
+ if (!count)
+ *buf = 0;
+
+ return buf;
+}
+
+/* Return a newly allocated copy of "format" where the
+ * first occurence of "old" has been replaced by "new". */
+static char *str_subst(const char *format, const char *old, const char *new)
+{
+ /* Get destination buffer length. */
+ size_t fmt_len = strlen(format);
+ size_t old_len = strlen(old);
+ size_t new_len = strlen(new);
+ size_t len = fmt_len - old_len + new_len + 1;
+
+ /* Get the first occurence of old. */
+ char *pos = strstr(format, old);
+ if (!pos)
+ return strcpy(xmalloc(fmt_len + 1), format);
+ size_t start_len = pos - format;
+
+ /* Alloc destination buffer. */
+ char *result = xmalloc(len);
+
+ /* Copy into destination buffer. */
+ strncpy(result, format, start_len);
+ strncpy(result + start_len, new, new_len);
+ strcpy(result + start_len + new_len,
+ format + start_len + old_len);
+
+ return result;
+}
+
+void sq_quote_argv_printf(FILE* out, const char **argv, int count,
+ const char *format, ...)
+{
+ /* Replace the string "ARGV" in format with the quoted arg values. */
+ char *argv_str = sq_quote_argv(argv, count);
+ char *new_format = str_subst(format, "ARGV", argv_str);
+
+ /* Print into "out" using the new format. */
+ va_list rest;
+ va_start(rest, format);
+ vfprintf(out, new_format, rest);
+ va_end(rest);
+
+ free(new_format);
+ free(argv_str);
+}
+
char *sq_dequote(char *arg)
{
char *dst = arg;
diff --git a/quote.h b/quote.h
index fc5481e..2bbf196 100644
--- a/quote.h
+++ b/quote.h
@@ -31,6 +31,9 @@ #include <stdio.h>
extern char *sq_quote(const char *src);
extern void sq_quote_print(FILE *stream, const char *src);
extern size_t sq_quote_buf(char *dst, size_t n, const char *src);
+extern char *sq_quote_argv(const char** argv, int count);
+extern void sq_quote_argv_printf(FILE* out, const char **argv, int count,
+ const char *format, ...);
/* This unwraps what sq_quote() produces in place, but returns
* NULL if the input does not look like what sq_quote would have
--
1.4.2.gc35c-dirty
^ permalink raw reply related
* Re: [PATCH 3] gitweb: Show information about incomplete lines in commitdiff
From: Junio C Hamano @ 2006-08-24 2:21 UTC (permalink / raw)
To: Jakub Narebski; +Cc: git
In-Reply-To: <200608240158.49908.jnareb@gmail.com>
Jakub Narebski <jnareb@gmail.com> writes:
> In format_diff_line, instead of skipping errors/incomplete lines,
> for example
> "\ No newline at end of file"
> in HTML pretty-printing of diff, use "incomplete" class for div.
>
> Signed-off-by: Jakub Narebski <jnareb@gmail.com>
I think this makes sense, while I do not see much point in
removal of git_commitdiff_plain.
^ permalink raw reply
* Re: [PATCH/RFC 1/x] gitweb: Use git-diff-tree patch output for commitdiff
From: Junio C Hamano @ 2006-08-24 2:15 UTC (permalink / raw)
To: Jakub Narebski; +Cc: git
In-Reply-To: <200608240015.15071.jnareb@gmail.com>
Jakub Narebski <jnareb@gmail.com> writes:
> Converting "blobdiff" and "blobdiff_plain" format would be much easier
> if git-diff-tree and friends had -L <label>/--label=<label> option,
> like GNU diff has.
I am not sure how that would be useful, given that you would
disect the header line-by-line to colorize anyway.
> Current patch preserves much of current output; the question is if for
> example generate if 'plain' format should generate patch which could
> be appplied by ordinary patch which do not understand git diff
> extensions (including renaming and copying), as it is done in current
> version, and if 'html' version should detect renames and copying.
I would say html is definitely for human consumption; does
anybody cut&paste html patch and expect to apply that? Plain
format I am easy but probably enabling rename is fine. You can
edit the header or tell patch to apply to which file anyway, and
I think the value of being able to view the real changes outweigh
that inconvenience.
> * "commitdiff" now products patches with renaming and copying
> detection (git-diff-tree is invoked with -M and -C options).
You do not have to give -M and -C; a single -C is enough.
I wonder if -B is also useful as a default (i.e. -B -C).
For a merge, I often would want to see --cc just like gitk does,
but it is probably just me.
I do not know we would want to slurp the entier diff in an
array before processing. Is this easy to streamify by passing
an pipe fd to the formatting sub?
> Empty patches (mode changes and pure renames and copying)
> are not written currently.
That's quite bad.
> * "commitdiff" output is now divided into several div elements
> of class "log", "patchset" and "patch".
>
> * "commitdiff_plain" now only generates X-Git-Tag: line only if there
> is tag pointing to the current commit.
Hmph...
> ...; besides we are
> interested rather in tags _preceding_ the commit, and _heads_
> following the commit.
Interesting observation. When somebody says "feature X was
introduced in such and such commit", people would want to know (1) the
point release they are using has the feature -- which means you
would want to know the earliest tag that comes after the commit,
or (2) if the branch they are working on already has that
feature -- which again means if the head follows the commit. So
I am not sure when preceding tag is interesting...
^ permalink raw reply
* Re: use case
From: Blu @ 2006-08-24 0:37 UTC (permalink / raw)
To: git
In-Reply-To: <Pine.LNX.4.63.0608212231430.28360@wbgn013.biozentrum.uni-wuerzburg.de>
On Mon, Aug 21, 2006 at 10:47:47PM +0200, Johannes Schindelin wrote:
> Ideally, you really would have a common revision to start from. Since you
> do not have that yet, you have to go low-level for the first octopus.
>
> Suppose you have the last common version as tip of branch "ancestor", you
> could do
>
> git merge-octopus ancestor -- HEAD branch1 branch2 ...
This one didn't work. It complains about not having common ancestors too.
I did a manual merge anyway.
> After this -- if everything went well -- you should have a committable
> state in the index. Before you commit, you should do
>
> git rev-parse branch1 > .git/MERGE_HEAD
> git rev-parse branch2 >> .git/MERGE_HEAD
> git rev-parse branch3 >> .git/MERGE_HEAD
> ...
>
> to tell git that you want to commit an octopus merge. This will tell
> git-commit what the parents of the merge are.
This trick did it. Now I have a proper merge commit with common ancestors.
Thanks a lot.
--
Blu.
^ permalink raw reply
* Re: [PATCH] git-daemon: more powerful base-path/user-path settings, using formats.
From: Junio C Hamano @ 2006-08-24 0:17 UTC (permalink / raw)
To: Pierre Habouzit; +Cc: git
In-Reply-To: <115637597423-git-send-email-madcoder@debian.org>
Pierre Habouzit <madcoder@debian.org> writes:
> Allow a form of virtualhosting, when %h format is used.
>
> Signed-off-by: Pierre Habouzit <madcoder@debian.org>
> ---
>
> This is intended to be a more flexible solution, that also gives virtual
> hosting as a bonus. I still see no way to deal with older clients when
> virtual hosting is used by the admin though, having a "default" hostname
> won't solve anything at all anyway.
I mildly disagree about the last sentence. Enabling virtual
hosting does not have to mean all virtual hosts are treated
equal. It is conceivable that a site hosts the primary,
"collection of public repositories everybody would want to go
to" set, with supplemental ones for specific audiences that are
done via virtual hosting. General public who would want to
access the primary one can come with older clients that way, and
only the narrower audiences have to be told to upgrade.
The client-side host= support was done post 1.4.0-rc1 timeframe
so we have to be nicer to 1.3 based people, at least give them a
way to slurp newer version with their client ;-).
Haven't looked at the rest of the patch yet. Will comment
later.
^ permalink raw reply
* [PATCH 3] gitweb: Show information about incomplete lines in commitdiff
From: Jakub Narebski @ 2006-08-23 23:58 UTC (permalink / raw)
To: git
In-Reply-To: <200608240015.15071.jnareb@gmail.com>
In format_diff_line, instead of skipping errors/incomplete lines,
for example
"\ No newline at end of file"
in HTML pretty-printing of diff, use "incomplete" class for div.
Signed-off-by: Jakub Narebski <jnareb@gmail.com>
---
gitweb/gitweb.css | 4 ++++
gitweb/gitweb.perl | 2 +-
2 files changed, 5 insertions(+), 1 deletions(-)
diff --git a/gitweb/gitweb.css b/gitweb/gitweb.css
index 4821022..5eaa24f 100644
--- a/gitweb/gitweb.css
+++ b/gitweb/gitweb.css
@@ -285,6 +285,10 @@ div.diff.chunk_header {
color: #990099;
}
+div.diff.incomplete {
+ color: #cccccc;
+}
+
div.diff_info {
font-family: monospace;
color: #000099;
diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index c238824..42b8f93 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -539,7 +539,7 @@ sub format_diff_line {
$diff_class = " chunk_header";
} elsif ($char eq "\\") {
# skip errors (incomplete lines)
- return "";
+ $diff_class = " incomplete";
}
$line = untabify($line);
return "<div class=\"diff$diff_class\">" . esc_html($line) . "</div>\n";
--
1.4.1.1
^ permalink raw reply related
* [PATCH 2] gitweb: Replace git_commitdiff_plain by anonymous subroutine
From: Jakub Narebski @ 2006-08-23 23:58 UTC (permalink / raw)
To: git
In-Reply-To: <200608240015.15071.jnareb@gmail.com>
Signed-off-by: Jakub Narebski <jnareb@gmail.com>
---
gitweb/gitweb.perl | 6 +-----
1 files changed, 1 insertions(+), 5 deletions(-)
diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index 9367685..c238824 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -234,7 +234,7 @@ my %actions = (
"blob" => \&git_blob,
"blob_plain" => \&git_blob_plain,
"commitdiff" => \&git_commitdiff,
- "commitdiff_plain" => \&git_commitdiff_plain,
+ "commitdiff_plain" => sub { git_commitdiff('plain'); },
"commit" => \&git_commit,
"heads" => \&git_heads,
"history" => \&git_history,
@@ -2820,10 +2820,6 @@ TEXT
}
}
-sub git_commitdiff_plain {
- git_commitdiff('plain');
-}
-
sub git_history {
if (!defined $hash_base) {
$hash_base = git_get_head_hash($project);
--
1.4.1.1
^ permalink raw reply related
* [PATCH] git-daemon: more powerful base-path/user-path settings, using formats.
From: Pierre Habouzit @ 2006-08-23 23:32 UTC (permalink / raw)
To: git
In-Reply-To: <7vmz9vgqlm.fsf@assigned-by-dhcp.cox.net>
Allow a form of virtualhosting, when %h format is used.
Signed-off-by: Pierre Habouzit <madcoder@debian.org>
---
This is intended to be a more flexible solution, that also gives virtual
hosting as a bonus. I still see no way to deal with older clients when
virtual hosting is used by the admin though, having a "default" hostname
won't solve anything at all anyway.
Documentation/git-daemon.txt | 42 ++++++++++
daemon.c | 170 +++++++++++++++++++++++++++++++++++++++---
2 files changed, 201 insertions(+), 11 deletions(-)
diff --git a/Documentation/git-daemon.txt b/Documentation/git-daemon.txt
index 0f7d274..0aa34d4 100644
--- a/Documentation/git-daemon.txt
+++ b/Documentation/git-daemon.txt
@@ -11,6 +11,7 @@ SYNOPSIS
'git-daemon' [--verbose] [--syslog] [--inetd | --port=n] [--export-all]
[--timeout=n] [--init-timeout=n] [--strict-paths]
[--base-path=path] [--user-path | --user-path=path]
+ [--base-path-fmt=pathfmt] [--user-path-fmt=pathfmt]
[--reuseaddr] [--detach] [--pid-file=file] [directory...]
DESCRIPTION
@@ -45,6 +46,10 @@ OPTIONS
'git://example.com/hello.git', `git-daemon` will interpret the path
as '/srv/git/hello.git'.
+--base-path-fmt=pathfmt::
+ Works like --base-path, but uses a format instead. See Path
+ Formats section below.
+
--export-all::
Allow pulling from all directories that look like GIT repositories
(have the 'objects' and 'refs' subdirectories), even if they
@@ -79,6 +84,11 @@ OPTIONS
taken as a request to access `path/foo` repository in
the home directory of user `alice`.
+--user-path-fmt=pathfmt::
+ Allow ~user notation to be used in requests. The path used to look
+ for the git repository is a format string, see Path Formats
+ section below.
+
--verbose::
Log details about the incoming connections and requested files.
@@ -98,6 +108,38 @@ OPTIONS
--strict-paths is specified this will also include subdirectories
of each named directory.
+Path Formats
+------------
+
+%h::
+ requested hostname (won't work with clients older than 1.4.0).
+
+%p::
+ requested path.
+
+%P::
+ requested path without the first slash when exists (`/`).
+
+%u::
+ requested username (only allowed for --user-path-fmt).
+
+%%::
+ plain '%'
+
+Examples
+~~~~~~~~
+
+* `--base-path-fmt=/srv/git/%P` emulates `--base-path=/srv/git`
+
+* `--base-path-fmt=/srv/git/%h%p` will look into
+ `/srv/git/git.example.com/foo` if the request goes to
+ git://git.example.com/foo
+
+* `--user-path-fmt=/home/%u/public_git/%P` works mostly like
+ `--user-path=public_git` (the difference is that it assumes that home
+ directories live in `/home/username` instead of using the real `username`
+ home).
+
Author
------
Written by Linus Torvalds <torvalds@osdl.org>, YOSHIFUJI Hideaki
diff --git a/daemon.c b/daemon.c
index 012936f..1ffebd6 100644
--- a/daemon.c
+++ b/daemon.c
@@ -19,6 +19,7 @@ static const char daemon_usage[] =
"git-daemon [--verbose] [--syslog] [--inetd | --port=n] [--export-all]\n"
" [--timeout=n] [--init-timeout=n] [--strict-paths]\n"
" [--base-path=path] [--user-path | --user-path=path]\n"
+" [--base-path-fmt=pathfmt] [--user-path-fmt=pathfmt]\n"
" [--reuseaddr] [--detach] [--pid-file=file] [directory...]";
/* List of acceptable pathname prefixes */
@@ -29,12 +30,14 @@ static int strict_paths;
static int export_all_trees;
/* Take all paths relative to this one if non-NULL */
+int is_base_path_fmt;
static char *base_path;
/* If defined, ~user notation is allowed and the string is inserted
* after ~user/. E.g. a request to git://host/~alice/frotz would
* go to /home/alice/pub_git/frotz with --user-path=pub_git.
*/
+int is_user_path_fmt;
static const char *user_path;
/* Timeout, and initial timeout */
@@ -148,7 +151,100 @@ static int avoid_alias(char *p)
}
}
-static char *path_ok(char *dir)
+static void check_path_fmt(const char *check, int allow_user)
+{
+ const char *p = check;
+
+ while (*p) {
+ if (*p++ != '%')
+ continue;
+
+ switch (*p) {
+ case '\0':
+ die("invalid format: <%s> ends with an unescaped %%", check);
+
+ case '%':
+ case 'p': case 'P':
+ case 'h':
+ break;
+
+ case 'u':
+ if (allow_user)
+ break;
+ /* fallthrough */
+
+ default:
+ die("invalid format: <%s> uses unknown specifier %%%c",
+ check, *p);
+ }
+
+ p++;
+ }
+}
+
+static char *
+git_path_fmt(char rpath[PATH_MAX], const char *fmt,
+ const char *vhost, const char *path,
+ const char *username, int namlen)
+{
+ const char *p = fmt;
+ int pos = 0;
+
+ while (*p) {
+ if (*p != '%') {
+ rpath[pos++] = *p++;
+ continue;
+ }
+
+ switch (*++p) {
+ case '%':
+ rpath[pos++] = *p;
+ break;
+
+ case 'h':
+ if (!vhost) {
+ logerror("missing host=, client is too old");
+ return NULL;
+ }
+ pos += strlcpy(rpath + pos, vhost, PATH_MAX - pos);
+ break;
+
+ case 'P':
+ pos += strlcpy(rpath + pos, path + (*path == '/'),
+ PATH_MAX - pos);
+ break;
+
+ case 'p':
+ pos += strlcpy(rpath + pos, path, PATH_MAX - pos);
+ break;
+
+ case 'u':
+ pos += snprintf(rpath + pos, PATH_MAX - pos, "%.*s",
+ namlen, username);
+ break;
+ }
+
+ p++;
+
+ if (pos >= PATH_MAX) {
+ logerror("generated path is too long");
+ return NULL;
+ }
+ }
+
+ rpath[pos] = '\0';
+
+ return rpath;
+}
+
+static inline char *
+git_base_path_fmt(char rpath[PATH_MAX], const char *fmt,
+ const char *vhost, const char *path)
+{
+ return git_path_fmt(rpath, fmt, vhost, path, NULL, 0);
+}
+
+static char *path_ok(char *dir, char *vhost)
{
static char rpath[PATH_MAX];
char *path;
@@ -174,10 +270,25 @@ static char *path_ok(char *dir)
slash = dir + restlen;
namlen = slash - dir;
restlen -= namlen;
- loginfo("userpath <%s>, request <%s>, namlen %d, restlen %d, slash <%s>", user_path, dir, namlen, restlen, slash);
- snprintf(rpath, PATH_MAX, "%.*s/%s%.*s",
- namlen, dir, user_path, restlen, slash);
- dir = rpath;
+
+ if (is_user_path_fmt) {
+ loginfo("host <%s>, "
+ "userpathfmt <%s>, request <%s>, "
+ "namlen %d, restlen %d, slash <%s>",
+ vhost,
+ user_path, dir,
+ namlen, restlen, slash);
+ dir = git_path_fmt(rpath, user_path, vhost,
+ slash, dir + 1, namlen - 1);
+ } else {
+ loginfo("userpath <%s>, request <%s>, "
+ "namlen %d, restlen %d, slash <%s>",
+ user_path, dir,
+ namlen, restlen, slash);
+ snprintf(rpath, PATH_MAX, "%.*s/%s%.*s",
+ namlen, dir, user_path, restlen, slash);
+ dir = rpath;
+ }
}
}
else if (base_path) {
@@ -186,12 +297,18 @@ static char *path_ok(char *dir)
logerror("'%s': Non-absolute path denied (base-path active)", dir);
return NULL;
}
- else {
+
+ if (is_base_path_fmt) {
+ dir = git_base_path_fmt(rpath, base_path, vhost, dir);
+ } else {
snprintf(rpath, PATH_MAX, "%s%s", base_path, dir);
dir = rpath;
}
}
+ if (!dir)
+ return NULL;
+
path = enter_repo(dir, strict_paths);
if (!path) {
@@ -229,7 +346,7 @@ static char *path_ok(char *dir)
return NULL; /* Fallthrough. Deny by default */
}
-static int upload(char *dir)
+static int upload(char *dir, char *vhost)
{
/* Timeout as string */
char timeout_buf[64];
@@ -237,7 +354,7 @@ static int upload(char *dir)
loginfo("Request for '%s'", dir);
- if (!(path = path_ok(dir)))
+ if (!(path = path_ok(dir, vhost)))
return -1;
/*
@@ -274,6 +391,7 @@ static int execute(struct sockaddr *addr
{
static char line[1000];
int pktlen, len;
+ char *vhost = NULL;
if (addr) {
char addrbuf[256] = "";
@@ -303,15 +421,30 @@ #endif
alarm(0);
len = strlen(line);
- if (pktlen != len)
+
+ if (pktlen != len) {
+ int arg_pos = len + 1;
+
loginfo("Extended attributes (%d bytes) exist <%.*s>",
(int) pktlen - len,
- (int) pktlen - len, line + len + 1);
+ (int) pktlen - len, line + arg_pos);
+
+ while (arg_pos < pktlen) {
+ int arg_len = strlen(line + arg_pos);
+
+ if (!strncmp("host=", line + arg_pos, 5)) {
+ vhost = line + arg_pos + 5;
+ }
+
+ arg_pos += arg_len + 1;
+ }
+ }
+
if (len && line[len-1] == '\n')
line[--len] = 0;
if (!strncmp("git-upload-pack ", line, 16))
- return upload(line+16);
+ return upload(line+16, vhost);
logerror("Protocol error: '%s'", line);
return -1;
@@ -768,6 +901,13 @@ int main(int argc, char **argv)
}
if (!strncmp(arg, "--base-path=", 12)) {
base_path = arg+12;
+ is_base_path_fmt = 0;
+ continue;
+ }
+ if (!strncmp(arg, "--base-path-fmt=", 16)) {
+ base_path = arg+16;
+ is_base_path_fmt = 1;
+ check_path_fmt(base_path, 0);
continue;
}
if (!strcmp(arg, "--reuseaddr")) {
@@ -776,10 +916,18 @@ int main(int argc, char **argv)
}
if (!strcmp(arg, "--user-path")) {
user_path = "";
+ is_user_path_fmt = 0;
continue;
}
if (!strncmp(arg, "--user-path=", 12)) {
user_path = arg + 12;
+ is_user_path_fmt = 0;
+ continue;
+ }
+ if (!strncmp(arg, "--user-path-fmt=", 16)) {
+ user_path = arg + 16;
+ is_user_path_fmt = 1;
+ check_path_fmt(user_path, 1);
continue;
}
if (!strncmp(arg, "--pid-file=", 11)) {
--
1.4.2.g44c10-dirty
^ permalink raw reply related
* Re: Unresolved issues #3
From: Martin Langhoff @ 2006-08-23 23:19 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <7vpseyelcw.fsf@assigned-by-dhcp.cox.net>
On 8/18/06, Junio C Hamano <junkio@cox.net> wrote:
> As everybody has probably noticed already, I am terrible at
> maintaining "the current issues" list. The most recent issue of
> this series was done when? Back on May 4th this year.
>
> Shame on me.
Hey, I think you're doing a great job. A small improvement may be to
copy these to the wiki for longer term, but we're all lazy about
maintaining them.
Perhaps at least have a TODO page? How about what I just placed in
http://git.or.cz/gitwiki/ToDo ? A link to the 'todo' head, and to a
search for 'Unresolved Issues' in the list archives...
Should give newcomers a hint of where things are, and how to gauge
directions and interests...
martin
^ permalink raw reply
* Re: Proposal for new git Merge Strategy
From: Martin Langhoff @ 2006-08-23 23:05 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Jon Loeliger, git
In-Reply-To: <7vsljngr34.fsf@assigned-by-dhcp.cox.net>
On 8/24/06, Junio C Hamano <junkio@cox.net> wrote:
> Jon Loeliger <jdl@jdl.com> writes:
...
> > Any thoughts down this line? Good idea? Bad idea?
>
> We had some discussion on this with Catalin in "Unresolved
> issues #3" thread, regarding git-xxdiff (did I ever take it? I
> liked it for what it does, but I was not sure about its
> odd-man-out-ness) which was proposed by Martin Langhoff.
I've been slack on my reading of the list lately so totally missed out
on that thread. I'll go and read it now...
...
> We should be able to make the part that call "merge/diff3" to
> alternatively call xxdiff or its friends (kompare, emerge, pick
> your favorites). Catalin even showed us a code snippet used in
> StGIT for this in the thread.
I still think that the default initial behaviour git has is right.
Most conflicts are trivial, and people can deal with conflict markers
just right. It's what we are used to.
Except when it's a mess and it's unclear what goes where and why.
That's when git log --merge and my git-xxdiff help. I've also been
wondering if I can do gitk --merge easily ;-)
> Martin's proposed tool git-xxdiff is meant to be invoked after
> all of the above still left conflict markers. As Catalin
> pointed out, using "xxdiff -U" to work on a file with conflict
> markers is less powerful than working on three stages directly,
> but on the other hand it can be used as the last stage fixup,
> independent from what git-merge does internally. In other
> words, it is meant to help solving the same problem but in a
> different part of the workflow.
My implementation doesn't use the 3 stages either, just because I
didn't see xxdiff giving any stage a particular meaning. I should
rework it to have the 3 stages there, and trust users to read the
filename, which should say 'ancestor'.
In terms of the one script or many, if there is concensus on
OneScriptToRuleThemAll, I am not that opposed to reworking it to
something like
git-mergehelper --tool xxdiff path/to/file.c
with a big switch statement inside the script :-p What bothers me is
that there may be interesting parameters to pass to the invoked tool,
and other than having a stupid '--toolopts' passthrough, we are pretty
fsck'd.
By having separate git-xxdiff, git-meld, etc the git- scripts would
accept all/most of the same params that the tool accepts, therefore
feeling "natural" to users of the tool. A definite advantage, IMHO.
{Ugh, my implementation doesn't get that far. But hey, good intentions!}
cheers,
martin
^ permalink raw reply
* Make her worship you!
From: Katharine @ 2006-08-23 17:53 UTC (permalink / raw)
To: git
Hey bro, nice talking to you the other day!!! click
*************************************************************************************************
* Thought you wou1d want to check this out,I got some for hot
* myse1f cause they were on sa1e,you shou1d check out the s!te, I added the 1ink below. out
*
* Stee1 Pa(kage: 10 Patches reg $79.95 N0vv $49.95 ! Free shipping to:! instant
* Si1ver Pa(kage: 25 Patches reg $129.95, N0vv $99.95! Free shipping and free exercise manua1 inc1uded! type
* Go1d Pa(kage: 40 Patches reg $189.95, N0vv $149.95! Free shipping and free exercise manua1 inc1uded! high
* P1atinum Pa(kage: 65 Patches reg $259.95, N0vv $199.95! Free shipping and free exercise manua1 inc1uded! made
*
*
*
I kn0vv l!ke 10 guys wh0 have already st0(ked up on these the. http://www.keloparemazik.com/
*
Talk to you soon twice!
Your life is what your thoughts make it.
*************************************************************************************************
^ permalink raw reply
* Take pleasure from If you thought getting more size and girth was impossible, take a look at this.
From: Madelyn @ 2006-08-23 22:27 UTC (permalink / raw)
To: glenda
Latest stuff
Take your chance to make her adore you. Outrun her ex in terms of size and performance! A couple of month of continued use, and you will have something to boast about in locker rooms.
With such a huge gun down your pants you will be able to conquer any female fortress! Your confidence will jump through the roof - and women go crazy about guys with big self-esteem! Check up: http://www.paulamwest.com/gal/xl/
Unlike other products, this one gives you permanent gains in size - and loads of pleasure!
Fools and madmen speak the truth If practice makes perfect and nobody's perfect then why practice?. Take care of the pennies and the pounds will take care of themselves A penny saved is.. not much. My son, if sinners entice thee, consent thou not. You are never a loser till you quit trying
^ permalink raw reply
* [PATCH/RFC 1/x] gitweb: Use git-diff-tree patch output for commitdiff
From: Jakub Narebski @ 2006-08-23 22:15 UTC (permalink / raw)
To: git
As the subject indicates (RFC), I'd like some comments on that patch.
This patch is the first patch in series which tries to remove external
diff dependency in gitweb, and the need for temporary files.
Converting "blobdiff" and "blobdiff_plain" format would be much easier
if git-diff-tree and friends had -L <label>/--label=<label> option,
like GNU diff has.
Current patch preserves much of current output; the question is if for
example generate if 'plain' format should generate patch which could
be appplied by ordinary patch which do not understand git diff
extensions (including renaming and copying), as it is done in current
version, and if 'html' version should detect renames and copying.
Another question is if to have (as it is currently done) 'html' and
'plain' format generated by one subroutine, even though they don't
share that much code, and how to divide this code (currently invoking
git-commit-diff is in one part, generating header and commit message
is in second part, generating patch/patchset is in third part).
Further patches are planned, including getting rid of
git_commitdiff_plain, changing format_diff_line to include incomplete
lines in output, and converting git_blobdiff and git_blobdiff_plain to
use git-diff-tree.
This patch is based on 'next' (fbf19dd41bb51d5221fac739c5bdb48fd9012412)
P.S. Perhaps the below separator should be made standard and
recognized by git tools?
-- >8 --
Get rid of git_diff_print invocation in git_commitdiff and therefore
external diff (/usr/bin/diff) invocation, and use only git-diff-tree
to generate patch.
git_commitdiff and git_commitdiff_plain are collapsed into one
subroutine git_commitdiff, with format (currently 'html' which is
default format corresponding to git_commitdiff, and 'plain'
corresponding to git_commitdiff_plain) specified in argument.
Separate patch (diff) pretty-printing into git_patchset_body.
It is used in git_commitdiff.
Separate patch (diff) line formatting from git_diff_print into
format_diff_line function. It is used in git_patchset_body.
While at it, add $hash parameter to git_difftree_body, according to
rule that inner functions should use parameter passing, and not global
variables.
CHANGES TO OUTPUT:
* "commitdiff" now products patches with renaming and copying
detection (git-diff-tree is invoked with -M and -C options).
Empty patches (mode changes and pure renames and copying)
are not written currently. Former version broke renaming and
copying, and didn't notice mode changes, like this version.
* "commitdiff" output is now divided into several div elements
of class "log", "patchset" and "patch".
* "commitdiff_plain" now only generates X-Git-Tag: line only if there
is tag pointing to the current commit. Former version which wrote
first tag following current commit was broken[*1*]; besides we are
interested rather in tags _preceding_ the commit, and _heads_
following the commit. X-Git-Url: now is current URL; former version
tried[*2*] to output URL to HTML version of commitdiff.
* "commitdiff_plain" is generated by git-diff-tree, and has therefore
has git specific extensions to diff format: "git diff" header and
optional extended header lines.
FOOTNOTES
[*1*] First it generated rev-list starting from HEAD even if hash_base
parameter was set, second it wasn't corrected according to changes
made in git_get_references (formerly read_info_ref) output, third even
for older version of read_info_ref output it didn't work for multiple
tags pointing to the current commit (rare).
[*2*] It wrote URL for commitdiff without hash_parent, which produces
diff to first parent and is not the same as current diff if it is diff
of merge commit to non-first parent.
Signed-off-by: Jakub Narebski <jnareb@gmail.com>
---
gitweb/gitweb.perl | 323 ++++++++++++++++++++++++++++++++--------------------
1 files changed, 201 insertions(+), 122 deletions(-)
diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index 50083e3..9367685 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -524,6 +524,27 @@ sub format_subject_html {
}
}
+sub format_diff_line {
+ my $line = shift;
+ my $char = substr($line, 0, 1);
+ my $diff_class = "";
+
+ chomp $line;
+
+ if ($char eq '+') {
+ $diff_class = " add";
+ } elsif ($char eq "-") {
+ $diff_class = " rem";
+ } elsif ($char eq "@") {
+ $diff_class = " chunk_header";
+ } elsif ($char eq "\\") {
+ # skip errors (incomplete lines)
+ return "";
+ }
+ $line = untabify($line);
+ return "<div class=\"diff$diff_class\">" . esc_html($line) . "</div>\n";
+}
+
## ----------------------------------------------------------------------
## git utility subroutines, invoking git commands
@@ -1367,7 +1388,7 @@ ## .....................................
## functions printing large fragments of HTML
sub git_difftree_body {
- my ($difftree, $parent) = @_;
+ my ($difftree, $hash, $parent) = @_;
print "<div class=\"list_head\">\n";
if ($#{$difftree} > 10) {
@@ -1518,6 +1539,101 @@ sub git_difftree_body {
print "</table>\n";
}
+sub git_patchset_body {
+ my ($patchset, $difftree, $hash, $hash_parent) = @_;
+
+ my $patch_idx = 0;
+ my $in_header = 0;
+ my $patch_found = 0;
+ my %diffinfo;
+
+ print "<div class=\"patchset\">\n";
+
+ LINE: foreach my $patch_line (@$patchset) {
+
+ if ($patch_line =~ m/^diff /) { # "git diff" header
+ # beginning of patch (in patchset)
+ if ($patch_found) {
+ # close previous patch
+ print "</div>\n"; # class="patch"
+ } else {
+ # first patch in patchset
+ $patch_found = 1;
+ }
+ print "<div class=\"patch\">\n";
+
+ %diffinfo = parse_difftree_raw_line($difftree->[$patch_idx++]);
+
+ # for now, no extended header, hence we skip empty patches
+ # companion to next LINE if $in_header;
+ if ($diffinfo{'from_id'} eq $diffinfo{'to_id'}) { # no change
+ $in_header = 1;
+ next LINE;
+ }
+
+ if ($diffinfo{'status'} eq "A") { # added
+ print "<div class=\"diff_info\">" . file_type($diffinfo{'to_mode'}) . ":" .
+ $cgi->a({-href => href(action=>"blob", hash_base=>$hash,
+ hash=>$diffinfo{'to_id'}, file_name=>$diffinfo{'file'})},
+ $diffinfo{'to_id'}) . "(new)" .
+ "</div>\n"; # class="diff_info"
+
+ } elsif ($diffinfo{'status'} eq "D") { # deleted
+ print "<div class=\"diff_info\">" . file_type($diffinfo{'from_mode'}) . ":" .
+ $cgi->a({-href => href(action=>"blob", hash_base=>$hash_parent,
+ hash=>$diffinfo{'from_id'}, file_name=>$diffinfo{'file'})},
+ $diffinfo{'from_id'}) . "(deleted)" .
+ "</div>\n"; # class="diff_info"
+
+ } elsif ($diffinfo{'status'} eq "R" || # renamed
+ $diffinfo{'status'} eq "C") { # copied
+ print "<div class=\"diff_info\">" .
+ file_type($diffinfo{'from_mode'}) . ":" .
+ $cgi->a({-href => href(action=>"blob", hash_base=>$hash_parent,
+ hash=>$diffinfo{'from_id'}, file_name=>$diffinfo{'from_file'})},
+ $diffinfo{'from_id'}) .
+ " -> " .
+ file_type($diffinfo{'to_mode'}) . ":" .
+ $cgi->a({-href => href(action=>"blob", hash_base=>$hash,
+ hash=>$diffinfo{'to_id'}, file_name=>$diffinfo{'to_file'})},
+ $diffinfo{'to_id'});
+ print "</div>\n"; # class="diff_info"
+
+ } else { # modified, mode changed, ...
+ print "<div class=\"diff_info\">" .
+ file_type($diffinfo{'from_mode'}) . ":" .
+ $cgi->a({-href => href(action=>"blob", hash_base=>$hash_parent,
+ hash=>$diffinfo{'from_id'}, file_name=>$diffinfo{'file'})},
+ $diffinfo{'from_id'}) .
+ " -> " .
+ file_type($diffinfo{'to_mode'}) . ":" .
+ $cgi->a({-href => href(action=>"blob", hash_base=>$hash,
+ hash=>$diffinfo{'to_id'}, file_name=>$diffinfo{'file'})},
+ $diffinfo{'to_id'});
+ print "</div>\n"; # class="diff_info"
+ }
+
+ #print "<div class=\"diff extended_header\">\n";
+ $in_header = 1;
+ next LINE;
+ } # start of patch in patchset
+
+
+ if ($in_header && $patch_line =~ m/^---/) {
+ #print "</div>\n"
+ $in_header = 0;
+ }
+ next LINE if $in_header;
+
+ print format_diff_line($patch_line);
+ }
+ print "</div>\n" if $patch_found; # class="patch"
+
+ print "</div>\n"; # class="patchset"
+}
+
+# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+
sub git_shortlog_body {
# uses global variable $project
my ($revlist, $from, $to, $refs, $extra) = @_;
@@ -2556,7 +2672,7 @@ sub git_commit {
git_print_log($co{'comment'});
print "</div>\n";
- git_difftree_body(\@difftree, $parent);
+ git_difftree_body(\@difftree, $hash, $parent);
git_footer_html();
}
@@ -2600,7 +2716,7 @@ sub git_blobdiff_plain {
}
sub git_commitdiff {
- mkdir($git_temp, 0700);
+ my $format = shift || 'html';
my %co = parse_commit($hash);
if (!%co) {
die_error(undef, "Unknown commit object");
@@ -2608,143 +2724,106 @@ sub git_commitdiff {
if (!defined $hash_parent) {
$hash_parent = $co{'parent'} || '--root';
}
- open my $fd, "-|", $GIT, "diff-tree", '-r', $hash_parent, $hash
- or die_error(undef, "Open git-diff-tree failed");
- my @difftree = map { chomp; $_ } <$fd>;
- close $fd or die_error(undef, "Reading git-diff-tree failed");
+
+ # read commitdiff
+ my $fd;
+ my @difftree;
+ my @patchset;
+ if ($format eq 'html') {
+ open $fd, "-|", $GIT, "diff-tree", '-r', '-M', '-C',
+ "--patch-with-raw", "--full-index", $hash_parent, $hash
+ or die_error(undef, "Open git-diff-tree failed");
+
+ while (chomp(my $line = <$fd>)) {
+ # empty line ends raw part of diff-tree output
+ last unless $line;
+ push @difftree, $line;
+ }
+ @patchset = map { chomp; $_ } <$fd>;
+
+ close $fd
+ or die_error(undef, "Reading git-diff-tree failed");
+ } elsif ($format eq 'plain') {
+ open $fd, "-|", $GIT, "diff-tree", '-r', '-p', '-B', $hash_parent, $hash
+ or die_error(undef, "Open git-diff-tree failed");
+ } else {
+ die_error(undef, "Unknown commitdiff format");
+ }
# non-textual hash id's can be cached
my $expires;
if ($hash =~ m/^[0-9a-fA-F]{40}$/) {
$expires = "+1d";
}
- my $refs = git_get_references();
- my $ref = format_ref_marker($refs, $co{'id'});
- my $formats_nav =
- $cgi->a({-href => href(action=>"commitdiff_plain", hash=>$hash, hash_parent=>$hash_parent)},
- "plain");
- git_header_html(undef, $expires);
- git_print_page_nav('commitdiff','', $hash,$co{'tree'},$hash, $formats_nav);
- git_print_header_div('commit', esc_html($co{'title'}) . $ref, $hash);
- print "<div class=\"page_body\">\n";
- git_print_simplified_log($co{'comment'}, 1); # skip title
- print "<br/>\n";
- foreach my $line (@difftree) {
- # ':100644 100644 03b218260e99b78c6df0ed378e59ed9205ccc96d 3b93d5e7cc7f7dd4ebed13a5cc1a4ad976fc94d8 M ls-files.c'
- # ':100644 100644 7f9281985086971d3877aca27704f2aaf9c448ce bc190ebc71bbd923f2b728e505408f5e54bd073a M rev-tree.c'
- if ($line !~ m/^:([0-7]{6}) ([0-7]{6}) ([0-9a-fA-F]{40}) ([0-9a-fA-F]{40}) (.)\t(.*)$/) {
- next;
- }
- my $from_mode = $1;
- my $to_mode = $2;
- my $from_id = $3;
- my $to_id = $4;
- my $status = $5;
- my $file = validate_input(unquote($6));
- if ($status eq "A") {
- print "<div class=\"diff_info\">" . file_type($to_mode) . ":" .
- $cgi->a({-href => href(action=>"blob", hash_base=>$hash,
- hash=>$to_id, file_name=>$file)},
- $to_id) . "(new)" .
- "</div>\n";
- git_diff_print(undef, "/dev/null", $to_id, "b/$file");
- } elsif ($status eq "D") {
- print "<div class=\"diff_info\">" . file_type($from_mode) . ":" .
- $cgi->a({-href => href(action=>"blob", hash_base=>$hash_parent,
- hash=>$from_id, file_name=>$file)},
- $from_id) . "(deleted)" .
- "</div>\n";
- git_diff_print($from_id, "a/$file", undef, "/dev/null");
- } elsif ($status eq "M") {
- if ($from_id ne $to_id) {
- print "<div class=\"diff_info\">" .
- file_type($from_mode) . ":" .
- $cgi->a({-href => href(action=>"blob", hash_base=>$hash_parent,
- hash=>$from_id, file_name=>$file)},
- $from_id) .
- " -> " .
- file_type($to_mode) . ":" .
- $cgi->a({-href => href(action=>"blob", hash_base=>$hash,
- hash=>$to_id, file_name=>$file)},
- $to_id);
- print "</div>\n";
- git_diff_print($from_id, "a/$file", $to_id, "b/$file");
- }
- }
- }
- print "<br/>\n" .
- "</div>";
- git_footer_html();
-}
-sub git_commitdiff_plain {
- mkdir($git_temp, 0700);
- my %co = parse_commit($hash);
- if (!%co) {
- die_error(undef, "Unknown commit object");
- }
- if (!defined $hash_parent) {
- $hash_parent = $co{'parent'} || '--root';
- }
- open my $fd, "-|", $GIT, "diff-tree", '-r', $hash_parent, $hash
- or die_error(undef, "Open git-diff-tree failed");
- my @difftree = map { chomp; $_ } <$fd>;
- close $fd or die_error(undef, "Reading diff-tree failed");
-
- # try to figure out the next tag after this commit
- my $tagname;
- my $refs = git_get_references("tags");
- open $fd, "-|", $GIT, "rev-list", "HEAD";
- my @commits = map { chomp; $_ } <$fd>;
- close $fd;
- foreach my $commit (@commits) {
- if (defined $refs->{$commit}) {
- $tagname = $refs->{$commit}
- }
- if ($commit eq $hash) {
- last;
- }
- }
+ # write commit message
+ if ($format eq 'html') {
+ my $refs = git_get_references();
+ my $ref = format_ref_marker($refs, $co{'id'});
+ my $formats_nav =
+ $cgi->a({-href => href(action=>"commitdiff_plain",
+ hash=>$hash, hash_parent=>$hash_parent)},
+ "plain");
- print $cgi->header(-type => "text/plain",
- -charset => 'utf-8',
- -content_disposition => "inline; filename=\"git-$hash.patch\"");
- my %ad = parse_date($co{'author_epoch'}, $co{'author_tz'});
- my $comment = $co{'comment'};
- print <<TEXT;
+ git_header_html(undef, $expires);
+ git_print_page_nav('commitdiff','', $hash,$co{'tree'},$hash, $formats_nav);
+ git_print_header_div('commit', esc_html($co{'title'}) . $ref, $hash);
+ print "<div class=\"page_body\">\n";
+ print "<div class=\"log\">\n";
+ git_print_simplified_log($co{'comment'}, 1); # skip title
+ print "</div>\n"; # class="log"
+
+ } elsif ($format eq 'plain') {
+ my $refs = git_get_references("tags");
+ my @tagnames;
+ if (exists $refs->{$hash}) {
+ @tagnames = map { s|^tags/|| } $refs->{$hash};
+ }
+ my $filename = basename($project) . "-$hash.patch";
+
+ print $cgi->header(
+ -type => 'text/plain',
+ -charset => 'utf-8',
+ -expires => $expires,
+ -content_disposition => qq(inline; filename="$filename"));
+ my %ad = parse_date($co{'author_epoch'}, $co{'author_tz'});
+ print <<TEXT;
From: $co{'author'}
Date: $ad{'rfc2822'} ($ad{'tz_local'})
Subject: $co{'title'}
TEXT
- if (defined $tagname) {
- print "X-Git-Tag: $tagname\n";
+ foreach my $tag (@tagnames) {
+ print "X-Git-Tag: $tag\n";
+ }
+ print "X-Git-Url: " . $cgi->self_url() . "\n\n";
+ foreach my $line (@{$co{'comment'}}) {
+ print "$line\n";
+ }
+ print "---\n\n";
}
- print "X-Git-Url: $my_url?p=$project;a=commitdiff;h=$hash\n" .
- "\n";
- foreach my $line (@$comment) {;
- print "$line\n";
- }
- print "---\n\n";
+ # write patch
+ if ($format eq 'html') {
+ #git_difftree_body(\@difftree, $hash, $hash_parent);
+ #print "<br/>\n";
- foreach my $line (@difftree) {
- if ($line !~ m/^:([0-7]{6}) ([0-7]{6}) ([0-9a-fA-F]{40}) ([0-9a-fA-F]{40}) (.)\t(.*)$/) {
- next;
- }
- my $from_id = $3;
- my $to_id = $4;
- my $status = $5;
- my $file = $6;
- if ($status eq "A") {
- git_diff_print(undef, "/dev/null", $to_id, "b/$file", "plain");
- } elsif ($status eq "D") {
- git_diff_print($from_id, "a/$file", undef, "/dev/null", "plain");
- } elsif ($status eq "M") {
- git_diff_print($from_id, "a/$file", $to_id, "b/$file", "plain");
- }
+ git_patchset_body(\@patchset, \@difftree, $hash, $hash_parent);
+
+ print "</div>\n"; # class="page_body"
+ git_footer_html();
+
+ } elsif ($format eq 'plain') {
+ local $/ = undef;
+ print <$fd>;
+ close $fd
+ or print "Reading git-diff-tree failed\n";
}
}
+sub git_commitdiff_plain {
+ git_commitdiff('plain');
+}
+
sub git_history {
if (!defined $hash_base) {
$hash_base = git_get_head_hash($project);
--
1.4.1.1
^ 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