* Re: Blaming diffs
From: Frank Lichtenheld @ 2007-09-16 17:05 UTC (permalink / raw)
To: Mike Hommey; +Cc: git
In-Reply-To: <20070916163829.GA6679@glandium.org>
On Sun, Sep 16, 2007 at 06:38:29PM +0200, Mike Hommey wrote:
> It seems to me there is no tool to "blame diffs", i.e. something to know
> what commit(s) is(are) responsible for a set of changes.
>
> For example, the following script tries to get the set of commits
> involved in the changes between $A and $B. Note it only works for text
> additions.
>
> git diff --unified=0 $A $B | awk 'BEGIN { FS="(^(--- a/|+++ b/)|^@@ -[0-9,]+ \\+| @@)" } /^---/ || ( /^+++ b\/(.*)/ && file=="" ) { file = $2 } /^@@/ {split($2, a, /,/); a[2] = a[2] ? a[2] + a[1] - 1 : a[1]; print "git blame -l -L " a[1] "," a[2], "'$A..$B'", file }' | sh | cut -f 1 -d " " | sort -u
>
> Has anyone tried to work on something similar yet ?
>
> If not, as git users, what kind of output would you expect from such a
> tool, and where do you think this should lie (extension to git diff, or
> separate tool) ?
What do you use for $A and $B? commits? What is the difference between
your script and "git log --pretty=format:%H $A..$B"
then?
Gruesse,
--
Frank Lichtenheld <frank@lichtenheld.de>
www: http://www.djpig.de/
^ permalink raw reply
* Re: RFC: German translation vocabulary
From: Alexander Wuerstlein @ 2007-09-16 17:23 UTC (permalink / raw)
To: git
In-Reply-To: <200709161438.37733.stimming@tuhh.de>
On 070916 14:46, Christian Stimming <stimming@tuhh.de> wrote:
> msgid "commit [noun]"
> msgstr "?bertragung (Sendung?, ?bergabe?, Einspielung?, Ablagevorgang?)"
"Vorgang"? (think Beamtendeutsch)
Ciao,
Alexander Wuerstlein.
^ permalink raw reply
* Re: [RFC] strbuf's in builtin-apply
From: Pierre Habouzit @ 2007-09-16 17:28 UTC (permalink / raw)
To: git, Junio C Hamano
In-Reply-To: <20070916172134.GA26457@artemis.corp>
[-- Attachment #1: Type: text/plain, Size: 688 bytes --]
Damn it I forgot to add -n to my format-patch invocation *again*. The
proper ordering is:
The builtin-apply part:
[1/6] New strbuf APIs: splice and attach.
[2/6] Rewrite convert_to_{git,working_tree} to use strbuf's.
[3/6] Now that cache.h needs strbuf.h, remove useless includes.
[4/6] builtin-apply: use strbuf's instead of buffer_desc's.
And the two somehow more independant patches (need 1/6 still):
[5/6] Refactor replace_encoding_header.
[6/6] Remove preemptive allocations.
--
·O· Pierre Habouzit
··O madcoder@debian.org
OOO http://www.madism.org
[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply
* [PATCH] Remove preemptive allocations.
From: Pierre Habouzit @ 2007-09-16 8:19 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <20070916172134.GA26457@artemis.corp>
Careful profiling shows that we spend more time guessing what pattern
allocation will have, whereas we can delay it only at the point where
add_rfc2047 will be used and don't allocate huge memory area for the many
cases where it's not.
Signed-off-by: Pierre Habouzit <madcoder@debian.org>
---
commit.c | 35 +++++------------------------------
1 files changed, 5 insertions(+), 30 deletions(-)
diff --git a/commit.c b/commit.c
index 13af933..85889f9 100644
--- a/commit.c
+++ b/commit.c
@@ -501,6 +501,7 @@ static void add_rfc2047(struct strbuf *sb, const char *line, int len,
return;
needquote:
+ strbuf_grow(sb, len * 3 + strlen(encoding) + 100);
strbuf_addf(sb, "=?%s?q?", encoding);
for (i = last = 0; i < len; i++) {
unsigned ch = line[i] & 0xFF;
@@ -520,14 +521,6 @@ needquote:
strbuf_addstr(sb, "?=");
}
-static unsigned long bound_rfc2047(unsigned long len, const char *encoding)
-{
- /* upper bound of q encoded string of length 'len' */
- unsigned long elen = strlen(encoding);
-
- return len * 3 + elen + 100;
-}
-
static void add_user_info(const char *what, enum cmit_fmt fmt, struct strbuf *sb,
const char *line, enum date_mode dmode,
const char *encoding)
@@ -560,8 +553,7 @@ static void add_user_info(const char *what, enum cmit_fmt fmt, struct strbuf *sb
add_rfc2047(sb, line, display_name_length, encoding);
strbuf_add(sb, name_tail, namelen - display_name_length);
strbuf_addch(sb, '\n');
- }
- else {
+ } else {
strbuf_addf(sb, "%s: %.*s%.*s\n", what,
(fmt == CMIT_FMT_FULLER) ? 4 : 0,
filler, namelen, line);
@@ -955,19 +947,12 @@ static void pp_header(enum cmit_fmt fmt,
* FULLER shows both authors and dates.
*/
if (!memcmp(line, "author ", 7)) {
- unsigned long len = linelen;
- if (fmt == CMIT_FMT_EMAIL)
- len = bound_rfc2047(linelen, encoding);
- strbuf_grow(sb, len + 80);
+ strbuf_grow(sb, linelen + 80);
add_user_info("Author", fmt, sb, line + 7, dmode, encoding);
}
-
if (!memcmp(line, "committer ", 10) &&
(fmt == CMIT_FMT_FULL || fmt == CMIT_FMT_FULLER)) {
- unsigned long len = linelen;
- if (fmt == CMIT_FMT_EMAIL)
- len = bound_rfc2047(linelen, encoding);
- strbuf_grow(sb, len + 80);
+ strbuf_grow(sb, linelen + 80);
add_user_info("Commit", fmt, sb, line + 10, dmode, encoding);
}
}
@@ -982,7 +967,6 @@ static void pp_title_line(enum cmit_fmt fmt,
int plain_non_ascii)
{
struct strbuf title;
- unsigned long len;
strbuf_init(&title, 80);
@@ -1004,16 +988,7 @@ static void pp_title_line(enum cmit_fmt fmt,
strbuf_add(&title, line, linelen);
}
- /* Enough slop for the MIME header and rfc2047 */
- len = bound_rfc2047(title.len, encoding) + 1000;
- if (subject)
- len += strlen(subject);
- if (after_subject)
- len += strlen(after_subject);
- if (encoding)
- len += strlen(encoding);
-
- strbuf_grow(sb, title.len + len);
+ strbuf_grow(sb, title.len + 1024);
if (subject) {
strbuf_addstr(sb, subject);
add_rfc2047(sb, title.buf, title.len, encoding);
--
1.5.3.1
^ permalink raw reply related
* [PATCH] builtin-apply: use strbuf's instead of buffer_desc's.
From: Pierre Habouzit @ 2007-09-16 16:54 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <20070916172134.GA26457@artemis.corp>
Signed-off-by: Pierre Habouzit <madcoder@debian.org>
---
builtin-apply.c | 212 +++++++++++++++++++------------------------------------
1 files changed, 72 insertions(+), 140 deletions(-)
diff --git a/builtin-apply.c b/builtin-apply.c
index ae708d7..05011bb 100644
--- a/builtin-apply.c
+++ b/builtin-apply.c
@@ -1441,37 +1441,28 @@ static void show_stats(struct patch *patch)
free(qname);
}
-static int read_old_data(struct stat *st, const char *path, char **buf_p, unsigned long *alloc_p, unsigned long *size_p)
+static int read_old_data(struct stat *st, const char *path, struct strbuf *buf)
{
int fd;
- unsigned long got;
- struct strbuf nbuf;
- unsigned long size = *size_p;
- char *buf = *buf_p;
switch (st->st_mode & S_IFMT) {
case S_IFLNK:
- return readlink(path, buf, size) != size;
+ strbuf_grow(buf, st->st_size);
+ if (readlink(path, buf->buf, st->st_size) != st->st_size)
+ return -1;
+ strbuf_setlen(buf, st->st_size);
+ return 0;
case S_IFREG:
fd = open(path, O_RDONLY);
if (fd < 0)
return error("unable to open %s", path);
- got = 0;
- for (;;) {
- ssize_t ret = xread(fd, buf + got, size - got);
- if (ret <= 0)
- break;
- got += ret;
+ if (strbuf_read(buf, fd, st->st_size) < 0) {
+ close(fd);
+ return -1;
}
close(fd);
- strbuf_init(&nbuf, 0);
- if (convert_to_git(path, buf, size, &nbuf)) {
- free(buf);
- *buf_p = nbuf.buf;
- *alloc_p = nbuf.alloc;
- *size_p = nbuf.len;
- }
- return got != size;
+ convert_to_git(path, buf->buf, buf->len, buf);
+ return 0;
default:
return -1;
}
@@ -1576,12 +1567,6 @@ static void remove_last_line(const char **rbuf, int *rsize)
*rsize = offset + 1;
}
-struct buffer_desc {
- char *buffer;
- unsigned long size;
- unsigned long alloc;
-};
-
static int apply_line(char *output, const char *patch, int plen)
{
/* plen is number of bytes to be copied from patch,
@@ -1651,10 +1636,9 @@ static int apply_line(char *output, const char *patch, int plen)
return output + plen - buf;
}
-static int apply_one_fragment(struct buffer_desc *desc, struct fragment *frag, int inaccurate_eof)
+static int apply_one_fragment(struct strbuf *buf, struct fragment *frag, int inaccurate_eof)
{
int match_beginning, match_end;
- char *buf = desc->buffer;
const char *patch = frag->patch;
int offset, size = frag->size;
char *old = xmalloc(size);
@@ -1765,24 +1749,17 @@ static int apply_one_fragment(struct buffer_desc *desc, struct fragment *frag, i
lines = 0;
pos = frag->newpos;
for (;;) {
- offset = find_offset(buf, desc->size,
+ offset = find_offset(buf->buf, buf->len,
oldlines, oldsize, pos, &lines);
- if (match_end && offset + oldsize != desc->size)
+ if (match_end && offset + oldsize != buf->len)
offset = -1;
if (match_beginning && offset)
offset = -1;
if (offset >= 0) {
- int diff;
- unsigned long size, alloc;
-
if (new_whitespace == strip_whitespace &&
- (desc->size - oldsize - offset == 0)) /* end of file? */
+ (buf->len - oldsize - offset == 0)) /* end of file? */
newsize -= new_blank_lines_at_end;
- diff = newsize - oldsize;
- size = desc->size + diff;
- alloc = desc->alloc;
-
/* Warn if it was necessary to reduce the number
* of context lines.
*/
@@ -1792,19 +1769,8 @@ static int apply_one_fragment(struct buffer_desc *desc, struct fragment *frag, i
" to apply fragment at %d\n",
leading, trailing, pos + lines);
- if (size > alloc) {
- alloc = size + 8192;
- desc->alloc = alloc;
- buf = xrealloc(buf, alloc);
- desc->buffer = buf;
- }
- desc->size = size;
- memmove(buf + offset + newsize,
- buf + offset + oldsize,
- size - offset - newsize);
- memcpy(buf + offset, newlines, newsize);
+ strbuf_splice(buf, offset, oldsize, newlines, newsize);
offset = 0;
-
break;
}
@@ -1840,12 +1806,11 @@ static int apply_one_fragment(struct buffer_desc *desc, struct fragment *frag, i
return offset;
}
-static int apply_binary_fragment(struct buffer_desc *desc, struct patch *patch)
+static int apply_binary_fragment(struct strbuf *buf, struct patch *patch)
{
- unsigned long dst_size;
struct fragment *fragment = patch->fragments;
- void *data;
- void *result;
+ unsigned long len;
+ void *dst;
/* Binary patch is irreversible without the optional second hunk */
if (apply_in_reverse) {
@@ -1856,29 +1821,24 @@ static int apply_binary_fragment(struct buffer_desc *desc, struct patch *patch)
? patch->new_name : patch->old_name);
fragment = fragment->next;
}
- data = (void*) fragment->patch;
switch (fragment->binary_patch_method) {
case BINARY_DELTA_DEFLATED:
- result = patch_delta(desc->buffer, desc->size,
- data,
- fragment->size,
- &dst_size);
- free(desc->buffer);
- desc->buffer = result;
- break;
+ dst = patch_delta(buf->buf, buf->len, fragment->patch,
+ fragment->size, &len);
+ if (!dst)
+ return -1;
+ /* XXX patch_delta NUL-terminates */
+ strbuf_attach(buf, dst, len, len + 1);
+ return 0;
case BINARY_LITERAL_DEFLATED:
- free(desc->buffer);
- desc->buffer = data;
- dst_size = fragment->size;
- break;
+ strbuf_reset(buf);
+ strbuf_add(buf, fragment->patch, fragment->size);
+ return 0;
}
- if (!desc->buffer)
- return -1;
- desc->size = desc->alloc = dst_size;
- return 0;
+ return -1;
}
-static int apply_binary(struct buffer_desc *desc, struct patch *patch)
+static int apply_binary(struct strbuf *buf, struct patch *patch)
{
const char *name = patch->old_name ? patch->old_name : patch->new_name;
unsigned char sha1[20];
@@ -1897,7 +1857,7 @@ static int apply_binary(struct buffer_desc *desc, struct patch *patch)
/* See if the old one matches what the patch
* applies to.
*/
- hash_sha1_file(desc->buffer, desc->size, blob_type, sha1);
+ hash_sha1_file(buf->buf, buf->len, blob_type, sha1);
if (strcmp(sha1_to_hex(sha1), patch->old_sha1_prefix))
return error("the patch applies to '%s' (%s), "
"which does not match the "
@@ -1906,16 +1866,14 @@ static int apply_binary(struct buffer_desc *desc, struct patch *patch)
}
else {
/* Otherwise, the old one must be empty. */
- if (desc->size)
+ if (buf->len)
return error("the patch applies to an empty "
"'%s' but it is not empty", name);
}
get_sha1_hex(patch->new_sha1_prefix, sha1);
if (is_null_sha1(sha1)) {
- free(desc->buffer);
- desc->alloc = desc->size = 0;
- desc->buffer = NULL;
+ strbuf_release(buf);
return 0; /* deletion patch */
}
@@ -1923,43 +1881,44 @@ static int apply_binary(struct buffer_desc *desc, struct patch *patch)
/* We already have the postimage */
enum object_type type;
unsigned long size;
+ char *result;
- free(desc->buffer);
- desc->buffer = read_sha1_file(sha1, &type, &size);
- if (!desc->buffer)
+ result = read_sha1_file(sha1, &type, &size);
+ if (!result)
return error("the necessary postimage %s for "
"'%s' cannot be read",
patch->new_sha1_prefix, name);
- desc->alloc = desc->size = size;
- }
- else {
- /* We have verified desc matches the preimage;
+ /* XXX read_sha1_file NUL-terminates */
+ strbuf_attach(buf, result, size, size + 1);
+ } else {
+ /* We have verified buf matches the preimage;
* apply the patch data to it, which is stored
* in the patch->fragments->{patch,size}.
*/
- if (apply_binary_fragment(desc, patch))
+ if (apply_binary_fragment(buf, patch))
return error("binary patch does not apply to '%s'",
name);
/* verify that the result matches */
- hash_sha1_file(desc->buffer, desc->size, blob_type, sha1);
+ hash_sha1_file(buf->buf, buf->len, blob_type, sha1);
if (strcmp(sha1_to_hex(sha1), patch->new_sha1_prefix))
- return error("binary patch to '%s' creates incorrect result (expecting %s, got %s)", name, patch->new_sha1_prefix, sha1_to_hex(sha1));
+ return error("binary patch to '%s' creates incorrect result (expecting %s, got %s)",
+ name, patch->new_sha1_prefix, sha1_to_hex(sha1));
}
return 0;
}
-static int apply_fragments(struct buffer_desc *desc, struct patch *patch)
+static int apply_fragments(struct strbuf *buf, struct patch *patch)
{
struct fragment *frag = patch->fragments;
const char *name = patch->old_name ? patch->old_name : patch->new_name;
if (patch->is_binary)
- return apply_binary(desc, patch);
+ return apply_binary(buf, patch);
while (frag) {
- if (apply_one_fragment(desc, frag, patch->inaccurate_eof)) {
+ if (apply_one_fragment(buf, frag, patch->inaccurate_eof)) {
error("patch failed: %s:%ld", name, frag->oldpos);
if (!apply_with_reject)
return -1;
@@ -1970,76 +1929,57 @@ static int apply_fragments(struct buffer_desc *desc, struct patch *patch)
return 0;
}
-static int read_file_or_gitlink(struct cache_entry *ce, char **buf_p,
- unsigned long *size_p)
+static int read_file_or_gitlink(struct cache_entry *ce, struct strbuf *buf)
{
if (!ce)
return 0;
if (S_ISGITLINK(ntohl(ce->ce_mode))) {
- *buf_p = xmalloc(100);
- *size_p = snprintf(*buf_p, 100,
- "Subproject commit %s\n", sha1_to_hex(ce->sha1));
+ strbuf_grow(buf, 100);
+ strbuf_addf(buf, "Subproject commit %s\n", sha1_to_hex(ce->sha1));
} else {
enum object_type type;
- *buf_p = read_sha1_file(ce->sha1, &type, size_p);
- if (!*buf_p)
+ unsigned long sz;
+ char *result;
+
+ result = read_sha1_file(ce->sha1, &type, &sz);
+ if (!result)
return -1;
+ /* XXX read_sha1_file NUL-terminates */
+ strbuf_attach(buf, result, sz, sz + 1);
}
return 0;
}
static int apply_data(struct patch *patch, struct stat *st, struct cache_entry *ce)
{
- char *buf;
- unsigned long size, alloc;
- struct buffer_desc desc;
+ struct strbuf buf;
- size = 0;
- alloc = 0;
- buf = NULL;
+ strbuf_init(&buf, 0);
if (cached) {
- if (read_file_or_gitlink(ce, &buf, &size))
+ if (read_file_or_gitlink(ce, &buf))
return error("read of %s failed", patch->old_name);
- alloc = size;
} else if (patch->old_name) {
if (S_ISGITLINK(patch->old_mode)) {
- if (ce)
- read_file_or_gitlink(ce, &buf, &size);
- else {
+ if (ce) {
+ read_file_or_gitlink(ce, &buf);
+ } else {
/*
* There is no way to apply subproject
* patch without looking at the index.
*/
patch->fragments = NULL;
- size = 0;
}
- }
- else {
- size = xsize_t(st->st_size);
- alloc = size + 8192;
- buf = xmalloc(alloc);
- if (read_old_data(st, patch->old_name,
- &buf, &alloc, &size))
- return error("read of %s failed",
- patch->old_name);
+ } else {
+ if (read_old_data(st, patch->old_name, &buf))
+ return error("read of %s failed", patch->old_name);
}
}
- desc.size = size;
- desc.alloc = alloc;
- desc.buffer = buf;
-
- if (apply_fragments(&desc, patch) < 0)
+ if (apply_fragments(&buf, patch) < 0)
return -1; /* note with --reject this succeeds. */
-
- /* NUL terminate the result */
- if (desc.alloc <= desc.size)
- desc.buffer = xrealloc(desc.buffer, desc.size + 1);
- desc.buffer[desc.size] = 0;
-
- patch->result = desc.buffer;
- patch->resultsize = desc.size;
+ patch->result = buf.buf;
+ patch->resultsize = buf.len;
if (0 < patch->is_delete && patch->resultsize)
return error("removal patch leaves file contents");
@@ -2459,19 +2399,11 @@ static int try_create_file(const char *path, unsigned int mode, const char *buf,
size = nbuf.len;
buf = nbuf.buf;
}
+ write_or_die(fd, buf, size);
+ strbuf_release(&nbuf);
- while (size) {
- int written = xwrite(fd, buf, size);
- if (written < 0)
- die("writing file %s: %s", path, strerror(errno));
- if (!written)
- die("out of space writing file %s", path);
- buf += written;
- size -= written;
- }
if (close(fd) < 0)
die("closing file %s: %s", path, strerror(errno));
- strbuf_release(&nbuf);
return 0;
}
--
1.5.3.1
^ permalink raw reply related
* [PATCH] Rewrite convert_to_{git,working_tree} to use strbuf's.
From: Pierre Habouzit @ 2007-09-16 13:51 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <20070916172134.GA26457@artemis.corp>
* Now, those functions take an "out" strbuf argument, where they store their
result if any. In that case, it also returns 1, else it returns 0.
* those functions support "in place" editing, in the sense that it's OK to
call them this way:
convert_to_git(path, sb->buf, sb->len, sb);
When doable, conversions are done in place for real, else the strbuf
content is just replaced with the new one, transparentely for the caller.
If you want to create a new filter working this way, being the accumulation
of filter1, filter2, ... filtern, then your meta_filter would be:
int meta_filter(..., const char *src, size_t len, struct strbuf *sb)
{
int ret = 0;
ret |= filter1(...., src, len, sb);
if (ret) {
src = sb->buf;
len = sb->len;
}
ret |= filter2(...., src, len, sb);
if (ret) {
src = sb->buf;
len = sb->len;
}
....
return ret | filtern(..., src, len, sb);
}
That's why subfilters the convert_to_* functions called were also rewritten
to work this way.
Signed-off-by: Pierre Habouzit <madcoder@debian.org>
---
builtin-apply.c | 27 ++--
builtin-archive.c | 78 +++++------
cache.h | 6 +-
convert.c | 414 ++++++++++++++++++++++-------------------------------
diff.c | 12 +-
entry.c | 10 +-
sha1_file.c | 10 +-
7 files changed, 240 insertions(+), 317 deletions(-)
diff --git a/builtin-apply.c b/builtin-apply.c
index 7057d0d..9735b47 100644
--- a/builtin-apply.c
+++ b/builtin-apply.c
@@ -1446,8 +1446,7 @@ static int read_old_data(struct stat *st, const char *path, char **buf_p, unsign
{
int fd;
unsigned long got;
- unsigned long nsize;
- char *nbuf;
+ struct strbuf nbuf;
unsigned long size = *size_p;
char *buf = *buf_p;
@@ -1466,13 +1465,12 @@ static int read_old_data(struct stat *st, const char *path, char **buf_p, unsign
got += ret;
}
close(fd);
- nsize = got;
- nbuf = convert_to_git(path, buf, &nsize);
- if (nbuf) {
+ strbuf_init(&nbuf, 0);
+ if (convert_to_git(path, buf, size, &nbuf)) {
free(buf);
- *buf_p = nbuf;
- *alloc_p = nsize;
- *size_p = nsize;
+ *buf_p = nbuf.buf;
+ *alloc_p = nbuf.alloc;
+ *size_p = nbuf.len;
}
return got != size;
default:
@@ -2438,7 +2436,7 @@ static void add_index_file(const char *path, unsigned mode, void *buf, unsigned
static int try_create_file(const char *path, unsigned int mode, const char *buf, unsigned long size)
{
int fd;
- char *nbuf;
+ struct strbuf nbuf;
if (S_ISGITLINK(mode)) {
struct stat st;
@@ -2457,9 +2455,11 @@ static int try_create_file(const char *path, unsigned int mode, const char *buf,
if (fd < 0)
return -1;
- nbuf = convert_to_working_tree(path, buf, &size);
- if (nbuf)
- buf = nbuf;
+ strbuf_init(&nbuf, 0);
+ if (convert_to_working_tree(path, buf, size, &nbuf)) {
+ size = nbuf.len;
+ buf = nbuf.buf;
+ }
while (size) {
int written = xwrite(fd, buf, size);
@@ -2472,8 +2472,7 @@ static int try_create_file(const char *path, unsigned int mode, const char *buf,
}
if (close(fd) < 0)
die("closing file %s: %s", path, strerror(errno));
- if (nbuf)
- free(nbuf);
+ strbuf_release(&nbuf);
return 0;
}
diff --git a/builtin-archive.c b/builtin-archive.c
index 6fa424d..843a9e3 100644
--- a/builtin-archive.c
+++ b/builtin-archive.c
@@ -81,22 +81,21 @@ static int run_remote_archiver(const char *remote, int argc,
return !!rv;
}
-static void *format_subst(const struct commit *commit, const char *format,
- unsigned long *sizep)
+static void format_subst(const struct commit *commit,
+ const char *src, size_t len,
+ struct strbuf *buf)
{
- unsigned long len = *sizep;
- const char *a = format;
- struct strbuf result;
+ char *to_free = NULL;
struct strbuf fmt;
- strbuf_init(&result, 0);
+ if (src == buf->buf)
+ to_free = strbuf_detach(buf);
strbuf_init(&fmt, 0);
-
for (;;) {
const char *b, *c;
- b = memmem(a, len, "$Format:", 8);
- if (!b || a + len < b + 9)
+ b = memmem(src, len, "$Format:", 8);
+ if (!b || src + len < b + 9)
break;
c = memchr(b + 8, '$', len - 8);
if (!c)
@@ -105,62 +104,57 @@ static void *format_subst(const struct commit *commit, const char *format,
strbuf_reset(&fmt);
strbuf_add(&fmt, b + 8, c - b - 8);
- strbuf_add(&result, a, b - a);
- format_commit_message(commit, fmt.buf, &result);
- len -= c + 1 - a;
- a = c + 1;
+ strbuf_add(buf, src, b - src);
+ format_commit_message(commit, fmt.buf, buf);
+ len -= c + 1 - src;
+ src = c + 1;
}
-
- strbuf_add(&result, a, len);
-
- *sizep = result.len;
-
+ strbuf_add(buf, src, len);
strbuf_release(&fmt);
- return strbuf_detach(&result);
+ free(to_free);
}
-static void *convert_to_archive(const char *path,
- const void *src, unsigned long *sizep,
- const struct commit *commit)
+static int convert_to_archive(const char *path,
+ const void *src, size_t len,
+ struct strbuf *buf,
+ const struct commit *commit)
{
static struct git_attr *attr_export_subst;
struct git_attr_check check[1];
if (!commit)
- return NULL;
+ return 0;
- if (!attr_export_subst)
- attr_export_subst = git_attr("export-subst", 12);
+ if (!attr_export_subst)
+ attr_export_subst = git_attr("export-subst", 12);
check[0].attr = attr_export_subst;
if (git_checkattr(path, ARRAY_SIZE(check), check))
- return NULL;
+ return 0;
if (!ATTR_TRUE(check[0].value))
- return NULL;
+ return 0;
- return format_subst(commit, src, sizep);
+ format_subst(commit, src, len, buf);
+ return 1;
}
void *sha1_file_to_archive(const char *path, const unsigned char *sha1,
unsigned int mode, enum object_type *type,
- unsigned long *size,
+ unsigned long *sizep,
const struct commit *commit)
{
- void *buffer, *converted;
+ void *buffer;
- buffer = read_sha1_file(sha1, type, size);
+ buffer = read_sha1_file(sha1, type, sizep);
if (buffer && S_ISREG(mode)) {
- converted = convert_to_working_tree(path, buffer, size);
- if (converted) {
- free(buffer);
- buffer = converted;
- }
-
- converted = convert_to_archive(path, buffer, size, commit);
- if (converted) {
- free(buffer);
- buffer = converted;
- }
+ struct strbuf buf;
+
+ strbuf_init(&buf, 0);
+ strbuf_attach(&buf, buffer, *sizep, *sizep + 1);
+ convert_to_working_tree(path, buf.buf, buf.len, &buf);
+ convert_to_archive(path, buf.buf, buf.len, &buf, commit);
+ *sizep = buf.len;
+ buffer = buf.buf;
}
return buffer;
diff --git a/cache.h b/cache.h
index b9a461a..8650d62 100644
--- a/cache.h
+++ b/cache.h
@@ -2,6 +2,7 @@
#define CACHE_H
#include "git-compat-util.h"
+#include "strbuf.h"
#include SHA1_HEADER
#include <zlib.h>
@@ -590,8 +591,9 @@ extern void trace_printf(const char *format, ...);
extern void trace_argv_printf(const char **argv, int count, const char *format, ...);
/* convert.c */
-extern char *convert_to_git(const char *path, const char *src, unsigned long *sizep);
-extern char *convert_to_working_tree(const char *path, const char *src, unsigned long *sizep);
+/* returns 1 if *dst was used */
+extern int convert_to_git(const char *path, const char *src, size_t len, struct strbuf *dst);
+extern int convert_to_working_tree(const char *path, const char *src, size_t len, struct strbuf *dst);
/* diff.c */
extern int diff_auto_refresh_index;
diff --git a/convert.c b/convert.c
index d77c8eb..00a341c 100644
--- a/convert.c
+++ b/convert.c
@@ -1,6 +1,7 @@
#include "cache.h"
#include "attr.h"
#include "run-command.h"
+#include "strbuf.h"
/*
* convert.c - convert a file when checking it out and checking it in.
@@ -80,24 +81,19 @@ static int is_binary(unsigned long size, struct text_stat *stats)
return 0;
}
-static char *crlf_to_git(const char *path, const char *src, unsigned long *sizep, int action)
+static int crlf_to_git(const char *path, const char *src, size_t len,
+ struct strbuf *buf, int action)
{
- char *buffer, *dst;
- unsigned long size, nsize;
struct text_stat stats;
+ char *dst;
- if ((action == CRLF_BINARY) || !auto_crlf)
- return NULL;
-
- size = *sizep;
- if (!size)
- return NULL;
-
- gather_stats(src, size, &stats);
+ if ((action == CRLF_BINARY) || !auto_crlf || !len)
+ return 0;
+ gather_stats(src, len, &stats);
/* No CR? Nothing to convert, regardless. */
if (!stats.cr)
- return NULL;
+ return 0;
if (action == CRLF_GUESS) {
/*
@@ -106,24 +102,17 @@ static char *crlf_to_git(const char *path, const char *src, unsigned long *sizep
* stuff?
*/
if (stats.cr != stats.crlf)
- return NULL;
+ return 0;
/*
* And add some heuristics for binary vs text, of course...
*/
- if (is_binary(size, &stats))
- return NULL;
+ if (is_binary(len, &stats))
+ return 0;
}
- /*
- * Ok, allocate a new buffer, fill it in, and return it
- * to let the caller know that we switched buffers.
- */
- nsize = size - stats.crlf;
- buffer = xmalloc(nsize);
- *sizep = nsize;
-
- dst = buffer;
+ strbuf_grow(buf, len);
+ dst = buf->buf;
if (action == CRLF_GUESS) {
/*
* If we guessed, we already know we rejected a file with
@@ -134,71 +123,72 @@ static char *crlf_to_git(const char *path, const char *src, unsigned long *sizep
unsigned char c = *src++;
if (c != '\r')
*dst++ = c;
- } while (--size);
+ } while (--len);
} else {
do {
unsigned char c = *src++;
- if (! (c == '\r' && (1 < size && *src == '\n')))
+ if (! (c == '\r' && (1 < len && *src == '\n')))
*dst++ = c;
- } while (--size);
+ } while (--len);
}
-
- return buffer;
+ strbuf_setlen(buf, dst - buf->buf);
+ return 1;
}
-static char *crlf_to_worktree(const char *path, const char *src, unsigned long *sizep, int action)
+static int crlf_to_worktree(const char *path, const char *src, size_t len,
+ struct strbuf *buf, int action)
{
- char *buffer, *dst;
- unsigned long size, nsize;
+ char *to_free = NULL;
struct text_stat stats;
- unsigned char last;
if ((action == CRLF_BINARY) || (action == CRLF_INPUT) ||
auto_crlf <= 0)
- return NULL;
+ return 0;
- size = *sizep;
- if (!size)
- return NULL;
+ if (!len)
+ return 0;
- gather_stats(src, size, &stats);
+ gather_stats(src, len, &stats);
/* No LF? Nothing to convert, regardless. */
if (!stats.lf)
- return NULL;
+ return 0;
/* Was it already in CRLF format? */
if (stats.lf == stats.crlf)
- return NULL;
+ return 0;
if (action == CRLF_GUESS) {
/* If we have any bare CR characters, we're not going to touch it */
if (stats.cr != stats.crlf)
- return NULL;
+ return 0;
- if (is_binary(size, &stats))
- return NULL;
+ if (is_binary(len, &stats))
+ return 0;
}
- /*
- * Ok, allocate a new buffer, fill it in, and return it
- * to let the caller know that we switched buffers.
- */
- nsize = size + stats.lf - stats.crlf;
- buffer = xmalloc(nsize);
- *sizep = nsize;
- last = 0;
-
- dst = buffer;
- do {
- unsigned char c = *src++;
- if (c == '\n' && last != '\r')
- *dst++ = '\r';
- *dst++ = c;
- last = c;
- } while (--size);
-
- return buffer;
+ /* are we "faking" in place editing ? */
+ if (src == buf->buf)
+ to_free = strbuf_detach(buf);
+
+ strbuf_grow(buf, len + stats.lf - stats.crlf);
+ for (;;) {
+ const char *nl = memchr(src, '\n', len);
+ if (!nl)
+ break;
+ if (nl > src && nl[-1] == '\r') {
+ strbuf_add(buf, src, nl + 1 - src);
+ } else {
+ strbuf_add(buf, src, nl - src);
+ strbuf_addstr(buf, "\r\n");
+ }
+ len -= nl + 1 - src;
+ src = nl + 1;
+ }
+ strbuf_add(buf, src, len);
+
+ free(to_free);
+ return 1;
}
static int filter_buffer(const char *path, const char *src,
@@ -246,8 +236,8 @@ static int filter_buffer(const char *path, const char *src,
return (write_err || status);
}
-static char *apply_filter(const char *path, const char *src,
- unsigned long *sizep, const char *cmd)
+static int apply_filter(const char *path, const char *src, size_t len,
+ struct strbuf *dst, const char *cmd)
{
/*
* Create a pipeline to have the command filter the buffer's
@@ -255,21 +245,19 @@ static char *apply_filter(const char *path, const char *src,
*
* (child --> cmd) --> us
*/
- const int SLOP = 4096;
int pipe_feed[2];
- int status;
- char *dst;
- unsigned long dstsize, dstalloc;
+ int status, ret = 1;
struct child_process child_process;
+ struct strbuf nbuf;
if (!cmd)
- return NULL;
+ return 0;
memset(&child_process, 0, sizeof(child_process));
if (pipe(pipe_feed) < 0) {
error("cannot create pipe to run external filter %s", cmd);
- return NULL;
+ return 0;
}
fflush(NULL);
@@ -278,54 +266,37 @@ static char *apply_filter(const char *path, const char *src,
error("cannot fork to run external filter %s", cmd);
close(pipe_feed[0]);
close(pipe_feed[1]);
- return NULL;
+ return 0;
}
if (!child_process.pid) {
dup2(pipe_feed[1], 1);
close(pipe_feed[0]);
close(pipe_feed[1]);
- exit(filter_buffer(path, src, *sizep, cmd));
+ exit(filter_buffer(path, src, len, cmd));
}
close(pipe_feed[1]);
- dstalloc = *sizep;
- dst = xmalloc(dstalloc);
- dstsize = 0;
-
- while (1) {
- ssize_t numread = xread(pipe_feed[0], dst + dstsize,
- dstalloc - dstsize);
-
- if (numread <= 0) {
- if (!numread)
- break;
- error("read from external filter %s failed", cmd);
- free(dst);
- dst = NULL;
- break;
- }
- dstsize += numread;
- if (dstalloc <= dstsize + SLOP) {
- dstalloc = dstsize + SLOP;
- dst = xrealloc(dst, dstalloc);
- }
+ strbuf_init(&nbuf, 0);
+ if (strbuf_read(&nbuf, pipe_feed[0], len) < 0) {
+ error("read from external filter %s failed", cmd);
+ ret = 0;
}
if (close(pipe_feed[0])) {
- error("read from external filter %s failed", cmd);
- free(dst);
- dst = NULL;
+ ret = error("read from external filter %s failed", cmd);
+ ret = 0;
}
-
status = finish_command(&child_process);
if (status) {
- error("external filter %s failed %d", cmd, -status);
- free(dst);
- dst = NULL;
+ ret = error("external filter %s failed %d", cmd, -status);
+ ret = 0;
}
- if (dst)
- *sizep = dstsize;
- return dst;
+ if (ret) {
+ *dst = nbuf;
+ } else {
+ strbuf_release(&nbuf);
+ }
+ return ret;
}
static struct convert_driver {
@@ -449,137 +420,104 @@ static int count_ident(const char *cp, unsigned long size)
return cnt;
}
-static char *ident_to_git(const char *path, const char *src, unsigned long *sizep, int ident)
+static int ident_to_git(const char *path, const char *src, size_t len,
+ struct strbuf *buf, int ident)
{
- int cnt;
- unsigned long size;
- char *dst, *buf;
+ char *dst, *dollar;
- if (!ident)
- return NULL;
- size = *sizep;
- cnt = count_ident(src, size);
- if (!cnt)
- return NULL;
- buf = xmalloc(size);
-
- for (dst = buf; size; size--) {
- char ch = *src++;
- *dst++ = ch;
- if ((ch == '$') && (3 <= size) &&
- !memcmp("Id:", src, 3)) {
- unsigned long rem = size - 3;
- const char *cp = src + 3;
- do {
- ch = *cp++;
- if (ch == '$')
- break;
- rem--;
- } while (rem);
- if (!rem)
- continue;
+ if (!ident || !count_ident(src, len))
+ return 0;
+
+ strbuf_grow(buf, len);
+ dst = buf->buf;
+ for (;;) {
+ dollar = memchr(src, '$', len);
+ if (!dollar)
+ break;
+ memcpy(dst, src, dollar + 1 - src);
+ dst += dollar + 1 - src;
+ len -= dollar + 1 - src;
+ src = dollar + 1;
+
+ if (len > 3 && !memcmp(src, "Id:", 3)) {
+ dollar = memchr(src + 3, '$', len - 3);
+ if (!dollar)
+ break;
memcpy(dst, "Id$", 3);
dst += 3;
- size -= (cp - src);
- src = cp;
+ len -= dollar + 1 - src;
+ src = dollar + 1;
}
}
-
- *sizep = dst - buf;
- return buf;
+ memcpy(dst, src, len);
+ strbuf_setlen(buf, dst + len - buf->buf);
+ return 1;
}
-static char *ident_to_worktree(const char *path, const char *src, unsigned long *sizep, int ident)
+static int ident_to_worktree(const char *path, const char *src, size_t len,
+ struct strbuf *buf, int ident)
{
- int cnt;
- unsigned long size;
- char *dst, *buf;
unsigned char sha1[20];
+ char *to_free = NULL, *dollar;
+ int cnt;
if (!ident)
- return NULL;
+ return 0;
- size = *sizep;
- cnt = count_ident(src, size);
+ cnt = count_ident(src, len);
if (!cnt)
- return NULL;
+ return 0;
- hash_sha1_file(src, size, "blob", sha1);
- buf = xmalloc(size + cnt * 43);
-
- for (dst = buf; size; size--) {
- const char *cp;
- /* Fetch next source character, move the pointer on */
- char ch = *src++;
- /* Copy the current character to the destination */
- *dst++ = ch;
- /* If the current character is "$" or there are less than three
- * remaining bytes or the two bytes following this one are not
- * "Id", then simply read the next character */
- if ((ch != '$') || (size < 3) || memcmp("Id", src, 2))
- continue;
- /*
- * Here when
- * - There are more than 2 bytes remaining
- * - The current three bytes are "$Id"
- * with
- * - ch == "$"
- * - src[0] == "I"
- */
+ /* are we "faking" in place editing ? */
+ if (src == buf->buf)
+ to_free = strbuf_detach(buf);
+ hash_sha1_file(src, len, "blob", sha1);
- /*
- * It's possible that an expanded Id has crept its way into the
- * repository, we cope with that by stripping the expansion out
- */
- if (src[2] == ':') {
- /* Expanded keywords have "$Id:" at the front */
+ strbuf_grow(buf, len + cnt * 43);
+ for (;;) {
+ /* step 1: run to the next '$' */
+ dollar = memchr(src, '$', len);
+ if (!dollar)
+ break;
+ strbuf_add(buf, src, dollar + 1 - src);
+ len -= dollar + 1 - src;
+ src = dollar + 1;
- /* discard up to but not including the closing $ */
- unsigned long rem = size - 3;
- /* Point at first byte after the ":" */
- cp = src + 3;
- /*
- * Throw away characters until either
- * - we reach a "$"
- * - we run out of bytes (rem == 0)
- */
- do {
- ch = *cp;
- if (ch == '$')
- break;
- cp++;
- rem--;
- } while (rem);
- /* If the above finished because it ran out of characters, then
- * this is an incomplete keyword, so don't run the expansion */
- if (!rem)
- continue;
- } else if (src[2] == '$')
- cp = src + 2;
- else
- /* Anything other than "$Id:XXX$" or $Id$ and we skip the
- * expansion */
+ /* step 2: does it looks like a bit like Id:xxx$ or Id$ ? */
+ if (len < 3 || memcmp("Id", src, 2))
continue;
- /* cp is now pointing at the last $ of the keyword */
-
- memcpy(dst, "Id: ", 4);
- dst += 4;
- memcpy(dst, sha1_to_hex(sha1), 40);
- dst += 40;
- *dst++ = ' ';
+ /* step 3: skip over Id$ or Id:xxxxx$ */
+ if (src[2] == '$') {
+ src += 3;
+ len -= 3;
+ } else if (src[2] == ':') {
+ /*
+ * It's possible that an expanded Id has crept its way into the
+ * repository, we cope with that by stripping the expansion out
+ */
+ dollar = memchr(src + 3, '$', len - 3);
+ if (!dollar) {
+ /* incomplete keyword, no more '$', so just quit the loop */
+ break;
+ }
- /* Adjust for the characters we've discarded */
- size -= (cp - src);
- src = cp;
+ len -= dollar + 1 - src;
+ src = dollar + 1;
+ } else {
+ /* it wasn't a "Id$" or "Id:xxxx$" */
+ continue;
+ }
- /* Copy the final "$" */
- *dst++ = *src++;
- size--;
+ /* step 4: substitute */
+ strbuf_addstr(buf, "Id: ");
+ strbuf_add(buf, sha1_to_hex(sha1), 40);
+ strbuf_addstr(buf, " $");
}
+ strbuf_add(buf, src, len);
- *sizep = dst - buf;
- return buf;
+ free(to_free);
+ return 1;
}
static int git_path_check_crlf(const char *path, struct git_attr_check *check)
@@ -618,13 +556,12 @@ static int git_path_check_ident(const char *path, struct git_attr_check *check)
return !!ATTR_TRUE(value);
}
-char *convert_to_git(const char *path, const char *src, unsigned long *sizep)
+int convert_to_git(const char *path, const char *src, size_t len, struct strbuf *dst)
{
struct git_attr_check check[3];
int crlf = CRLF_GUESS;
- int ident = 0;
+ int ident = 0, ret = 0;
char *filter = NULL;
- char *buf, *buf2;
setup_convert_check(check);
if (!git_checkattr(path, ARRAY_SIZE(check), check)) {
@@ -636,30 +573,25 @@ char *convert_to_git(const char *path, const char *src, unsigned long *sizep)
filter = drv->clean;
}
- buf = apply_filter(path, src, sizep, filter);
-
- buf2 = crlf_to_git(path, buf ? buf : src, sizep, crlf);
- if (buf2) {
- free(buf);
- buf = buf2;
+ ret |= apply_filter(path, src, len, dst, filter);
+ if (ret) {
+ src = dst->buf;
+ len = dst->len;
}
-
- buf2 = ident_to_git(path, buf ? buf : src, sizep, ident);
- if (buf2) {
- free(buf);
- buf = buf2;
+ ret |= crlf_to_git(path, src, len, dst, crlf);
+ if (ret) {
+ src = dst->buf;
+ len = dst->len;
}
-
- return buf;
+ return ret | ident_to_git(path, src, len, dst, ident);
}
-char *convert_to_working_tree(const char *path, const char *src, unsigned long *sizep)
+int convert_to_working_tree(const char *path, const char *src, size_t len, struct strbuf *dst)
{
struct git_attr_check check[3];
int crlf = CRLF_GUESS;
- int ident = 0;
+ int ident = 0, ret = 0;
char *filter = NULL;
- char *buf, *buf2;
setup_convert_check(check);
if (!git_checkattr(path, ARRAY_SIZE(check), check)) {
@@ -671,19 +603,15 @@ char *convert_to_working_tree(const char *path, const char *src, unsigned long *
filter = drv->smudge;
}
- buf = ident_to_worktree(path, src, sizep, ident);
-
- buf2 = crlf_to_worktree(path, buf ? buf : src, sizep, crlf);
- if (buf2) {
- free(buf);
- buf = buf2;
+ ret |= ident_to_worktree(path, src, len, dst, ident);
+ if (ret) {
+ src = dst->buf;
+ len = dst->len;
}
-
- buf2 = apply_filter(path, buf ? buf : src, sizep, filter);
- if (buf2) {
- free(buf);
- buf = buf2;
+ ret |= crlf_to_worktree(path, src, len, dst, crlf);
+ if (ret) {
+ src = dst->buf;
+ len = dst->len;
}
-
- return buf;
+ return ret | apply_filter(path, src, len, dst, filter);
}
diff --git a/diff.c b/diff.c
index 693140b..d46dd11 100644
--- a/diff.c
+++ b/diff.c
@@ -1600,10 +1600,9 @@ int diff_populate_filespec(struct diff_filespec *s, int size_only)
if (!s->sha1_valid ||
reuse_worktree_file(s->path, s->sha1, 0)) {
+ struct strbuf buf;
struct stat st;
int fd;
- char *buf;
- unsigned long size;
if (!strcmp(s->path, "-"))
return populate_from_stdin(s);
@@ -1644,13 +1643,12 @@ int diff_populate_filespec(struct diff_filespec *s, int size_only)
/*
* Convert from working tree format to canonical git format
*/
- size = s->size;
- buf = convert_to_git(s->path, s->data, &size);
- if (buf) {
+ strbuf_init(&buf, 0);
+ if (convert_to_git(s->path, s->data, s->size, &buf)) {
munmap(s->data, s->size);
s->should_munmap = 0;
- s->data = buf;
- s->size = size;
+ s->data = buf.buf;
+ s->size = buf.len;
s->should_free = 1;
}
}
diff --git a/entry.c b/entry.c
index fc3a506..4a8c73b 100644
--- a/entry.c
+++ b/entry.c
@@ -104,7 +104,8 @@ static int write_entry(struct cache_entry *ce, char *path, const struct checkout
long wrote;
switch (ntohl(ce->ce_mode) & S_IFMT) {
- char *buf, *new;
+ char *new;
+ struct strbuf buf;
unsigned long size;
case S_IFREG:
@@ -116,10 +117,11 @@ static int write_entry(struct cache_entry *ce, char *path, const struct checkout
/*
* Convert from git internal format to working tree format
*/
- buf = convert_to_working_tree(ce->name, new, &size);
- if (buf) {
+ strbuf_init(&buf, 0);
+ if (convert_to_working_tree(ce->name, new, size, &buf)) {
free(new);
- new = buf;
+ new = buf.buf;
+ size = buf.len;
}
if (to_tempfile) {
diff --git a/sha1_file.c b/sha1_file.c
index aea1096..64b5b46 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -2343,12 +2343,12 @@ int index_fd(unsigned char *sha1, int fd, struct stat *st, int write_object,
* Convert blobs to git internal format
*/
if ((type == OBJ_BLOB) && S_ISREG(st->st_mode)) {
- unsigned long nsize = size;
- char *nbuf = convert_to_git(path, buf, &nsize);
- if (nbuf) {
+ struct strbuf nbuf;
+ strbuf_init(&nbuf, 0);
+ if (convert_to_git(path, buf, size, &nbuf)) {
munmap(buf, size);
- size = nsize;
- buf = nbuf;
+ size = nbuf.len;
+ buf = nbuf.buf;
re_allocated = 1;
}
}
--
1.5.3.1
^ permalink raw reply related
* [PATCH] Now that cache.h needs strbuf.h, remove useless includes.
From: Pierre Habouzit @ 2007-09-15 13:56 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <20070916172134.GA26457@artemis.corp>
Signed-off-by: Pierre Habouzit <madcoder@debian.org>
---
archive-tar.c | 1 -
builtin-apply.c | 1 -
builtin-blame.c | 1 -
builtin-checkout-index.c | 1 -
builtin-commit-tree.c | 1 -
builtin-fetch--tool.c | 1 -
builtin-rerere.c | 1 -
builtin-stripspace.c | 1 -
builtin-tag.c | 1 -
builtin-update-index.c | 1 -
cache-tree.c | 1 -
convert.c | 1 -
diff.c | 1 -
fast-import.c | 1 -
fetch.c | 1 -
imap-send.c | 1 -
mktag.c | 1 -
mktree.c | 1 -
sha1_file.c | 1 -
strbuf.c | 1 -
20 files changed, 0 insertions(+), 20 deletions(-)
diff --git a/archive-tar.c b/archive-tar.c
index cc94cf3..a87bc4b 100644
--- a/archive-tar.c
+++ b/archive-tar.c
@@ -3,7 +3,6 @@
*/
#include "cache.h"
#include "commit.h"
-#include "strbuf.h"
#include "tar.h"
#include "builtin.h"
#include "archive.h"
diff --git a/builtin-apply.c b/builtin-apply.c
index 9735b47..ae708d7 100644
--- a/builtin-apply.c
+++ b/builtin-apply.c
@@ -12,7 +12,6 @@
#include "blob.h"
#include "delta.h"
#include "builtin.h"
-#include "strbuf.h"
/*
* --check turns on checking that the working tree matches the
diff --git a/builtin-blame.c b/builtin-blame.c
index b004f06..e364b6c 100644
--- a/builtin-blame.c
+++ b/builtin-blame.c
@@ -18,7 +18,6 @@
#include "cache-tree.h"
#include "path-list.h"
#include "mailmap.h"
-#include "strbuf.h"
static char blame_usage[] =
"git-blame [-c] [-b] [-l] [--root] [-t] [-f] [-n] [-s] [-p] [-w] [-L n,m] [-S <revs-file>] [-M] [-C] [-C] [--contents <filename>] [--incremental] [commit] [--] file\n"
diff --git a/builtin-checkout-index.c b/builtin-checkout-index.c
index 153ba7d..85e8efe 100644
--- a/builtin-checkout-index.c
+++ b/builtin-checkout-index.c
@@ -38,7 +38,6 @@
*/
#include "builtin.h"
#include "cache.h"
-#include "strbuf.h"
#include "quote.h"
#include "cache-tree.h"
diff --git a/builtin-commit-tree.c b/builtin-commit-tree.c
index 325334f..88b0ab3 100644
--- a/builtin-commit-tree.c
+++ b/builtin-commit-tree.c
@@ -8,7 +8,6 @@
#include "tree.h"
#include "builtin.h"
#include "utf8.h"
-#include "strbuf.h"
#define BLOCKING (1ul << 14)
diff --git a/builtin-fetch--tool.c b/builtin-fetch--tool.c
index 90bdc32..514a3cc 100644
--- a/builtin-fetch--tool.c
+++ b/builtin-fetch--tool.c
@@ -2,7 +2,6 @@
#include "cache.h"
#include "refs.h"
#include "commit.h"
-#include "strbuf.h"
static char *get_stdin(void)
{
diff --git a/builtin-rerere.c b/builtin-rerere.c
index 826d346..58288f6 100644
--- a/builtin-rerere.c
+++ b/builtin-rerere.c
@@ -1,7 +1,6 @@
#include "builtin.h"
#include "cache.h"
#include "path-list.h"
-#include "strbuf.h"
#include "xdiff/xdiff.h"
#include "xdiff-interface.h"
diff --git a/builtin-stripspace.c b/builtin-stripspace.c
index c4cf2f0..1ce2847 100644
--- a/builtin-stripspace.c
+++ b/builtin-stripspace.c
@@ -1,6 +1,5 @@
#include "builtin.h"
#include "cache.h"
-#include "strbuf.h"
/*
* Returns the length of a line, without trailing spaces.
diff --git a/builtin-tag.c b/builtin-tag.c
index 9f29342..82ebda1 100644
--- a/builtin-tag.c
+++ b/builtin-tag.c
@@ -8,7 +8,6 @@
#include "cache.h"
#include "builtin.h"
-#include "strbuf.h"
#include "refs.h"
#include "tag.h"
#include "run-command.h"
diff --git a/builtin-update-index.c b/builtin-update-index.c
index e02431c..0b60513 100644
--- a/builtin-update-index.c
+++ b/builtin-update-index.c
@@ -4,7 +4,6 @@
* Copyright (C) Linus Torvalds, 2005
*/
#include "cache.h"
-#include "strbuf.h"
#include "quote.h"
#include "cache-tree.h"
#include "tree-walk.h"
diff --git a/cache-tree.c b/cache-tree.c
index 8f53c99..5471844 100644
--- a/cache-tree.c
+++ b/cache-tree.c
@@ -1,5 +1,4 @@
#include "cache.h"
-#include "strbuf.h"
#include "tree.h"
#include "cache-tree.h"
diff --git a/convert.c b/convert.c
index 00a341c..508d30b 100644
--- a/convert.c
+++ b/convert.c
@@ -1,7 +1,6 @@
#include "cache.h"
#include "attr.h"
#include "run-command.h"
-#include "strbuf.h"
/*
* convert.c - convert a file when checking it out and checking it in.
diff --git a/diff.c b/diff.c
index d46dd11..a5b69ed 100644
--- a/diff.c
+++ b/diff.c
@@ -9,7 +9,6 @@
#include "xdiff-interface.h"
#include "color.h"
#include "attr.h"
-#include "strbuf.h"
#ifdef NO_FAST_WORKING_DIRECTORY
#define FAST_WORKING_DIRECTORY 0
diff --git a/fast-import.c b/fast-import.c
index 2c0bfb9..1866d34 100644
--- a/fast-import.c
+++ b/fast-import.c
@@ -149,7 +149,6 @@ Format of STDIN stream:
#include "pack.h"
#include "refs.h"
#include "csum-file.h"
-#include "strbuf.h"
#include "quote.h"
#define PACK_ID_BITS 16
diff --git a/fetch.c b/fetch.c
index dd6ed9e..c256e6f 100644
--- a/fetch.c
+++ b/fetch.c
@@ -6,7 +6,6 @@
#include "tag.h"
#include "blob.h"
#include "refs.h"
-#include "strbuf.h"
int get_tree = 0;
int get_history = 0;
diff --git a/imap-send.c b/imap-send.c
index ecd4216..86e4a0f 100644
--- a/imap-send.c
+++ b/imap-send.c
@@ -23,7 +23,6 @@
*/
#include "cache.h"
-#include "strbuf.h"
typedef struct store_conf {
char *name;
diff --git a/mktag.c b/mktag.c
index 7567f9e..b05260c 100644
--- a/mktag.c
+++ b/mktag.c
@@ -1,5 +1,4 @@
#include "cache.h"
-#include "strbuf.h"
#include "tag.h"
/*
diff --git a/mktree.c b/mktree.c
index 3891cd9..5dab4bd 100644
--- a/mktree.c
+++ b/mktree.c
@@ -4,7 +4,6 @@
* Copyright (c) Junio C Hamano, 2006
*/
#include "cache.h"
-#include "strbuf.h"
#include "quote.h"
#include "tree.h"
diff --git a/sha1_file.c b/sha1_file.c
index 64b5b46..59325d4 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -14,7 +14,6 @@
#include "tag.h"
#include "tree.h"
#include "refs.h"
-#include "strbuf.h"
#ifndef O_NOATIME
#if defined(__linux__) && (defined(__i386__) || defined(__PPC__))
diff --git a/strbuf.c b/strbuf.c
index ff551ac..c5f9e2a 100644
--- a/strbuf.c
+++ b/strbuf.c
@@ -1,5 +1,4 @@
#include "cache.h"
-#include "strbuf.h"
void strbuf_init(struct strbuf *sb, size_t hint)
{
--
1.5.3.1
^ permalink raw reply related
* [PATCH] New strbuf APIs: splice and attach.
From: Pierre Habouzit @ 2007-09-15 13:56 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <20070916172134.GA26457@artemis.corp>
* strbuf_splice replace a portion of the buffer with another.
* strbuf_attach replace a strbuf buffer with the given one, that should be
malloc'ed. Then it enforces strbuf's invariants. If alloc > len, then this
function has negligible cost, else it will perform a realloc, possibly
with a cost.
Also some style issues are fixed now.
Signed-off-by: Pierre Habouzit <madcoder@debian.org>
---
strbuf.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++++-------------
strbuf.h | 5 ++++
2 files changed, 57 insertions(+), 15 deletions(-)
diff --git a/strbuf.c b/strbuf.c
index d919047..ff551ac 100644
--- a/strbuf.c
+++ b/strbuf.c
@@ -1,30 +1,45 @@
#include "cache.h"
#include "strbuf.h"
-void strbuf_init(struct strbuf *sb, size_t hint) {
+void strbuf_init(struct strbuf *sb, size_t hint)
+{
memset(sb, 0, sizeof(*sb));
if (hint)
strbuf_grow(sb, hint);
}
-void strbuf_release(struct strbuf *sb) {
+void strbuf_release(struct strbuf *sb)
+{
free(sb->buf);
memset(sb, 0, sizeof(*sb));
}
-void strbuf_reset(struct strbuf *sb) {
+void strbuf_reset(struct strbuf *sb)
+{
if (sb->len)
strbuf_setlen(sb, 0);
sb->eof = 0;
}
-char *strbuf_detach(struct strbuf *sb) {
+char *strbuf_detach(struct strbuf *sb)
+{
char *res = sb->buf;
strbuf_init(sb, 0);
return res;
}
-void strbuf_grow(struct strbuf *sb, size_t extra) {
+void strbuf_attach(struct strbuf *sb, void *buf, size_t len, size_t alloc)
+{
+ strbuf_release(sb);
+ sb->buf = buf;
+ sb->len = len;
+ sb->alloc = alloc;
+ strbuf_grow(sb, 0);
+ sb->buf[sb->len] = '\0';
+}
+
+void strbuf_grow(struct strbuf *sb, size_t extra)
+{
if (sb->len + extra + 1 <= sb->len)
die("you want to use way too much memory");
ALLOC_GROW(sb->buf, sb->len + extra + 1, sb->alloc);
@@ -37,24 +52,44 @@ void strbuf_rtrim(struct strbuf *sb)
sb->buf[sb->len] = '\0';
}
-void strbuf_insert(struct strbuf *sb, size_t pos, const void *data, size_t len) {
+void strbuf_insert(struct strbuf *sb, size_t pos, const void *data, size_t len)
+{
strbuf_grow(sb, len);
- if (pos >= sb->len) {
- pos = sb->len;
- } else {
- memmove(sb->buf + pos + len, sb->buf + pos, sb->len - pos);
- }
+ if (pos > sb->len)
+ die("`pos' is too far after the end of the buffer");
+ memmove(sb->buf + pos + len, sb->buf + pos, sb->len - pos);
memcpy(sb->buf + pos, data, len);
strbuf_setlen(sb, sb->len + len);
}
-void strbuf_add(struct strbuf *sb, const void *data, size_t len) {
+void strbuf_splice(struct strbuf *sb, size_t pos, size_t len,
+ const void *data, size_t dlen)
+{
+ if (pos + len < pos)
+ die("you want to use way too much memory");
+ if (pos > sb->len)
+ die("`pos' is too far after the end of the buffer");
+ if (pos + len > sb->len)
+ die("`pos + len' is too far after the end of the buffer");
+
+ if (dlen >= len)
+ strbuf_grow(sb, dlen - len);
+ memmove(sb->buf + pos + dlen,
+ sb->buf + pos + len,
+ sb->len - pos - len);
+ memcpy(sb->buf + pos, data, dlen);
+ strbuf_setlen(sb, sb->len + dlen - len);
+}
+
+void strbuf_add(struct strbuf *sb, const void *data, size_t len)
+{
strbuf_grow(sb, len);
memcpy(sb->buf + sb->len, data, len);
strbuf_setlen(sb, sb->len + len);
}
-void strbuf_addf(struct strbuf *sb, const char *fmt, ...) {
+void strbuf_addf(struct strbuf *sb, const char *fmt, ...)
+{
int len;
va_list ap;
@@ -76,7 +111,8 @@ void strbuf_addf(struct strbuf *sb, const char *fmt, ...) {
strbuf_setlen(sb, sb->len + len);
}
-size_t strbuf_fread(struct strbuf *sb, size_t size, FILE *f) {
+size_t strbuf_fread(struct strbuf *sb, size_t size, FILE *f)
+{
size_t res;
strbuf_grow(sb, size);
@@ -110,7 +146,8 @@ ssize_t strbuf_read(struct strbuf *sb, int fd, size_t hint)
return sb->len - oldlen;
}
-void read_line(struct strbuf *sb, FILE *fp, int term) {
+void read_line(struct strbuf *sb, FILE *fp, int term)
+{
int ch;
if (feof(fp)) {
strbuf_release(sb);
diff --git a/strbuf.h b/strbuf.h
index 21fc111..f163c63 100644
--- a/strbuf.h
+++ b/strbuf.h
@@ -55,6 +55,7 @@ extern void strbuf_init(struct strbuf *, size_t);
extern void strbuf_release(struct strbuf *);
extern void strbuf_reset(struct strbuf *);
extern char *strbuf_detach(struct strbuf *);
+extern void strbuf_attach(struct strbuf *, void *, size_t, size_t);
/*----- strbuf size related -----*/
static inline size_t strbuf_avail(struct strbuf *sb) {
@@ -81,6 +82,10 @@ static inline void strbuf_addch(struct strbuf *sb, int c) {
/* inserts after pos, or appends if pos >= sb->len */
extern void strbuf_insert(struct strbuf *, size_t pos, const void *, size_t);
+/* splice pos..pos+len with given data */
+extern void strbuf_splice(struct strbuf *, size_t pos, size_t len,
+ const void *, size_t);
+
extern void strbuf_add(struct strbuf *, const void *, size_t);
static inline void strbuf_addstr(struct strbuf *sb, const char *s) {
strbuf_add(sb, s, strlen(s));
--
1.5.3.1
^ permalink raw reply related
* [PATCH] Refactor replace_encoding_header.
From: Pierre Habouzit @ 2007-09-15 21:50 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <20070916172134.GA26457@artemis.corp>
* Be more clever in how we search for "encoding ...\n": parse for real
instead of the sloppy strstr's.
* use strbuf_splice to do the substring replacements.
Signed-off-by: Pierre Habouzit <madcoder@debian.org>
---
commit.c | 59 +++++++++++++++++++++++------------------------------------
1 files changed, 23 insertions(+), 36 deletions(-)
diff --git a/commit.c b/commit.c
index 6602e2c..13af933 100644
--- a/commit.c
+++ b/commit.c
@@ -648,47 +648,34 @@ static char *get_header(const struct commit *commit, const char *key)
static char *replace_encoding_header(char *buf, const char *encoding)
{
- char *encoding_header = strstr(buf, "\nencoding ");
- char *header_end = strstr(buf, "\n\n");
- char *end_of_encoding_header;
- int encoding_header_pos;
- int encoding_header_len;
- int new_len;
- int need_len;
- int buflen = strlen(buf) + 1;
-
- if (!header_end)
- header_end = buf + buflen;
- if (!encoding_header || encoding_header >= header_end)
- return buf;
- encoding_header++;
- end_of_encoding_header = strchr(encoding_header, '\n');
- if (!end_of_encoding_header)
+ struct strbuf tmp;
+ size_t start, len;
+ char *cp = buf;
+
+ /* guess if there is an encoding header before a \n\n */
+ while (strncmp(cp, "encoding ", strlen("encoding "))) {
+ cp = strchr(cp, '\n');
+ if (!cp || *++cp == '\n')
+ return buf;
+ }
+ start = cp - buf;
+ cp = strchr(cp, '\n');
+ if (!cp)
return buf; /* should not happen but be defensive */
- end_of_encoding_header++;
-
- encoding_header_len = end_of_encoding_header - encoding_header;
- encoding_header_pos = encoding_header - buf;
+ len = cp + 1 - (buf + start);
+ strbuf_init(&tmp, 0);
+ strbuf_attach(&tmp, buf, strlen(buf), strlen(buf) + 1);
if (is_encoding_utf8(encoding)) {
/* we have re-coded to UTF-8; drop the header */
- memmove(encoding_header, end_of_encoding_header,
- buflen - (encoding_header_pos + encoding_header_len));
- return buf;
- }
- new_len = strlen(encoding);
- need_len = new_len + strlen("encoding \n");
- if (encoding_header_len < need_len) {
- buf = xrealloc(buf, buflen + (need_len - encoding_header_len));
- encoding_header = buf + encoding_header_pos;
- end_of_encoding_header = encoding_header + encoding_header_len;
+ strbuf_splice(&tmp, start, len, NULL, 0);
+ } else {
+ /* just replaces XXXX in 'encoding XXXX\n' */
+ strbuf_splice(&tmp, start + strlen("encoding "),
+ len - strlen("encoding \n"),
+ encoding, strlen(encoding));
}
- memmove(end_of_encoding_header + (need_len - encoding_header_len),
- end_of_encoding_header,
- buflen - (encoding_header_pos + encoding_header_len));
- memcpy(encoding_header + 9, encoding, strlen(encoding));
- encoding_header[9 + new_len] = '\n';
- return buf;
+ return tmp.buf;
}
static char *logmsg_reencode(const struct commit *commit,
--
1.5.3.1
^ permalink raw reply related
* Re: [RFC] strbuf's in builtin-apply
From: Pierre Habouzit @ 2007-09-16 17:21 UTC (permalink / raw)
To: git, Junio C Hamano
In-Reply-To: <20070915141210.GA27494@artemis.corp>
[-- Attachment #1: Type: text/plain, Size: 1700 bytes --]
Following this mail will happen a new janitoring series. This is a
rewrite of the former, using Junio's advice to use strbufs in
convert_to_* functions. The patch hence becomes more intrusive than
before (in convert.c mostly). Note that this imply that now strbuf.h is
included from cache.h so all git sources see strbuf's.
The convert_to_git patches gain some marginal efficiency as the new API
makes the reuse of the buffers possible when in-place editing works
(e.g. the \r\n -> \n can be done in place, we save a malloc here). Else
nothing should have changed significantly.
The last 2 patches are new. The first one is a simplification of the
code splicing the "encoding" header in commit.c, reusing the logic
already in strbuf.c for that matter, and also making the parsing code
easier to read (IMHO).
The latter further simplify some code that was trying to guess if
rfc2047 encoding of some header was needed. Thanks to strbuf_grow, and
the fact that now at each point we can grow buffers (which was harder
before), I tried to wait until we are sure if rfc2047 encoding will be
needed or not to extend the buffer. I've benchmarked many tools (on real
repositories, with commiters having non ascii chars in their name) using
the pretty printer without noticeable changes in the numbers (and rather
again, a trend to be faster, but with less than a percent gain, so I
won't call it a real gain).
The series is based on next, as many patches are definitely not suitable
for master :)
--
·O· Pierre Habouzit
··O madcoder@debian.org
OOO http://www.madism.org
[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply
* Re: Blaming diffs
From: Mike Hommey @ 2007-09-16 17:16 UTC (permalink / raw)
To: Frank Lichtenheld; +Cc: git
In-Reply-To: <20070916170534.GU22865@planck.djpig.de>
On Sun, Sep 16, 2007 at 07:05:35PM +0200, Frank Lichtenheld <frank@lichtenheld.de> wrote:
> On Sun, Sep 16, 2007 at 06:38:29PM +0200, Mike Hommey wrote:
> > It seems to me there is no tool to "blame diffs", i.e. something to know
> > what commit(s) is(are) responsible for a set of changes.
> >
> > For example, the following script tries to get the set of commits
> > involved in the changes between $A and $B. Note it only works for text
> > additions.
> >
> > git diff --unified=0 $A $B | awk 'BEGIN { FS="(^(--- a/|+++ b/)|^@@ -[0-9,]+ \\+| @@)" } /^---/ || ( /^+++ b\/(.*)/ && file=="" ) { file = $2 } /^@@/ {split($2, a, /,/); a[2] = a[2] ? a[2] + a[1] - 1 : a[1]; print "git blame -l -L " a[1] "," a[2], "'$A..$B'", file }' | sh | cut -f 1 -d " " | sort -u
> >
> > Has anyone tried to work on something similar yet ?
> >
> > If not, as git users, what kind of output would you expect from such a
> > tool, and where do you think this should lie (extension to git diff, or
> > separate tool) ?
>
> What do you use for $A and $B? commits? What is the difference between
> your script and "git log --pretty=format:%H $A..$B"
> then?
In my typical usecase, $A is upstream and $B is HEAD. What happens is
that my work branch includes some changes that have been merged upstream
and some others that are not yet, or won't because it's not appropriate.
I obviously occasionally merge the upstream branch back, in which case
my changes that were committed upstream don't appear in a git diff $A $B
anymore.
git log --pretty=format:%H $A..$B would give me the list of all commits
that occurred on my branch, while my script only gives the commits
containing changes that are still not applied upstream.
Mike
^ permalink raw reply
* [PATCH] preserve executable bits in zip archives
From: Dmitry Potapov @ 2007-09-16 17:07 UTC (permalink / raw)
To: git
[-- Attachment #1: Type: text/plain, Size: 1122 bytes --]
Correct `git-archive --format=zip' command to preserve executable bits in
zip archives.
---
archive-zip.c | 6 ++++--
1 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/archive-zip.c b/archive-zip.c
index 444e162..5f9b7e6 100644
--- a/archive-zip.c
+++ b/archive-zip.c
@@ -191,7 +191,8 @@ static int write_zip_entry(const unsigned char *sha1,
compressed_size = 0;
} else if (S_ISREG(mode) || S_ISLNK(mode)) {
method = 0;
- attr2 = S_ISLNK(mode) ? ((mode | 0777) << 16) : 0;
+ attr2 = S_ISLNK(mode) ? ((mode | 0777) << 16) :
+ (mode & 0111) ? ((mode) << 16) : 0;
if (S_ISREG(mode) && zlib_compression_level != 0)
method = 8;
result = 0;
@@ -229,7 +230,8 @@ static int write_zip_entry(const unsigned char *sha1,
}
copy_le32(dirent.magic, 0x02014b50);
- copy_le16(dirent.creator_version, S_ISLNK(mode) ? 0x0317 : 0);
+ copy_le16(dirent.creator_version,
+ S_ISLNK(mode) || (S_ISREG(mode) && (mode & 0111)) ? 0x0317 : 0);
copy_le16(dirent.version, 10);
copy_le16(dirent.flags, 0);
copy_le16(dirent.compression_method, method);
--
1.5.3.1
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply related
* Blaming diffs
From: Mike Hommey @ 2007-09-16 16:38 UTC (permalink / raw)
To: git
Hi,
It seems to me there is no tool to "blame diffs", i.e. something to know
what commit(s) is(are) responsible for a set of changes.
For example, the following script tries to get the set of commits
involved in the changes between $A and $B. Note it only works for text
additions.
git diff --unified=0 $A $B | awk 'BEGIN { FS="(^(--- a/|+++ b/)|^@@ -[0-9,]+ \\+| @@)" } /^---/ || ( /^+++ b\/(.*)/ && file=="" ) { file = $2 } /^@@/ {split($2, a, /,/); a[2] = a[2] ? a[2] + a[1] - 1 : a[1]; print "git blame -l -L " a[1] "," a[2], "'$A..$B'", file }' | sh | cut -f 1 -d " " | sort -u
Has anyone tried to work on something similar yet ?
If not, as git users, what kind of output would you expect from such a
tool, and where do you think this should lie (extension to git diff, or
separate tool) ?
Cheers,
Mike
^ permalink raw reply
* Re: metastore (was: Track /etc directory using Git)
From: Jan Hudec @ 2007-09-16 15:59 UTC (permalink / raw)
To: david
Cc: Johannes Schindelin, Daniel Barkalow, martin f krafft, git,
Thomas Harning Jr., Francis Moreau, Nicolas Vilz,
David Härdeman
In-Reply-To: <Pine.LNX.4.64.0709151737400.24221@asgard.lang.hm>
[-- Attachment #1: Type: text/plain, Size: 699 bytes --]
On Sat, Sep 15, 2007 at 18:30:53 -0700, david@lang.hm wrote:
> 1. whatever is trying to write the files with the correct permissions
> needs to be able to query the permission store before files are
> written. This needs to either be an API call into git to retreive the
> information for any file when it's written, or the ability to define a
> specific file to be checked out first so that it can be used for
> everything else.
You seem to be forgetting about the index. Git never writes trees directly to
filesystem, but always with intermediate step in the index. So the API
actually exists -- simply read from the index.
--
Jan 'Bulb' Hudec <bulb@ucw.cz>
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply
* Re: metastore (was: Track /etc directory using Git)
From: Jan Hudec @ 2007-09-16 15:51 UTC (permalink / raw)
To: martin f krafft
Cc: git, Johannes Schindelin, Daniel Barkalow, Thomas Harning Jr.,
Francis Moreau, Nicolas Vilz, David Härdeman
In-Reply-To: <20070916061411.GC24124@piper.oerlikon.madduck.net>
[-- Attachment #1: Type: text/plain, Size: 1958 bytes --]
On Sun, Sep 16, 2007 at 08:14:11 +0200, martin f krafft wrote:
> also sprach Johannes Schindelin <Johannes.Schindelin@gmx.de> [2007.09.16.0014 +0200]:
> > While at it, you should invent a fallback what to do when the
> > owner is not present on the system you check out on. And
> > a fallback when checking out on a filesystem that does not support
> > owners.
>
> Like rsync, git would use numerical UIDs (which are always present)
> by default, but could be told to try to map account names.
>
> If the filesystem does not support owners, chown() would not exist.
> I actually tend to think of things the other way around: instead of
> a fallback when chown() does not work (what would such a fallback be
> other than not chown()ing?), it would only try chown() if such
> functionality existed.
There's a problem. You need to know that the functionality is missing and not
try to read attributes back, but instead consider them unchanged. Nothing
that can't be taken care of, but it needs to be handled carefuly.
> > And a fallback when a non-root user uses it.
>
> That's easy, Unix already provides you with that "fallback": pack up
> /etc in a tar and unpack it as a normal user...
But if you tar that up again, the owners will be different. But you don't
want the change.
> > Oh, and while you're at it (you said that it would be nice not to
> > restrict git in any way: "it is a content tracker") support the
> > Windows style "Group-or-User-or-something:[FRW]" ACLs.
>
> Provided we find a way to implement this in an extensible manner,
> this should not be hard to do. I can't do it since I don't have
> access to a Windows machine.
>
> Your statement does catch me off-guard though. Does git now
> officially target Windows?
Official git works in cygwin. There is also a port to msys, which is
not official in a sense it is not merged into mainline.
--
Jan 'Bulb' Hudec <bulb@ucw.cz>
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply
* Re: metastore
From: Daniel Barkalow @ 2007-09-16 15:51 UTC (permalink / raw)
To: Junio C Hamano
Cc: david, Johannes Schindelin, martin f krafft, git,
Thomas Harning Jr., Francis Moreau, Nicolas Vilz,
David Härdeman
In-Reply-To: <7vwsur590q.fsf@gitster.siamese.dyndns.org>
On Sun, 16 Sep 2007, Junio C Hamano wrote:
> I however think your idea to have extra "permission information
> file" is very interesting. What would be more palatable, than
> mucking with the core level git, would be to have an external
> command that takes two tree object names that tells it what the
> old and new trees our work tree is switching between, and have
> that command to:
>
> - inspect the diff-tree output to find out what were checked
> out and might need their permission information tweaked;
>
> - inspect the differences between the "permission information
> file" in these trees to find out what were _not_ checked out,
> but still need their permission information tweaked.
>
> - tweak whatever external information you are interested in
> expressing in your "permission information file" in the work
> tree for the paths it discovered in the above two steps.
> This step may involve actions specific to projects and call
> hook scripts with <path, info from "permission information
> file" for that path> tuples to carry out the actual tweaking.
Why not have the command also responsible for creating the files that need
to be created (calling back into git to read their contents)? That way,
there's no window where they've been created without their metadata, and
there's more that the core git doesn't have to worry about.
I could see the program getting the index, the target tree, and the
directory to put files in, and being told to do the whole 2-way merge
(except, perhaps, updating the index to match the tree, which git could do
afterwards). As far as git would be concerned, it would mostly be like a
bare repository.
-Daniel
*This .sig left intentionally blank*
^ permalink raw reply
* Re: RFC: German translation vocabulary
From: David Soria @ 2007-09-16 15:12 UTC (permalink / raw)
To: git
In-Reply-To: <857imq4pi0.fsf@lola.goethe.zz>
> Oder "Zusammenfassung"?
>
probably the best translation yet
^ permalink raw reply
* Re: RFC: German translation vocabulary
From: David Kastrup @ 2007-09-16 15:08 UTC (permalink / raw)
To: David Soria; +Cc: git
In-Reply-To: <85bqc24pjg.fsf@lola.goethe.zz>
David Kastrup <dak@gnu.org> writes:
> David Soria <sn_@gmx.net> writes:
>
>> Am Sun, 16 Sep 2007 14:38:37 +0200 schrieb Christian Stimming:
>>
>> Hi Christian,
>>
>> thank you for bringing up the topic, it's really worth discussing it.
>>
>>> [commit] message - Meldung (Nachricht?; Source Safe: Kommentar)
>> I prefer "Kommentar" here. It describes better what the commit message is
>> about. "Meldung" has some co-notations that don't fit (like e.g.
>> "Meldung" often involes other people, like you "meldest" something to
>> somebody).
>
> "Beschreibung"?
Oder "Zusammenfassung"?
--
David Kastrup, Kriemhildstr. 15, 44793 Bochum
^ permalink raw reply
* Re: RFC: German translation vocabulary
From: David Kastrup @ 2007-09-16 15:07 UTC (permalink / raw)
To: David Soria; +Cc: git
In-Reply-To: <fcjgfg$56m$1@sea.gmane.org>
David Soria <sn_@gmx.net> writes:
> Am Sun, 16 Sep 2007 14:38:37 +0200 schrieb Christian Stimming:
>
> Hi Christian,
>
> thank you for bringing up the topic, it's really worth discussing it.
>
>> [commit] message - Meldung (Nachricht?; Source Safe: Kommentar)
> I prefer "Kommentar" here. It describes better what the commit message is
> about. "Meldung" has some co-notations that don't fit (like e.g.
> "Meldung" often involes other people, like you "meldest" something to
> somebody).
"Beschreibung"?
--
David Kastrup, Kriemhildstr. 15, 44793 Bochum
^ permalink raw reply
* Re: RFC: German translation vocabulary
From: David Soria @ 2007-09-16 15:01 UTC (permalink / raw)
To: git
In-Reply-To: <200709161438.37733.stimming@tuhh.de>
Am Sun, 16 Sep 2007 14:38:37 +0200 schrieb Christian Stimming:
Hi Christian,
thank you for bringing up the topic, it's really worth discussing it.
> [commit] message - Meldung (Nachricht?; Source Safe: Kommentar)
I prefer "Kommentar" here. It describes better what the commit message is
about. "Meldung" has some co-notations that don't fit (like e.g.
"Meldung" often involes other people, like you "meldest" something to
somebody).
> I'm still rather unsure what to do about them. One problem here is that
> both words are used in several different meanings all at once. For
> example, the "commit [noun]" is used interchangeably with "revision".
> I'm actually inclined to translate it with "Version" for exactly that
> reason. And then "checkout": The noun is probably used interchangeably
> with "working copy". Hence, it could be translated as such. OTOH the
> verb means "to update the working copy", and it could be translated as
> such instead of one single word. This would leave only "commit [verb]"
> as the last tricky issue for which a single-word translation must be
> found. "übertragen" is my current favorite but I'm absolutely open for
> further proposals here.
>
> As you can see in the glossary file, I'm still unhappy with the
> translations for those, but anyway here's the current status (not taking
> into account the discussion of the previous paragraph so far):
>
Really hard. I would prefer some larger explanations if they fit into the
application and make sense on every label in the gui.
> msgid "commit [noun]"
> msgstr "Übertragung (Sendung?, Übergabe?, Einspielung?, Ablagevorgang?)"
Übertragung fits well, but for me it has a co-notation that something is
transfered from one point to another (e.g. using an internet connection)
So this translation would fit perfectly for centralized versioning
systems, where the changeset is really "transfered" to somewhere. I would
prefer the term "Einspielung" as I think it reflects better, that the
commit is locally.
David
^ permalink raw reply
* RFC: German translation vocabulary
From: Christian Stimming @ 2007-09-16 12:38 UTC (permalink / raw)
To: git
Dear all,
as git-gui has now picked up the i18n features and the initial German
translation has been included as well, it is about time to discuss and
finalize the actual translation wordings of git terminology in German.
In particular, for all keywords of git and git-gui one needs to find
corresponding keywords in German, which will then be used consistently
throughout all of git-gui translations. Those keywords and (for some of them)
their english definition are contained in the "glossary" file, see [1]. I
would like to invite all German-speaking readers here to review the German
keyword translations that have been chosen in the glossary, and I'll denote
the most important ones below for immediate feedback.
(I'll mostly stick to an english discussion so that other languages can use
this as a model on how to discuss this, if they want to.)
One word on the intended audience for the translated git-gui: The translated
form of git-gui is *not for you* :-). In other words, it is not intended for
those who are reading this list and, by doing so, are completely familiar
with all the English terminology of git. Instead, the translation is intended
for German developers who know *some* English, but feel much more comfortable
with a fully German development environment and probably wouldn't touch an
english-language git-gui anyway. Hence, the translation should try really
hard to find German words wherever possible.
Also, other version control systems have worked on their German translation as
well. If you want to check the wordings that have been chosen there, I'd
recommend looking into their translations [2].
I'll list the most important glossary terms here, starting with the easier
ones:
repository - Projektarchiv
revision - Version
staging area - Bereitstellung
branch [noun] - Zweig
branch [verb] - verzweigen
working copy, working tree - Arbeitskopie
[commit] message - Meldung (Nachricht?; Source Safe: Kommentar)
For some of them you can see alternatives considered in the glossary [1], but
overall the above ones were rather easy. Now for the difficult ones:
commit [noun]
commit [verb]
checkout [noun]
checkout [verb]
I'm still rather unsure what to do about them. One problem here is that both
words are used in several different meanings all at once. For example,
the "commit [noun]" is used interchangeably with "revision". I'm actually
inclined to translate it with "Version" for exactly that reason. And
then "checkout": The noun is probably used interchangeably with "working
copy". Hence, it could be translated as such. OTOH the verb means "to update
the working copy", and it could be translated as such instead of one single
word. This would leave only "commit [verb]" as the last tricky issue for
which a single-word translation must be found. "übertragen" is my current
favorite but I'm absolutely open for further proposals here.
As you can see in the glossary file, I'm still unhappy with the translations
for those, but anyway here's the current status (not taking into account the
discussion of the previous paragraph so far):
msgid "checkout [noun]"
msgstr "Auscheck? Ausspielung? Abruf? (Source Safe: Auscheckvorgang)"
msgid "checkout [verb]"
msgstr "auschecken? ausspielen? abrufen? (Source Safe: auschecken)"
msgid "commit [noun]"
msgstr "Übertragung (Sendung?, Übergabe?, Einspielung?, Ablagevorgang?)"
msgid "commit [verb]"
msgstr "übertragen (TortoiseSVN: übertragen; Source Safe: einchecken; senden?,
übergeben?, einspielen?, einpflegen?, ablegen?)"
Regards,
Christian Stimming
[1] http://repo.or.cz/w/git-gui.git?a=blob_plain;f=po/glossary/de.po;hb=HEAD
(note: the file is in UTF-8, but repo.or.cz's webserver claims it is latin1,
hence the messed-up Umlauts)
[2]
* http://tortoisesvn.net/docs/release/TortoiseSVN_de/index.html (very good)
* http://msdn.microsoft.com/de-de/library/ms181038(vs.80).aspx (MS Visual
Source Safe, commercial)
* http://cvsbook.red-bean.com/translations/german/Kap_06.html (not so good)
*
http://tortoisecvs.cvs.sourceforge.net/tortoisecvs/po/TortoiseCVS/de_DE.po?view=markup
(not so good)
* http://rapidsvn.tigris.org/svn/rapidsvn/trunk/src/locale/de/rapidsvn.po
(username=guest, password empty, quite bad)
^ permalink raw reply
* Re: git-gui i18n status?
From: Christian Stimming @ 2007-09-16 12:03 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: Shawn O. Pearce, Junio C Hamano, git
In-Reply-To: <Pine.LNX.4.64.0709021320230.28586@racer.site>
Hi Shawn et al.,
Am Sonntag, 2. September 2007 14:20 schrieb Johannes Schindelin:
> > > > Hmm. I am not enough involved in i18n stuff to form a proper opinion
> > > > here... Do you suggest to move the initialisation earlier?
> > >
> > > Yea, I think that's what we are going to have to do here. If we don't
> > > setup the directory for the .msg files early enough than we cannot do
> > > translations through [mc]. Unfortunately that means we have to also
> > > break up the library initialization.
> > >
> > > I'll try to work up a patch that does this.
> >
> > This two patch series is based on my current master (gitgui-0.8.2).
> > Its also now in my pu branch.
>
> Sound both good to me. Christian?
Thanks for including the i18n framework and existing translations into the
master of git-gui. I loosely watched the progress here, but due to other
commitments I cannot spend as much time on git-gui i18n as I initially
thought. I'd happily update and polish the German translation, though (will
send other email for that), but I probably can't follow any of the ongoing
i18n cleanup work.
One question came up when seeing the i18n code really in git-gui.git: How are
translators supposed to submit new or updated translations? Is
git-gui-i18n.git of any use anymore? This doesn't seem so. Should updated
translations just be submitted by email to git@vger? In any case, the
instructions in po/README should probably be updated to explain the
recommended way of submitting translation updates.
Oh, and po/git-gui.pot should probably be updated to reflect the latest string
additions and changes.
Thanks a lot.
Christian
^ permalink raw reply
* Re: git-svn error when cloning apache repo
From: Sam Vilain @ 2007-09-16 11:46 UTC (permalink / raw)
To: jingxue; +Cc: git
In-Reply-To: <20070915230833.GA8525@falcon.digizenstudio.com>
Jing Xue wrote:
> $ git svn clone https://svn.apache.org/repos/asf/incubator/ivy/core/ ivy-core -T trunk -b branches -t tags
> Initialized empty Git repository in .git/
> Using higher level of URL: https://svn.apache.org/repos/asf/incubator/ivy/core => https://svn.apache.org/repos/asf
>
I'm fairly sure this is where it went wrong. Try editing .git/config and
putting your original URL in the source URL, and re-try the fetch.
Sam.
^ permalink raw reply
* Re: Conflicting "-n" short options for git-pull?
From: Frans Pop @ 2007-09-16 11:17 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <7vfy1f8pmm.fsf@gitster.siamese.dyndns.org>
On Sunday 16 September 2007, Junio C Hamano wrote:
> Frans Pop <elendil@planet.nl> writes:
> > According to the man page for git-pull from git-core 1.5.3.1 (Debian
> > package), two options are defined as having the short option "-n":
> >
> > -n, --no-summary
> > Do not show diffstat at the end of the merge.
> > [...]
> > -n, --no-tags
> > By default, git-fetch fetches tags that point at objects that
> > are downloaded from the remote repository and stores them locally. This
> > option disables this automatic tag following.
>
> The manpage option descriptions are shared between the
> commands. Maybe we should drop mention of the shorthand form.
Not sure if that last is the correct solution. Wouldn't it mean that short
options would not be documented at all anymore?
> When git-fetch is used -n means --no-tags because there is no
> other -n; when git-pull indirectly invokes git-fetch, you need
> to spell it --no-tags because --no-summary takes precedence.
That does explain, but it is not at all obvious from the documentation.
Guess this is a general "problem" in git then.
Another question.
Is it possible to set default options for commands somehow?
I'd like to run git-pull with '--no-summary' by default. I could of course
define an alias, but that only covers 'git-pull' and not 'git pull'.
Does git itself have some mechanism for this?
Thanks,
Frans Pop
^ permalink raw reply
* Re: [StGit PATCH 00/13] Eliminate 'top' and 'bottom' files
From: David Kågedal @ 2007-09-16 10:28 UTC (permalink / raw)
To: Catalin Marinas; +Cc: Karl Hasselström , git
In-Reply-To: <b0943d9e0709160028h41a67474g6b379a45c4c88432@mail.gmail.com>
16 sep 2007 kl. 09.28 skrev Catalin Marinas:
> On 16/09/2007, Karl Hasselström <kha@treskal.com> wrote:
>> On 2007-09-15 00:31:09 +0200, David Kågedal wrote:
>>
>>> The following series removes the 'bottom' and 'top' files for each
>>> patch, and instead uses the commit objects to keep track of the
>>> patches.
>>
>> Wonderful! Does this ensure that there's a bijection between patches
>> and commits at _all_ times, or am I missing something?
>
> We should get rid of top.old and bottom.old as well.
>
> My question - does this conflict with the DAG patches in any way? I
> intend to include the them at some point, once I get a chance to test
> the performance penalty with a big tree like the Linux kernel.
My refactoring of the push_patch function will conflict because of
refactoring, but it doesn't change how the appliedness is used, so it
should be pretty simple to resolve.
Or I could try to redo the patches so it only has the minimal changes
to actually remove the top and bottom files.
>> Hmm, wait, no. Right. We also have to create commits for those
>> patches
>> that don't have exactly one commit object. Not that there'll be many
>> of them, but better not make assumptions ...
>
> Is there any patch which consists of more than one commit? Maybe only
> uncommit could generate one but I think we put some tests in place.
I haven't seen any such case. Can uncommit create one? Or did it use
to do that before? I added checks to detect it, and no test case
caught it at least.
--
David Kågedal
davidk@lysator.liu.se
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox