* Re: Git archive and trailing "/" in prefix
From: Junio C Hamano @ 2009-10-09 6:50 UTC (permalink / raw)
To: René Scharfe; +Cc: Sergio Callegari, git, Junio C Hamano
In-Reply-To: <4ACE177E.209@lsrfire.ath.cx>
René Scharfe <rene.scharfe@lsrfire.ath.cx> writes:
> Sergio Callegari schrieb:
> ...
>> As a matter of fact, the archiver behaves quite strangely if that slash is
>> missing. Files in the root of the working dir are added to the archive with
>> their own name modified by the prefix and the same happens for working dir
>> sub-directories. However, no file present in the sub-directories, nor
>> sub-sub-directories are added.
>
> The latter is a bug.
> ...
> The following patch fixes...
Thanks. Applied with a trivial test.
^ permalink raw reply
* Re: [PATCH v2] git-send-email.perl: fold multiple entry "Cc:" and multiple single line "RCPT TO:"s
From: Junio C Hamano @ 2009-10-09 6:50 UTC (permalink / raw)
To: Joe Perches; +Cc: Junio C Hamano, git, Jay Soffian
In-Reply-To: <1255021406.2056.122.camel@Joe-Laptop.home>
Joe Perches <joe@perches.com> writes:
> Some MTAs reject Cc: lines longer than 78 chars.
> Avoid this by using the same join as "To:" ",\n\t"
> so each subsequent Cc entry is on a new line.
>
> RCPT TO: should have a single entry per line.
> see: http://www.ietf.org/rfc/rfc2821.txt
>
> Signed-off-by: Joe Perches <joe@perches.com>
Thanks.
^ permalink raw reply
* Re: [PATCH] Fix the exit code of MSVC build scripts on cygwin
From: Junio C Hamano @ 2009-10-09 6:49 UTC (permalink / raw)
To: Alex Riesen; +Cc: Ramsay Jones, Junio C Hamano, mstormo, GIT Mailing-list
In-Reply-To: <81b0412b0910081313x31f72916p6fddd1a23df154df@mail.gmail.com>
Alex Riesen <raa.lkml@gmail.com> writes:
> On Thu, Oct 8, 2009 at 17:33, Ramsay Jones <ramsay@ramsay1.demon.co.uk> wrote:
>> diff --git a/compat/vcbuild/scripts/clink.pl b/compat/vcbuild/scripts/clink.pl
>> index 0ffd59f..26aec61 100644
>> --- a/compat/vcbuild/scripts/clink.pl
>> +++ b/compat/vcbuild/scripts/clink.pl
>> @@ -45,4 +45,6 @@ if ($is_linking) {
>> push(@args, @cflags);
>> }
>> #printf("**** @args\n");
>> -exit system(@args);
>> +system(@args) == 0
>> + or exit 1;
>> +exit 0;
>
> exit(system(@args) != 0);
>
> Yours looks a little verbose...
Thanks, will queue with a fixup.
^ permalink raw reply
* Re: [PATCH] Fix MSVC build on cygwin
From: Junio C Hamano @ 2009-10-09 6:48 UTC (permalink / raw)
To: Ramsay Jones; +Cc: mstormo, GIT Mailing-list
In-Reply-To: <4ACE0388.6070706@ramsay1.demon.co.uk>
Ramsay Jones <ramsay@ramsay1.demon.co.uk> writes:
> In the MSVC section of the Makefile, BASIC_CFLAGS is set to a
> value which contains the string "-DWIN32-D_CONSOLE". This results
> in a (single) malformed -Define being passed to the compiler.
> At least on my cygwin installation, the msvc compiler seems to
> ignore this parameter, without issuing an error or warning, and
> results in the WIN32 and _CONSOLE macros being undefined. This
> breaks the build.
>
> In order to fix the build, we simply insert a space between the
> two -Define parameters, "-DWIN32" and "-D_CONSOLE", as originally
> intended.
>
> Signed-off-by: Ramsay Jones <ramsay@ramsay1.demon.co.uk>
Thanks; that's quite a detailed description to explain why -DFOO-DBAR is
bad when -DFOO -DBAR was wanted ;-)
^ permalink raw reply
* Re: What's cooking in git.git (Oct 2009, #01; Wed, 07)
From: Junio C Hamano @ 2009-10-09 6:47 UTC (permalink / raw)
To: Erik Faye-Lund; +Cc: Marius Storm-Olsen, git
In-Reply-To: <40aa078e0910081115q1bf924e8s22f3ee11dbe7c8b7@mail.gmail.com>
Erik Faye-Lund <kusmabite@googlemail.com> writes:
> On Thu, Oct 8, 2009 at 8:58 AM, Marius Storm-Olsen <mstormo@gmail.com> wrote:
>> Junio C Hamano said the following on 08.10.2009 08:33:
>>>
>>> * ef/msys-imap (2009-10-03) 7 commits
>> ...
>> Don't forget about the MSVC patch ontop of this series:
>> Message-ID: <18cd41840910031300i32c74b15t74eb9eee23ff8469@mail.gmail.com>
>> Subject: [PATCH] MSVC: Enable OpenSSL, and translate -lcrypto
>
> I will include it in the next round I send out (unless someone objects)
Thanks.
^ permalink raw reply
* Re: What's cooking in git.git (Oct 2009, #01; Wed, 07)
From: Junio C Hamano @ 2009-10-09 6:46 UTC (permalink / raw)
To: Jakub Narebski; +Cc: git
In-Reply-To: <m3iqepgxcc.fsf@localhost.localdomain>
Jakub Narebski <jnareb@gmail.com> writes:
> Junio C Hamano <gitster@pobox.com> writes:
>
>> --------------------------------------------------
>> [New Topics]
>
>> * jn/gitweb-patch (2009-09-30) 1 commit
>> - gitweb: Do not show 'patch' link in 'commit' view for merges
>>
>> jk: After some comments with Jakub, I think the code is right but he
>> promised a re-roll with more in the commit message.
>
> Not only better commit message, but a more complete patch as well.
Ok; I'll wait.
>> * mr/gitweb-snapshot (2009-09-26) 2 commits
>> - gitweb: append short hash ids to snapshot files
>> - gitweb: check given hash before trying to create snapshot
>>
>> jk: He posted a v5 of his series. I didn't look at it closely, but Jakub
>> ack'd it.
> ...
> In short: first patch is a go, second needs more work.
Ok; I'll merge fdb0c36 (gitweb: check given hash before trying to create
snapshot, 2009-09-26) to 'next'.
>> * jc/pretty-lf (2009-10-04) 1 commit
>> - Pretty-format: %[+-]x to tweak inter-item newlines
>>
>> I am not happy with this one yet. I am contemplating to introduce a new
>> syntax "%[magic(param)<anything>%]" to generalize expressions of this and
>> line wrapping features in an extensible way.
>> ...
> So... it is magic %[...%] or %{...} or %{...%}?
The escape does not matter. %() is fine, too. It is non-essential for the
purpose of the upcoming release so I have backburnered coming up with and
thinking the details through.
>> --------------------------------------------------
>> [Cooking]
>
>> * jn/gitweb-show-size (2009-09-07) 1 commit
>> - gitweb: Add 'show-sizes' feature to show blob sizes in tree view
>
> What this one requires (beside better name for a feature)?
Name before 'next', and then the usual cooking, I guess.
>> * jn/gitweb-blame (2009-09-01) 5 commits
>> ...
>> Ajax-y blame.
>
> I reordered patches so JSMIN one is first (as it is less
> controversial), but the 'create blame_incremental links' one needs
> more work.
Ok; I'll wait.
Thanks.
^ permalink raw reply
* [PATCH 1/2] completion: fix completion of git <TAB><TAB>
From: Stephen Boyd @ 2009-10-09 6:21 UTC (permalink / raw)
To: Shawn O. Pearce; +Cc: Junio C Hamano, git, Johannes Sixt
After commit 511a3fc (wrap git's main usage string., 2009-09-12), the
bash completion for git commands includes COMMAND and [ARGS] when it
shouldn't. Fix this by grepping more strictly for a line with git
commands. It's doubtful whether git will ever have commands starting
with anything besides numbers and letters so this should be fine. At
least by being stricter we'll know when we break the completion earlier.
Signed-off-by: Stephen Boyd <bebarino@gmail.com>
---
contrib/completion/git-completion.bash | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash
index 88b1b3c..652a47c 100755
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -496,7 +496,7 @@ __git_all_commands ()
return
fi
local i IFS=" "$'\n'
- for i in $(git help -a|egrep '^ ')
+ for i in $(git help -a|egrep '^ [a-zA-Z0-9]')
do
case $i in
*--*) : helper pattern;;
--
1.6.5.rc3
^ permalink raw reply related
* [PATCHv2 2/2] completion: fix alias listings with newlines
From: Stephen Boyd @ 2009-10-09 6:21 UTC (permalink / raw)
To: Shawn O. Pearce; +Cc: Junio C Hamano, git, Johannes Sixt
In-Reply-To: <1255069304-8953-1-git-send-email-bebarino@gmail.com>
Aliases with newlines have been a problem since commit 56fc25f (Bash
completion support for remotes in .git/config., 2006-11-05). The chance
of the problem occurring has been slim at best, until commit 518ef8f
(completion: Replace config --list with --get-regexp, 2009-09-11)
removed the case statement introduced by commit 56fc25f. Before removing
the case statement, most aliases with newlines would work unless they
were specially crafted as follows
[alias]
foo = "log -1 --pretty='format:%s\nalias.error=broken'"
After removing the case statement, a more benign alias like
[alias]
whowhat = "log -1 --pretty='format:%an <%ae>\n%s'"
wont-complete = ...
would cause the completion to break badly.
For now, revert the removal of the case statement until someone comes up
with a better way to get keys from git-config.
Signed-off-by: Stephen Boyd <bebarino@gmail.com>
---
This is an alternate fix to my previous 1/3 patch.
Hannes has convinced me to go this route. I don't really see a problem, it
basically reverts to broken behavior that nobody's complained about in 3
years. At least it's less broken?
contrib/completion/git-completion.bash | 8 ++++++--
1 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash
index 652a47c..e482c8d 100755
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -602,8 +602,12 @@ __git_aliases ()
{
local i IFS=$'\n'
for i in $(git --git-dir="$(__gitdir)" config --get-regexp "alias\..*" 2>/dev/null); do
- i="${i#alias.}"
- echo "${i/ */}"
+ case "$i" in
+ alias.*)
+ i="${i#alias.}"
+ echo "${i/ */}"
+ ;;
+ esac
done
}
--
1.6.5.rc3
^ permalink raw reply related
* Re: combine git repo historically
From: Johannes Sixt @ 2009-10-09 6:02 UTC (permalink / raw)
To: bill lam; +Cc: git
In-Reply-To: <20091009012254.GA3980@debian.b2j>
bill lam schrieb:
> I have two git repos, no branches.
>
> repo 1.
> emptyrootcommit -- A ... M
>
> repo 2.
> emptyrootcommit -- N ... Z
>
> N was evolved from M but the time gap is large, how can I combine them
> into one repo
>
> emptyrootcommit -- A ... M -- N ... Z
>
> so that snapshots N .. Z will not be changed.
$ echo $(git rev-parse N) $(git rev-parse M) >> .git/info/grafts
$ git filter-branch --tag-name-filter cat -- --all --not M
i.e. you graft the older history right before the younger history, then
you use git filter-branch to rewrite the parentship of the younger commits.
-- Hannes
^ permalink raw reply
* Re: [RFC PATCH 2/4] Git-aware CGI to provide dumb HTTP transport
From: J.H. @ 2009-10-09 5:52 UTC (permalink / raw)
To: Shawn O. Pearce; +Cc: git
In-Reply-To: <1255065768-10428-3-git-send-email-spearce@spearce.org>
I dunno I kinda object to it being called http-backend, personally I'd
rather it be called git-smart since this is the smart http protocol ;-)
- John 'Warthog9' Hawley
Shawn O. Pearce wrote:
> The git-http-backend CGI can be configured into any Apache server
> using ScriptAlias, such as with the following configuration:
>
> LoadModule cgi_module /usr/libexec/apache2/mod_cgi.so
> LoadModule alias_module /usr/libexec/apache2/mod_alias.so
> ScriptAlias /git/ /usr/libexec/git-core/git-http-backend/
>
> Repositories are accessed via the translated PATH_INFO.
>
> The CGI is backwards compatible with the dumb client, allowing all
> older HTTP clients to continue to download repositories which are
> managed by the CGI.
>
> Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
> ---
> .gitignore | 1 +
> Makefile | 1 +
> http-backend.c | 261 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 263 insertions(+), 0 deletions(-)
> create mode 100644 http-backend.c
>
> diff --git a/.gitignore b/.gitignore
> index 51a37b1..353d22f 100644
> --- a/.gitignore
> +++ b/.gitignore
> @@ -55,6 +55,7 @@ git-get-tar-commit-id
> git-grep
> git-hash-object
> git-help
> +git-http-backend
> git-http-fetch
> git-http-push
> git-imap-send
> diff --git a/Makefile b/Makefile
> index dd3d520..c80fb56 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -361,6 +361,7 @@ PROGRAMS += git-show-index$X
> PROGRAMS += git-unpack-file$X
> PROGRAMS += git-upload-pack$X
> PROGRAMS += git-var$X
> +PROGRAMS += git-http-backend$X
>
> # List built-in command $C whose implementation cmd_$C() is not in
> # builtin-$C.o but is linked in as part of some other command.
> diff --git a/http-backend.c b/http-backend.c
> new file mode 100644
> index 0000000..39cfd25
> --- /dev/null
> +++ b/http-backend.c
> @@ -0,0 +1,261 @@
> +#include "cache.h"
> +#include "refs.h"
> +#include "pkt-line.h"
> +#include "object.h"
> +#include "tag.h"
> +#include "exec_cmd.h"
> +#include "run-command.h"
> +
> +static const char content_type[] = "Content-Type";
> +static const char content_length[] = "Content-Length";
> +
> +static char buffer[1024];
> +
> +static const char *http_date(unsigned long time)
> +{
> + return show_date(time, 0, DATE_RFC2822);
> +}
> +
> +static void format_write(const char *fmt, ...)
> +{
> + va_list args;
> + unsigned n;
> +
> + va_start(args, fmt);
> + n = vsnprintf(buffer, sizeof(buffer), fmt, args);
> + va_end(args);
> + if (n >= sizeof(buffer))
> + die("protocol error: impossibly long line");
> +
> + safe_write(1, buffer, n);
> +}
> +
> +static void write_status(unsigned code, const char *msg)
> +{
> + format_write("Status: %u %s\r\n", code, msg);
> +}
> +
> +static void write_header(const char *name, const char *value)
> +{
> + format_write("%s: %s\r\n", name, value);
> +}
> +
> +static void end_headers(void)
> +{
> + safe_write(1, "\r\n", 2);
> +}
> +
> +static void write_nocache(void)
> +{
> + write_header("Expires", "Fri, 01 Jan 1980 00:00:00 GMT");
> + write_header("Pragma", "no-cache");
> + write_header("Cache-Control", "no-cache, max-age=0, must-revalidate");
> +}
> +
> +static void write_cache_forever(void)
> +{
> + unsigned long now = time(NULL);
> + write_header("Date", http_date(now));
> + write_header("Expires", http_date(now + 31536000));
> + write_header("Cache-Control", "public, max-age=31536000");
> +}
> +
> +static NORETURN void not_found(const char *err, ...)
> +{
> + va_list params;
> +
> + write_status(404, "Not Found");
> + write_nocache();
> + end_headers();
> +
> + va_start(params, err);
> + if (err && *err) {
> + vsnprintf(buffer, sizeof(buffer), err, params);
> + fprintf(stderr, "%s\n", buffer);
> + }
> + va_end(params);
> + exit(0);
> +}
> +
> +static void write_file(const char *the_type, const char *name)
> +{
> + const char *p = git_path("%s", name);
> + int fd;
> + struct stat sb;
> + uintmax_t remaining;
> +
> + fd = open(p, O_RDONLY);
> + if (fd < 0)
> + not_found("Cannot open '%s': %s", p, strerror(errno));
> + if (fstat(fd, &sb) < 0)
> + die_errno("Cannot stat '%s'", p);
> + remaining = (uintmax_t)sb.st_size;
> +
> + write_header(content_type, the_type);
> + write_header("Last-Modified", http_date(sb.st_mtime));
> + format_write("Content-Length: %" PRIuMAX "\r\n", remaining);
> + end_headers();
> +
> + while (remaining) {
> + ssize_t n = xread(fd, buffer, sizeof(buffer));
> + if (n < 0)
> + die_errno("Cannot read '%s'", p);
> + n = safe_write(1, buffer, n);
> + if (n <= 0)
> + break;
> + }
> + close(fd);
> +}
> +
> +static void get_text_file(char *name)
> +{
> + write_nocache();
> + write_file("text/plain; charset=utf-8", name);
> +}
> +
> +static void get_loose_object(char *name)
> +{
> + write_cache_forever();
> + write_file("application/x-git-loose-object", name);
> +}
> +
> +static void get_pack_file(char *name)
> +{
> + write_cache_forever();
> + write_file("application/x-git-packed-objects", name);
> +}
> +
> +static void get_idx_file(char *name)
> +{
> + write_cache_forever();
> + write_file("application/x-git-packed-objects-toc", name);
> +}
> +
> +static int show_text_ref(const char *name, const unsigned char *sha1,
> + int flag, void *cb_data)
> +{
> + struct object *o = parse_object(sha1);
> + if (!o)
> + return 0;
> +
> + format_write("%s\t%s\n", sha1_to_hex(sha1), name);
> + if (o->type == OBJ_TAG) {
> + o = deref_tag(o, name, 0);
> + if (!o)
> + return 0;
> + format_write("%s\t%s^{}\n", sha1_to_hex(o->sha1), name);
> + }
> +
> + return 0;
> +}
> +
> +static void get_info_refs(char *arg)
> +{
> + write_nocache();
> + write_header(content_type, "text/plain; charset=utf-8");
> + end_headers();
> +
> + for_each_ref(show_text_ref, NULL);
> +}
> +
> +static void get_info_packs(char *arg)
> +{
> + size_t objdirlen = strlen(get_object_directory());
> + struct packed_git *p;
> +
> + write_nocache();
> + write_header(content_type, "text/plain; charset=utf-8");
> + end_headers();
> +
> + prepare_packed_git();
> + for (p = packed_git; p; p = p->next) {
> + if (!p->pack_local)
> + continue;
> + format_write("P %s\n", p->pack_name + objdirlen + 6);
> + }
> + safe_write(1, "\n", 1);
> +}
> +
> +static NORETURN void die_webcgi(const char *err, va_list params)
> +{
> + write_status(500, "Internal Server Error");
> + write_nocache();
> + end_headers();
> +
> + vsnprintf(buffer, sizeof(buffer), err, params);
> + fprintf(stderr, "fatal: %s\n", buffer);
> + exit(0);
> +}
> +
> +static struct service_cmd {
> + const char *method;
> + const char *pattern;
> + void (*imp)(char *);
> +} services[] = {
> + {"GET", "/HEAD$", get_text_file},
> + {"GET", "/info/refs$", get_info_refs},
> + {"GET", "/objects/info/packs$", get_info_packs},
> + {"GET", "/objects/info/[^/]*$", get_text_file},
> + {"GET", "/objects/[0-9a-f]{2}/[0-9a-f]{38}$", get_loose_object},
> + {"GET", "/objects/pack/pack-[0-9a-f]{40}\\.pack$", get_pack_file},
> + {"GET", "/objects/pack/pack-[0-9a-f]{40}\\.idx$", get_idx_file}
> +};
> +
> +int main(int argc, char **argv)
> +{
> + char *dir = getenv("PATH_TRANSLATED");
> + char *input_method = getenv("REQUEST_METHOD");
> + struct service_cmd *cmd = NULL;
> + char *cmd_arg = NULL;
> + int i;
> +
> + set_die_routine(die_webcgi);
> +
> + if (!dir)
> + die("No PATH_TRANSLATED from server");
> + if (!input_method)
> + die("No REQUEST_METHOD from server");
> + if (!strcmp(input_method, "HEAD"))
> + input_method = "GET";
> +
> + for (i = 0; i < ARRAY_SIZE(services); i++) {
> + struct service_cmd *c = &services[i];
> + regex_t re;
> + regmatch_t out[1];
> +
> + if (regcomp(&re, c->pattern, REG_EXTENDED))
> + die("Bogus regex in service table: %s", c->pattern);
> + if (!regexec(&re, dir, 1, out, 0)) {
> + size_t n = out[0].rm_eo - out[0].rm_so;
> +
> + if (strcmp(input_method, c->method)) {
> + const char *proto = getenv("SERVER_PROTOCOL");
> + if (proto && !strcmp(proto, "HTTP/1.1"))
> + write_status(405, "Method Not Allowed");
> + else
> + write_status(400, "Bad Request");
> + write_nocache();
> + end_headers();
> + return 0;
> + }
> +
> + cmd = c;
> + cmd_arg = xmalloc(n);
> + strncpy(cmd_arg, dir + out[0].rm_so + 1, n);
> + cmd_arg[n] = '\0';
> + dir[out[0].rm_so] = 0;
> + break;
> + }
> + regfree(&re);
> + }
> +
> + if (!cmd)
> + not_found("Request not supported: '%s'", dir);
> +
> + setup_path();
> + if (!enter_repo(dir, 0))
> + not_found("Not a git repository: '%s'", dir);
> +
> + cmd->imp(cmd_arg);
> + return 0;
> +}
^ permalink raw reply
* [RFC PATCH 3/4] Add smart-http options to upload-pack, receive-pack
From: Shawn O. Pearce @ 2009-10-09 5:22 UTC (permalink / raw)
To: git
In-Reply-To: <1255065768-10428-3-git-send-email-spearce@spearce.org>
When --smart-http is passed as a command line parameter to
upload-pack or receive-pack the programs now assume they may
perform only a single read-write cycle with stdin and stdout.
This fits with the HTTP POST request processing model where a
program may read the request, write a response, and must exit.
When --advertise-refs is passed as a command line parameter only
the initial ref advertisement is output, and the program exits
immediately. This fits with the HTTP GET request model, where
no request content is received but a response must be produced.
HTTP headers and/or environment are not processed here, but
instead are assumed to be handled by the program invoking
either service backend.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
---
builtin-receive-pack.c | 26 ++++++++++++++++++++------
upload-pack.c | 40 ++++++++++++++++++++++++++++++++++++----
2 files changed, 56 insertions(+), 10 deletions(-)
diff --git a/builtin-receive-pack.c b/builtin-receive-pack.c
index b771fe9..a075785 100644
--- a/builtin-receive-pack.c
+++ b/builtin-receive-pack.c
@@ -615,6 +615,8 @@ static void add_alternate_refs(void)
int cmd_receive_pack(int argc, const char **argv, const char *prefix)
{
+ int advertise_refs = 0;
+ int smart_http = 0;
int i;
char *dir = NULL;
@@ -623,7 +625,15 @@ int cmd_receive_pack(int argc, const char **argv, const char *prefix)
const char *arg = *argv++;
if (*arg == '-') {
- /* Do flag handling here */
+ if (!strcmp(arg, "--advertise-refs")) {
+ advertise_refs = 1;
+ continue;
+ }
+ if (!strcmp(arg, "--smart-http")) {
+ smart_http = 1;
+ continue;
+ }
+
usage(receive_pack_usage);
}
if (dir)
@@ -652,12 +662,16 @@ int cmd_receive_pack(int argc, const char **argv, const char *prefix)
" report-status delete-refs ofs-delta " :
" report-status delete-refs ";
- add_alternate_refs();
- write_head_info();
- clear_extra_refs();
+ if (advertise_refs || !smart_http) {
+ add_alternate_refs();
+ write_head_info();
+ clear_extra_refs();
- /* EOF */
- packet_flush(1);
+ /* EOF */
+ packet_flush(1);
+ }
+ if (advertise_refs)
+ return 0;
read_head_info();
if (commands) {
diff --git a/upload-pack.c b/upload-pack.c
index 38ddac2..ae67039 100644
--- a/upload-pack.c
+++ b/upload-pack.c
@@ -39,6 +39,8 @@ static unsigned int timeout;
*/
static int use_sideband;
static int debug_fd;
+static int advertise_refs;
+static int smart_http;
static void reset_timeout(void)
{
@@ -509,6 +511,8 @@ static int get_common_commits(void)
if (!len) {
if (have_obj.nr == 0 || multi_ack)
packet_write(1, "NAK\n");
+ if (smart_http)
+ exit(0);
continue;
}
strip(line, len);
@@ -705,12 +709,32 @@ static int send_ref(const char *refname, const unsigned char *sha1, int flag, vo
return 0;
}
+static int mark_our_ref(const char *refname, const unsigned char *sha1, int flag, void *cb_data)
+{
+ struct object *o = parse_object(sha1);
+ if (!o)
+ die("git upload-pack: cannot find object %s:", sha1_to_hex(sha1));
+ if (!(o->flags & OUR_REF)) {
+ o->flags |= OUR_REF;
+ nr_our_refs++;
+ }
+ return 0;
+}
+
static void upload_pack(void)
{
- reset_timeout();
- head_ref(send_ref, NULL);
- for_each_ref(send_ref, NULL);
- packet_flush(1);
+ if (advertise_refs || !smart_http) {
+ reset_timeout();
+ head_ref(send_ref, NULL);
+ for_each_ref(send_ref, NULL);
+ packet_flush(1);
+ } else {
+ head_ref(mark_our_ref, NULL);
+ for_each_ref(mark_our_ref, NULL);
+ }
+ if (advertise_refs)
+ return;
+
receive_needs();
if (want_obj.nr) {
get_common_commits();
@@ -732,6 +756,14 @@ int main(int argc, char **argv)
if (arg[0] != '-')
break;
+ if (!strcmp(arg, "--advertise-refs")) {
+ advertise_refs = 1;
+ continue;
+ }
+ if (!strcmp(arg, "--smart-http")) {
+ smart_http = 1;
+ continue;
+ }
if (!strcmp(arg, "--strict")) {
strict = 1;
continue;
--
1.6.5.rc3.193.gdf7a
^ permalink raw reply related
* [RFC PATCH 2/4] Git-aware CGI to provide dumb HTTP transport
From: Shawn O. Pearce @ 2009-10-09 5:22 UTC (permalink / raw)
To: git
In-Reply-To: <1255065768-10428-2-git-send-email-spearce@spearce.org>
The git-http-backend CGI can be configured into any Apache server
using ScriptAlias, such as with the following configuration:
LoadModule cgi_module /usr/libexec/apache2/mod_cgi.so
LoadModule alias_module /usr/libexec/apache2/mod_alias.so
ScriptAlias /git/ /usr/libexec/git-core/git-http-backend/
Repositories are accessed via the translated PATH_INFO.
The CGI is backwards compatible with the dumb client, allowing all
older HTTP clients to continue to download repositories which are
managed by the CGI.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
---
.gitignore | 1 +
Makefile | 1 +
http-backend.c | 261 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 263 insertions(+), 0 deletions(-)
create mode 100644 http-backend.c
diff --git a/.gitignore b/.gitignore
index 51a37b1..353d22f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -55,6 +55,7 @@ git-get-tar-commit-id
git-grep
git-hash-object
git-help
+git-http-backend
git-http-fetch
git-http-push
git-imap-send
diff --git a/Makefile b/Makefile
index dd3d520..c80fb56 100644
--- a/Makefile
+++ b/Makefile
@@ -361,6 +361,7 @@ PROGRAMS += git-show-index$X
PROGRAMS += git-unpack-file$X
PROGRAMS += git-upload-pack$X
PROGRAMS += git-var$X
+PROGRAMS += git-http-backend$X
# List built-in command $C whose implementation cmd_$C() is not in
# builtin-$C.o but is linked in as part of some other command.
diff --git a/http-backend.c b/http-backend.c
new file mode 100644
index 0000000..39cfd25
--- /dev/null
+++ b/http-backend.c
@@ -0,0 +1,261 @@
+#include "cache.h"
+#include "refs.h"
+#include "pkt-line.h"
+#include "object.h"
+#include "tag.h"
+#include "exec_cmd.h"
+#include "run-command.h"
+
+static const char content_type[] = "Content-Type";
+static const char content_length[] = "Content-Length";
+
+static char buffer[1024];
+
+static const char *http_date(unsigned long time)
+{
+ return show_date(time, 0, DATE_RFC2822);
+}
+
+static void format_write(const char *fmt, ...)
+{
+ va_list args;
+ unsigned n;
+
+ va_start(args, fmt);
+ n = vsnprintf(buffer, sizeof(buffer), fmt, args);
+ va_end(args);
+ if (n >= sizeof(buffer))
+ die("protocol error: impossibly long line");
+
+ safe_write(1, buffer, n);
+}
+
+static void write_status(unsigned code, const char *msg)
+{
+ format_write("Status: %u %s\r\n", code, msg);
+}
+
+static void write_header(const char *name, const char *value)
+{
+ format_write("%s: %s\r\n", name, value);
+}
+
+static void end_headers(void)
+{
+ safe_write(1, "\r\n", 2);
+}
+
+static void write_nocache(void)
+{
+ write_header("Expires", "Fri, 01 Jan 1980 00:00:00 GMT");
+ write_header("Pragma", "no-cache");
+ write_header("Cache-Control", "no-cache, max-age=0, must-revalidate");
+}
+
+static void write_cache_forever(void)
+{
+ unsigned long now = time(NULL);
+ write_header("Date", http_date(now));
+ write_header("Expires", http_date(now + 31536000));
+ write_header("Cache-Control", "public, max-age=31536000");
+}
+
+static NORETURN void not_found(const char *err, ...)
+{
+ va_list params;
+
+ write_status(404, "Not Found");
+ write_nocache();
+ end_headers();
+
+ va_start(params, err);
+ if (err && *err) {
+ vsnprintf(buffer, sizeof(buffer), err, params);
+ fprintf(stderr, "%s\n", buffer);
+ }
+ va_end(params);
+ exit(0);
+}
+
+static void write_file(const char *the_type, const char *name)
+{
+ const char *p = git_path("%s", name);
+ int fd;
+ struct stat sb;
+ uintmax_t remaining;
+
+ fd = open(p, O_RDONLY);
+ if (fd < 0)
+ not_found("Cannot open '%s': %s", p, strerror(errno));
+ if (fstat(fd, &sb) < 0)
+ die_errno("Cannot stat '%s'", p);
+ remaining = (uintmax_t)sb.st_size;
+
+ write_header(content_type, the_type);
+ write_header("Last-Modified", http_date(sb.st_mtime));
+ format_write("Content-Length: %" PRIuMAX "\r\n", remaining);
+ end_headers();
+
+ while (remaining) {
+ ssize_t n = xread(fd, buffer, sizeof(buffer));
+ if (n < 0)
+ die_errno("Cannot read '%s'", p);
+ n = safe_write(1, buffer, n);
+ if (n <= 0)
+ break;
+ }
+ close(fd);
+}
+
+static void get_text_file(char *name)
+{
+ write_nocache();
+ write_file("text/plain; charset=utf-8", name);
+}
+
+static void get_loose_object(char *name)
+{
+ write_cache_forever();
+ write_file("application/x-git-loose-object", name);
+}
+
+static void get_pack_file(char *name)
+{
+ write_cache_forever();
+ write_file("application/x-git-packed-objects", name);
+}
+
+static void get_idx_file(char *name)
+{
+ write_cache_forever();
+ write_file("application/x-git-packed-objects-toc", name);
+}
+
+static int show_text_ref(const char *name, const unsigned char *sha1,
+ int flag, void *cb_data)
+{
+ struct object *o = parse_object(sha1);
+ if (!o)
+ return 0;
+
+ format_write("%s\t%s\n", sha1_to_hex(sha1), name);
+ if (o->type == OBJ_TAG) {
+ o = deref_tag(o, name, 0);
+ if (!o)
+ return 0;
+ format_write("%s\t%s^{}\n", sha1_to_hex(o->sha1), name);
+ }
+
+ return 0;
+}
+
+static void get_info_refs(char *arg)
+{
+ write_nocache();
+ write_header(content_type, "text/plain; charset=utf-8");
+ end_headers();
+
+ for_each_ref(show_text_ref, NULL);
+}
+
+static void get_info_packs(char *arg)
+{
+ size_t objdirlen = strlen(get_object_directory());
+ struct packed_git *p;
+
+ write_nocache();
+ write_header(content_type, "text/plain; charset=utf-8");
+ end_headers();
+
+ prepare_packed_git();
+ for (p = packed_git; p; p = p->next) {
+ if (!p->pack_local)
+ continue;
+ format_write("P %s\n", p->pack_name + objdirlen + 6);
+ }
+ safe_write(1, "\n", 1);
+}
+
+static NORETURN void die_webcgi(const char *err, va_list params)
+{
+ write_status(500, "Internal Server Error");
+ write_nocache();
+ end_headers();
+
+ vsnprintf(buffer, sizeof(buffer), err, params);
+ fprintf(stderr, "fatal: %s\n", buffer);
+ exit(0);
+}
+
+static struct service_cmd {
+ const char *method;
+ const char *pattern;
+ void (*imp)(char *);
+} services[] = {
+ {"GET", "/HEAD$", get_text_file},
+ {"GET", "/info/refs$", get_info_refs},
+ {"GET", "/objects/info/packs$", get_info_packs},
+ {"GET", "/objects/info/[^/]*$", get_text_file},
+ {"GET", "/objects/[0-9a-f]{2}/[0-9a-f]{38}$", get_loose_object},
+ {"GET", "/objects/pack/pack-[0-9a-f]{40}\\.pack$", get_pack_file},
+ {"GET", "/objects/pack/pack-[0-9a-f]{40}\\.idx$", get_idx_file}
+};
+
+int main(int argc, char **argv)
+{
+ char *dir = getenv("PATH_TRANSLATED");
+ char *input_method = getenv("REQUEST_METHOD");
+ struct service_cmd *cmd = NULL;
+ char *cmd_arg = NULL;
+ int i;
+
+ set_die_routine(die_webcgi);
+
+ if (!dir)
+ die("No PATH_TRANSLATED from server");
+ if (!input_method)
+ die("No REQUEST_METHOD from server");
+ if (!strcmp(input_method, "HEAD"))
+ input_method = "GET";
+
+ for (i = 0; i < ARRAY_SIZE(services); i++) {
+ struct service_cmd *c = &services[i];
+ regex_t re;
+ regmatch_t out[1];
+
+ if (regcomp(&re, c->pattern, REG_EXTENDED))
+ die("Bogus regex in service table: %s", c->pattern);
+ if (!regexec(&re, dir, 1, out, 0)) {
+ size_t n = out[0].rm_eo - out[0].rm_so;
+
+ if (strcmp(input_method, c->method)) {
+ const char *proto = getenv("SERVER_PROTOCOL");
+ if (proto && !strcmp(proto, "HTTP/1.1"))
+ write_status(405, "Method Not Allowed");
+ else
+ write_status(400, "Bad Request");
+ write_nocache();
+ end_headers();
+ return 0;
+ }
+
+ cmd = c;
+ cmd_arg = xmalloc(n);
+ strncpy(cmd_arg, dir + out[0].rm_so + 1, n);
+ cmd_arg[n] = '\0';
+ dir[out[0].rm_so] = 0;
+ break;
+ }
+ regfree(&re);
+ }
+
+ if (!cmd)
+ not_found("Request not supported: '%s'", dir);
+
+ setup_path();
+ if (!enter_repo(dir, 0))
+ not_found("Not a git repository: '%s'", dir);
+
+ cmd->imp(cmd_arg);
+ return 0;
+}
--
1.6.5.rc3.193.gdf7a
^ permalink raw reply related
* [RFC PATCH 4/4] Smart fetch and push over HTTP: server side
From: Shawn O. Pearce @ 2009-10-09 5:22 UTC (permalink / raw)
To: git
In-Reply-To: <1255065768-10428-4-git-send-email-spearce@spearce.org>
Requests for $GIT_URL/git-receive-pack and $GIT_URL/git-upload-pack
are forwarded to the corresponding backend process by directly
executing it and leaving stdin and stdout connected to the web
server. Prior to starting the backend HTTP headers are sent, thereby
freeing the backend from needing to know about the HTTP protocol.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
---
http-backend.c | 135 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 134 insertions(+), 1 deletions(-)
diff --git a/http-backend.c b/http-backend.c
index 39cfd25..978f820 100644
--- a/http-backend.c
+++ b/http-backend.c
@@ -77,6 +77,95 @@ static NORETURN void not_found(const char *err, ...)
exit(0);
}
+static NORETURN void forbidden(const char *err, ...)
+{
+ va_list params;
+
+ write_status(403, "Forbidden");
+ write_nocache();
+ end_headers();
+
+ va_start(params, err);
+ if (err && *err) {
+ vsnprintf(buffer, sizeof(buffer), err, params);
+ fprintf(stderr, "%s\n", buffer);
+ }
+ va_end(params);
+ exit(0);
+}
+
+struct http_service {
+ const char *name;
+ const char *config_name;
+ int enabled;
+};
+static struct http_service *service;
+
+static struct http_service http_service[] = {
+ { "upload-pack", "uploadpack", 1 },
+ { "receive-pack", "receivepack", 0 },
+};
+
+static int http_config(const char *var, const char *value, void *cb)
+{
+ if (!prefixcmp(var, "http.") &&
+ !strcmp(var + 7, service->config_name)) {
+ service->enabled = git_config_bool(var, value);
+ return 0;
+ }
+
+ /* we are not interested in parsing any other configuration here */
+ return 0;
+}
+
+static void select_service(const char *name)
+{
+ int i;
+
+ if (prefixcmp(name, "git-"))
+ forbidden("Unsupported service: '%s'", name);
+
+ for (i = 0; i < ARRAY_SIZE(http_service); i++) {
+ service = &http_service[i];
+ if (!strcmp(service->name, name + 4)) {
+ git_config(http_config, NULL);
+ if (!service->enabled)
+ forbidden("Service not enabled: '%s'", name);
+ return;
+ }
+ }
+ forbidden("Unsupported service: '%s'", name);
+}
+
+static void run_service(const char **argv)
+{
+#ifndef WIN32
+ execv_git_cmd(argv);
+#else
+ struct child_process cld;
+
+ memset(&cld, 0, sizeof(cld));
+ cld.argv = argv;
+ cld.git_cmd = 1;
+ if (start_command(&cld))
+ die("Cannot start git-%s service", service->name);
+ close(0);
+ close(1);
+ finish_command(&cld);
+#endif
+}
+
+static void require_content_type(const char *need_type)
+{
+ const char *input_type = getenv("CONTENT_TYPE");
+ if (!input_type || strcmp(input_type, need_type)) {
+ write_status(415, "Unsupported Media Type");
+ write_nocache();
+ end_headers();
+ exit(0);
+ }
+}
+
static void write_file(const char *the_type, const char *name)
{
const char *p = git_path("%s", name);
@@ -151,6 +240,25 @@ static int show_text_ref(const char *name, const unsigned char *sha1,
static void get_info_refs(char *arg)
{
+ char *query = getenv("QUERY_STRING");
+
+ if (query && !prefixcmp(query, "service=")) {
+ const char *argv[] = {NULL /* service name */,
+ "--smart-http", "--advertise-refs",
+ ".", NULL};
+
+ select_service(query + 8);
+
+ write_nocache();
+ format_write("%s: application/x-git-%s-advertisement\r\n",
+ content_type, service->name);
+ end_headers();
+ packet_write(1, "# service=git-%s\n", service->name);
+
+ argv[0] = service->name;
+ run_service(argv);
+ }
+
write_nocache();
write_header(content_type, "text/plain; charset=utf-8");
end_headers();
@@ -176,6 +284,28 @@ static void get_info_packs(char *arg)
safe_write(1, "\n", 1);
}
+static void post_to_service(char *service_name)
+{
+ const char *argv[] = {NULL, "--smart-http", ".", NULL};
+ unsigned n;
+
+ select_service(service_name);
+
+ n = snprintf(buffer, sizeof(buffer),
+ "application/x-git-%s-request", service->name);
+ if (n >= sizeof(buffer))
+ die("impossibly long service name");
+ require_content_type(buffer);
+
+ write_nocache();
+ format_write("%s: application/x-git-%s-result\r\n",
+ content_type, service->name);
+ end_headers();
+
+ argv[0] = service->name;
+ run_service(argv);
+}
+
static NORETURN void die_webcgi(const char *err, va_list params)
{
write_status(500, "Internal Server Error");
@@ -198,7 +328,10 @@ static struct service_cmd {
{"GET", "/objects/info/[^/]*$", get_text_file},
{"GET", "/objects/[0-9a-f]{2}/[0-9a-f]{38}$", get_loose_object},
{"GET", "/objects/pack/pack-[0-9a-f]{40}\\.pack$", get_pack_file},
- {"GET", "/objects/pack/pack-[0-9a-f]{40}\\.idx$", get_idx_file}
+ {"GET", "/objects/pack/pack-[0-9a-f]{40}\\.idx$", get_idx_file},
+
+ {"POST", "/git-upload-pack$", post_to_service},
+ {"POST", "/git-receive-pack$", post_to_service}
};
int main(int argc, char **argv)
--
1.6.5.rc3.193.gdf7a
^ permalink raw reply related
* [RFC PATCH 1/4] Document the HTTP transport protocol
From: Shawn O. Pearce @ 2009-10-09 5:22 UTC (permalink / raw)
To: git
In-Reply-To: <1255065768-10428-1-git-send-email-spearce@spearce.org>
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
---
Documentation/technical/http-protocol.txt | 542 +++++++++++++++++++++++++++++
1 files changed, 542 insertions(+), 0 deletions(-)
create mode 100644 Documentation/technical/http-protocol.txt
diff --git a/Documentation/technical/http-protocol.txt b/Documentation/technical/http-protocol.txt
new file mode 100644
index 0000000..316d9b6
--- /dev/null
+++ b/Documentation/technical/http-protocol.txt
@@ -0,0 +1,542 @@
+HTTP transfer protocols
+=======================
+
+Git supports two HTTP based transfer protocols. A "dumb" protocol
+which requires only a standard HTTP server on the server end of the
+connection, and a "smart" protocol which requires a Git aware CGI
+(or server module). This document describes both protocols.
+
+As a design feature smart clients can automatically upgrade "dumb"
+protocol URLs to smart URLs. This permits all users to have the
+same published URL, and the peers automatically select the most
+efficient transport available to them.
+
+
+URL Format
+----------
+
+URLs for Git repositories accessed by HTTP use the standard HTTP
+URL syntax documented by RFC 1738, so they are of the form:
+
+ http://<host>:<port>/<path>
+
+Within this documentation the placeholder $GIT_URL will stand for
+the http:// repository URL entered by the end-user.
+
+Both the "smart" and "dumb" HTTP protocols used by Git operate
+by appending additional path components onto the end of the user
+supplied $GIT_URL string.
+
+Clients MUST strip a trailing '/', if present, from the user supplied
+$GIT_URL string to prevent empty path tokens ('//') from appearing
+in any URL sent to a server. Compatible clients must expand
+'$GIT_URL/info/refs' as 'foo/info/refs' and not 'foo//info/refs'.
+
+
+Authentication
+--------------
+
+Standard HTTP authentication is used if authentication is required
+to access a repository, and MAY be configured and enforced by the
+HTTP server software.
+
+Because Git repositories are accessed by standard path components
+server administrators MAY use directory based permissions within
+their HTTP server to control repository access.
+
+Clients SHOULD support Basic authentication as described by RFC 2616.
+Servers SHOULD support Basic authentication by relying upon the
+HTTP server placed in front of the Git server software.
+
+Servers MUST NOT require HTTP cookies for the purposes of
+authentication or access control.
+
+Clients and servers MAY support other common forms of HTTP based
+authentication, such as Digest authentication.
+
+
+SSL
+---
+
+Clients and servers SHOULD support SSL, particularly to protect
+passwords when relying on Basic HTTP authentication.
+
+
+Session State
+-------------
+
+The Git over HTTP protocol (much like HTTP itself) is stateless
+from the perspective of the HTTP server side. All state must be
+retained and managed by the client process. This permits simple
+round-robin load-balancing on the server side, without needing to
+worry about state mangement.
+
+Clients MUST NOT require state management on the server side in
+order to function correctly.
+
+Servers MUST NOT require HTTP cookies in order to function correctly.
+Clients MAY store and forward HTTP cookies during request processing
+as described by RFC 2616 (HTTP/1.1). Servers SHOULD ignore any
+cookies sent by a client.
+
+
+pkt-line Format
+---------------
+
+Much (but not all) of the payload is described around pkt-lines.
+
+A pkt-line is a variable length binary string. The first four bytes
+of the line indicates the total length of the line, in hexadecimal.
+The total length includes the 4 bytes used to denote the length.
+A line SHOULD BE terminated by an LF, which if present MUST be
+included in the total length.
+
+A pkt-line MAY contain binary data, so implementors MUST ensure all
+pkt-line parsing/formatting routines are 8-bit clean. The maximum
+length of a pkt-line's data is 65532 bytes (65536 - 4).
+
+Examples (as C-style strings):
+
+ pkt-line actual value
+ ---------------------------------
+ "0006a\n" "a\n"
+ "0005a" "a"
+ "000bfoobar\n" "foobar\n"
+ "0004" ""
+
+A pkt-line with a length of 0 ("0000") is a special case and MUST
+be treated as a message break or terminator in the payload.
+
+
+General Request Processing
+--------------------------
+
+Except where noted, all standard HTTP behavior SHOULD be assumed
+by both client and server. This includes (but is not necessarily
+limited to):
+
+If there is no repository at $GIT_URL, the server MUST respond with
+the '404 Not Found' HTTP status code.
+
+If there is a repository at $GIT_URL, but access is not currently
+permitted, the server MUST respond with the '403 Forbidden' HTTP
+status code.
+
+Servers SHOULD support both HTTP 1.0 and HTTP 1.1.
+Servers SHOULD support chunked encoding for both
+request and response bodies.
+
+Clients SHOULD support both HTTP 1.0 and HTTP 1.1.
+Clients SHOULD support chunked encoding for both
+request and response bodies.
+
+Servers MAY return ETag and/or Last-Modified headers.
+
+Clients MAY revalidate cached entities by including If-Modified-Since
+and/or If-None-Match request headers.
+
+Servers MAY return '304 Not Modified' if the relevant headers appear
+in the request and the entity has not changed. Clients MUST treat
+'304 Not Modified' identical to '200 OK' by reusing the cached entity.
+
+Clients MAY reuse a cached entity without revalidation if the
+Cache-Control and/or Expires header permits caching. Clients and
+servers MUST follow RFC 2616 for cache controls.
+
+
+Discovering References
+----------------------
+
+All HTTP clients MUST begin either a fetch or a push exchange by
+discovering the references available on the remote repository.
+
+Dumb Clients
+~~~~~~~~~~~~
+
+HTTP clients that only support the "dumb" protocol MUST discover
+references by making a request for the special info/refs file of
+the repository.
+
+Dumb HTTP clients MUST NOT include search/query parameters when
+fetching the info/refs file. (That is, '?' must not appear in the
+requested URL.)
+
+ C: GET $GIT_URL/info/refs HTTP/1.0
+
+ S: 200 OK
+ S:
+ S: 95dcfa3633004da0049d3d0fa03f80589cbcaf31 refs/heads/maint
+ S: d049f6c27a2244e12041955e262a404c7faba355 refs/heads/master
+ S: 2cb58b79488a98d2721cea644875a8dd0026b115 refs/tags/v1.0
+ S: a3c2e2402b99163d1d59756e5f207ae21cccba4c refs/tags/v1.0^{}
+
+The Content-Type of the returned info/refs entity SHOULD be
+"text/plain; charset=utf-8", but MAY be any content type.
+Clients MUST NOT attempt to validate the returned Content-Type.
+Dumb servers MUST NOT return a return type starting with
+"application/x-git-".
+
+Cache-Control headers MAY be returned to disable caching of the
+returned entity.
+
+When examining the response clients SHOULD only examine the HTTP
+status code. Valid responses are '200 OK', or '304 Not Modified'.
+
+The returned content is a UNIX formatted text file describing
+each ref and its known value. The file SHOULD be sorted by name
+according to the C locale ordering. The file SHOULD NOT include
+the default ref named 'HEAD'.
+
+ info_refs = *( ref_record )
+ ref_record = any_ref | peeled_ref
+
+ any_ref = id HT name LF
+ peeled_ref = id HT name LF
+ id HT name "^{}" LF
+ id = 40*HEX
+
+ HEX = "0".."9" | "a".."f"
+ LF = <US-ASCII LF, linefeed (10)>
+ HT = <US-ASCII HT, horizontal-tab (9)>
+
+Smart Clients
+~~~~~~~~~~~~~
+
+HTTP clients that support the "smart" protocol (or both the
+"smart" and "dumb" protocols) MUST discover references by making
+a paramterized request for the info/refs file of the repository.
+
+The request MUST contain exactly one query parameter,
+'service=$servicename', where $servicename MUST be the service
+name the client wishes to contact to complete the operation.
+The request MUST NOT contain additional query parameters.
+
+ C: GET $GIT_URL/info/refs?service=git-upload-pack HTTP/1.0
+
+ dumb server reply:
+ S: 200 OK
+ S:
+ S: 95dcfa3633004da0049d3d0fa03f80589cbcaf31 refs/heads/maint
+ S: d049f6c27a2244e12041955e262a404c7faba355 refs/heads/master
+ S: 2cb58b79488a98d2721cea644875a8dd0026b115 refs/tags/v1.0
+ S: a3c2e2402b99163d1d59756e5f207ae21cccba4c refs/tags/v1.0^{}
+
+ smart server reply:
+ S: 200 OK
+ S: Content-Type: application/x-git-upload-pack-advertisement
+ S: Cache-Control: no-cache
+ S:
+ S: ....# service=git-upload-pack
+ S: ....95dcfa3633004da0049d3d0fa03f80589cbcaf31 refs/heads/maint\0 multi_ack
+ S: ....d049f6c27a2244e12041955e262a404c7faba355 refs/heads/master
+ S: ....2cb58b79488a98d2721cea644875a8dd0026b115 refs/tags/v1.0
+ S: ....a3c2e2402b99163d1d59756e5f207ae21cccba4c refs/tags/v1.0^{}
+
+Dumb Server Response
+^^^^^^^^^^^^^^^^^^^^
+Dumb servers MUST respond with the dumb server reply format.
+
+See the prior section under dumb clients for a more detailed
+description of the dumb server response.
+
+Smart Server Response
+^^^^^^^^^^^^^^^^^^^^^
+Smart servers MUST respond with the smart server reply format.
+
+If the server does not recognize the requested service name, or the
+requested service name has been disabled by the server administrator,
+the server MUST respond with the '403 Forbidden' HTTP status code.
+
+Cache-Control headers SHOULD be used to disable caching of the
+returned entity.
+
+The Content-Type MUST be 'application/x-$servicename-advertisement'.
+Clients SHOULD fall back to the dumb protocol if another content
+type is returned. When falling back to the dumb protocol clients
+SHOULD NOT make an additional request to $GIT_URL/info/refs, but
+instead SHOULD use the response already in hand. Clients MUST NOT
+continue if they do not support the dumb protocol.
+
+Clients MUST validate the status code is either '200 OK' or
+'304 Not Modified'.
+
+Clients MUST validate the first five bytes of the response entity
+matches the regex "^[0-9a-f]{4}#". If this test fails, clients
+MUST NOT continue.
+
+Clients MUST parse the entire response as a sequence of pkt-line
+records.
+
+Clients MUST verify the first pkt-line is "# service=$servicename".
+Servers MUST set $servicename to be the request parameter value.
+Servers SHOULD include an LF at the end of this line.
+Clients MUST ignore an LF at the end of the line.
+
+Servers MUST terminate the response with the magic "0000" end
+pkt-line marker.
+
+The returned response is a pkt-line stream describing each ref and
+its known value. The stream SHOULD be sorted by name according to
+the C locale ordering. The stream SHOULD include the default ref
+named 'HEAD' as the first ref. The stream MUST include capability
+declarations behind a NUL on the first ref.
+
+ smart_reply = PKT-LINE("# service=$servicename" LF)
+ ref_list
+ "0000"
+ ref_list = empty_list | populated_list
+
+ empty_list = PKT-LINE(id SP "capabilities^{}" NUL cap_list LF)
+
+ non_empty_list = PKT-LINE(id SP name NUL cap_list LF)
+ *ref_record
+
+ cap_list = *(SP capability) SP
+ ref_record = any_ref | peeled_ref
+
+ any_ref = PKT-LINE(id SP name LF)
+ peeled_ref = PKT-LINE(id SP name LF)
+ PKT-LINE(id SP name "^{}" LF
+ id = 40*HEX
+
+ HEX = "0".."9" | "a".."f"
+ NL = <US-ASCII NUL, null (0)>
+ LF = <US-ASCII LF, linefeed (10)>
+ SP = <US-ASCII SP, horizontal-tab (9)>
+
+
+Smart Service git-upload-pack
+------------------------------
+This service reads from the remote repository.
+
+Clients MUST first perform ref discovery with
+'$GIT_URL/info/refs?service=git-upload-pack'.
+
+ C: POST $GIT_URL/git-upload-pack HTTP/1.0
+ C: Content-Type: application/x-git-upload-pack-request
+ C:
+ C: ....want 0a53e9ddeaddad63ad106860237bbf53411d11a7
+ C: ....have 441b40d833fdfa93eb2908e52742248faf0ee993
+ C: 0000
+
+ S: 200 OK
+ S: Content-Type: application/x-git-upload-pack-result
+ S: Cache-Control: no-cache
+ S:
+ S: ....ACK %s, continue
+ S: ....NAK
+
+Clients MUST NOT reuse or revalidate a cached reponse.
+Servers MUST include sufficient Cache-Control headers
+to prevent caching of the response.
+
+Servers SHOULD support all capabilities defined here.
+
+Clients MUST send at least one 'want' command in the request body.
+Clients MUST NOT reference an id in a 'want' command which did not
+appear in the response obtained through ref discovery.
+
+ compute_request = want_list
+ have_list
+ request_end
+ request_end = "0000" | "done"
+
+ want_list = PKT-LINE(want NUL cap_list LF)
+ *(want_pkt)
+ want_pkt = PKT-LINE(want LF)
+ want = "want" SP id
+ cap_list = *(SP capability) SP
+
+ have_list = *PKT-LINE("have" SP id LF)
+
+ command = create | delete | update
+ create = 40*"0" SP new_id SP name
+ delete = old_id SP 40*"0" SP name
+ update = old_id SP new_id SP name
+
+TODO: Document this further.
+TODO: Don't use uppercase for variable names below.
+
+Capability include-tag
+~~~~~~~~~~~~~~~~~~~~~~
+
+When packing an object that an annotated tag points at, include the
+tag object too. Clients can request this if they want to fetch
+tags, but don't know which tags they will need until after they
+receive the branch data. By enabling include-tag an entire call
+to upload-pack can be avoided.
+
+Capability thin-pack
+~~~~~~~~~~~~~~~~~~~~
+
+When packing a deltified object the base is not included if the base
+is reachable from an object listed in the COMMON set by the client.
+This reduces the bandwidth required to transfer, but it does slightly
+increase processing time for the client to save the pack to disk.
+
+The Negotiation Algorithm
+~~~~~~~~~~~~~~~~~~~~~~~~~
+The computation to select the minimal pack proceeds as follows
+(c = client, s = server):
+
+ init step:
+ (c) Use ref discovery to obtain the advertised refs.
+ (c) Place any object seen into set ADVERTISED.
+
+ (c) Build an empty set, COMMON, to hold the objects that are later
+ determined to be on both ends.
+ (c) Build a set, WANT, of the objects from ADVERTISED the client
+ wants to fetch, based on what it saw during ref discovery.
+
+ (c) Start a queue, C_PENDING, ordered by commit time (popping newest
+ first). Add all client refs. When a commit is popped from
+ the queue its parents should be automatically inserted back.
+ Commits MUST only enter the queue once.
+
+ one compute step:
+ (c) Send one $GIT_URL/git-upload-pack request:
+
+ C: 0032want <WANT #1>...............................
+ C: 0032want <WANT #2>...............................
+ ....
+ C: 0032have <COMMON #1>.............................
+ C: 0032have <COMMON #2>.............................
+ ....
+ C: 0032have <HAVE #1>...............................
+ C: 0032have <HAVE #2>...............................
+ ....
+ C: 0000
+
+ The stream is organized into "commands", with each command
+ appearing by itself in a pkt-line. Within a command line
+ the text leading up to the first space is the command name,
+ and the remainder of the line to the first LF is the value.
+ Command lines are terminated with an LF as the last byte of
+ the pkt-line value.
+
+ Commands MUST appear in the following order, if they appear
+ at all in the request stream:
+
+ * want
+ * have
+
+ The stream is terminated by a pkt-line flush ("0000").
+
+ A single "want" or "have" command MUST have one hex formatted
+ SHA-1 as its value. Multiple SHA-1s MUST be sent by sending
+ multiple commands.
+
+ The HAVE list is created by popping the first 32 commits
+ from C_PENDING. Less can be supplied if C_PENDING empties.
+
+ If the client has sent 256 HAVE commits and has not yet
+ received one of those back from S_COMMON, or the client has
+ emptied C_PENDING it should include a "done" command to let
+ the server know it won't proceed:
+
+ C: 0009done
+
+ (s) Parse the git-upload-pack request:
+
+ Verify all objects in WANT are directly reachable from refs.
+
+ The server MAY walk backwards through history or through
+ the reflog to permit slightly stale requests.
+
+ If no WANT objects are received, send an error:
+
+TODO: Define error if no want lines are requested.
+
+ If any WANT object is not reachable, send an error:
+
+TODO: Define error if an invalid want is requested.
+
+ Create an empty list, S_COMMON.
+
+ If 'have' was sent:
+
+ Loop through the objects in the order supplied by the client.
+ For each object, if the server has the object reachable from
+ a ref, add it to S_COMMON. If a commit is added to S_COMMON,
+ do not add any ancestors, even if they also appear in HAVE.
+
+ (s) Send the git-upload-pack response:
+
+ If the server has found a closed set of objects to pack or the
+ request ends with "done", it replies with the pack.
+
+TODO: Document the pack based response
+ S: PACK...
+
+ The returned stream is the side-band-64k protocol supported
+ by the git-upload-pack service, and the pack is embedded into
+ stream 1. Progress messages from the server side may appear
+ in stream 2.
+
+ Here a "closed set of objects" is defined to have at least
+ one path from every WANT to at least one COMMON object.
+
+ If the server needs more information, it replies with a
+ status continue response:
+
+TODO: Document the non-pack response
+
+ (c) Parse the upload-pack response:
+
+TODO: Document parsing response
+
+ Do another compute step.
+
+
+Smart Service git-receive-pack
+------------------------------
+This service modifies the remote repository.
+
+Clients MUST first perform ref discovery with
+'$GIT_URL/info/refs?service=git-receive-pack'.
+
+ C: POST $GIT_URL/git-receive-pack HTTP/1.0
+ C: Content-Type: application/x-git-receive-pack-request
+ C:
+ C: ....0a53e9ddeaddad63ad106860237bbf53411d11a7 441b40d833fdfa93eb2908e52742248faf0ee993 refs/heads/maint\0 report-status
+ C: 0000
+ C: PACK....
+
+ S: 200 OK
+ S: Content-Type: application/x-git-receive-pack-result
+ S: Cache-Control: no-cache
+ S:
+ S: ....
+
+Clients MUST NOT reuse or revalidate a cached reponse.
+Servers MUST include sufficient Cache-Control headers
+to prevent caching of the response.
+
+Servers SHOULD support all capabilities defined here.
+
+Clients MUST send at least one command in the request body.
+Within the command portion of the request body clients SHOULD send
+the id obtained through ref discovery as old_id.
+
+ update_request = command_list
+ "PACK" <binary data>
+
+ command_list = PKT-LINE(command NUL cap_list LF)
+ *(command_pkt)
+ command_pkt = PKT-LINE(command LF)
+ cap_list = *(SP capability) SP
+
+ command = create | delete | update
+ create = 40*"0" SP new_id SP name
+ delete = old_id SP 40*"0" SP name
+ update = old_id SP new_id SP name
+
+TODO: Document this further.
+
+
+References
+----------
+
+link:http://www.ietf.org/rfc/rfc1738.txt[RFC 1738: Uniform Resource Locators (URL)]
+link:http://www.ietf.org/rfc/rfc2616.txt[RFC 2616: Hypertext Transfer Protocol -- HTTP/1.1]
+
--
1.6.5.rc3.193.gdf7a
^ permalink raw reply related
* [RFC PATCH 0/4] Return of smart HTTP
From: Shawn O. Pearce @ 2009-10-09 5:22 UTC (permalink / raw)
To: git
This is an RFC series to restart the smart HTTP transport work.
Those familiar with the native git:// protocol should be able to
quickly understand what I'm doing here by looking at only the last
two patches.
This time around I actually have the whole thing fully implemented
in JGit (both client and server), and am now trying to port that
over to C git.git, as well as document it in depth.
The JGit series can be found here at Eclipse.org:
http://egit.eclipse.org/r/
git://egit.eclipse.org/egit/parallelip-jgit refs/changes/50/50/4
This RFC C Git series only implements the server side, and only
has partial documentation. I did some limited smoke testing with
the JGit client against this server, it seems to work as expected.
I plan on trying to write the C Git clients tomorrow. The
send-pack/receive-pack protocol is trivial and shouldn't be
that hard, but the fetch-pack/upload-pack protocol is going
to be somewhat interesting...
Shawn O. Pearce (4):
Document the HTTP transport protocol
Git-aware CGI to provide dumb HTTP transport
Add smart-http options to upload-pack, receive-pack
Smart fetch and push over HTTP: server side
.gitignore | 1 +
Documentation/technical/http-protocol.txt | 542 +++++++++++++++++++++++++++++
Makefile | 1 +
builtin-receive-pack.c | 26 +-
http-backend.c | 394 +++++++++++++++++++++
upload-pack.c | 40 ++-
6 files changed, 994 insertions(+), 10 deletions(-)
create mode 100644 Documentation/technical/http-protocol.txt
create mode 100644 http-backend.c
^ permalink raw reply
* [PATCH] ls-files: die instead of fprintf/exit in -i error
From: Ben Walton @ 2009-10-09 1:53 UTC (permalink / raw)
To: bebarino, gitster; +Cc: git, Ben Walton
In-Reply-To: <4ACE4C72.4050400@gmail.com>
When ls-files was called with -i but no exclude pattern, it was
calling fprintf(stderr, "...", NULL) and then exiting. On Solaris,
passing NULL into fprintf was causing a segfault. On glibc systems,
it was simply producing incorrect output (eg: "(null)": ...). The
NULL pointer was a result of argv[0] not being preserved by the option
parser. Instead of requesting that the option parser preserve
argv[0], use die() with a constant string.
A trigger for this bug was: `git ls-files -i`
Signed-off-by: Ben Walton <bwalton@artsci.utoronto.ca>
---
This is the alternate solution to this bug as proposed earlier today.
I don't have a preference either way for which solution is better or
more inline with the 'git way,' so please choose the most appropriate.
I've run the test suite with both patches on Linux and Solaris
and everything passes.
builtin-ls-files.c | 7 ++-----
1 files changed, 2 insertions(+), 5 deletions(-)
diff --git a/builtin-ls-files.c b/builtin-ls-files.c
index f473220..2c95ca6 100644
--- a/builtin-ls-files.c
+++ b/builtin-ls-files.c
@@ -524,11 +524,8 @@ int cmd_ls_files(int argc, const char **argv, const char *prefix)
ps_matched = xcalloc(1, num);
}
- if ((dir.flags & DIR_SHOW_IGNORED) && !exc_given) {
- fprintf(stderr, "%s: --ignored needs some exclude pattern\n",
- argv[0]);
- exit(1);
- }
+ if ((dir.flags & DIR_SHOW_IGNORED) && !exc_given)
+ die("ls-files --ignored needs some exclude pattern");
/* With no flags, we default to showing the cached files */
if (!(show_stage | show_deleted | show_others | show_unmerged |
--
1.6.4.4
^ permalink raw reply related
* Re: What's cooking in git.git (Oct 2009, #01; Wed, 07)
From: Jakub Narebski @ 2009-10-09 1:38 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <7viqeqjsx6.fsf@alter.siamese.dyndns.org>
Junio C Hamano <gitster@pobox.com> writes:
> --------------------------------------------------
> [New Topics]
> * jn/gitweb-patch (2009-09-30) 1 commit
> - gitweb: Do not show 'patch' link in 'commit' view for merges
>
> jk: After some comments with Jakub, I think the code is right but he
> promised a re-roll with more in the commit message.
Not only better commit message, but a more complete patch as well.
> * mr/gitweb-snapshot (2009-09-26) 2 commits
> - gitweb: append short hash ids to snapshot files
> - gitweb: check given hash before trying to create snapshot
>
> jk: He posted a v5 of his series. I didn't look at it closely, but Jakub
> ack'd it.
Actually I acked first patch in series (the "check hash" one), but the
second needs review, and I think corrections. First there is matter
of tests and matter of not calling git_get_short_hash if it would not
be used (what was mentioned in my review). But what is more important
that now that gitweb doesn't use full SHA-1 unconditionally, we have
to deal with stripping prefix from refs/tags/v1.6.3-rc3 and
refs/heads/master, and with hierarchical branch names such as
'mr/gitweb-snapshot'. I'll post improved review soon.
In short: first patch is a go, second needs more work.
> * jc/pretty-lf (2009-10-04) 1 commit
> - Pretty-format: %[+-]x to tweak inter-item newlines
>
> I am not happy with this one yet. I am contemplating to introduce a new
> syntax "%[magic(param)<anything>%]" to generalize expressions of this and
> line wrapping features in an extensible way.
>
> * js/log-rewrap (2008-11-10) 3 commits
> . Add "%w" to pretty formats, which rewraps the commit message
> - Add strbuf_add_wrapped_text() to utf8.[ch]
> - print_wrapped_text(): allow hard newlines
>
> ... and the first two from this series will be useful to implement an
> example magic "wrap", e.g. "%{wrap(i,j,w)%s%+b%]".
So... it is magic %[...%] or %{...} or %{...%}?
BTW we can take rpm's queryformat as an example (or counterexample).
Also perhaps we can reuse minilanguage of git-for-each-ref format,
i.e. %(field:modifier).
> --------------------------------------------------
> [Cooking]
> * jn/gitweb-show-size (2009-09-07) 1 commit
> - gitweb: Add 'show-sizes' feature to show blob sizes in tree view
What this one requires (beside better name for a feature)?
> * jn/gitweb-blame (2009-09-01) 5 commits
> - gitweb: Minify gitweb.js if JSMIN is defined
> - gitweb: Create links leading to 'blame_incremental' using JavaScript
> (merged to 'next' on 2009-09-07 at 3622199)
> + gitweb: Colorize 'blame_incremental' view during processing
> + gitweb: Incremental blame (using JavaScript)
> + gitweb: Add optional "time to generate page" info in footer
>
> Ajax-y blame.
I reordered patches so JSMIN one is first (as it is less
controversial), but the 'create blame_incremental links' one needs
more work.
--
Jakub Narebski
Poland
ShadeHawk on #git
^ permalink raw reply
* combine git repo historically
From: bill lam @ 2009-10-09 1:22 UTC (permalink / raw)
To: git
I have two git repos, no branches.
repo 1.
emptyrootcommit -- A ... M
repo 2.
emptyrootcommit -- N ... Z
N was evolved from M but the time gap is large, how can I combine them
into one repo
emptyrootcommit -- A ... M -- N ... Z
so that snapshots N .. Z will not be changed.
--
regards,
====================================================
GPG key 1024D/4434BAB3 2008-08-24
gpg --keyserver subkeys.pgp.net --recv-keys 4434BAB3
^ permalink raw reply
* [PATCH] git-gui: Fixed compatibility for screen height equal 600 px
From: Vietor Liu @ 2009-10-09 0:32 UTC (permalink / raw)
To: spearce; +Cc: git, Vietor Liu
When the screen height equal 600 px, The Main Window should be hide
the Push button and Status bar. This patch support screen height
equal 600 (e.g. 800*600 1024*600).
Signed-off-by: Vietor Liu <vietor.liu@gmail.com>
---
git-gui.sh | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/git-gui.sh b/git-gui.sh
index 09b2720..037a1f2 100755
--- a/git-gui.sh
+++ b/git-gui.sh
@@ -3083,7 +3083,7 @@ frame .vpane.lower.diff.body
set ui_diff .vpane.lower.diff.body.t
text $ui_diff -background white -foreground black \
-borderwidth 0 \
- -width 80 -height 15 -wrap none \
+ -width 80 -height 5 -wrap none \
-font font_diff \
-xscrollcommand {.vpane.lower.diff.body.sbx set} \
-yscrollcommand {.vpane.lower.diff.body.sby set} \
--
1.6.5.rc3
^ permalink raw reply related
* Re: [PATCH] Makefile: add a note about the NO_MMAP setting on IRIX and IRIX64
From: Brandon Casey @ 2009-10-09 0:15 UTC (permalink / raw)
To: gitster; +Cc: git, Brandon Casey
In-Reply-To: <wTau-ugyVF7kG6Pxm7DRuWdrZABot_lbCcrG1e9aKIiNkU3X9L4ELEaLmN_rFVebheOs8fQEyx028yJUR9W-0w@cipher.nrlssc.navy.mil>
Brandon Casey wrote:
> From: Brandon Casey <drafnel@gmail.com>
>
> When git is compiled with the MIPSpro 7.4.4m compiler, and NO_PTHREADS is
> set, and NO_MMAP is _not_ set, then git segfaults when trying to access the
> first entry in a reflog. If NO_PTHREADS is not set (which implies that the
> pthread library is linked in), or NO_MMAP _is_ set, then the segfault is
> not encountered. The conservative choise has been made to set NO_MMAP in
^^^
I misspelled 'choice'. Doesn't seem worth a resend. If you can fix it before
you apply, that would be great. If you forget, no big deal.
-brandon
^ permalink raw reply
* [PATCH] Makefile: add a note about the NO_MMAP setting on IRIX and IRIX64
From: Brandon Casey @ 2009-10-09 0:09 UTC (permalink / raw)
To: gitster; +Cc: git, Brandon Casey
From: Brandon Casey <drafnel@gmail.com>
When git is compiled with the MIPSpro 7.4.4m compiler, and NO_PTHREADS is
set, and NO_MMAP is _not_ set, then git segfaults when trying to access the
first entry in a reflog. If NO_PTHREADS is not set (which implies that the
pthread library is linked in), or NO_MMAP _is_ set, then the segfault is
not encountered. The conservative choise has been made to set NO_MMAP in
the Makefile to avoid this flaw. The GNU C compiler does not produce this
behavior.
The segfault happens in refs.c:read_ref_at(). The mmap succeeds, and the
loop is executed properly until rec is rewound into the first line (reflog
entry) of the file. The segfault is caught by test 28 of
t1400-update-ref.sh which fails when 'git rev-parse --verify "master@{May 25
2005}"' is called.
So, add a comment in the Makefile to describe why NO_MMAP is set and as a
hint to those who may be interested in unsetting it.
Signed-off-by: Brandon Casey <casey@nrlssc.navy.mil>
---
Makefile | 12 ++++++++++++
1 files changed, 12 insertions(+), 0 deletions(-)
diff --git a/Makefile b/Makefile
index dd3d520..a340fb1 100644
--- a/Makefile
+++ b/Makefile
@@ -841,6 +841,12 @@ ifeq ($(uname_S),IRIX)
NO_MEMMEM = YesPlease
NO_MKSTEMPS = YesPlease
NO_MKDTEMP = YesPlease
+ # When compiled with the MIPSpro 7.4.4m compiler, and without pthreads
+ # (i.e. NO_PTHREADS is set), and _with_ MMAP (i.e. NO_MMAP is not set),
+ # git dies with a segmentation fault when trying to access the first
+ # entry of a reflog. The conservative choice is made to always set
+ # NO_MMAP. If you suspect that your compiler is not affected by this
+ # issue, comment out the NO_MMAP statement.
NO_MMAP = YesPlease
NO_EXTERNAL_GREP = UnfortunatelyYes
SNPRINTF_RETURNS_BOGUS = YesPlease
@@ -854,6 +860,12 @@ ifeq ($(uname_S),IRIX64)
NO_MEMMEM = YesPlease
NO_MKSTEMPS = YesPlease
NO_MKDTEMP = YesPlease
+ # When compiled with the MIPSpro 7.4.4m compiler, and without pthreads
+ # (i.e. NO_PTHREADS is set), and _with_ MMAP (i.e. NO_MMAP is not set),
+ # git dies with a segmentation fault when trying to access the first
+ # entry of a reflog. The conservative choice is made to always set
+ # NO_MMAP. If you suspect that your compiler is not affected by this
+ # issue, comment out the NO_MMAP statement.
NO_MMAP = YesPlease
NO_EXTERNAL_GREP = UnfortunatelyYes
SNPRINTF_RETURNS_BOGUS = YesPlease
--
1.6.5.rc2.17.gdbc1b
^ permalink raw reply related
* Re: [PATCH/RFC 5/7] imap-send: provide fall-back random-source
From: Jeff King @ 2009-10-09 0:03 UTC (permalink / raw)
To: Erik Faye-Lund; +Cc: msysgit, git, mike
In-Reply-To: <40aa078e0910081616wc1129edr2e1397964a0e6ae5@mail.gmail.com>
On Fri, Oct 09, 2009 at 01:16:50AM +0200, Erik Faye-Lund wrote:
> > And here is a patch (on top of the earlier one) to do that.
>
> Alright, so I'm spinning a new version of this series, and I'm
> wondering a bit how to include patches like these, where there's no
> commit message (because it was a sketch or something, I guess) or
> sign-off. Should I send the commit-messages to the author and have the
> him/her sign off on them, or should I set me as author and credit the
> real author for the actual work in the commit message? I see the
> latter have been done quite a bit in git.git already. The benefit of
> the first one is of course that authorship is retained, but the
> backside is that it incorrectly looks like the author wrote the commit
> message.
>
> Are there any preferences?
Usually a "something like this" patch means it is not very well tested,
and that was certainly the case here (I don't even used imap-send). But
if somebody else (like you) concurs that it is the sane thing to do and
has tested or run with it for a while, then maybe it is time to promote
it.
As for how to do that, both of your proposed solutions happen in
practice. Usually I would only mark myself as author if I picked up
somebody's "how about this" and tweaked it significantly or added
something to it. If you write the commit message, or add tests, or
whatever, then usually it is a good idea to just say so in the commit
message.
But when in doubt, ask the original author what they want to do. In this
case, I think it is best for me to write the message, as I did a fair
bit of looking into the reasons for this code.
So here goes. It's still only lightly tested by me, but we have no test
scripts at all for imap-send. I suspect getting it into 'next' is the
best way to actually get it tested.
-- >8 --
Subject: [PATCH] imap-send: remove useless uid code
The imap-send code is based on code from isync, a program
for syncing imap mailboxes. Because of this, it has
inherited some code that makes sense for isync, but not for
imap-send.
In particular, when storing a message, it does one of:
- if the server supports it, note the server-assigned
unique identifier (UID) given to each message
- otherwise, assigned a random UID and store it in the
message header as X-TUID
Presumably this is used in isync to be able to synchronize
mailstores multiple times without duplication. But for
imap-send, it the values are useless; we never do anything
with them and simply forget them at the end of the program.
This patch removes the useless code. Not only is it nice for
maintainability to get rid of dead code, but the removed
code relied on the existence of /dev/urandom, which made it
a portability problem for non-Unix platforms.
Signed-off-by: Jeff King <peff@peff.net>
---
As you may be able to tell from the commit message, this is both of the
patches rolled into one. I could probably rip out even more, but it's
not really worth the time. This one solves the portability issue.
imap-send.c | 155 ++++------------------------------------------------------
1 files changed, 11 insertions(+), 144 deletions(-)
diff --git a/imap-send.c b/imap-send.c
index 3847fd1..8da7a94 100644
--- a/imap-send.c
+++ b/imap-send.c
@@ -123,9 +123,6 @@ static int nfvasprintf(char **strp, const char *fmt, va_list ap)
return len;
}
-static void arc4_init(void);
-static unsigned char arc4_getbyte(void);
-
struct imap_server_conf {
char *name;
char *tunnel;
@@ -489,52 +486,6 @@ static int nfsnprintf(char *buf, int blen, const char *fmt, ...)
return ret;
}
-static struct {
- unsigned char i, j, s[256];
-} rs;
-
-static void arc4_init(void)
-{
- int i, fd;
- unsigned char j, si, dat[128];
-
- if ((fd = open("/dev/urandom", O_RDONLY)) < 0 && (fd = open("/dev/random", O_RDONLY)) < 0) {
- fprintf(stderr, "Fatal: no random number source available.\n");
- exit(3);
- }
- if (read_in_full(fd, dat, 128) != 128) {
- fprintf(stderr, "Fatal: cannot read random number source.\n");
- exit(3);
- }
- close(fd);
-
- for (i = 0; i < 256; i++)
- rs.s[i] = i;
- for (i = j = 0; i < 256; i++) {
- si = rs.s[i];
- j += si + dat[i & 127];
- rs.s[i] = rs.s[j];
- rs.s[j] = si;
- }
- rs.i = rs.j = 0;
-
- for (i = 0; i < 256; i++)
- arc4_getbyte();
-}
-
-static unsigned char arc4_getbyte(void)
-{
- unsigned char si, sj;
-
- rs.i++;
- si = rs.s[rs.i];
- rs.j += si;
- sj = rs.s[rs.j];
- rs.s[rs.i] = sj;
- rs.s[rs.j] = si;
- return rs.s[(si + sj) & 0xff];
-}
-
static struct imap_cmd *v_issue_imap_cmd(struct imap_store *ctx,
struct imap_cmd_cb *cb,
const char *fmt, va_list ap)
@@ -1198,88 +1149,20 @@ static int imap_make_flags(int flags, char *buf)
return d;
}
-#define TUIDL 8
-
-static int imap_store_msg(struct store *gctx, struct msg_data *data, int *uid)
+static int imap_store_msg(struct store *gctx, struct msg_data *data)
{
struct imap_store *ctx = (struct imap_store *)gctx;
struct imap *imap = ctx->imap;
struct imap_cmd_cb cb;
- char *fmap, *buf;
const char *prefix, *box;
- int ret, i, j, d, len, extra, nocr;
- int start, sbreak = 0, ebreak = 0;
- char flagstr[128], tuid[TUIDL * 2 + 1];
+ int ret, d;
+ char flagstr[128];
memset(&cb, 0, sizeof(cb));
- fmap = data->data;
- len = data->len;
- nocr = !data->crlf;
- extra = 0, i = 0;
- if (!CAP(UIDPLUS) && uid) {
- nloop:
- start = i;
- while (i < len)
- if (fmap[i++] == '\n') {
- extra += nocr;
- if (i - 2 + nocr == start) {
- sbreak = ebreak = i - 2 + nocr;
- goto mktid;
- }
- if (!memcmp(fmap + start, "X-TUID: ", 8)) {
- extra -= (ebreak = i) - (sbreak = start) + nocr;
- goto mktid;
- }
- goto nloop;
- }
- /* invalid message */
- free(fmap);
- return DRV_MSG_BAD;
- mktid:
- for (j = 0; j < TUIDL; j++)
- sprintf(tuid + j * 2, "%02x", arc4_getbyte());
- extra += 8 + TUIDL * 2 + 2;
- }
- if (nocr)
- for (; i < len; i++)
- if (fmap[i] == '\n')
- extra++;
-
- cb.dlen = len + extra;
- buf = cb.data = xmalloc(cb.dlen);
- i = 0;
- if (!CAP(UIDPLUS) && uid) {
- if (nocr) {
- for (; i < sbreak; i++)
- if (fmap[i] == '\n') {
- *buf++ = '\r';
- *buf++ = '\n';
- } else
- *buf++ = fmap[i];
- } else {
- memcpy(buf, fmap, sbreak);
- buf += sbreak;
- }
- memcpy(buf, "X-TUID: ", 8);
- buf += 8;
- memcpy(buf, tuid, TUIDL * 2);
- buf += TUIDL * 2;
- *buf++ = '\r';
- *buf++ = '\n';
- i = ebreak;
- }
- if (nocr) {
- for (; i < len; i++)
- if (fmap[i] == '\n') {
- *buf++ = '\r';
- *buf++ = '\n';
- } else
- *buf++ = fmap[i];
- } else
- memcpy(buf, fmap + i, len - i);
-
- free(fmap);
+ cb.dlen = data->len;
+ cb.data = xmalloc(cb.dlen);
+ memcpy(cb.data, data->data, data->len);
d = 0;
if (data->flags) {
@@ -1288,26 +1171,14 @@ static int imap_store_msg(struct store *gctx, struct msg_data *data, int *uid)
}
flagstr[d] = 0;
- if (!uid) {
- box = gctx->conf->trash;
- prefix = ctx->prefix;
- cb.create = 1;
- if (ctx->trashnc)
- imap->caps = imap->rcaps & ~(1 << LITERALPLUS);
- } else {
- box = gctx->name;
- prefix = !strcmp(box, "INBOX") ? "" : ctx->prefix;
- cb.create = 0;
- }
- cb.ctx = uid;
+ box = gctx->name;
+ prefix = !strcmp(box, "INBOX") ? "" : ctx->prefix;
+ cb.create = 0;
ret = imap_exec_m(ctx, &cb, "APPEND \"%s%s\" %s", prefix, box, flagstr);
imap->caps = imap->rcaps;
if (ret != DRV_OK)
return ret;
- if (!uid)
- ctx->trashnc = 0;
- else
- gctx->count++;
+ gctx->count++;
return DRV_OK;
}
@@ -1483,7 +1354,6 @@ int main(int argc, char **argv)
{
struct msg_data all_msgs, msg;
struct store *ctx = NULL;
- int uid = 0;
int ofs = 0;
int r;
int total, n = 0;
@@ -1491,9 +1361,6 @@ int main(int argc, char **argv)
git_extract_argv0_path(argv[0]);
- /* init the random number generator */
- arc4_init();
-
setup_git_directory_gently(&nongit_ok);
git_config(git_imap_config, NULL);
@@ -1540,7 +1407,7 @@ int main(int argc, char **argv)
break;
if (server.use_html)
wrap_in_html(&msg);
- r = imap_store_msg(ctx, &msg, &uid);
+ r = imap_store_msg(ctx, &msg);
if (r != DRV_OK)
break;
n++;
--
1.6.5.rc3.206.g63d9c
^ permalink raw reply related
* Re: [PATCH/RFC 5/7] imap-send: provide fall-back random-source
From: Erik Faye-Lund @ 2009-10-08 23:16 UTC (permalink / raw)
To: Jeff King; +Cc: msysgit, git, mike
In-Reply-To: <20091003205217.GC9058@sigill.intra.peff.net>
On Sat, Oct 3, 2009 at 10:52 PM, Jeff King <peff@peff.net> wrote:
>> So that could probably be ripped out, too, with no ill effect.
>
> And here is a patch (on top of the earlier one) to do that.
Alright, so I'm spinning a new version of this series, and I'm
wondering a bit how to include patches like these, where there's no
commit message (because it was a sketch or something, I guess) or
sign-off. Should I send the commit-messages to the author and have the
him/her sign off on them, or should I set me as author and credit the
real author for the actual work in the commit message? I see the
latter have been done quite a bit in git.git already. The benefit of
the first one is of course that authorship is retained, but the
backside is that it incorrectly looks like the author wrote the commit
message.
Are there any preferences?
--
Erik "kusma" Faye-Lund
kusmabite@gmail.com
(+47) 986 59 656
^ permalink raw reply
* [PATCH] Makefile: enable THREADED_DELTA_SEARCH on IRIX and IRIX64
From: Brandon Casey @ 2009-10-08 23:07 UTC (permalink / raw)
To: gitster; +Cc: git, Brandon Casey
From: Brandon Casey <drafnel@gmail.com>
Since commit dcda3614 removed the use of a variable length array from
builtin-pack-objects.c, it is now safe to compile with the threaded delta
search feature enabled. Formerly, the MIPSpro 7.4.4m compiler warned that
variable length arrays should not be used with pthreads.
Signed-off-by: Brandon Casey <casey@nrlssc.navy.mil>
---
Makefile | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/Makefile b/Makefile
index dd3d520..c956ce9 100644
--- a/Makefile
+++ b/Makefile
@@ -846,6 +846,7 @@ ifeq ($(uname_S),IRIX)
SNPRINTF_RETURNS_BOGUS = YesPlease
SHELL_PATH = /usr/gnu/bin/bash
NEEDS_LIBGEN = YesPlease
+ THREADED_DELTA_SEARCH = YesPlease
endif
ifeq ($(uname_S),IRIX64)
NO_SETENV=YesPlease
@@ -859,6 +860,7 @@ ifeq ($(uname_S),IRIX64)
SNPRINTF_RETURNS_BOGUS = YesPlease
SHELL_PATH=/usr/gnu/bin/bash
NEEDS_LIBGEN = YesPlease
+ THREADED_DELTA_SEARCH = YesPlease
endif
ifeq ($(uname_S),HP-UX)
NO_IPV6=YesPlease
--
1.6.5.rc2.17.gdbc1b
^ permalink raw reply related
* Re: git log -S not finding all commits?
From: Randal L. Schwartz @ 2009-10-08 22:52 UTC (permalink / raw)
To: Matthieu Moy; +Cc: Daniel, Andreas Ericsson, git
In-Reply-To: <vpq63aqxflu.fsf@bauges.imag.fr>
>>>>> "Matthieu" == Matthieu Moy <Matthieu.Moy@grenoble-inp.fr> writes:
Matthieu> Matthieu Moy <Matthieu.Moy@grenoble-inp.fr> writes:
>> git log -p --format="%s\n%x00" | perl -0 -ne 'print if(/whatever-you-search/);'
That "if" is noisier than it needs to be:
perl -0 -ne 'print if /this/'
suffices.
--
Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095
<merlyn@stonehenge.com> <URL:http://www.stonehenge.com/merlyn/>
Smalltalk/Perl/Unix consulting, Technical writing, Comedy, etc. etc.
See http://methodsandmessages.vox.com/ for Smalltalk and Seaside discussion
^ permalink raw reply
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