* Re: More on git over HTTP POST
From: H. Peter Anvin @ 2008-08-03 4:01 UTC (permalink / raw)
To: Shawn O. Pearce; +Cc: Git Mailing List
In-Reply-To: <20080803025602.GB27465@spearce.org>
Shawn O. Pearce wrote:
> Chunked Transfer Encoding
> -------------------------
>
> For performance reasons the HTTP/1.1 chunked transfer encoding is
> used frequently to transfer variable length objects. This avoids
> needing to produce large results in memory to compute the proper
> content-length.
One more thing about chunked transfer encodings: you cannot assume that
a proxy will maintain chunk boundaries, any more than you can assume
that a firewall will maintain TCP packet boundaries.
> Detecting Smart Servers
> -----------------------
>
> HTTP clients can detect a smart Git-aware server by sending the
> show-ref request (below) to the server. If the response has a
> status of 200 and the magic x-application/git-refs content type
> then the server can be assumed to be a smart Git-aware server.
>
> If any other response is received the client must assume dumb
> protocol support, as the server did not correctly response to
> the request.
I think it should be application/x-git-refs, but that's splitting hairs.
> Obtains the available refs from the remote repository. The response
> is a sequence of git "packet lines", one per ref, and a final flush
> packet line to indicate the end of stream.
>
> C: GET /path/to/repository.git?show-ref HTTP/1.0
>
I really think it would make more sense to use POST requests for
everything, and have the command part of the POSTed payload. Putting
stuff in the URL just complicates the namespace to the detriment of the
admin.
> S: HTTP/1.1 200 OK
> S: Content-Type: x-application/git-refs
> S: Transfer-Encoding: chunked
Transfer-encoding: chunked is illegal with a HTTP/1.0 client.
-hpa
^ permalink raw reply
* Re: More on git over HTTP POST
From: Shawn O. Pearce @ 2008-08-03 4:10 UTC (permalink / raw)
To: H. Peter Anvin; +Cc: Junio C Hamano, Git Mailing List
In-Reply-To: <48952A62.6050709@zytor.com>
"H. Peter Anvin" <hpa@zytor.com> wrote:
> Junio C Hamano wrote:
>> For example, putting them [capabilities] on extra HTTP headers is probably Ok.
>
> I think that would be a mistake, just because it's one more thing for
> proxies to screw up on.
I didn't realize we were in an era of proxies that are that
brain-damaged that they cannot relay the other headers. The Amazon
S3 service relies heavily upon their own extended headers to make
their REST API work. If proxies stripped that stuff out then the
client wouldn't work at all.
IOW I had thought we were past this dark age of the Internet.
> It's better to have negotiation information in
> the payload, before the "real" data.
I guess I could do that. At least for the really complex stuff.
> Obviously one thing that needs to be included in each transaction is a
> transaction ID that will be reported back on the next transaction, since
> you can't rely on a persistent connection.
No. That requires the server to maintain state. We don't want to
do that if we can avoid it. I would much rather have the clients
handle the state management as it simplifies the server side,
especially when you start talking about reverse proxies and/or
load-balancers running in front of the server farm.
--
Shawn.
^ permalink raw reply
* Re: More on git over HTTP POST
From: Shawn O. Pearce @ 2008-08-03 4:12 UTC (permalink / raw)
To: H. Peter Anvin; +Cc: Git Mailing List
In-Reply-To: <48952B2E.3030209@zytor.com>
"H. Peter Anvin" <hpa@zytor.com> wrote:
> Shawn O. Pearce wrote:
>> Chunked Transfer Encoding
>> -------------------------
>>
>> For performance reasons the HTTP/1.1 chunked transfer encoding is
>> used frequently to transfer variable length objects. This avoids
>> needing to produce large results in memory to compute the proper
>> content-length.
>
> Note: you cannot rely on HTTP/1.1 being supported by an intermediate
> proxy; you might have to handle HTTP/1.0, where the data is terminated
> by connection close.
Well, that proxy is going to be crying when we upload a 120M pack
during a push to it, and it buffers the damn thing to figure out
the proper Content-Length so it can convert an HTTP/1.1 client
request into an HTTP/1.0 request to forward to the server. That's
just _stupid_.
But from the client side perspective the chunked transfer encoding
is used only to avoid generating in advance and producing the
content-length header. I fully expect the encoding to disappear
(e.g. in a proxy, or in the HTTP client library) before any sort
of Git code gets its fingers on the data.
Hence to your other remark, I _do not_ rely upon the encoding
boundaries to remain intact. That is why there is Git pkt-line
encodings inside of the HTTP data stream. We can rely on the
pkt-line encoding being present, even if the HTTP chunks were
moved around (or removed entirely) by a proxy.
--
Shawn.
^ permalink raw reply
* I've tried to read the manuals, but "git pull" just won't work
From: Bruce Korb @ 2008-08-03 4:58 UTC (permalink / raw)
To: git
Sorry, I don't know where else to turn.
I've modified my local copy of ChangeLog and my "git pull" says, "Oh, oh!
You'd overwrite your changes" and refuses to pull. I tried
"git reset HEAD ChangeLog", but it says all sorts of crazy things
that make no sense and I'm still stuck. I know I can fix this:
pull my edits into a patch, throw away my repository, clone a fresh
copy. There has to be a better way. The better way is just too
obtuse to figure out.....Help, please? Thank you.
^ permalink raw reply
* Re: I've tried to read the manuals, but "git pull" just won't work
From: Matt Pearson @ 2008-08-03 5:21 UTC (permalink / raw)
To: Bruce Korb; +Cc: git
In-Reply-To: <668c430c0808022158s56e22c56t3bbd61eef59d7b32@mail.gmail.com>
On Sun, Aug 3, 2008 at 12:58 AM, Bruce Korb <bruce.korb@gmail.com> wrote:
> Sorry, I don't know where else to turn.
> I've modified my local copy of ChangeLog and my "git pull" says, "Oh, oh!
> You'd overwrite your changes" and refuses to pull. I tried
> "git reset HEAD ChangeLog", but it says all sorts of crazy things
> that make no sense and I'm still stuck. I know I can fix this:
> pull my edits into a patch, throw away my repository, clone a fresh
> copy. There has to be a better way. The better way is just too
> obtuse to figure out.....Help, please? Thank you.
Depends on whether you want to keep the changes you made or not. If
you don't care about the changes, 'git checkout -- ChangeLog' will
remove the local changes. If you want to keep the changes, you can
stash them away with 'git stash', then do the pull, then re-add the
changes (and maybe have to resolve conflicts) with 'git stash apply'.
You could also just commit the changes. If you still can't get it to
work, you're going to have to paste actual program output (the output
from status would probably help).
Matt
^ permalink raw reply
* Re: [PATCH] hash-object --no-filters
From: Dmitry Potapov @ 2008-08-03 5:42 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Alexander Litvinov, git, Eric Wong
In-Reply-To: <7vmyjvnx76.fsf_-_@gitster.siamese.dyndns.org>
On Sat, Aug 02, 2008 at 10:28:13AM -0700, Junio C Hamano wrote:
> Dmitry Potapov <dpotapov@gmail.com> writes:
>
> > The --no-filters option makes git hash-object to work as there were no
> > input filters. This option is useful for importers such as git-svn to
> > put new version of files as is even if autocrlf is set.
>
> I think this is going in the right direction, but I have to wonder a few
> things.
>
> First, on hash-object.
>
> (1) "hash-object --stdin" always hashes literally. We may want to be
> able to say "The contents is this but pretend it came from this path
> and apply the usual input rules", perhaps with "--path=" option;
It makes sense.
>
> (2) "hash-object temporaryfile" may want to honor the same "--path"
> option;
Agreed.
>
> (3) "hash-object --stdin-paths" may want to get pair of paths (i.e. two
> lines per entry) to do the same.
I cannot come up with a good name for this option.
>
> If we want to do the above, the existing low-level interface needs to be
> adjusted.
>
> index_pipe() and index_fd() can learn to take an additional string
> parameter for attribute lookup to implement (1) and (2) above.
index_fd already has the 'path' parameter, which is used as hint for
for blob conversion.
> Perhaps
> the string can be NULL to signal --no-filter behaviour, in which case the
> HASH_OBJECT_LITERALLY change may not be necessary for this codepath.
Sounds like a good idea :)
>
> By the way, why do we have index_pipe() and index_fd() to begin with? Is
> it because users of index_pipe() do not know what the path it is hashing
> and also the fd being a pipe we cannot mmap it?
index_fd() does not need the path for anything but to choose filters.
So, if index_pipe supported filters, it would have the same parameter.
There is one more parameter that index_fd() has and index_pipe() does
not. It is 'struct stat'. So I decided to look what this parameter is
used for in index_fd(), and it turned out for two things:
- to determine the size that needs to mmap
- to check whether the file is regular and if it is not then skip
convert_to_git().
That made me wonder whether index_fd() can be ever called for a non-
regular file? I studied the source code and with the exception to git
hash-object, which can pass anything what it can bed opened, in all
other cases, we always call it for what is know as a regular file. In
fact, it could be otherwise. It won't work for non-regular files. It
is quite obvious that git hash-object for a directory will fail, but
I wondered what would happen if I'd give it something different. For
instance, a named pipe (FIFO)
$mkfifo fifofile
$git hash-object
<wait for the other process to start write to it>
e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
i.e. the same SHA-1 as for an empty file, and here is why: index_fd()
tries to mmap the file descriptor and that obviously fails, but xmmap()
has this particular code:
if (ret == MAP_FAILED) {
if (!length)
return NULL;
apparently, it was workaround for empty files, but because st_size is 0
for pipes, index_fd treats any pipe as empty file!
>
> If these two are the only reasons, then I wonder if we can:
>
> - accept NULL as path and stat parameters for callers without a filename
> (which automatically implies we are doing a regular blob and we hash
> literally); and
I like this idea.
>
> - first try to mmap(), and if it fails fall back to the "read once into
> strbuf" codepath to solve mmap-vs-pipe issue.
I have an alternative proposal:
Because we have stat structure given as a parameter, we can always
check whether the file is regular or not. If it is regular, we can use
mmap() and if it is not then use "read once into strbuf" approach.
> I am not sure if such a unification of these two functions is useful,
> though.
I have implemented this unification, and it reduces the code size,
makes git-hash-object to work with named pipes, and makes easier to
add the --path and --no-filters options, because there is no need
to modify the index_fd interface anymore, and there is a single place
where convert_to_git is invoked. So it looks like a good idea.
Here is the patch:
-- >8 --
From: Dmitry Potapov <dpotapov@gmail.com>
Date: Sun, 3 Aug 2008 08:39:16 +0400
Subject: [PATCH] teach index_fd to work with pipes
index_fd can now work with file descriptors that are not normal files
but any readable file. If the given file descriptor is a regular file
then mmap() is used; for other files, strbuf_read is used.
The path parameter, which has been used as hint for filters, can be
NULL now to indicate that the file should be hashed literally without
any filter.
The index_pipe function is removed as redundant.
Signed-off-by: Dmitry Potapov <dpotapov@gmail.com>
---
cache.h | 1 -
hash-object.c | 29 +++++++++++--------------
sha1_file.c | 64 +++++++++++++++++++++++++++-----------------------------
3 files changed, 44 insertions(+), 50 deletions(-)
git-hash-object before
text data bss dec hex filename
148751 1332 93164 243247 3b62f git-hash-object
and after patch
text data bss dec hex filename
148687 1332 93164 243183 3b5ef git-hash-object
diff --git a/cache.h b/cache.h
index 2475de9..68ce6e6 100644
--- a/cache.h
+++ b/cache.h
@@ -391,7 +391,6 @@ extern int ie_modified(const struct index_state *, struct cache_entry *, struct
extern int ce_path_match(const struct cache_entry *ce, const char **pathspec);
extern int index_fd(unsigned char *sha1, int fd, struct stat *st, int write_object, enum object_type type, const char *path);
-extern int index_pipe(unsigned char *sha1, int fd, const char *type, int write_object);
extern int index_path(unsigned char *sha1, const char *path, struct stat *st, int write_object);
extern void fill_stat_cache_info(struct cache_entry *ce, struct stat *st);
diff --git a/hash-object.c b/hash-object.c
index 46c06a9..ce027b9 100644
--- a/hash-object.c
+++ b/hash-object.c
@@ -8,28 +8,25 @@
#include "blob.h"
#include "quote.h"
-static void hash_object(const char *path, enum object_type type, int write_object)
+static void hash_fd(int fd, const char *type, int write_object, const char *path)
{
- int fd;
struct stat st;
unsigned char sha1[20];
- fd = open(path, O_RDONLY);
- if (fd < 0 ||
- fstat(fd, &st) < 0 ||
- index_fd(sha1, fd, &st, write_object, type, path))
+ if (fstat(fd, &st) < 0 ||
+ index_fd(sha1, fd, &st, write_object, type_from_string(type), path))
die(write_object
? "Unable to add %s to database"
: "Unable to hash %s", path);
printf("%s\n", sha1_to_hex(sha1));
maybe_flush_or_die(stdout, "hash to stdout");
}
-
-static void hash_stdin(const char *type, int write_object)
+static void hash_object(const char *path, const char *type, int write_object)
{
- unsigned char sha1[20];
- if (index_pipe(sha1, 0, type, write_object))
- die("Unable to add stdin to database");
- printf("%s\n", sha1_to_hex(sha1));
+ int fd;
+ fd = open(path, O_RDONLY);
+ if (fd < 0)
+ die("Cannot open %s", path);
+ hash_fd(fd, type, write_object, path);
}
static void hash_stdin_paths(const char *type, int write_objects)
@@ -45,7 +42,7 @@ static void hash_stdin_paths(const char *type, int write_objects)
die("line is badly quoted");
strbuf_swap(&buf, &nbuf);
}
- hash_object(buf.buf, type_from_string(type), write_objects);
+ hash_object(buf.buf, type, write_objects);
}
strbuf_release(&buf);
strbuf_release(&nbuf);
@@ -116,13 +113,13 @@ int main(int argc, char **argv)
}
if (hashstdin) {
- hash_stdin(type, write_object);
+ hash_fd(0, type, write_object, NULL);
hashstdin = 0;
}
if (0 <= prefix_length)
arg = prefix_filename(prefix, prefix_length,
arg);
- hash_object(arg, type_from_string(type), write_object);
+ hash_object(arg, type, write_object);
no_more_flags = 1;
}
}
@@ -131,6 +128,6 @@ int main(int argc, char **argv)
hash_stdin_paths(type, write_object);
if (hashstdin)
- hash_stdin(type, write_object);
+ hash_fd(0, type, write_object, NULL);
return 0;
}
diff --git a/sha1_file.c b/sha1_file.c
index e281c14..765a7e7 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -2353,51 +2353,22 @@ int has_sha1_file(const unsigned char *sha1)
return has_loose_object(sha1);
}
-int index_pipe(unsigned char *sha1, int fd, const char *type, int write_object)
+static int index_mem(unsigned char *sha1, void *buf, size_t size,
+ int write_object, enum object_type type, const char *path)
{
- struct strbuf buf;
- int ret;
-
- strbuf_init(&buf, 0);
- if (strbuf_read(&buf, fd, 4096) < 0) {
- strbuf_release(&buf);
- return -1;
- }
-
- if (!type)
- type = blob_type;
- if (write_object)
- ret = write_sha1_file(buf.buf, buf.len, type, sha1);
- else
- ret = hash_sha1_file(buf.buf, buf.len, type, sha1);
- strbuf_release(&buf);
-
- return ret;
-}
-
-int index_fd(unsigned char *sha1, int fd, struct stat *st, int write_object,
- enum object_type type, const char *path)
-{
- size_t size = xsize_t(st->st_size);
- void *buf = NULL;
int ret, re_allocated = 0;
- if (size)
- buf = xmmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0);
- close(fd);
-
if (!type)
type = OBJ_BLOB;
/*
* Convert blobs to git internal format
*/
- if ((type == OBJ_BLOB) && S_ISREG(st->st_mode)) {
+ if ((type == OBJ_BLOB) && path) {
struct strbuf nbuf;
strbuf_init(&nbuf, 0);
if (convert_to_git(path, buf, size, &nbuf,
write_object ? safe_crlf : 0)) {
- munmap(buf, size);
buf = strbuf_detach(&nbuf, &size);
re_allocated = 1;
}
@@ -2411,8 +2382,35 @@ int index_fd(unsigned char *sha1, int fd, struct stat *st, int write_object,
free(buf);
return ret;
}
- if (size)
+ return ret;
+}
+
+int index_fd(unsigned char *sha1, int fd, struct stat *st, int write_object,
+ enum object_type type, const char *path)
+{
+ size_t size = xsize_t(st->st_size);
+ int ret;
+
+ if (!S_ISREG(st->st_mode))
+ {
+ struct strbuf sbuf;
+ strbuf_init(&sbuf, 0);
+ if (strbuf_read(&sbuf, fd, 4096) >= 0)
+ ret = index_mem(sha1, sbuf.buf, sbuf.len, write_object,
+ type, path);
+ else
+ ret = -1;
+ strbuf_release(&sbuf);
+ }
+ else if (size)
+ {
+ void *buf = xmmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0);
+ ret = index_mem(sha1, buf, size, write_object, type, path);
munmap(buf, size);
+ }
+ else
+ ret = index_mem(sha1, NULL, size, write_object, type, path);
+ close(fd);
return ret;
}
--
1.6.0.rc1.53.gaeaa.dirty
^ permalink raw reply related
* Re: [PATCH] hash-object --no-filters
From: Dmitry Potapov @ 2008-08-03 5:56 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Alexander Litvinov, git, Eric Wong
In-Reply-To: <20080803054218.GM7008@dpotapov.dyndns.org>
On Sun, Aug 03, 2008 at 09:42:18AM +0400, Dmitry Potapov wrote:
>
> Here is the patch:
I am sorry, I forgot to commit a micro cleanup to my patch:
@@ -2378,10 +2378,8 @@ static int index_mem(unsigned char *sha1, void *buf, size_t size,
ret = write_sha1_file(buf, size, typename(type), sha1);
else
ret = hash_sha1_file(buf, size, typename(type), sha1);
- if (re_allocated) {
+ if (re_allocated)
free(buf);
- return ret;
- }
return ret;
}
So, here is the corrected version of my patch:
-- >8 --
From: Dmitry Potapov <dpotapov@gmail.com>
Date: Sun, 3 Aug 2008 08:39:16 +0400
Subject: [PATCH] teach index_fd to work with pipes
index_fd can now work with file descriptors that are not normal files
but any readable file. If the given file descriptor is a regular file
then mmap() is used; for other files, strbuf_read is used.
The path parameter, which has been used as hint for filters, can be
NULL now to indicate that the file should be hashed literally without
any filter.
The index_pipe function is removed as redundant.
Signed-off-by: Dmitry Potapov <dpotapov@gmail.com>
---
cache.h | 1 -
hash-object.c | 29 +++++++++++-------------
sha1_file.c | 66 ++++++++++++++++++++++++++------------------------------
3 files changed, 44 insertions(+), 52 deletions(-)
diff --git a/cache.h b/cache.h
index 2475de9..68ce6e6 100644
--- a/cache.h
+++ b/cache.h
@@ -391,7 +391,6 @@ extern int ie_modified(const struct index_state *, struct cache_entry *, struct
extern int ce_path_match(const struct cache_entry *ce, const char **pathspec);
extern int index_fd(unsigned char *sha1, int fd, struct stat *st, int write_object, enum object_type type, const char *path);
-extern int index_pipe(unsigned char *sha1, int fd, const char *type, int write_object);
extern int index_path(unsigned char *sha1, const char *path, struct stat *st, int write_object);
extern void fill_stat_cache_info(struct cache_entry *ce, struct stat *st);
diff --git a/hash-object.c b/hash-object.c
index 46c06a9..ce027b9 100644
--- a/hash-object.c
+++ b/hash-object.c
@@ -8,28 +8,25 @@
#include "blob.h"
#include "quote.h"
-static void hash_object(const char *path, enum object_type type, int write_object)
+static void hash_fd(int fd, const char *type, int write_object, const char *path)
{
- int fd;
struct stat st;
unsigned char sha1[20];
- fd = open(path, O_RDONLY);
- if (fd < 0 ||
- fstat(fd, &st) < 0 ||
- index_fd(sha1, fd, &st, write_object, type, path))
+ if (fstat(fd, &st) < 0 ||
+ index_fd(sha1, fd, &st, write_object, type_from_string(type), path))
die(write_object
? "Unable to add %s to database"
: "Unable to hash %s", path);
printf("%s\n", sha1_to_hex(sha1));
maybe_flush_or_die(stdout, "hash to stdout");
}
-
-static void hash_stdin(const char *type, int write_object)
+static void hash_object(const char *path, const char *type, int write_object)
{
- unsigned char sha1[20];
- if (index_pipe(sha1, 0, type, write_object))
- die("Unable to add stdin to database");
- printf("%s\n", sha1_to_hex(sha1));
+ int fd;
+ fd = open(path, O_RDONLY);
+ if (fd < 0)
+ die("Cannot open %s", path);
+ hash_fd(fd, type, write_object, path);
}
static void hash_stdin_paths(const char *type, int write_objects)
@@ -45,7 +42,7 @@ static void hash_stdin_paths(const char *type, int write_objects)
die("line is badly quoted");
strbuf_swap(&buf, &nbuf);
}
- hash_object(buf.buf, type_from_string(type), write_objects);
+ hash_object(buf.buf, type, write_objects);
}
strbuf_release(&buf);
strbuf_release(&nbuf);
@@ -116,13 +113,13 @@ int main(int argc, char **argv)
}
if (hashstdin) {
- hash_stdin(type, write_object);
+ hash_fd(0, type, write_object, NULL);
hashstdin = 0;
}
if (0 <= prefix_length)
arg = prefix_filename(prefix, prefix_length,
arg);
- hash_object(arg, type_from_string(type), write_object);
+ hash_object(arg, type, write_object);
no_more_flags = 1;
}
}
@@ -131,6 +128,6 @@ int main(int argc, char **argv)
hash_stdin_paths(type, write_object);
if (hashstdin)
- hash_stdin(type, write_object);
+ hash_fd(0, type, write_object, NULL);
return 0;
}
diff --git a/sha1_file.c b/sha1_file.c
index e281c14..fe863f5 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -2353,51 +2353,22 @@ int has_sha1_file(const unsigned char *sha1)
return has_loose_object(sha1);
}
-int index_pipe(unsigned char *sha1, int fd, const char *type, int write_object)
+static int index_mem(unsigned char *sha1, void *buf, size_t size,
+ int write_object, enum object_type type, const char *path)
{
- struct strbuf buf;
- int ret;
-
- strbuf_init(&buf, 0);
- if (strbuf_read(&buf, fd, 4096) < 0) {
- strbuf_release(&buf);
- return -1;
- }
-
- if (!type)
- type = blob_type;
- if (write_object)
- ret = write_sha1_file(buf.buf, buf.len, type, sha1);
- else
- ret = hash_sha1_file(buf.buf, buf.len, type, sha1);
- strbuf_release(&buf);
-
- return ret;
-}
-
-int index_fd(unsigned char *sha1, int fd, struct stat *st, int write_object,
- enum object_type type, const char *path)
-{
- size_t size = xsize_t(st->st_size);
- void *buf = NULL;
int ret, re_allocated = 0;
- if (size)
- buf = xmmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0);
- close(fd);
-
if (!type)
type = OBJ_BLOB;
/*
* Convert blobs to git internal format
*/
- if ((type == OBJ_BLOB) && S_ISREG(st->st_mode)) {
+ if ((type == OBJ_BLOB) && path) {
struct strbuf nbuf;
strbuf_init(&nbuf, 0);
if (convert_to_git(path, buf, size, &nbuf,
write_object ? safe_crlf : 0)) {
- munmap(buf, size);
buf = strbuf_detach(&nbuf, &size);
re_allocated = 1;
}
@@ -2407,12 +2378,37 @@ int index_fd(unsigned char *sha1, int fd, struct stat *st, int write_object,
ret = write_sha1_file(buf, size, typename(type), sha1);
else
ret = hash_sha1_file(buf, size, typename(type), sha1);
- if (re_allocated) {
+ if (re_allocated)
free(buf);
- return ret;
+ return ret;
+}
+
+int index_fd(unsigned char *sha1, int fd, struct stat *st, int write_object,
+ enum object_type type, const char *path)
+{
+ size_t size = xsize_t(st->st_size);
+ int ret;
+
+ if (!S_ISREG(st->st_mode))
+ {
+ struct strbuf sbuf;
+ strbuf_init(&sbuf, 0);
+ if (strbuf_read(&sbuf, fd, 4096) >= 0)
+ ret = index_mem(sha1, sbuf.buf, sbuf.len, write_object,
+ type, path);
+ else
+ ret = -1;
+ strbuf_release(&sbuf);
}
- if (size)
+ else if (size)
+ {
+ void *buf = xmmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0);
+ ret = index_mem(sha1, buf, size, write_object, type, path);
munmap(buf, size);
+ }
+ else
+ ret = index_mem(sha1, NULL, size, write_object, type, path);
+ close(fd);
return ret;
}
--
1.6.0.rc1.53.gf8e95
^ permalink raw reply related
* Re: More on git over HTTP POST
From: Mike Hommey @ 2008-08-03 6:43 UTC (permalink / raw)
To: Shawn O. Pearce; +Cc: Git Mailing List
In-Reply-To: <20080803025602.GB27465@spearce.org>
On Sat, Aug 02, 2008 at 07:56:02PM -0700, Shawn O. Pearce wrote:
> Smart 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 the "smart" protocol.
If you want, I have a patch series that introduces a small API to make
HTTP requests easier to make.
Mike
^ permalink raw reply
* [RFC 1/2] Add backdoor options to receive-pack for use in Git-aware CGI
From: Shawn O. Pearce @ 2008-08-03 7:25 UTC (permalink / raw)
To: git, H. Peter Anvin
In-Reply-To: <20080803025602.GB27465@spearce.org>
The new --report-status flag forces the status report feature of
the push protocol to be enabled. This can be useful in a CGI
program that implements the server side of a "smart" Git-aware
HTTP transport. The CGI code can perform the selection of the
feature and ask receive-pack to enable it automatically.
The new --no-advertise-heads causes receive-pack to bypass its usual
display of known refs to the client, and instead immediately start
reading the commands and pack from stdin. This is useful in a CGI
situation where we want to hand off all input to receive-pack.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
---
receive-pack.c | 19 ++++++++++++++-----
1 files changed, 14 insertions(+), 5 deletions(-)
diff --git a/receive-pack.c b/receive-pack.c
index d44c19e..512eae6 100644
--- a/receive-pack.c
+++ b/receive-pack.c
@@ -464,6 +464,7 @@ static int delete_only(struct command *cmd)
int main(int argc, char **argv)
{
+ int advertise_heads = 1;
int i;
char *dir = NULL;
@@ -472,7 +473,15 @@ int main(int argc, char **argv)
char *arg = *argv++;
if (*arg == '-') {
- /* Do flag handling here */
+ if (!strcmp(arg, "--report-status")) {
+ report_status = 1;
+ continue;
+ }
+ if (!strcmp(arg, "--no-advertise-heads")) {
+ advertise_heads = 0;
+ continue;
+ }
+
usage(receive_pack_usage);
}
if (dir)
@@ -497,10 +506,10 @@ int main(int argc, char **argv)
else if (0 <= receive_unpack_limit)
unpack_limit = receive_unpack_limit;
- write_head_info();
-
- /* EOF */
- packet_flush(1);
+ if (advertise_heads) {
+ write_head_info();
+ packet_flush(1);
+ }
read_head_info();
if (commands) {
--
1.6.0.rc1.221.g9ae23
^ permalink raw reply related
* [RFC 2/2] Add Git-aware CGI for Git-aware smart HTTP transport
From: Shawn O. Pearce @ 2008-08-03 7:25 UTC (permalink / raw)
To: git, H. Peter Anvin
In-Reply-To: <1217748317-70096-1-git-send-email-spearce@spearce.org>
This CGI can be loaded into an 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 the
client to detect the server's smarts by looking at the content-type
returned from "GET /repo.git/info/refs". If the returned content
type is the magic application/x-git-refs type then the client can
assume the server is Git-aware.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
---
.gitignore | 1 +
Documentation/technical/http-protocol.txt | 88 +++++++++
Makefile | 1 +
http-backend.c | 302 +++++++++++++++++++++++++++++
4 files changed, 392 insertions(+), 0 deletions(-)
create mode 100644 Documentation/technical/http-protocol.txt
create mode 100644 http-backend.c
diff --git a/.gitignore b/.gitignore
index a213e8e..02eaf3a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -51,6 +51,7 @@ git-gc
git-get-tar-commit-id
git-grep
git-hash-object
+git-http-backend
git-http-fetch
git-http-push
git-imap-send
diff --git a/Documentation/technical/http-protocol.txt b/Documentation/technical/http-protocol.txt
new file mode 100644
index 0000000..6cb96f3
--- /dev/null
+++ b/Documentation/technical/http-protocol.txt
@@ -0,0 +1,88 @@
+Smart 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 the "smart" protocol.
+
+As a design feature smart servers automatically degrade to the
+dumb protocol when speaking with a dumb client. This may cause
+more load to be placed on the server as the file GET requests are
+handled by a CGI rather than the server itself.
+
+
+Authentication
+--------------
+
+Standard HTTP authentication is used, and must be configured and
+enforced by the HTTP server software.
+
+Chunked Transfer Encoding
+-------------------------
+
+For performance reasons the HTTP/1.1 chunked transfer encoding is
+used frequently to transfer variable length objects. This avoids
+needing to produce large results in memory to compute the proper
+content-length.
+
+Detecting Smart Servers
+-----------------------
+
+HTTP clients can detect a smart Git-aware server by sending the
+/info/refs request (below) to the server. If the response has a
+status of 200 and the magic application/x-git-refs content type
+then the server can be assumed to be a smart Git-aware server.
+
+
+Show Refs
+---------
+
+Obtains the available refs from the remote repository. The response
+is a sequence of refs, one per line. The actual format matches that
+of the $GIT_DIR/info/refs file normally used by a "dumb" protocol.
+
+ C: GET /path/to/repository.git/info/refs HTTP/1.0
+
+ S: HTTP/1.1 200 OK
+ S: Content-Type: application/x-git-refs
+ S: Transfer-Encoding: chunked
+ S:
+ S: 62
+ S: 95dcfa3633004da0049d3d0fa03f80589cbcaf31 refs/heads/maint
+ S:
+ S: 63
+ S: d049f6c27a2244e12041955e262a404c7faba355 refs/heads/master
+ S:
+ S: 59
+ S: 2cb58b79488a98d2721cea644875a8dd0026b115 refs/heads/pu
+ S:
+
+Push Pack
+---------
+
+Uploads a pack and updates refs. The start of the stream is the
+commands to update the refs and the remainder of the stream is the
+pack file itself. See git-receive-pack and its network protocol
+in pack-protocol.txt, as this is essentially the same.
+
+ C: POST /path/to/repository.git/receive-pack HTTP/1.0
+ C: Content-Type: application/x-git-receive-pack
+ C: Transfer-Encoding: chunked
+ C:
+ C: 103
+ C: 006395dcfa3633004da0049d3d0fa03f80589cbcaf31 d049f6c27a2244e12041955e262a404c7faba355 refs/heads/maint
+ C: 4
+ C: 0000
+ C: 12
+ C: PACK
+ ...
+ C: 0
+
+ S: HTTP/1.0 200 OK
+ S: Content-type: application/x-git-receive-pack-status
+ S: Transfer-Encoding: chunked
+ S:
+ S: ...<output of receive-pack>...
+
+
diff --git a/Makefile b/Makefile
index 52c67c1..3a93bf6 100644
--- a/Makefile
+++ b/Makefile
@@ -298,6 +298,7 @@ PROGRAMS += git-unpack-file$X
PROGRAMS += git-update-server-info$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..a498f89
--- /dev/null
+++ b/http-backend.c
@@ -0,0 +1,302 @@
+#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 int can_chunk;
+static char buffer[1000];
+
+static void send_status(unsigned code, const char *msg)
+{
+ size_t n;
+
+ n = snprintf(buffer, sizeof(buffer), "Status: %u %s\r\n", code, msg);
+ if (n >= sizeof(buffer))
+ die("protocol error: impossibly long header");
+ safe_write(1, buffer, n);
+}
+
+static void send_header(const char *name, const char *value)
+{
+ size_t n;
+
+ n = snprintf(buffer, sizeof(buffer), "%s: %s\r\n", name, value);
+ if (n >= sizeof(buffer))
+ die("protocol error: impossibly long header");
+ safe_write(1, buffer, n);
+}
+
+static void end_headers(void)
+{
+ safe_write(1, "\r\n", 2);
+}
+
+static void send_nocaching(void)
+{
+ const char *proto = getenv("SERVER_PROTOCOL");
+ if (!proto || !strcmp(proto, "HTTP/1.0"))
+ send_header("Expires", "Mon, 17 Sep 2001 00:00:00 GMT");
+ else
+ send_header("Cache-Control", "no-cache");
+}
+
+static void send_connection_close(void)
+{
+ send_header("Connection", "close");
+}
+
+static void enable_chunking(void)
+{
+ const char *proto = getenv("SERVER_PROTOCOL");
+
+ can_chunk = proto && strcmp(proto, "HTTP/1.0");
+ if (can_chunk)
+ send_header("Transfer-Encoding", "chunked");
+ else
+ send_connection_close();
+}
+
+#define hex(a) (hexchar[(a) & 15])
+static void chunked_write(const char *fmt, ...)
+{
+ static const char hexchar[] = "0123456789abcdef";
+ va_list args;
+ unsigned n;
+
+ va_start(args, fmt);
+ n = vsnprintf(buffer + 6, sizeof(buffer) - 8, fmt, args);
+ va_end(args);
+ if (n >= sizeof(buffer) - 8)
+ die("protocol error: impossibly long line");
+
+ if (can_chunk) {
+ unsigned len = n + 4, b = 4;
+
+ buffer[4] = '\r';
+ buffer[5] = '\n';
+ buffer[n + 6] = '\r';
+ buffer[n + 7] = '\n';
+
+ while (n > 0) {
+ buffer[--b] = hex(n);
+ n >>= 4;
+ len++;
+ }
+
+ safe_write(1, buffer + b, len);
+ } else
+ safe_write(1, buffer + 6, n);
+}
+
+static void end_chunking(void)
+{
+ static const char flush_chunk[] = "0\r\n\r\n";
+ if (can_chunk)
+ safe_write(1, flush_chunk, strlen(flush_chunk));
+}
+
+static void NORETURN invalid_request(const char *msg)
+{
+ static const char header[] = "error: ";
+
+ send_status(400, "Bad Request");
+ send_header(content_type, "text/plain");
+ end_headers();
+
+ safe_write(1, header, strlen(header));
+ safe_write(1, msg, strlen(msg));
+ safe_write(1, "\n", 1);
+
+ exit(0);
+}
+
+static void not_found(void)
+{
+ send_status(404, "Not Found");
+ end_headers();
+}
+
+static void server_error(void)
+{
+ send_status(500, "Internal Error");
+ end_headers();
+}
+
+static void require_content_type(const char *need_type)
+{
+ const char *input_type = getenv("CONTENT_TYPE");
+ if (!input_type || strcmp(input_type, need_type))
+ invalid_request("Unsupported content-type");
+}
+
+static void do_GET_any_file(char *name)
+{
+ const char *p = git_path("%s", name);
+ struct stat sb;
+ uintmax_t remaining;
+ size_t n;
+ int fd = open(p, O_RDONLY);
+
+ if (fd < 0) {
+ not_found();
+ return;
+ }
+ if (fstat(fd, &sb) < 0) {
+ close(fd);
+ server_error();
+ die("fstat on plain file failed");
+ }
+ remaining = (uintmax_t)sb.st_size;
+
+ n = snprintf(buffer, sizeof(buffer),
+ "Content-Length: %" PRIuMAX "\r\n", remaining);
+ if (n >= sizeof(buffer))
+ die("protocol error: impossibly long header");
+ safe_write(1, buffer, n);
+ send_header(content_type, "application/octet-stream");
+ end_headers();
+
+ while (remaining) {
+ n = xread(fd, buffer, sizeof(buffer));
+ if (n < 0)
+ die("error reading from %s", p);
+ n = safe_write(1, buffer, n);
+ if (n <= 0)
+ break;
+ }
+ close(fd);
+}
+
+static int show_one_ref(const char *name, const unsigned char *sha1,
+ int flag, void *cb_data)
+{
+ struct object *o = parse_object(sha1);
+ if (!o)
+ return 0;
+
+ chunked_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;
+ chunked_write("%s\t%s^{}\n", sha1_to_hex(o->sha1), name);
+ }
+
+ return 0;
+}
+
+static void do_GET_info_refs(char *arg)
+{
+ send_header(content_type, "application/x-git-refs");
+ send_nocaching();
+ enable_chunking();
+ end_headers();
+
+ for_each_ref(show_one_ref, NULL);
+ end_chunking();
+}
+
+static void do_GET_info_packs(char *arg)
+{
+ size_t objdirlen = strlen(get_object_directory());
+ struct packed_git *p;
+
+ send_nocaching();
+ enable_chunking();
+ end_headers();
+
+ prepare_packed_git();
+ for (p = packed_git; p; p = p->next) {
+ if (!p->pack_local)
+ continue;
+ chunked_write("P %s\n", p->pack_name + objdirlen + 6);
+ }
+ chunked_write("\n");
+ end_chunking();
+}
+
+static void do_POST_receive_pack(char *arg)
+{
+ require_content_type("application/x-git-receive-pack");
+ send_header(content_type, "application/x-git-receive-pack-status");
+ send_nocaching();
+ send_connection_close();
+ end_headers();
+
+ execl_git_cmd("receive-pack",
+ "--report-status",
+ "--no-advertise-heads",
+ ".",
+ NULL);
+ die("Failed to start receive-pack");
+}
+
+static struct service_cmd {
+ const char *method;
+ const char *pattern;
+ void (*imp)(char *);
+} services[] = {
+ {"GET", "/info/refs$", do_GET_info_refs},
+ {"GET", "/objects/info/packs", do_GET_info_packs},
+
+ {"GET", "/HEAD$", do_GET_any_file},
+ {"GET", "/objects/../.{38}$", do_GET_any_file},
+ {"GET", "/objects/pack/pack-[^/]*$", do_GET_any_file},
+ {"GET", "/objects/info/[^/]*$", do_GET_any_file},
+
+ {"POST", "/receive-pack", do_POST_receive_pack}
+};
+
+int main(int argc, char **argv)
+{
+ char *input_method = getenv("REQUEST_METHOD");
+ char *dir = getenv("PATH_TRANSLATED");
+ struct service_cmd *cmd = NULL;
+ char *cmd_arg = NULL;
+ int i;
+
+ if (!input_method)
+ die("No REQUEST_METHOD from server");
+ if (!strcmp(input_method, "HEAD"))
+ input_method = "GET";
+
+ if (!dir)
+ die("No PATH_TRANSLATED from server");
+
+ for (i = 0; i < ARRAY_SIZE(services); i++) {
+ struct service_cmd *c = &services[i];
+ regex_t re;
+ regmatch_t out[1];
+
+ if (strcmp(input_method, c->method))
+ continue;
+ if (regcomp(&re, c->pattern, REG_EXTENDED))
+ die("Bogus re in service table: %s", c->pattern);
+ if (!regexec(&re, dir, 2, out, 0)) {
+ size_t n = out[0].rm_eo - out[0].rm_so;
+ 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)
+ invalid_request("Unsupported query request");
+
+ setup_path();
+ if (!enter_repo(dir, 0))
+ invalid_request("Not a Git repository");
+
+ cmd->imp(cmd_arg);
+ return 0;
+}
--
1.6.0.rc1.221.g9ae23
^ permalink raw reply related
* Re: [ANNOUNCE] TopGit - A different patch queue manager
From: Miklos Vajna @ 2008-08-03 7:27 UTC (permalink / raw)
To: Petr Baudis; +Cc: git
In-Reply-To: <20080803031424.GV32184@machine.or.cz>
[-- Attachment #1: Type: text/plain, Size: 701 bytes --]
On Sun, Aug 03, 2008 at 05:14:24AM +0200, Petr Baudis <pasky@suse.cz> wrote:
> (iii) Actually _WORK_ in the distributed environment;
> you can have several repositories and develop your patches
> in all of them
As we discussed on IRC, this means that unlike git rebase -i and others,
the history of such rebases is not stored in reflogs (which are not
transfered) but stored with this "one branch, one patch" logic.
> P.P.S.: Can I get trademark on the (ironically) /[^p]g/ porcelains
> now? ;-)
Heh, no please. I have a porcelain called 'dg'[0] after 'darcs-git', which
imitates some of the darcs UI, but operating on a git repo. ;-)
[0] http://tinyurl.com/5lfs5g, http://tinyurl.com/6pb772
[-- Attachment #2: Type: application/pgp-signature, Size: 197 bytes --]
^ permalink raw reply
* Re: [PATCH] bash completion: Add completion for 'git grep'
From: Lee Marlow @ 2008-08-03 7:31 UTC (permalink / raw)
To: Shawn O. Pearce; +Cc: git
In-Reply-To: <20080802210525.GD24723@spearce.org>
On Sat, Aug 2, 2008 at 3:05 PM, Shawn O. Pearce <spearce@spearce.org> wrote:
>
> Hmm. The has_doubledash test seems redundant since we don't do
> anything with args that aren't --foo. Even though git-grep will
> accept a tree-ish and thus completion of __git_refs here may
> make sense.
>
> But that is very much a user question. Do users mostly search a
> file in the current working directory, or do they mostly search
> a tree-ish?
I haven't found myself using grep to search anything but the current
working directory. I wonder whether __git_complete_file would be
better than __git_refs. My issue with __git_complete_file in this
case and also doing completion for 'git mv' is that it falls back to
just __git_refs. Would it be better if it fell back to __git_refs and
ls-tree for HEAD? That way when using completion to get to
Documentation/git-grep.txt, it doesn't also show completions for
Documentation/git-grep.{1,html,xml}.
-Lee
^ permalink raw reply
* [PATCH] git-gui: update Japanese translation
From: しらいしななこ @ 2008-08-03 8:01 UTC (permalink / raw)
To: Shawn O. Pearce; +Cc: Junio C Hamano, git
This updates Japanese translation to match the updated git-gui.pot.
Signed-off-by: しらいしななこ <nanako3@lavabit.com>
---
po/ja.po | 527 +++++++++++++++++++++++++++++++++-----------------------------
1 files changed, 281 insertions(+), 246 deletions(-)
diff --git a/po/ja.po b/po/ja.po
index 28e6d62..5db44a4 100644
--- a/po/ja.po
+++ b/po/ja.po
@@ -8,41 +8,41 @@ msgid ""
msgstr ""
"Project-Id-Version: git-gui\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2008-03-14 07:18+0100\n"
-"PO-Revision-Date: 2008-03-15 20:12+0900\n"
-"Last-Translator: しらいし ななこ <nanako3@bluebottle.com>\n"
+"POT-Creation-Date: 2008-08-02 14:45-0700\n"
+"PO-Revision-Date: 2008-08-03 17:00+0900\n"
+"Last-Translator: しらいし ななこ <nanako3@lavabit.com>\n"
"Language-Team: Japanese\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-#: git-gui.sh:41 git-gui.sh:634 git-gui.sh:648 git-gui.sh:661 git-gui.sh:744
-#: git-gui.sh:763
+#: git-gui.sh:41 git-gui.sh:688 git-gui.sh:702 git-gui.sh:715 git-gui.sh:798
+#: git-gui.sh:817
msgid "git-gui: fatal error"
msgstr "git-gui: 致命的なエラー"
-#: git-gui.sh:593
+#: git-gui.sh:644
#, tcl-format
msgid "Invalid font specified in %s:"
msgstr "%s に無効なフォントが指定されています:"
-#: git-gui.sh:620
+#: git-gui.sh:674
msgid "Main Font"
msgstr "主フォント"
-#: git-gui.sh:621
+#: git-gui.sh:675
msgid "Diff/Console Font"
msgstr "diff/コンソール・フォント"
-#: git-gui.sh:635
+#: git-gui.sh:689
msgid "Cannot find git in PATH."
msgstr "PATH 中に git が見つかりません"
-#: git-gui.sh:662
+#: git-gui.sh:716
msgid "Cannot parse Git version string:"
msgstr "Git バージョン名が理解できません:"
-#: git-gui.sh:680
+#: git-gui.sh:734
#, tcl-format
msgid ""
"Git version cannot be determined.\n"
@@ -61,380 +61,381 @@ msgstr ""
"\n"
"'%s' はバージョン 1.5.0 と思って良いですか?\n"
-#: git-gui.sh:918
+#: git-gui.sh:972
msgid "Git directory not found:"
msgstr "Git ディレクトリが見つかりません:"
-#: git-gui.sh:925
+#: git-gui.sh:979
msgid "Cannot move to top of working directory:"
msgstr "作業ディレクトリの最上位に移動できません"
-#: git-gui.sh:932
+#: git-gui.sh:986
msgid "Cannot use funny .git directory:"
msgstr "変な .git ディレクトリは使えません"
-#: git-gui.sh:937
+#: git-gui.sh:991
msgid "No working directory"
msgstr "作業ディレクトリがありません"
-#: git-gui.sh:1084 lib/checkout_op.tcl:283
+#: git-gui.sh:1138 lib/checkout_op.tcl:305
msgid "Refreshing file status..."
msgstr "ファイル状態を更新しています…"
-#: git-gui.sh:1149
+#: git-gui.sh:1194
msgid "Scanning for modified files ..."
msgstr "変更されたファイルをスキャンしています…"
-#: git-gui.sh:1324 lib/browser.tcl:246
+#: git-gui.sh:1369 lib/browser.tcl:246
msgid "Ready."
msgstr "準備完了"
-#: git-gui.sh:1590
+#: git-gui.sh:1635
msgid "Unmodified"
msgstr "変更無し"
-#: git-gui.sh:1592
+#: git-gui.sh:1637
msgid "Modified, not staged"
msgstr "変更あり、コミット未予定"
-#: git-gui.sh:1593 git-gui.sh:1598
+#: git-gui.sh:1638 git-gui.sh:1643
msgid "Staged for commit"
msgstr "コミット予定済"
-#: git-gui.sh:1594 git-gui.sh:1599
+#: git-gui.sh:1639 git-gui.sh:1644
msgid "Portions staged for commit"
msgstr "部分的にコミット予定済"
-#: git-gui.sh:1595 git-gui.sh:1600
+#: git-gui.sh:1640 git-gui.sh:1645
msgid "Staged for commit, missing"
msgstr "コミット予定済、ファイル無し"
-#: git-gui.sh:1597
+#: git-gui.sh:1642
msgid "Untracked, not staged"
msgstr "管理外、コミット未予定"
-#: git-gui.sh:1602
+#: git-gui.sh:1647
msgid "Missing"
msgstr "ファイル無し"
-#: git-gui.sh:1603
+#: git-gui.sh:1648
msgid "Staged for removal"
msgstr "削除予定済"
-#: git-gui.sh:1604
+#: git-gui.sh:1649
msgid "Staged for removal, still present"
msgstr "削除予定済、ファイル未削除"
-#: git-gui.sh:1606 git-gui.sh:1607 git-gui.sh:1608 git-gui.sh:1609
+#: git-gui.sh:1651 git-gui.sh:1652 git-gui.sh:1653 git-gui.sh:1654
msgid "Requires merge resolution"
msgstr "要マージ解決"
-#: git-gui.sh:1644
+#: git-gui.sh:1689
msgid "Starting gitk... please wait..."
msgstr "gitk を起動中…お待ち下さい…"
-#: git-gui.sh:1653
-#, tcl-format
-msgid ""
-"Unable to start gitk:\n"
-"\n"
-"%s does not exist"
-msgstr ""
-"gitk を起動できません:\n"
-"\n"
-"%s がありません"
+#: git-gui.sh:1698
+msgid "Couldn't find gitk in PATH"
+msgstr "PATH 中に gitk が見つかりません"
-#: git-gui.sh:1860 lib/choose_repository.tcl:36
+#: git-gui.sh:1948 lib/choose_repository.tcl:36
msgid "Repository"
msgstr "リポジトリ"
-#: git-gui.sh:1861
+#: git-gui.sh:1949
msgid "Edit"
msgstr "編集"
-#: git-gui.sh:1863 lib/choose_rev.tcl:561
+#: git-gui.sh:1951 lib/choose_rev.tcl:561
msgid "Branch"
msgstr "ブランチ"
-#: git-gui.sh:1866 lib/choose_rev.tcl:548
+#: git-gui.sh:1954 lib/choose_rev.tcl:548
msgid "Commit@@noun"
msgstr "コミット"
-#: git-gui.sh:1869 lib/merge.tcl:120 lib/merge.tcl:149 lib/merge.tcl:167
+#: git-gui.sh:1957 lib/merge.tcl:120 lib/merge.tcl:149 lib/merge.tcl:167
msgid "Merge"
msgstr "マージ"
-#: git-gui.sh:1870 lib/choose_rev.tcl:557
+#: git-gui.sh:1958 lib/choose_rev.tcl:557
msgid "Remote"
msgstr "リモート"
-#: git-gui.sh:1879
+#: git-gui.sh:1967
msgid "Browse Current Branch's Files"
msgstr "現在のブランチのファイルを見る"
-#: git-gui.sh:1883
+#: git-gui.sh:1971
msgid "Browse Branch Files..."
msgstr "ブランチのファイルを見る…"
-#: git-gui.sh:1888
+#: git-gui.sh:1976
msgid "Visualize Current Branch's History"
msgstr "現在のブランチの履歴を見る"
-#: git-gui.sh:1892
+#: git-gui.sh:1980
msgid "Visualize All Branch History"
msgstr "全てのブランチの履歴を見る"
-#: git-gui.sh:1899
+#: git-gui.sh:1987
#, tcl-format
msgid "Browse %s's Files"
msgstr "ブランチ %s のファイルを見る"
-#: git-gui.sh:1901
+#: git-gui.sh:1989
#, tcl-format
msgid "Visualize %s's History"
msgstr "ブランチ %s の履歴を見る"
-#: git-gui.sh:1906 lib/database.tcl:27 lib/database.tcl:67
+#: git-gui.sh:1994 lib/database.tcl:27 lib/database.tcl:67
msgid "Database Statistics"
msgstr "データベース統計"
-#: git-gui.sh:1909 lib/database.tcl:34
+#: git-gui.sh:1997 lib/database.tcl:34
msgid "Compress Database"
msgstr "データベース圧縮"
-#: git-gui.sh:1912
+#: git-gui.sh:2000
msgid "Verify Database"
msgstr "データベース検証"
-#: git-gui.sh:1919 git-gui.sh:1923 git-gui.sh:1927 lib/shortcut.tcl:7
+#: git-gui.sh:2007 git-gui.sh:2011 git-gui.sh:2015 lib/shortcut.tcl:7
#: lib/shortcut.tcl:39 lib/shortcut.tcl:71
msgid "Create Desktop Icon"
msgstr "デスクトップ・アイコンを作る"
-#: git-gui.sh:1932 lib/choose_repository.tcl:177 lib/choose_repository.tcl:185
+#: git-gui.sh:2023 lib/choose_repository.tcl:177 lib/choose_repository.tcl:185
msgid "Quit"
msgstr "終了"
-#: git-gui.sh:1939
+#: git-gui.sh:2031
msgid "Undo"
msgstr "元に戻す"
-#: git-gui.sh:1942
+#: git-gui.sh:2034
msgid "Redo"
msgstr "やり直し"
-#: git-gui.sh:1946 git-gui.sh:2443
+#: git-gui.sh:2038 git-gui.sh:2545
msgid "Cut"
msgstr "切り取り"
-#: git-gui.sh:1949 git-gui.sh:2446 git-gui.sh:2520 git-gui.sh:2614
+#: git-gui.sh:2041 git-gui.sh:2548 git-gui.sh:2622 git-gui.sh:2715
#: lib/console.tcl:69
msgid "Copy"
msgstr "コピー"
-#: git-gui.sh:1952 git-gui.sh:2449
+#: git-gui.sh:2044 git-gui.sh:2551
msgid "Paste"
msgstr "貼り付け"
-#: git-gui.sh:1955 git-gui.sh:2452 lib/branch_delete.tcl:26
+#: git-gui.sh:2047 git-gui.sh:2554 lib/branch_delete.tcl:26
#: lib/remote_branch_delete.tcl:38
msgid "Delete"
msgstr "削除"
-#: git-gui.sh:1959 git-gui.sh:2456 git-gui.sh:2618 lib/console.tcl:71
+#: git-gui.sh:2051 git-gui.sh:2558 git-gui.sh:2719 lib/console.tcl:71
msgid "Select All"
msgstr "全て選択"
-#: git-gui.sh:1968
+#: git-gui.sh:2060
msgid "Create..."
msgstr "作成…"
-#: git-gui.sh:1974
+#: git-gui.sh:2066
msgid "Checkout..."
msgstr "チェックアウト"
-#: git-gui.sh:1980
+#: git-gui.sh:2072
msgid "Rename..."
msgstr "名前変更…"
-#: git-gui.sh:1985 git-gui.sh:2085
+#: git-gui.sh:2077 git-gui.sh:2187
msgid "Delete..."
msgstr "削除…"
-#: git-gui.sh:1990
+#: git-gui.sh:2082
msgid "Reset..."
msgstr "リセット…"
-#: git-gui.sh:2002 git-gui.sh:2389
+#: git-gui.sh:2094 git-gui.sh:2491
msgid "New Commit"
msgstr "新規コミット"
-#: git-gui.sh:2010 git-gui.sh:2396
+#: git-gui.sh:2102 git-gui.sh:2498
msgid "Amend Last Commit"
msgstr "最新コミットを訂正"
-#: git-gui.sh:2019 git-gui.sh:2356 lib/remote_branch_delete.tcl:99
+#: git-gui.sh:2111 git-gui.sh:2458 lib/remote_branch_delete.tcl:99
msgid "Rescan"
msgstr "再スキャン"
-#: git-gui.sh:2025
+#: git-gui.sh:2117
msgid "Stage To Commit"
msgstr "コミット予定する"
-#: git-gui.sh:2031
+#: git-gui.sh:2123
msgid "Stage Changed Files To Commit"
msgstr "変更されたファイルをコミット予定"
-#: git-gui.sh:2037
+#: git-gui.sh:2129
msgid "Unstage From Commit"
msgstr "コミットから降ろす"
-#: git-gui.sh:2042 lib/index.tcl:395
+#: git-gui.sh:2134 lib/index.tcl:395
msgid "Revert Changes"
msgstr "変更を元に戻す"
-#: git-gui.sh:2049 git-gui.sh:2368 git-gui.sh:2467
+#: git-gui.sh:2141 git-gui.sh:2702
+msgid "Show Less Context"
+msgstr "文脈を少なく"
+
+#: git-gui.sh:2145 git-gui.sh:2706
+msgid "Show More Context"
+msgstr "文脈を多く"
+
+#: git-gui.sh:2151 git-gui.sh:2470 git-gui.sh:2569
msgid "Sign Off"
msgstr "署名"
-#: git-gui.sh:2053 git-gui.sh:2372
+#: git-gui.sh:2155 git-gui.sh:2474
msgid "Commit@@verb"
msgstr "コミット"
-#: git-gui.sh:2064
+#: git-gui.sh:2166
msgid "Local Merge..."
msgstr "ローカル・マージ…"
-#: git-gui.sh:2069
+#: git-gui.sh:2171
msgid "Abort Merge..."
msgstr "マージ中止…"
-#: git-gui.sh:2081
+#: git-gui.sh:2183
msgid "Push..."
msgstr "プッシュ…"
-#: git-gui.sh:2092 lib/choose_repository.tcl:41
-msgid "Apple"
-msgstr "りんご"
-
-#: git-gui.sh:2095 git-gui.sh:2117 lib/about.tcl:14
+#: git-gui.sh:2197 git-gui.sh:2219 lib/about.tcl:14
#: lib/choose_repository.tcl:44 lib/choose_repository.tcl:50
#, tcl-format
msgid "About %s"
msgstr "%s について"
-#: git-gui.sh:2099
+#: git-gui.sh:2201
msgid "Preferences..."
msgstr "設定…"
-#: git-gui.sh:2107 git-gui.sh:2639
+#: git-gui.sh:2209 git-gui.sh:2740
msgid "Options..."
msgstr "オプション…"
-#: git-gui.sh:2113 lib/choose_repository.tcl:47
+#: git-gui.sh:2215 lib/choose_repository.tcl:47
msgid "Help"
msgstr "ヘルプ"
-#: git-gui.sh:2154
+#: git-gui.sh:2256
msgid "Online Documentation"
msgstr "オンライン・ドキュメント"
-#: git-gui.sh:2238
+#: git-gui.sh:2340
#, tcl-format
msgid "fatal: cannot stat path %s: No such file or directory"
msgstr ""
"致命的: パス %s が stat できません。そのようなファイルやディレクトリはありま"
"せん"
-#: git-gui.sh:2271
+#: git-gui.sh:2373
msgid "Current Branch:"
msgstr "現在のブランチ"
-#: git-gui.sh:2292
+#: git-gui.sh:2394
msgid "Staged Changes (Will Commit)"
msgstr "ステージングされた(コミット予定済の)変更"
-#: git-gui.sh:2312
+#: git-gui.sh:2414
msgid "Unstaged Changes"
msgstr "コミット予定に入っていない変更"
-#: git-gui.sh:2362
+#: git-gui.sh:2464
msgid "Stage Changed"
msgstr "変更をコミット予定に入れる"
-#: git-gui.sh:2378 lib/transport.tcl:93 lib/transport.tcl:182
+#: git-gui.sh:2480 lib/transport.tcl:93 lib/transport.tcl:182
msgid "Push"
msgstr "プッシュ"
-#: git-gui.sh:2408
+#: git-gui.sh:2510
msgid "Initial Commit Message:"
msgstr "最初のコミットメッセージ:"
-#: git-gui.sh:2409
+#: git-gui.sh:2511
msgid "Amended Commit Message:"
msgstr "訂正したコミットメッセージ:"
-#: git-gui.sh:2410
+#: git-gui.sh:2512
msgid "Amended Initial Commit Message:"
msgstr "訂正した最初のコミットメッセージ:"
-#: git-gui.sh:2411
+#: git-gui.sh:2513
msgid "Amended Merge Commit Message:"
msgstr "訂正したマージコミットメッセージ:"
-#: git-gui.sh:2412
+#: git-gui.sh:2514
msgid "Merge Commit Message:"
msgstr "マージコミットメッセージ:"
-#: git-gui.sh:2413
+#: git-gui.sh:2515
msgid "Commit Message:"
msgstr "コミットメッセージ:"
-#: git-gui.sh:2459 git-gui.sh:2622 lib/console.tcl:73
+#: git-gui.sh:2561 git-gui.sh:2723 lib/console.tcl:73
msgid "Copy All"
msgstr "全てコピー"
-#: git-gui.sh:2483 lib/blame.tcl:107
+#: git-gui.sh:2585 lib/blame.tcl:100
msgid "File:"
msgstr "ファイル:"
-#: git-gui.sh:2589
+#: git-gui.sh:2691
msgid "Apply/Reverse Hunk"
msgstr "パッチを適用/取り消す"
-#: git-gui.sh:2595
-msgid "Show Less Context"
-msgstr "文脈を少なく"
-
-#: git-gui.sh:2602
-msgid "Show More Context"
-msgstr "文脈を多く"
+#: git-gui.sh:2696
+msgid "Apply/Reverse Line"
+msgstr "パッチ行を適用/取り消す"
-#: git-gui.sh:2610
+#: git-gui.sh:2711
msgid "Refresh"
msgstr "再読み込み"
-#: git-gui.sh:2631
+#: git-gui.sh:2732
msgid "Decrease Font Size"
msgstr "フォントを小さく"
-#: git-gui.sh:2635
+#: git-gui.sh:2736
msgid "Increase Font Size"
msgstr "フォントを大きく"
-#: git-gui.sh:2646
+#: git-gui.sh:2747
msgid "Unstage Hunk From Commit"
msgstr "パッチをコミット予定から外す"
-#: git-gui.sh:2648
+#: git-gui.sh:2748
+msgid "Unstage Line From Commit"
+msgstr "コミット予定から行を外す"
+
+#: git-gui.sh:2750
msgid "Stage Hunk For Commit"
msgstr "パッチをコミット予定に加える"
-#: git-gui.sh:2667
+#: git-gui.sh:2751
+msgid "Stage Line For Commit"
+msgstr "パッチ行をコミット予定に加える"
+
+#: git-gui.sh:2771
msgid "Initializing..."
msgstr "初期化しています…"
-#: git-gui.sh:2762
+#: git-gui.sh:2876
#, tcl-format
msgid ""
"Possible environment issues exist.\n"
@@ -449,7 +450,7 @@ msgstr ""
"以下の環境変数は %s が起動する Git サブプロセスによって無視されるでしょう:\n"
"\n"
-#: git-gui.sh:2792
+#: git-gui.sh:2906
msgid ""
"\n"
"This is due to a known issue with the\n"
@@ -459,7 +460,7 @@ msgstr ""
"これは Cygwin で配布されている Tcl バイナリに\n"
"関しての既知の問題によります"
-#: git-gui.sh:2797
+#: git-gui.sh:2911
#, tcl-format
msgid ""
"\n"
@@ -478,64 +479,80 @@ msgstr ""
msgid "git-gui - a graphical user interface for Git."
msgstr "Git のグラフィカルUI git-gui"
-#: lib/blame.tcl:77
+#: lib/blame.tcl:70
msgid "File Viewer"
msgstr "ファイルピューワ"
-#: lib/blame.tcl:81
+#: lib/blame.tcl:74
msgid "Commit:"
msgstr "コミット:"
-#: lib/blame.tcl:264
+#: lib/blame.tcl:257
msgid "Copy Commit"
msgstr "コミットをコピー"
-#: lib/blame.tcl:384
+#: lib/blame.tcl:260
+msgid "Do Full Copy Detection"
+msgstr "コピー検知"
+
+#: lib/blame.tcl:388
#, tcl-format
msgid "Reading %s..."
msgstr "%s を読んでいます…"
-#: lib/blame.tcl:488
+#: lib/blame.tcl:492
msgid "Loading copy/move tracking annotations..."
msgstr "コピー・移動追跡データを読んでいます…"
-#: lib/blame.tcl:508
+#: lib/blame.tcl:512
msgid "lines annotated"
msgstr "行を注釈しました"
-#: lib/blame.tcl:689
+#: lib/blame.tcl:704
msgid "Loading original location annotations..."
msgstr "元位置行の注釈データを読んでいます…"
-#: lib/blame.tcl:692
+#: lib/blame.tcl:707
msgid "Annotation complete."
msgstr "注釈完了しました"
-#: lib/blame.tcl:746
+#: lib/blame.tcl:737
+msgid "Busy"
+msgstr "実行中"
+
+#: lib/blame.tcl:738
+msgid "Annotation process is already running."
+msgstr "すでに blame プロセスを実行中です。"
+
+#: lib/blame.tcl:777
+msgid "Running thorough copy detection..."
+msgstr "コピー検知を実行中…"
+
+#: lib/blame.tcl:827
msgid "Loading annotation..."
msgstr "注釈を読み込んでいます…"
-#: lib/blame.tcl:802
+#: lib/blame.tcl:883
msgid "Author:"
msgstr "作者:"
-#: lib/blame.tcl:806
+#: lib/blame.tcl:887
msgid "Committer:"
msgstr "コミット者:"
-#: lib/blame.tcl:811
+#: lib/blame.tcl:892
msgid "Original File:"
msgstr "元ファイル"
-#: lib/blame.tcl:925
+#: lib/blame.tcl:1006
msgid "Originally By:"
msgstr "原作者:"
-#: lib/blame.tcl:931
+#: lib/blame.tcl:1012
msgid "In File:"
msgstr "ファイル:"
-#: lib/blame.tcl:936
+#: lib/blame.tcl:1017
msgid "Copied Or Moved Here By:"
msgstr "複写・移動者:"
@@ -549,7 +566,7 @@ msgstr "チェックアウト"
#: lib/branch_checkout.tcl:27 lib/branch_create.tcl:35
#: lib/branch_delete.tcl:32 lib/branch_rename.tcl:30 lib/browser.tcl:282
-#: lib/checkout_op.tcl:522 lib/choose_font.tcl:43 lib/merge.tcl:171
+#: lib/checkout_op.tcl:544 lib/choose_font.tcl:43 lib/merge.tcl:171
#: lib/option.tcl:103 lib/remote_branch_delete.tcl:42 lib/transport.tcl:97
msgid "Cancel"
msgstr "中止"
@@ -558,7 +575,7 @@ msgstr "中止"
msgid "Revision"
msgstr "リビジョン"
-#: lib/branch_checkout.tcl:36 lib/branch_create.tcl:69 lib/option.tcl:242
+#: lib/branch_checkout.tcl:36 lib/branch_create.tcl:69 lib/option.tcl:244
msgid "Options"
msgstr "オプション"
@@ -610,7 +627,7 @@ msgstr "いいえ"
msgid "Fast Forward Only"
msgstr "早送りのみ"
-#: lib/branch_create.tcl:85 lib/checkout_op.tcl:514
+#: lib/branch_create.tcl:85 lib/checkout_op.tcl:536
msgid "Reset"
msgstr "リセット"
@@ -700,7 +717,7 @@ msgstr "新しい名前:"
msgid "Please select a branch to rename."
msgstr "名前を変更するブランチを選んで下さい。"
-#: lib/branch_rename.tcl:96 lib/checkout_op.tcl:179
+#: lib/branch_rename.tcl:96 lib/checkout_op.tcl:201
#, tcl-format
msgid "Branch '%s' already exists."
msgstr "'%s'というブランチは既に存在します。"
@@ -732,31 +749,36 @@ msgid "Browse Branch Files"
msgstr "現在のブランチのファイルを見る"
#: lib/browser.tcl:278 lib/choose_repository.tcl:387
-#: lib/choose_repository.tcl:474 lib/choose_repository.tcl:484
-#: lib/choose_repository.tcl:987
+#: lib/choose_repository.tcl:472 lib/choose_repository.tcl:482
+#: lib/choose_repository.tcl:985
msgid "Browse"
msgstr "ブラウズ"
-#: lib/checkout_op.tcl:79
+#: lib/checkout_op.tcl:84
#, tcl-format
msgid "Fetching %s from %s"
msgstr "%s から %s をフェッチしています"
-#: lib/checkout_op.tcl:127
+#: lib/checkout_op.tcl:132
#, tcl-format
msgid "fatal: Cannot resolve %s"
msgstr "致命的エラー: %s を解決できません"
-#: lib/checkout_op.tcl:140 lib/console.tcl:81 lib/database.tcl:31
+#: lib/checkout_op.tcl:145 lib/console.tcl:81 lib/database.tcl:31
msgid "Close"
msgstr "閉じる"
-#: lib/checkout_op.tcl:169
+#: lib/checkout_op.tcl:174
#, tcl-format
msgid "Branch '%s' does not exist."
msgstr "ブランチ'%s'は存在しません。"
-#: lib/checkout_op.tcl:206
+#: lib/checkout_op.tcl:193
+#, tcl-format
+msgid "Failed to configure simplified git-pull for '%s'."
+msgstr "'%s' に簡易 git-pull を設定できませんでした"
+
+#: lib/checkout_op.tcl:228
#, tcl-format
msgid ""
"Branch '%s' already exists.\n"
@@ -769,21 +791,21 @@ msgstr ""
"%s に早送りできません。\n"
"マージが必要です。"
-#: lib/checkout_op.tcl:220
+#: lib/checkout_op.tcl:242
#, tcl-format
msgid "Merge strategy '%s' not supported."
msgstr "'%s' マージ戦略はサポートされていません。"
-#: lib/checkout_op.tcl:239
+#: lib/checkout_op.tcl:261
#, tcl-format
msgid "Failed to update '%s'."
msgstr "'%s' の更新に失敗しました。"
-#: lib/checkout_op.tcl:251
+#: lib/checkout_op.tcl:273
msgid "Staging area (index) is already locked."
msgstr "インデックスは既にロックされています。"
-#: lib/checkout_op.tcl:266
+#: lib/checkout_op.tcl:288
msgid ""
"Last scanned state does not match repository state.\n"
"\n"
@@ -799,30 +821,30 @@ msgstr ""
"\n"
"自動的に再スキャンを開始します。\n"
-#: lib/checkout_op.tcl:322
+#: lib/checkout_op.tcl:344
#, tcl-format
msgid "Updating working directory to '%s'..."
msgstr "作業ディレクトリを '%s' に更新しています…"
-#: lib/checkout_op.tcl:323
+#: lib/checkout_op.tcl:345
msgid "files checked out"
msgstr "チェックアウトされたファイル"
-#: lib/checkout_op.tcl:353
+#: lib/checkout_op.tcl:375
#, tcl-format
msgid "Aborted checkout of '%s' (file level merging is required)."
msgstr "'%s' のチェックアウトを中止しました(ファイル毎のマージが必要です)。"
-#: lib/checkout_op.tcl:354
+#: lib/checkout_op.tcl:376
msgid "File level merge required."
msgstr "ファイル毎のマージが必要です。"
-#: lib/checkout_op.tcl:358
+#: lib/checkout_op.tcl:380
#, tcl-format
msgid "Staying on branch '%s'."
msgstr "ブランチ '%s' に滞まります。"
-#: lib/checkout_op.tcl:429
+#: lib/checkout_op.tcl:451
msgid ""
"You are no longer on a local branch.\n"
"\n"
@@ -834,30 +856,30 @@ msgstr ""
"ブランチ上に滞まりたいときは、この「分離されたチェックアウト」から新規ブラン"
"チを開始してください。"
-#: lib/checkout_op.tcl:446 lib/checkout_op.tcl:450
+#: lib/checkout_op.tcl:468 lib/checkout_op.tcl:472
#, tcl-format
msgid "Checked out '%s'."
msgstr "'%s' をチェックアウトしました"
-#: lib/checkout_op.tcl:478
+#: lib/checkout_op.tcl:500
#, tcl-format
msgid "Resetting '%s' to '%s' will lose the following commits:"
msgstr "'%s' を '%s' にリセットすると、以下のコミットが失なわれます:"
-#: lib/checkout_op.tcl:500
+#: lib/checkout_op.tcl:522
msgid "Recovering lost commits may not be easy."
msgstr "失なわれたコミットを回復するのは簡単ではありません。"
-#: lib/checkout_op.tcl:505
+#: lib/checkout_op.tcl:527
#, tcl-format
msgid "Reset '%s'?"
msgstr "'%s' をリセットしますか?"
-#: lib/checkout_op.tcl:510 lib/merge.tcl:163
+#: lib/checkout_op.tcl:532 lib/merge.tcl:163
msgid "Visualize"
msgstr "可視化"
-#: lib/checkout_op.tcl:578
+#: lib/checkout_op.tcl:600
#, tcl-format
msgid ""
"Failed to set current branch.\n"
@@ -909,7 +931,7 @@ msgstr "新しいリポジトリを作る"
msgid "New..."
msgstr "新規…"
-#: lib/choose_repository.tcl:94 lib/choose_repository.tcl:460
+#: lib/choose_repository.tcl:94 lib/choose_repository.tcl:458
msgid "Clone Existing Repository"
msgstr "既存リポジトリを複製する"
@@ -917,7 +939,7 @@ msgstr "既存リポジトリを複製する"
msgid "Clone..."
msgstr "複製…"
-#: lib/choose_repository.tcl:107 lib/choose_repository.tcl:976
+#: lib/choose_repository.tcl:107 lib/choose_repository.tcl:974
msgid "Open Existing Repository"
msgstr "既存リポジトリを開く"
@@ -939,183 +961,183 @@ msgstr "最近使ったリポジトリを開く"
msgid "Failed to create repository %s:"
msgstr "リポジトリ %s を作製できません:"
-#: lib/choose_repository.tcl:381 lib/choose_repository.tcl:478
+#: lib/choose_repository.tcl:381 lib/choose_repository.tcl:476
msgid "Directory:"
msgstr "ディレクトリ:"
-#: lib/choose_repository.tcl:412 lib/choose_repository.tcl:537
-#: lib/choose_repository.tcl:1011
+#: lib/choose_repository.tcl:410 lib/choose_repository.tcl:535
+#: lib/choose_repository.tcl:1007
msgid "Git Repository"
msgstr "GIT リポジトリ"
-#: lib/choose_repository.tcl:437
+#: lib/choose_repository.tcl:435
#, tcl-format
msgid "Directory %s already exists."
msgstr "ディレクトリ '%s' は既に存在します。"
-#: lib/choose_repository.tcl:441
+#: lib/choose_repository.tcl:439
#, tcl-format
msgid "File %s already exists."
msgstr "ファイル '%s' は既に存在します。"
-#: lib/choose_repository.tcl:455
+#: lib/choose_repository.tcl:453
msgid "Clone"
msgstr "複製"
-#: lib/choose_repository.tcl:468
+#: lib/choose_repository.tcl:466
msgid "URL:"
msgstr "URL:"
-#: lib/choose_repository.tcl:489
+#: lib/choose_repository.tcl:487
msgid "Clone Type:"
msgstr "複製方式:"
-#: lib/choose_repository.tcl:495
+#: lib/choose_repository.tcl:493
msgid "Standard (Fast, Semi-Redundant, Hardlinks)"
msgstr "標準(高速・中冗長度・ハードリンク)"
-#: lib/choose_repository.tcl:501
+#: lib/choose_repository.tcl:499
msgid "Full Copy (Slower, Redundant Backup)"
msgstr "全複写(低速・冗長バックアップ)"
-#: lib/choose_repository.tcl:507
+#: lib/choose_repository.tcl:505
msgid "Shared (Fastest, Not Recommended, No Backup)"
msgstr "共有(最高速・非推奨・バックアップ無し)"
-#: lib/choose_repository.tcl:543 lib/choose_repository.tcl:590
-#: lib/choose_repository.tcl:736 lib/choose_repository.tcl:806
-#: lib/choose_repository.tcl:1017 lib/choose_repository.tcl:1025
+#: lib/choose_repository.tcl:541 lib/choose_repository.tcl:588
+#: lib/choose_repository.tcl:734 lib/choose_repository.tcl:804
+#: lib/choose_repository.tcl:1013 lib/choose_repository.tcl:1021
#, tcl-format
msgid "Not a Git repository: %s"
msgstr "Git リポジトリではありません: %s"
-#: lib/choose_repository.tcl:579
+#: lib/choose_repository.tcl:577
msgid "Standard only available for local repository."
msgstr "標準方式は同一計算機上のリポジトリにのみ使えます。"
-#: lib/choose_repository.tcl:583
+#: lib/choose_repository.tcl:581
msgid "Shared only available for local repository."
msgstr "共有方式は同一計算機上のリポジトリにのみ使えます。"
-#: lib/choose_repository.tcl:604
+#: lib/choose_repository.tcl:602
#, tcl-format
msgid "Location %s already exists."
msgstr "'%s' は既に存在します。"
-#: lib/choose_repository.tcl:615
+#: lib/choose_repository.tcl:613
msgid "Failed to configure origin"
msgstr "origin を設定できませんでした"
-#: lib/choose_repository.tcl:627
+#: lib/choose_repository.tcl:625
msgid "Counting objects"
msgstr "オブジェクトを数えています"
-#: lib/choose_repository.tcl:628
+#: lib/choose_repository.tcl:626
msgid "buckets"
msgstr "バケツ"
-#: lib/choose_repository.tcl:652
+#: lib/choose_repository.tcl:650
#, tcl-format
msgid "Unable to copy objects/info/alternates: %s"
msgstr "objects/info/alternates を複写できません: %s"
-#: lib/choose_repository.tcl:688
+#: lib/choose_repository.tcl:686
#, tcl-format
msgid "Nothing to clone from %s."
msgstr "%s から複製する内容はありません"
-#: lib/choose_repository.tcl:690 lib/choose_repository.tcl:904
-#: lib/choose_repository.tcl:916
+#: lib/choose_repository.tcl:688 lib/choose_repository.tcl:902
+#: lib/choose_repository.tcl:914
msgid "The 'master' branch has not been initialized."
msgstr "'master' ブランチが初期化されていません"
-#: lib/choose_repository.tcl:703
+#: lib/choose_repository.tcl:701
msgid "Hardlinks are unavailable. Falling back to copying."
msgstr "ハードリンクが作れないので、コピーします"
-#: lib/choose_repository.tcl:715
+#: lib/choose_repository.tcl:713
#, tcl-format
msgid "Cloning from %s"
msgstr "%s から複製しています"
-#: lib/choose_repository.tcl:746
+#: lib/choose_repository.tcl:744
msgid "Copying objects"
msgstr "オブジェクトを複写しています"
-#: lib/choose_repository.tcl:747
+#: lib/choose_repository.tcl:745
msgid "KiB"
msgstr "KiB"
-#: lib/choose_repository.tcl:771
+#: lib/choose_repository.tcl:769
#, tcl-format
msgid "Unable to copy object: %s"
msgstr "オブジェクトを複写できません: %s"
-#: lib/choose_repository.tcl:781
+#: lib/choose_repository.tcl:779
msgid "Linking objects"
msgstr "オブジェクトを連結しています"
-#: lib/choose_repository.tcl:782
+#: lib/choose_repository.tcl:780
msgid "objects"
msgstr "オブジェクト"
-#: lib/choose_repository.tcl:790
+#: lib/choose_repository.tcl:788
#, tcl-format
msgid "Unable to hardlink object: %s"
msgstr "オブジェクトをハードリンクできません: %s"
-#: lib/choose_repository.tcl:845
+#: lib/choose_repository.tcl:843
msgid "Cannot fetch branches and objects. See console output for details."
msgstr "ブランチやオブジェクトを取得できません。コンソール出力を見て下さい"
-#: lib/choose_repository.tcl:856
+#: lib/choose_repository.tcl:854
msgid "Cannot fetch tags. See console output for details."
msgstr "タグを取得できません。コンソール出力を見て下さい"
-#: lib/choose_repository.tcl:880
+#: lib/choose_repository.tcl:878
msgid "Cannot determine HEAD. See console output for details."
msgstr "HEAD を確定できません。コンソール出力を見て下さい"
-#: lib/choose_repository.tcl:889
+#: lib/choose_repository.tcl:887
#, tcl-format
msgid "Unable to cleanup %s"
msgstr "%s を掃除できません"
-#: lib/choose_repository.tcl:895
+#: lib/choose_repository.tcl:893
msgid "Clone failed."
msgstr "複写に失敗しました。"
-#: lib/choose_repository.tcl:902
+#: lib/choose_repository.tcl:900
msgid "No default branch obtained."
msgstr "デフォールト・ブランチが取得されませんでした"
-#: lib/choose_repository.tcl:913
+#: lib/choose_repository.tcl:911
#, tcl-format
msgid "Cannot resolve %s as a commit."
msgstr "%s をコミットとして解釈できません"
-#: lib/choose_repository.tcl:925
+#: lib/choose_repository.tcl:923
msgid "Creating working directory"
msgstr "作業ディレクトリを作成しています"
-#: lib/choose_repository.tcl:926 lib/index.tcl:65 lib/index.tcl:127
+#: lib/choose_repository.tcl:924 lib/index.tcl:65 lib/index.tcl:127
#: lib/index.tcl:193
msgid "files"
msgstr "ファイル"
-#: lib/choose_repository.tcl:955
+#: lib/choose_repository.tcl:953
msgid "Initial file checkout failed."
msgstr "初期チェックアウトに失敗しました"
-#: lib/choose_repository.tcl:971
+#: lib/choose_repository.tcl:969
msgid "Open"
msgstr "開く"
-#: lib/choose_repository.tcl:981
+#: lib/choose_repository.tcl:979
msgid "Repository:"
msgstr "リポジトリ:"
-#: lib/choose_repository.tcl:1031
+#: lib/choose_repository.tcl:1027
#, tcl-format
msgid "Failed to open repository %s:"
msgstr "リポジトリ %s を開けません:"
@@ -1405,7 +1427,7 @@ msgstr ""
msgid "Invalid date from Git: %s"
msgstr "Git から出た無効な日付: %s"
-#: lib/diff.tcl:42
+#: lib/diff.tcl:44
#, tcl-format
msgid ""
"No differences detected.\n"
@@ -1427,40 +1449,48 @@ msgstr ""
"\n"
"同様な状態のファイルを探すために、自動的に再スキャンを開始します。"
-#: lib/diff.tcl:81
+#: lib/diff.tcl:83
#, tcl-format
msgid "Loading diff of %s..."
msgstr "%s の変更点をロード中…"
-#: lib/diff.tcl:114 lib/diff.tcl:184
+#: lib/diff.tcl:116 lib/diff.tcl:190
#, tcl-format
msgid "Unable to display %s"
msgstr "%s を表示できません"
-#: lib/diff.tcl:115
+#: lib/diff.tcl:117
msgid "Error loading file:"
msgstr "ファイルを読む際のエラーです:"
-#: lib/diff.tcl:122
+#: lib/diff.tcl:124
msgid "Git Repository (subproject)"
msgstr "Git リポジトリ(サブプロジェクト)"
-#: lib/diff.tcl:134
+#: lib/diff.tcl:136
msgid "* Binary file (not showing content)."
msgstr "* バイナリファイル(内容は表示しません)"
-#: lib/diff.tcl:185
+#: lib/diff.tcl:191
msgid "Error loading diff:"
msgstr "diff を読む際のエラーです:"
-#: lib/diff.tcl:303
+#: lib/diff.tcl:313
msgid "Failed to unstage selected hunk."
msgstr "選択されたパッチをコミット予定から外せません。"
-#: lib/diff.tcl:310
+#: lib/diff.tcl:320
msgid "Failed to stage selected hunk."
msgstr "選択されたパッチをコミット予定に加えられません。"
+#: lib/diff.tcl:386
+msgid "Failed to unstage selected line."
+msgstr "選択されたパッチ行をコミット予定から外せません。"
+
+#: lib/diff.tcl:394
+msgid "Failed to stage selected line."
+msgstr "選択されたパッチ行をコミット予定に加えられません。"
+
#: lib/error.tcl:20 lib/error.tcl:114
msgid "error"
msgstr "エラー"
@@ -1662,11 +1692,11 @@ msgstr "中断しています"
msgid "files reset"
msgstr "リセットしたファイル"
-#: lib/merge.tcl:265
+#: lib/merge.tcl:266
msgid "Abort failed."
msgstr "中断に失敗しました。"
-#: lib/merge.tcl:267
+#: lib/merge.tcl:268
msgid "Abort completed. Ready."
msgstr "中断完了。"
@@ -1720,42 +1750,62 @@ msgid "Match Tracking Branches"
msgstr "トラッキングブランチを合わせる"
#: lib/option.tcl:126
+msgid "Blame Copy Only On Changed Files"
+msgstr "変更されたファイルのみコピー検知を行なう"
+
+#: lib/option.tcl:127
+msgid "Minimum Letters To Blame Copy On"
+msgstr "コピーを検知する最少文字数"
+
+#: lib/option.tcl:128
msgid "Number of Diff Context Lines"
msgstr "diff の文脈行数"
-#: lib/option.tcl:127
+#: lib/option.tcl:129
msgid "Commit Message Text Width"
msgstr "コミットメッセージのテキスト幅"
-#: lib/option.tcl:128
+#: lib/option.tcl:130
msgid "New Branch Name Template"
msgstr "新しいブランチ名のテンプレート"
-#: lib/option.tcl:192
+#: lib/option.tcl:194
msgid "Spelling Dictionary:"
msgstr "スペルチェック辞書"
-#: lib/option.tcl:216
+#: lib/option.tcl:218
msgid "Change Font"
msgstr "フォントを変更"
-#: lib/option.tcl:220
+#: lib/option.tcl:222
#, tcl-format
msgid "Choose %s"
msgstr "%s を選択"
-#: lib/option.tcl:226
+#: lib/option.tcl:228
msgid "pt."
msgstr "ポイント"
-#: lib/option.tcl:240
+#: lib/option.tcl:242
msgid "Preferences"
msgstr "設定"
-#: lib/option.tcl:275
+#: lib/option.tcl:277
msgid "Failed to completely save options:"
msgstr "完全にオプションを保存できません:"
+#: lib/remote.tcl:165
+msgid "Prune from"
+msgstr "から刈込む…"
+
+#: lib/remote.tcl:170
+msgid "Fetch from"
+msgstr "取得元"
+
+#: lib/remote.tcl:213
+msgid "Push to"
+msgstr "プッシュ先"
+
#: lib/remote_branch_delete.tcl:29 lib/remote_branch_delete.tcl:34
msgid "Delete Remote Branch"
msgstr "リモート・ブランチを削除"
@@ -1840,18 +1890,6 @@ msgstr "リポジトリが選択されていません。"
msgid "Scanning %s..."
msgstr "%s をスキャンしています…"
-#: lib/remote.tcl:165
-msgid "Prune from"
-msgstr "から刈込む…"
-
-#: lib/remote.tcl:170
-msgid "Fetch from"
-msgstr "取得元"
-
-#: lib/remote.tcl:213
-msgid "Push to"
-msgstr "プッシュ先"
-
#: lib/shortcut.tcl:20 lib/shortcut.tcl:61
msgid "Cannot write shortcut:"
msgstr "ショートカットが書けません:"
@@ -1885,15 +1923,15 @@ msgstr "スペルチェッカーの起動に失敗しました"
msgid "Unrecognized spell checker"
msgstr "スペルチェッカーが判別できません"
-#: lib/spellcheck.tcl:180
+#: lib/spellcheck.tcl:186
msgid "No Suggestions"
msgstr "提案なし"
-#: lib/spellcheck.tcl:381
+#: lib/spellcheck.tcl:387
msgid "Unexpected EOF from spell checker"
msgstr "スペルチェッカーが予想外の EOF を返しました"
-#: lib/spellcheck.tcl:385
+#: lib/spellcheck.tcl:391
msgid "Spell Checker Failed"
msgstr "スペルチェック失敗"
@@ -1964,6 +2002,3 @@ msgstr "Thin Pack を使う(遅いネットワーク接続)"
#: lib/transport.tcl:168
msgid "Include tags"
msgstr "タグを含める"
-
-#~ msgid "Not connected to aspell"
-#~ msgstr "aspell に接続していません"
--
1.6.0.rc1
^ permalink raw reply related
* Re: More on git over HTTP POST
From: david @ 2008-08-03 8:10 UTC (permalink / raw)
To: Shawn O. Pearce; +Cc: H. Peter Anvin, Junio C Hamano, Git Mailing List
In-Reply-To: <20080803041014.GD27465@spearce.org>
On Sat, 2 Aug 2008, Shawn O. Pearce wrote:
>
> "H. Peter Anvin" <hpa@zytor.com> wrote:
>> Junio C Hamano wrote:
>>> For example, putting them [capabilities] on extra HTTP headers is probably Ok.
>>
>> I think that would be a mistake, just because it's one more thing for
>> proxies to screw up on.
>
> I didn't realize we were in an era of proxies that are that
> brain-damaged that they cannot relay the other headers. The Amazon
> S3 service relies heavily upon their own extended headers to make
> their REST API work. If proxies stripped that stuff out then the
> client wouldn't work at all.
>
> IOW I had thought we were past this dark age of the Internet.
actually, it's not just a matter of not getting 'past this dark age of the
Internet', it's an issue that so many people are tunneling _everyting_
over http (including the bad guys tunneling malware) that proxies are
getting more aggressive then they have ever been before in pulling apart
the payload and analysing it before letting it get through to the far
side.
David Lang
>> It's better to have negotiation information in
>> the payload, before the "real" data.
>
> I guess I could do that. At least for the really complex stuff.
>
>> Obviously one thing that needs to be included in each transaction is a
>> transaction ID that will be reported back on the next transaction, since
>> you can't rely on a persistent connection.
>
> No. That requires the server to maintain state. We don't want to
> do that if we can avoid it. I would much rather have the clients
> handle the state management as it simplifies the server side,
> especially when you start talking about reverse proxies and/or
> load-balancers running in front of the server farm.
>
>
^ permalink raw reply
* [RFC] gitattributes on a bare repo
From: Giuseppe Bilotta @ 2008-08-03 8:34 UTC (permalink / raw)
To: git
Hello all,
I realized recently that gitattributes don't work on a bare repo. It's
easy to see why (no .gitattributes file to look into) and the
'official' solution is to use .git/info/attributes for that, which has
the obvious problem of being local and not carried over to other repos
(so that e.g. you have to recreate it and keep it up to date on remote
repos too).
I was discussing this on IRC with pasky and he suggested that the best
way to approach the matter was to use the .gitattributes from the
relevant head. For example, a diff-tree would use the first
.gitattributes from the first tree-ish parameter. I have actually
looked into implementing this myself, but I'm afraid my git mojo isn't
strong enough yet.
A similar discussion would hold of course for .gitignore and the
corresponding info/excludes file.
I'm not sure how widespread the need for such a possibility (using
.gitignore and .gitattributes on bare repos) is, but at least
.gitattributes it would allow gitweb to use the correct diff
funcnames.
--
Giuseppe "Oblomov" Bilotta
^ permalink raw reply
* [RFC PATCH (GITK)] gitk: Allow overriding the default commit.
From: Alexander Gavrilov @ 2008-08-03 8:49 UTC (permalink / raw)
To: Paul Mackerras; +Cc: git
In-Reply-To: <bb6f213e0807310541s383c2938q91543a1c57a4d71f@mail.gmail.com>
Date: Sun, 27 Jul 2008 08:18:27 +0400
Other GUI tools may occasionally need to start
gitk and make it automatically select a certain
commit. This patch supports doing it through the
environment or command line.
Using the environment allows graceful degradation of
the tool when used with an old version of gitk:
unsupported command line options cause it to die.
Signed-off-by: Alexander Gavrilov <angavrilov@gmail.com>
---
On Thursday 31 July 2008 16:41:20 Alexander Gavrilov wrote:
> I have a patch WIP that allows specifying a commit on the command line
> to select instead of the head (I need it to enhance the git gui blame
> UI). It makes the function somewhat more intelligent. I'll submit it
> as soon as this series is sorted out.
I decided to send it now.
-- Alexander
gitk | 25 ++++++++++++++++++++++++-
1 files changed, 24 insertions(+), 1 deletions(-)
diff --git a/gitk b/gitk
index d093a39..2da885d 100755
--- a/gitk
+++ b/gitk
@@ -416,10 +416,12 @@ proc stop_rev_list {view} {
}
proc reset_pending_select {selid} {
- global pending_select mainheadid
+ global pending_select mainheadid selectheadid
if {$selid ne {}} {
set pending_select $selid
+ } elseif {$selectheadid ne {}} {
+ set pending_select $selectheadid
} else {
set pending_select $mainheadid
}
@@ -1607,6 +1609,7 @@ proc getcommit {id} {
proc readrefs {} {
global tagids idtags headids idheads tagobjid
global otherrefids idotherrefs mainhead mainheadid
+ global selecthead selectheadid
foreach v {tagids idtags headids idheads otherrefids idotherrefs} {
catch {unset $v}
@@ -1653,6 +1656,12 @@ proc readrefs {} {
set mainhead [string range $thehead 11 end]
}
}
+ set selectheadid {}
+ if {$selecthead ne {}} {
+ catch {
+ set selectheadid [exec git rev-parse --verify $selecthead]
+ }
+ }
}
# skip over fake commits
@@ -9863,6 +9872,13 @@ if {![file isdirectory $gitdir]} {
exit 1
}
+set selecthead {}
+set selectheadid {}
+
+if {[info exists env(GITK_SELECT_ID)]} {
+ set selecthead $env(GITK_SELECT_ID)
+}
+
set revtreeargs {}
set cmdline_files {}
set i 0
@@ -9874,6 +9890,9 @@ foreach arg $argv {
set cmdline_files [lrange $argv [expr {$i + 1}] end]
break
}
+ "--select-commit=*" {
+ set selecthead [string range $arg 16 end]
+ }
"--argscmd=*" {
set revtreeargscmd [string range $arg 10 end]
}
@@ -9884,6 +9903,10 @@ foreach arg $argv {
incr i
}
+if {$selecthead eq "HEAD"} {
+ set selecthead {}
+}
+
if {$i >= [llength $argv] && $revtreeargs ne {}} {
# no -- on command line, but some arguments (other than --argscmd)
if {[catch {
--
1.5.6.3.18.gfe82
^ permalink raw reply related
* Re: Missing pieces for 1.6.0 on MinGW?
From: Steffen Prohaska @ 2008-08-03 8:52 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Johannes Sixt, Johannes Schindelin, git
In-Reply-To: <7vljzfkzkv.fsf@gitster.siamese.dyndns.org>
On Aug 2, 2008, at 9:05 PM, Junio C Hamano wrote:
> Just a quick question before the weekend ends and -rc2 gets tagged.
> (I
> lost track of that argv0 vs bin/git vs libexec/git-core/git-foo
> discussion).
I haven't found time to work on this and I also haven't observed
any progress made by others.
> Are there any missing but necessary patches we need before 1.6.0 for
> MinGW?
So we don't have patches, although we still have the problem
discussed last weekend.
Unfortunately, I cannot promise that I'll find time the next couple
of days to work on the issue. I propose you just continue the
release cycle without waiting for MinGW.
Steffen
^ permalink raw reply
* Re: Missing pieces for 1.6.0 on MinGW?
From: Johannes Sixt @ 2008-08-03 9:16 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Steffen Prohaska, Johannes Schindelin, git
In-Reply-To: <7vljzfkzkv.fsf@gitster.siamese.dyndns.org>
Zitat von Junio C Hamano <gitster@pobox.com>:
> Just a quick question before the weekend ends and -rc2 gets tagged. (I
> lost track of that argv0 vs bin/git vs libexec/git-core/git-foo
> discussion).
>
> Are there any missing but necessary patches we need before 1.6.0 for
> MinGW?
Yes, there are some open issues:
(1) git-gui was fixed for the msysgit installer, but it broke for me; but I
think I know where to fix it.
(2) the non-builtins in $(bindir) don't set argv0_path, and consequently don't
find ETC_GITCONFIG.
(3) the 'mingw_main undefined' error is still a mystery. I'm about to send a
preprocessed file to Steffen (it's a bit large, even compressed, so I'll do
that in a private mail).
Item (1) I expect to work on later today, but needs some investigation by
Steffen and perhaps Shawn. (2) is probably a minor issue. (3) is, well, a
mystery, although Steffen's patch works for me, too. Nevertheless, I'd like to
know why my original approach does not always work.
-- Hannes
^ permalink raw reply
* Re: [PATCH 1/3] git-gui: Adapt discovery of oguilib to execdir 'libexec/git-core'
From: Johannes Sixt @ 2008-08-03 9:35 UTC (permalink / raw)
To: Steffen Prohaska, Shawn O. Pearce; +Cc: git
In-Reply-To: <AF6C526A-57ED-4386-A4CF-5260D82026B7@zib.de>
Zitat von Steffen Prohaska <prohaska@zib.de>:
>
> On Jul 27, 2008, at 11:24 PM, Shawn O. Pearce wrote:
>
> > Steffen Prohaska <prohaska@zib.de> wrote:
> >> The new execdir has is two levels below the root directory, while
> >> the old execdir 'bin' was only one level below. This commit
> >> adapts the discovery of oguilib that uses relative paths
> >> accordingly.
> > ...
> >> diff --git a/git-gui/git-gui.sh b/git-gui/git-gui.sh
> >> index 940677c..baccd57 100755
> >> --- a/git-gui/git-gui.sh
> >> +++ b/git-gui/git-gui.sh
> >> @@ -52,7 +52,9 @@ catch {rename send {}} ; # What an evil concept...
> >> set oguilib {@@GITGUI_LIBDIR@@}
> >> set oguirel {@@GITGUI_RELATIVE@@}
> >> if {$oguirel eq {1}} {
> >> - set oguilib [file dirname [file dirname [file normalize $argv0]]]
> >> + set oguilib [file dirname \
> >> + [file dirname \
> >> + [file dirname [file normalize $argv0]]]]
> >> set oguilib [file join $oguilib share git-gui lib]
> >
> > Hmmph. This actually comes up incorrectly on my system. The issue
> > appears to be `git --exec-path` gives me $prefix/libexec/git-core,
> > and git-gui installs its library into $prefix/libexec/share, which
> > is wrong. It should have gone to $prefix/share.
>
> I am not seeing this problem because I am installing using the
> toplevel makefile, which sets and exports sharedir to $prefix/share.
>
>
> > I wonder if this is better. Your other two patches seem fine.
> >
> > --8<--
> > [PATCH] git-gui: Correct installation of library to be $prefix/share
> >
> > We always wanted the library for git-gui to install into the
> > $prefix/share directory, not $prefix/libexec/share. All of
> > the files in our library are platform independent and may
> > be reused across systems, like any other content stored in
> > the share directory.
> >
> > Our computation of where our library should install to was broken
> > when git itself started installing to $prefix/libexec/git-core,
> > which was one level down from where we expected it to be.
> >
> > Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
> > ---
> > Makefile | 3 +++
> > 1 files changed, 3 insertions(+), 0 deletions(-)
> >
> > diff --git a/Makefile b/Makefile
> > index b19fb2d..f72ab6c 100644
> > --- a/Makefile
> > +++ b/Makefile
> > @@ -32,6 +32,9 @@ endif
> > ifndef gitexecdir
> > gitexecdir := $(shell git --exec-path)
> > endif
> > +ifeq (git-core,$(notdir $(gitexecdir)))
> > + gitexecdir := $(patsubst %/,%,$(dir $(gitexecdir)))
> > +endif
>
> But gitexecdir has the correct value, no? gitexecdir is used
> at several places in the makefile. It seems wrong to strip
> 'git-core' from gitexecdir. But I must admit that I do not
> understand all the details of git-gui's Makefile. So maybe
> you know better.
>
> Isn't only the computation of sharedir based on gitexecdir wrong?
>
> > ifndef sharedir
> > sharedir := $(dir $(gitexecdir))share
>
>
> and could be replaced with this (instead of your patch):
>
> ifndef sharedir
> +ifeq (git-core,$(notdir $(gitexecdir)))
> + sharedir := $(dir $(patsubst %/,%,$(dir $(gitexecdir))))share
> +else
> sharedir := $(dir $(gitexecdir))share
> endif
> +endif
This is not good enough in my environment. I run git-gui effectivly with
wish $prefix/libexec/git-core/git-gui
(and I have $PATH set up to contain $bindir, but not $gitexecdir), and this
needs the original hunk with the three [file dirname ... ], because $argv0
points to $prefix/libexec/git-core/git-gui.
I thought I understood what's going on, but I don't anymore.
Mybe the relative discovery of oguilib must be conditional on the "git-core"
part as well, just like you discover sharedir?
-- Hannes
^ permalink raw reply
* Re: [PATCH 1/3] git-gui: Adapt discovery of oguilib to execdir 'libexec/git-core'
From: Steffen Prohaska @ 2008-08-03 10:09 UTC (permalink / raw)
To: Johannes Sixt; +Cc: Git Mailing List, Shawn O. Pearce
In-Reply-To: <1217756103.48957bc76eda2@webmail.nextra.at>
On Aug 3, 2008, at 11:35 AM, Johannes Sixt wrote:
> Zitat von Steffen Prohaska <prohaska@zib.de>:
>>
>> On Jul 27, 2008, at 11:24 PM, Shawn O. Pearce wrote:
>>
>>> Steffen Prohaska <prohaska@zib.de> wrote:
>>>> The new execdir has is two levels below the root directory, while
>>>> the old execdir 'bin' was only one level below. This commit
>>>> adapts the discovery of oguilib that uses relative paths
>>>> accordingly.
>>> ...
>>>> diff --git a/git-gui/git-gui.sh b/git-gui/git-gui.sh
>>>> index 940677c..baccd57 100755
>>>> --- a/git-gui/git-gui.sh
>>>> +++ b/git-gui/git-gui.sh
>>>> @@ -52,7 +52,9 @@ catch {rename send {}} ; # What an evil
>>>> concept...
>>>> set oguilib {@@GITGUI_LIBDIR@@}
>>>> set oguirel {@@GITGUI_RELATIVE@@}
>>>> if {$oguirel eq {1}} {
>>>> - set oguilib [file dirname [file dirname [file normalize $argv0]]]
>>>> + set oguilib [file dirname \
>>>> + [file dirname \
>>>> + [file dirname [file normalize $argv0]]]]
>>>> set oguilib [file join $oguilib share git-gui lib]
>>>
>>> Hmmph. This actually comes up incorrectly on my system. The issue
>>> appears to be `git --exec-path` gives me $prefix/libexec/git-core,
>>> and git-gui installs its library into $prefix/libexec/share, which
>>> is wrong. It should have gone to $prefix/share.
>>
>> I am not seeing this problem because I am installing using the
>> toplevel makefile, which sets and exports sharedir to $prefix/share.
>>
>>
>>> I wonder if this is better. Your other two patches seem fine.
>>>
>>> --8<--
>>> [PATCH] git-gui: Correct installation of library to be $prefix/share
>>>
>>> We always wanted the library for git-gui to install into the
>>> $prefix/share directory, not $prefix/libexec/share. All of
>>> the files in our library are platform independent and may
>>> be reused across systems, like any other content stored in
>>> the share directory.
>>>
>>> Our computation of where our library should install to was broken
>>> when git itself started installing to $prefix/libexec/git-core,
>>> which was one level down from where we expected it to be.
>>>
>>> Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
>>> ---
>>> Makefile | 3 +++
>>> 1 files changed, 3 insertions(+), 0 deletions(-)
>>>
>>> diff --git a/Makefile b/Makefile
>>> index b19fb2d..f72ab6c 100644
>>> --- a/Makefile
>>> +++ b/Makefile
>>> @@ -32,6 +32,9 @@ endif
>>> ifndef gitexecdir
>>> gitexecdir := $(shell git --exec-path)
>>> endif
>>> +ifeq (git-core,$(notdir $(gitexecdir)))
>>> + gitexecdir := $(patsubst %/,%,$(dir $(gitexecdir)))
>>> +endif
>>
>> But gitexecdir has the correct value, no? gitexecdir is used
>> at several places in the makefile. It seems wrong to strip
>> 'git-core' from gitexecdir. But I must admit that I do not
>> understand all the details of git-gui's Makefile. So maybe
>> you know better.
>>
>> Isn't only the computation of sharedir based on gitexecdir wrong?
>>
>>> ifndef sharedir
>>> sharedir := $(dir $(gitexecdir))share
>>
>>
>> and could be replaced with this (instead of your patch):
>>
>> ifndef sharedir
>> +ifeq (git-core,$(notdir $(gitexecdir)))
>> + sharedir := $(dir $(patsubst %/,%,$(dir $(gitexecdir))))share
>> +else
>> sharedir := $(dir $(gitexecdir))share
>> endif
>> +endif
>
> This is not good enough in my environment.
This only fixes the installation directory.
> I run git-gui effectivly with
>
> wish $prefix/libexec/git-core/git-gui
>
> (and I have $PATH set up to contain $bindir, but not $gitexecdir),
> and this
> needs the original hunk with the three [file dirname ... ], because
> $argv0
> points to $prefix/libexec/git-core/git-gui.
The original hunk fixes the discovery of oguilib, i.e.
from $prefix/libexec/git-core/git-gui to $prefix/share/git-gui/lib
I didn't recognize that the the 'three [file dinames ...]' have
not been applied because I had this change already in 4msysgit
(and still have). Apologies for not checking this more carefully.
> I thought I understood what's going on, but I don't anymore.
>
> Mybe the relative discovery of oguilib must be conditional on the
> "git-core"
> part as well, just like you discover sharedir?
Hmm... you are right. If we want to maintain compatibility
with *both* directory layouts, obviously all computations
that depend on the layout need to be conditional on it.
Steffen
^ permalink raw reply
* Re: Missing pieces for 1.6.0 on MinGW?
From: Björn Steinbrink @ 2008-08-03 10:10 UTC (permalink / raw)
To: Johannes Sixt; +Cc: Junio C Hamano, Steffen Prohaska, Johannes Schindelin, git
In-Reply-To: <1217754985.4895776973fda@webmail.nextra.at>
On 2008.08.03 11:16:25 +0200, Johannes Sixt wrote:
> (3) the 'mingw_main undefined' error is still a mystery. I'm about to send a
> preprocessed file to Steffen (it's a bit large, even compressed, so I'll do
> that in a private mail).
FWIW, gcc 4.3 complains about such function declarations:
x.c:4: error: invalid storage class for function ‘foo’
Seems that gcc complains about that since 4.0, and linking failed with
older versions under some circumstances.
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=12738
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=17205
Björn
^ permalink raw reply
* [PATCH] Update to it.po
From: Paolo Ciarrocchi @ 2008-08-03 10:11 UTC (permalink / raw)
To: spearce, git, barra_cuda
Some fairly simply changes to it.po
Signed-off-by: Paolo Ciarrocchi <paolo.ciarrocchi@gmail.com>
---
Shawn,
a simple make in the git-gui-i18n repository fails with the following msg:
paolo@paolo-desktop:~/git-gui-i18n$ make
GITGUI_VERSION = 0.9.GITGUI-dirty
* new locations or Tcl/Tk interpreter
GEN git-gui
INDEX lib/
MSGFMT po/bg.msg 391 translated.
MSGFMT po/de.msg 383 translated, 5 fuzzy, 3 untranslated.
MSGFMT po/es.msg 122 translated, 269 untranslated.
MSGFMT po/fr.msg 391 translated.
MSGFMT po/hu.msg 391 translated.
MSGFMT po/it.msg make: *** [po/it.msg] Error 1
Before and after the following patch :-)
po/it.po | 13 ++++++-------
1 files changed, 6 insertions(+), 7 deletions(-)
diff --git a/po/it.po b/po/it.po
index 197e6fa..aa3ed13 100644
--- a/po/it.po
+++ b/po/it.po
@@ -10,12 +10,12 @@ msgstr ""
"Project-Id-Version: git-gui\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2008-03-14 07:18+0100\n"
-"PO-Revision-Date: 2008-03-17 14:12+0100\n"
-"Last-Translator: Michele Ballabio <barra_cuda@katamail.com>\n"
+"PO-Revision-Date: 2008-08-03 11:59+0200\n"
+"Last-Translator: Paolo Ciarrocchi <Paolo.Ciarrocchi@gmail.com>\n"
"Language-Team: Italian <tp@lists.linux.it>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
+"Content-Transfer-Encoding: 8bit"
#: git-gui.sh:41 git-gui.sh:634 git-gui.sh:648 git-gui.sh:661 git-gui.sh:744
#: git-gui.sh:763
@@ -1022,7 +1022,7 @@ msgstr "Calcolo oggetti"
#: lib/choose_repository.tcl:628
msgid "buckets"
-msgstr ""
+msgstr "buckets"
#: lib/choose_repository.tcl:652
#, tcl-format
@@ -1910,16 +1910,14 @@ msgid "Spell checker silently failed on startup"
msgstr "Il correttore ortografico ha riportato un errore all'avvio"
#: lib/spellcheck.tcl:80
-#, fuzzy
msgid "Unrecognized spell checker"
-msgstr "Correttore ortografico sconosciuto"
+msgstr "Correttore ortografico non riconosciuto"
#: lib/spellcheck.tcl:180
msgid "No Suggestions"
msgstr "Nessun suggerimento"
#: lib/spellcheck.tcl:381
-#, fuzzy
msgid "Unexpected EOF from spell checker"
msgstr "Il correttore ortografico ha mandato un EOF inaspettato"
@@ -1994,3 +1992,4 @@ msgstr "Utilizza 'thin pack' (per connessioni lente)"
#: lib/transport.tcl:168
msgid "Include tags"
msgstr "Includi etichette"
+
--
1.5.6.rc1.21.g03300
^ permalink raw reply related
* Re: Missing pieces for 1.6.0 on MinGW?
From: Steffen Prohaska @ 2008-08-03 10:17 UTC (permalink / raw)
To: Johannes Sixt; +Cc: Junio C Hamano, Johannes Schindelin, git
In-Reply-To: <1217754985.4895776973fda@webmail.nextra.at>
On Aug 3, 2008, at 11:16 AM, Johannes Sixt wrote:
> Zitat von Junio C Hamano <gitster@pobox.com>:
>> Just a quick question before the weekend ends and -rc2 gets
>> tagged. (I
>> lost track of that argv0 vs bin/git vs libexec/git-core/git-foo
>> discussion).
>>
>> Are there any missing but necessary patches we need before 1.6.0 for
>> MinGW?
>
> Yes, there are some open issues:
>
> (1) git-gui was fixed for the msysgit installer, but it broke for
> me; but I
> think I know where to fix it.
I now recognized that not all hunks that I have in 4msysgit were applied
by Shawn. See separate mail
http://article.gmane.org/gmane.comp.version-control.git/91221
> (2) the non-builtins in $(bindir) don't set argv0_path, and
> consequently don't
> find ETC_GITCONFIG.
Setting argv0_path correctly wouldn't help alone. The relative
path to $prefix is different in $prefix/bin and
$prefix/libexec/git-core. Thus, we cannot do the same computation.
system_path() would need to check from which directory the computation
starts.
> (3) the 'mingw_main undefined' error is still a mystery. I'm about
> to send a
> preprocessed file to Steffen (it's a bit large, even compressed, so
> I'll do
> that in a private mail).
ok.
Steffen
^ permalink raw reply
* Re: Missing pieces for 1.6.0 on MinGW?
From: Johannes Schindelin @ 2008-08-03 10:45 UTC (permalink / raw)
To: Johannes Sixt, Steve Haslam; +Cc: Junio C Hamano, Steffen Prohaska, git
In-Reply-To: <1217754985.4895776973fda@webmail.nextra.at>
Hi,
On Sun, 3 Aug 2008, Johannes Sixt wrote:
> (2) the non-builtins in $(bindir) don't set argv0_path, and consequently
> don't find ETC_GITCONFIG.
>
> (3) the 'mingw_main undefined' error is still a mystery. I'm about to
> send a preprocessed file to Steffen (it's a bit large, even compressed,
> so I'll do that in a private mail).
For both issues, IMHO Steve's patches should be superior, as they (with my
proposed lookup_program_in_path()) would not only make relative
ETC_GITCONFIG work on MinGW, but everywhere else, too. Obsoleting
mingw_main, of course.
Ciao,
Dscho
^ permalink raw reply
* [PATCH] git-gui: add a part about format strings in po/README
From: Michele Ballabio @ 2008-08-03 11:12 UTC (permalink / raw)
To: Paolo Ciarrocchi; +Cc: spearce, git
In-Reply-To: <20080803121131.589e672b@paolo-desktop>
This should help tranlators that need to reorder words and strings.
Original explanation by Christian Stimming.
Also remove unneeded backslashes.
Signed-off-by: Michele Ballabio <barra_cuda@katamail.com>
---
On Sunday 03 August 2008, Paolo Ciarrocchi wrote:
> Shawn,
> a simple make in the git-gui-i18n repository fails with the following msg:
> paolo@paolo-desktop:~/git-gui-i18n$ make
> GITGUI_VERSION = 0.9.GITGUI-dirty
> * new locations or Tcl/Tk interpreter
> GEN git-gui
> INDEX lib/
> MSGFMT po/bg.msg 391 translated.
> MSGFMT po/de.msg 383 translated, 5 fuzzy, 3 untranslated.
> MSGFMT po/es.msg 122 translated, 269 untranslated.
> MSGFMT po/fr.msg 391 translated.
> MSGFMT po/hu.msg 391 translated.
> MSGFMT po/it.msg make: *** [po/it.msg] Error 1
>
> Before and after the following patch :-)
I think that's this commit: c6fb29db5a50df150280b641d3c2a6703589b529
(Fixed usage of positional parameters in it.po and ja.po).
It didn't fix anything and was harmful instead.
Maybe this patch could be useful.
po/README | 17 +++++++++++------
1 files changed, 11 insertions(+), 6 deletions(-)
diff --git a/po/README b/po/README
index 5e77a7d..595bbf5 100644
--- a/po/README
+++ b/po/README
@@ -101,7 +101,7 @@ matching msgid lines. A few tips:
"printf()"-like functions. Make sure "%s", "%d", and "%%" in your
translated messages match the original.
- When you have to change the order of words, you can add "<number>\$"
+ When you have to change the order of words, you can add "<number>$"
between '%' and the conversion ('s', 'd', etc.) to say "<number>-th
parameter to the format string is used at this point". For example,
if the original message is like this:
@@ -111,12 +111,17 @@ matching msgid lines. A few tips:
and if for whatever reason your translation needs to say weight first
and then length, you can say something like:
- "WEIGHT IS %2\$d, LENGTH IS %1\$d"
+ "WEIGHT IS %2$d, LENGTH IS %1$d"
- The reason you need a backslash before dollar sign is because
- this is a double quoted string in Tcl language, and without
- it the letter introduces a variable interpolation, which you
- do not want here.
+ A format specification with a '*' (asterisk) refers to *two* arguments
+ instead of one, hence the succeeding argument number is two higher
+ instead of one. So, a message like this
+
+ "%s ... %*i of %*i %s (%3i%%)"
+
+ is equivalent to
+
+ "%1$s ... %2$*i of %4$*i %6$s (%7$3i%%)"
- A long message can be split across multiple lines by ending the
string with a double quote, and starting another string on the next
--
1.6.0.rc1
^ 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