* [PATCH 11/12] pretty: support truncating in %>, %< and %><
From: Nguyễn Thái Ngọc Duy @ 2013-03-16 2:24 UTC (permalink / raw)
To: git; +Cc: Junio C Hamano, Nguyễn Thái Ngọc Duy
In-Reply-To: <1363400683-14813-1-git-send-email-pclouds@gmail.com>
%>(N,trunc) truncates the righ part after N columns and replace the
last two letters with "..". ltrunc does the same on the left. mtrunc
cuts the middle out.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
Documentation/pretty-formats.txt | 6 +++--
pretty.c | 51 +++++++++++++++++++++++++++++++++++++---
utf8.c | 46 ++++++++++++++++++++++++++++++++++++
utf8.h | 2 ++
4 files changed, 100 insertions(+), 5 deletions(-)
diff --git a/Documentation/pretty-formats.txt b/Documentation/pretty-formats.txt
index 87ca2c4..17f82f4 100644
--- a/Documentation/pretty-formats.txt
+++ b/Documentation/pretty-formats.txt
@@ -162,8 +162,10 @@ The placeholders are:
- '%x00': print a byte from a hex code
- '%w([<w>[,<i1>[,<i2>]]])': switch line wrapping, like the -w option of
linkgit:git-shortlog[1].
-- '%<(<N>)': make the next placeholder take at least N columns,
- padding spaces on the right if necessary
+- '%<(<N>[,trunc|ltrunc|mtrunc])': make the next placeholder take at
+ least N columns, padding spaces on the right if necessary.
+ Optionally truncate at the beginning (ltrunc), the middle (mtrunc)
+ or the end (trunc) if the output is longer than N columns.
- '%<|(<N>)': make the next placeholder take at least until Nth
columns, padding spaces on the right if necessary
- '%>(<N>)', '%>|(<N>)': similar to '%<(<N<)', '%<|(<N<)'
diff --git a/pretty.c b/pretty.c
index 233d69c..29384b5 100644
--- a/pretty.c
+++ b/pretty.c
@@ -767,6 +767,13 @@ enum flush_type {
flush_both
};
+enum trunc_type {
+ trunc_none,
+ trunc_left,
+ trunc_middle,
+ trunc_right
+};
+
struct format_commit_context {
const struct commit *commit;
const struct pretty_print_context *pretty_ctx;
@@ -774,6 +781,7 @@ struct format_commit_context {
unsigned commit_message_parsed:1;
unsigned commit_signature_parsed:1;
enum flush_type flush_type;
+ enum trunc_type truncate;
struct {
char *gpg_output;
char good_bad;
@@ -1044,7 +1052,7 @@ static size_t parse_padding_placeholder(struct strbuf *sb,
if (*ch == '(') {
const char *start = ch + 1;
- const char *end = strchr(start, ')');
+ const char *end = start + strcspn(start, ",)");
char *next;
int width;
if (!end || end == start)
@@ -1054,6 +1062,23 @@ static size_t parse_padding_placeholder(struct strbuf *sb,
return 0;
c->padding = to_column ? -width : width;
c->flush_type = flush_type;
+
+ if (*end == ',') {
+ start = end + 1;
+ end = strchr(start, ')');
+ if (!end || end == start)
+ return 0;
+ if (!prefixcmp(start, "trunc)"))
+ c->truncate = trunc_right;
+ else if (!prefixcmp(start, "ltrunc)"))
+ c->truncate = trunc_left;
+ else if (!prefixcmp(start, "mtrunc)"))
+ c->truncate = trunc_middle;
+ else
+ return 0;
+ } else
+ c->truncate = trunc_none;
+
return end - placeholder + 1;
}
return 0;
@@ -1335,9 +1360,29 @@ static size_t format_and_pad_commit(struct strbuf *sb, /* in UTF-8 */
total_consumed++;
}
len = utf8_strnwidth(local_sb.buf, -1, 1);
- if (len > padding)
+ if (len > padding) {
+ switch (c->truncate) {
+ case trunc_left:
+ strbuf_utf8_replace(&local_sb,
+ 0, len - (padding - 2),
+ "..");
+ break;
+ case trunc_middle:
+ strbuf_utf8_replace(&local_sb,
+ padding / 2 - 1,
+ len - (padding - 2),
+ "..");
+ break;
+ case trunc_right:
+ strbuf_utf8_replace(&local_sb,
+ padding - 2, len - (padding - 2),
+ "..");
+ break;
+ case trunc_none:
+ break;
+ }
strbuf_addstr(sb, local_sb.buf);
- else {
+ } else {
int sb_len = sb->len, offset = 0;
if (c->flush_type == flush_left)
offset = padding - len;
diff --git a/utf8.c b/utf8.c
index 9d98043..766df80 100644
--- a/utf8.c
+++ b/utf8.c
@@ -421,6 +421,52 @@ void strbuf_add_wrapped_bytes(struct strbuf *buf, const char *data, int len,
free(tmp);
}
+void strbuf_utf8_replace(struct strbuf *sb_src, int pos, int width,
+ const char *subst)
+{
+ struct strbuf sb_dst = STRBUF_INIT;
+ char *src = sb_src->buf;
+ char *end = src + sb_src->len;
+ char *dst;
+ int w = 0, subst_len = 0;
+
+ if (subst)
+ subst_len = strlen(subst);
+ strbuf_grow(&sb_dst, sb_src->len + subst_len);
+ dst = sb_dst.buf;
+
+ while (src < end) {
+ char *old;
+ size_t n;
+
+ while ((n = display_mode_esc_sequence_len(src))) {
+ memcpy(dst, src, n);
+ src += n;
+ dst += n;
+ }
+
+ old = src;
+ n = utf8_width((const char**)&src, NULL);
+ if (!src) /* broken utf-8, do nothing */
+ return;
+ if (n && w >= pos && w < pos + width) {
+ if (subst) {
+ memcpy(dst, subst, subst_len);
+ dst += subst_len;
+ subst = NULL;
+ }
+ w += n;
+ continue;
+ }
+ memcpy(dst, old, src - old);
+ dst += src - old;
+ w += n;
+ }
+ strbuf_setlen(&sb_dst, dst - sb_dst.buf);
+ strbuf_attach(sb_src, strbuf_detach(&sb_dst, NULL),
+ sb_dst.len, sb_dst.alloc);
+}
+
int is_encoding_utf8(const char *name)
{
if (!name)
diff --git a/utf8.h b/utf8.h
index 99db3e0..faf2f91 100644
--- a/utf8.h
+++ b/utf8.h
@@ -15,6 +15,8 @@ void strbuf_add_wrapped_text(struct strbuf *buf,
const char *text, int indent, int indent2, int width);
void strbuf_add_wrapped_bytes(struct strbuf *buf, const char *data, int len,
int indent, int indent2, int width);
+void strbuf_utf8_replace(struct strbuf *sb, int pos, int width,
+ const char *subst);
#ifndef NO_ICONV
char *reencode_string_iconv(const char *in, size_t insz,
--
1.8.2.83.gc99314b
^ permalink raw reply related
* [PATCH 10/12] pretty: support padding placeholders, %< %> and %><
From: Nguyễn Thái Ngọc Duy @ 2013-03-16 2:24 UTC (permalink / raw)
To: git; +Cc: Junio C Hamano, Nguyễn Thái Ngọc Duy
In-Reply-To: <1363400683-14813-1-git-send-email-pclouds@gmail.com>
Either %<, %> or %<> standing before a placeholder specifies how many
columns (at least as the placeholder can exceed it) it takes. Each
differs on how spaces are padded:
%< pads on the right (aka left alignment)
%> pads on the left (aka right alignment)
%>< pads both ways equally (aka centered)
The (<N>) follows them, e.g. `%<(100)', to specify the number of
columns the next placeholder takes.
However, if '|' stands before (<N>), e.g. `%>|(100)', then the number
of columns is calculated so that it reaches the Nth column on screen.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
Documentation/pretty-formats.txt | 8 +++
pretty.c | 117 ++++++++++++++++++++++++++++++++++++++-
2 files changed, 124 insertions(+), 1 deletion(-)
diff --git a/Documentation/pretty-formats.txt b/Documentation/pretty-formats.txt
index 8734224..87ca2c4 100644
--- a/Documentation/pretty-formats.txt
+++ b/Documentation/pretty-formats.txt
@@ -162,6 +162,14 @@ The placeholders are:
- '%x00': print a byte from a hex code
- '%w([<w>[,<i1>[,<i2>]]])': switch line wrapping, like the -w option of
linkgit:git-shortlog[1].
+- '%<(<N>)': make the next placeholder take at least N columns,
+ padding spaces on the right if necessary
+- '%<|(<N>)': make the next placeholder take at least until Nth
+ columns, padding spaces on the right if necessary
+- '%>(<N>)', '%>|(<N>)': similar to '%<(<N<)', '%<|(<N<)'
+ respectively, but padding spaces on the left
+- '%><(<N>)', '%><|(<N>)': similar to '%<(<N<)', '%<|(<N<)'
+ respectively, but padding both sides (i.e. the text is centered)
NOTE: Some placeholders may depend on other options given to the
revision traversal engine. For example, the `%g*` reflog options will
diff --git a/pretty.c b/pretty.c
index c333fd6..233d69c 100644
--- a/pretty.c
+++ b/pretty.c
@@ -760,12 +760,20 @@ struct chunk {
size_t len;
};
+enum flush_type {
+ no_flush,
+ flush_right,
+ flush_left,
+ flush_both
+};
+
struct format_commit_context {
const struct commit *commit;
const struct pretty_print_context *pretty_ctx;
unsigned commit_header_parsed:1;
unsigned commit_message_parsed:1;
unsigned commit_signature_parsed:1;
+ enum flush_type flush_type;
struct {
char *gpg_output;
char good_bad;
@@ -775,6 +783,7 @@ struct format_commit_context {
char *commit_encoding;
size_t width, indent1, indent2;
int auto_color;
+ int padding;
/* These offsets are relative to the start of the commit message. */
struct chunk author;
@@ -1004,6 +1013,52 @@ static int format_reflog_person(struct strbuf *sb,
return format_person_part(sb, part, ident, strlen(ident), dmode);
}
+static size_t parse_padding_placeholder(struct strbuf *sb,
+ const char *placeholder,
+ struct format_commit_context *c)
+{
+ const char *ch = placeholder;
+ enum flush_type flush_type;
+ int to_column = 0;
+
+ switch (*ch++) {
+ case '<':
+ flush_type = flush_right;
+ break;
+ case '>':
+ if (*ch == '<') {
+ flush_type = flush_both;
+ ch++;
+ } else
+ flush_type = flush_left;
+ break;
+ default:
+ return 0;
+ }
+
+ /* the next value means "wide enough to that column" */
+ if (*ch == '|') {
+ to_column = 1;
+ ch++;
+ }
+
+ if (*ch == '(') {
+ const char *start = ch + 1;
+ const char *end = strchr(start, ')');
+ char *next;
+ int width;
+ if (!end || end == start)
+ return 0;
+ width = strtoul(start, &next, 10);
+ if (next == start || width == 0)
+ return 0;
+ c->padding = to_column ? -width : width;
+ c->flush_type = flush_type;
+ return end - placeholder + 1;
+ }
+ return 0;
+}
+
static size_t format_commit_one(struct strbuf *sb, /* in UTF-8 */
const char *placeholder,
void *context)
@@ -1090,6 +1145,10 @@ static size_t format_commit_one(struct strbuf *sb, /* in UTF-8 */
return end - placeholder + 1;
} else
return 0;
+
+ case '<':
+ case '>':
+ return parse_padding_placeholder(sb, placeholder, c);
}
/* these depend on the commit */
@@ -1247,6 +1306,59 @@ static size_t format_commit_one(struct strbuf *sb, /* in UTF-8 */
return 0; /* unknown placeholder */
}
+static size_t format_and_pad_commit(struct strbuf *sb, /* in UTF-8 */
+ const char *placeholder,
+ struct format_commit_context *c)
+{
+ struct strbuf local_sb = STRBUF_INIT;
+ int total_consumed = 0, len, padding = c->padding;
+ if (padding < 0) {
+ const char *start = strrchr(sb->buf, '\n');
+ int occupied;
+ if (!start)
+ start = sb->buf;
+ occupied = utf8_strnwidth(start, -1, 1);
+ padding = (-padding) - occupied;
+ }
+ while (1) {
+ int modifier = *placeholder == 'C';
+ int consumed = format_commit_one(&local_sb, placeholder, c);
+ total_consumed += consumed;
+
+ if (!modifier)
+ break;
+
+ placeholder += consumed;
+ if (*placeholder != '%')
+ break;
+ placeholder++;
+ total_consumed++;
+ }
+ len = utf8_strnwidth(local_sb.buf, -1, 1);
+ if (len > padding)
+ strbuf_addstr(sb, local_sb.buf);
+ else {
+ int sb_len = sb->len, offset = 0;
+ if (c->flush_type == flush_left)
+ offset = padding - len;
+ else if (c->flush_type == flush_both)
+ offset = (padding - len) / 2;
+ /*
+ * we calculate padding in columns, now
+ * convert it back to chars
+ */
+ padding = padding - len + local_sb.len;
+ strbuf_grow(sb, padding);
+ strbuf_setlen(sb, sb_len + padding);
+ memset(sb->buf + sb_len, ' ', sb->len - sb_len);
+ memcpy(sb->buf + sb_len + offset, local_sb.buf,
+ local_sb.len);
+ }
+ strbuf_release(&local_sb);
+ c->flush_type = no_flush;
+ return total_consumed;
+}
+
static size_t format_commit_item(struct strbuf *sb, /* in UTF-8 */
const char *placeholder,
void *context)
@@ -1277,7 +1389,10 @@ static size_t format_commit_item(struct strbuf *sb, /* in UTF-8 */
placeholder++;
orig_len = sb->len;
- consumed = format_commit_one(sb, placeholder, context);
+ if (((struct format_commit_context *)context)->flush_type != no_flush)
+ consumed = format_and_pad_commit(sb, placeholder, context);
+ else
+ consumed = format_commit_one(sb, placeholder, context);
if (magic == NO_MAGIC)
return consumed;
--
1.8.2.83.gc99314b
^ permalink raw reply related
* [PATCH 09/12] pretty: add %C(auto) for auto-coloring on the next placeholder
From: Nguyễn Thái Ngọc Duy @ 2013-03-16 2:24 UTC (permalink / raw)
To: git; +Cc: Junio C Hamano, Nguyễn Thái Ngọc Duy
In-Reply-To: <1363400683-14813-1-git-send-email-pclouds@gmail.com>
This is not simply convenient over $C(auto,xxx). Some placeholders
(actually only one, %d) do multi coloring and we can't emit a multiple
colors with %C(auto,xxx).
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
Documentation/pretty-formats.txt | 3 ++-
pretty.c | 15 +++++++++++++--
2 files changed, 15 insertions(+), 3 deletions(-)
diff --git a/Documentation/pretty-formats.txt b/Documentation/pretty-formats.txt
index 66345d1..8734224 100644
--- a/Documentation/pretty-formats.txt
+++ b/Documentation/pretty-formats.txt
@@ -154,7 +154,8 @@ The placeholders are:
adding `auto,` at the beginning will emit color only when colors are
enabled for log output (by `color.diff`, `color.ui`, or `--color`, and
respecting the `auto` settings of the former if we are going to a
- terminal)
+ terminal). `auto` alone (i.e. `%C(auto)`) will turn on auto coloring
+ on the following placeholder.
- '%m': left, right or boundary mark
- '%n': newline
- '%%': a raw '%'
diff --git a/pretty.c b/pretty.c
index 3f4809a..c333fd6 100644
--- a/pretty.c
+++ b/pretty.c
@@ -774,6 +774,7 @@ struct format_commit_context {
char *message;
char *commit_encoding;
size_t width, indent1, indent2;
+ int auto_color;
/* These offsets are relative to the start of the commit message. */
struct chunk author;
@@ -1011,7 +1012,7 @@ static size_t format_commit_one(struct strbuf *sb, /* in UTF-8 */
const struct commit *commit = c->commit;
const char *msg = c->message;
struct commit_list *p;
- int h1, h2;
+ int h1, h2, use_color;
/* these are independent of the commit */
switch (placeholder[0]) {
@@ -1023,6 +1024,10 @@ static size_t format_commit_one(struct strbuf *sb, /* in UTF-8 */
if (!end)
return 0;
+ if (!prefixcmp(begin, "auto)")) {
+ c->auto_color = 1;
+ return end - placeholder + 1;
+ }
if (!prefixcmp(begin, "auto,")) {
if (!want_color(c->pretty_ctx->color))
return end - placeholder + 1;
@@ -1090,16 +1095,22 @@ static size_t format_commit_one(struct strbuf *sb, /* in UTF-8 */
/* these depend on the commit */
if (!commit->object.parsed)
parse_object(commit->object.sha1);
+ use_color = c->auto_color;
+ c->auto_color = 0;
switch (placeholder[0]) {
case 'H': /* commit hash */
+ strbuf_addstr(sb, diff_get_color(use_color, DIFF_COMMIT));
strbuf_addstr(sb, sha1_to_hex(commit->object.sha1));
+ strbuf_addstr(sb, diff_get_color(use_color, DIFF_RESET));
return 1;
case 'h': /* abbreviated commit hash */
+ strbuf_addstr(sb, diff_get_color(use_color, DIFF_COMMIT));
if (add_again(sb, &c->abbrev_commit_hash))
return 1;
strbuf_addstr(sb, find_unique_abbrev(commit->object.sha1,
c->pretty_ctx->abbrev));
+ strbuf_addstr(sb, diff_get_color(use_color, DIFF_RESET));
c->abbrev_commit_hash.len = sb->len - c->abbrev_commit_hash.off;
return 1;
case 'T': /* tree hash */
@@ -1136,7 +1147,7 @@ static size_t format_commit_one(struct strbuf *sb, /* in UTF-8 */
strbuf_addstr(sb, get_revision_mark(NULL, commit));
return 1;
case 'd':
- format_decoration(sb, commit, 0);
+ format_decoration(sb, commit, use_color);
return 1;
case 'g': /* reflog info */
switch(placeholder[1]) {
--
1.8.2.83.gc99314b
^ permalink raw reply related
* [PATCH 06/12] pretty: get the correct encoding for --pretty:format=%e
From: Nguyễn Thái Ngọc Duy @ 2013-03-16 2:24 UTC (permalink / raw)
To: git; +Cc: Junio C Hamano, Nguyễn Thái Ngọc Duy
In-Reply-To: <1363400683-14813-1-git-send-email-pclouds@gmail.com>
parse_commit_header() provides the commit encoding for '%e' and it
reads it from the re-encoded message, which contains the new encoding,
not the original one in the commit object.
Get the commit encoding from logmsg_reencode() instead.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
pretty.c | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/pretty.c b/pretty.c
index ab5d70f..e2241e5 100644
--- a/pretty.c
+++ b/pretty.c
@@ -771,12 +771,12 @@ struct format_commit_context {
char *signer;
} signature;
char *message;
+ char *commit_encoding;
size_t width, indent1, indent2;
/* These offsets are relative to the start of the commit message. */
struct chunk author;
struct chunk committer;
- struct chunk encoding;
size_t message_off;
size_t subject_off;
size_t body_off;
@@ -823,9 +823,6 @@ static void parse_commit_header(struct format_commit_context *context)
} else if (!prefixcmp(msg + i, "committer ")) {
context->committer.off = i + 10;
context->committer.len = eol - i - 10;
- } else if (!prefixcmp(msg + i, "encoding ")) {
- context->encoding.off = i + 9;
- context->encoding.len = eol - i - 9;
}
i = eol;
}
@@ -1210,7 +1207,8 @@ static size_t format_commit_one(struct strbuf *sb, const char *placeholder,
msg + c->committer.off, c->committer.len,
c->pretty_ctx->date_mode);
case 'e': /* encoding */
- strbuf_add(sb, msg + c->encoding.off, c->encoding.len);
+ if (c->commit_encoding)
+ strbuf_addstr(sb, c->commit_encoding);
return 1;
case 'B': /* raw body */
/* message_off is always left at the initial newline */
@@ -1321,11 +1319,14 @@ void format_commit_message(const struct commit *commit,
context.commit = commit;
context.pretty_ctx = pretty_ctx;
context.wrap_start = sb->len;
- context.message = logmsg_reencode(commit, NULL, output_enc);
+ context.message = logmsg_reencode(commit,
+ &context.commit_encoding,
+ output_enc);
strbuf_expand(sb, format, format_commit_item, &context);
rewrap_message_tail(sb, &context, 0, 0, 0);
+ free(context.commit_encoding);
logmsg_free(context.message, commit);
free(context.signature.gpg_output);
free(context.signature.signer);
--
1.8.2.83.gc99314b
^ permalink raw reply related
* [PATCH 04/12] utf8.c: add utf8_strnwidth() with the ability to skip ansi sequences
From: Nguyễn Thái Ngọc Duy @ 2013-03-16 2:24 UTC (permalink / raw)
To: git; +Cc: Junio C Hamano, Nguyễn Thái Ngọc Duy
In-Reply-To: <1363400683-14813-1-git-send-email-pclouds@gmail.com>
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
utf8.c | 20 ++++++++++++++------
utf8.h | 1 +
2 files changed, 15 insertions(+), 6 deletions(-)
diff --git a/utf8.c b/utf8.c
index 82c2ddf..38322a1 100644
--- a/utf8.c
+++ b/utf8.c
@@ -266,18 +266,26 @@ int utf8_width(const char **start, size_t *remainder_p)
* string, assuming that the string is utf8. Returns strlen() instead
* if the string does not look like a valid utf8 string.
*/
-int utf8_strwidth(const char *string)
+int utf8_strnwidth(const char *string, int len, int skip_ansi)
{
int width = 0;
const char *orig = string;
- while (1) {
- if (!string)
- return strlen(orig);
- if (!*string)
- return width;
+ if (len == -1)
+ len = strlen(string);
+ while (string && string < orig + len) {
+ int skip;
+ while (skip_ansi &&
+ (skip = display_mode_esc_sequence_len(string)))
+ string += skip;
width += utf8_width(&string, NULL);
}
+ return string ? width : len;
+}
+
+int utf8_strwidth(const char *string)
+{
+ return utf8_strnwidth(string, -1, 0);
}
int is_utf8(const char *text)
diff --git a/utf8.h b/utf8.h
index 501b2bd..a556932 100644
--- a/utf8.h
+++ b/utf8.h
@@ -4,6 +4,7 @@
typedef unsigned int ucs_char_t; /* assuming 32bit int */
int utf8_width(const char **start, size_t *remainder_p);
+int utf8_strnwidth(const char *string, int len, int skip_ansi);
int utf8_strwidth(const char *string);
int is_utf8(const char *text);
int is_encoding_utf8(const char *name);
--
1.8.2.83.gc99314b
^ permalink raw reply related
* [PATCH 03/12] utf8.c: move display_mode_esc_sequence_len() for use by other functions
From: Nguyễn Thái Ngọc Duy @ 2013-03-16 2:24 UTC (permalink / raw)
To: git; +Cc: Junio C Hamano, Nguyễn Thái Ngọc Duy
In-Reply-To: <1363400683-14813-1-git-send-email-pclouds@gmail.com>
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
utf8.c | 28 ++++++++++++++--------------
1 file changed, 14 insertions(+), 14 deletions(-)
diff --git a/utf8.c b/utf8.c
index 1087870..82c2ddf 100644
--- a/utf8.c
+++ b/utf8.c
@@ -9,6 +9,20 @@ struct interval {
int last;
};
+static size_t display_mode_esc_sequence_len(const char *s)
+{
+ const char *p = s;
+ if (*p++ != '\033')
+ return 0;
+ if (*p++ != '[')
+ return 0;
+ while (isdigit(*p) || *p == ';')
+ p++;
+ if (*p++ != 'm')
+ return 0;
+ return p - s;
+}
+
/* auxiliary function for binary search in interval table */
static int bisearch(ucs_char_t ucs, const struct interval *table, int max)
{
@@ -303,20 +317,6 @@ static void strbuf_add_indented_text(struct strbuf *buf, const char *text,
}
}
-static size_t display_mode_esc_sequence_len(const char *s)
-{
- const char *p = s;
- if (*p++ != '\033')
- return 0;
- if (*p++ != '[')
- return 0;
- while (isdigit(*p) || *p == ';')
- p++;
- if (*p++ != 'm')
- return 0;
- return p - s;
-}
-
/*
* Wrap the text, if necessary. The variable indent is the indent for the
* first line, indent2 is the indent for all other lines.
--
1.8.2.83.gc99314b
^ permalink raw reply related
* [PATCH 02/12] pretty: share code between format_decoration and show_decorations
From: Nguyễn Thái Ngọc Duy @ 2013-03-16 2:24 UTC (permalink / raw)
To: git; +Cc: Junio C Hamano, Nguyễn Thái Ngọc Duy
In-Reply-To: <1363400683-14813-1-git-send-email-pclouds@gmail.com>
This also adds color support to format_decoration()
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
log-tree.c | 60 +++++++++++++++++++++++++---------------
log-tree.h | 3 ++
pretty.c | 19 +------------
t/t4207-log-decoration-colors.sh | 8 +++---
4 files changed, 45 insertions(+), 45 deletions(-)
diff --git a/log-tree.c b/log-tree.c
index 5dc45c4..7467a1d 100644
--- a/log-tree.c
+++ b/log-tree.c
@@ -174,36 +174,50 @@ static void show_children(struct rev_info *opt, struct commit *commit, int abbre
}
}
-void show_decorations(struct rev_info *opt, struct commit *commit)
+void format_decoration(struct strbuf *sb,
+ const struct commit *commit,
+ int use_color)
{
- const char *prefix;
- struct name_decoration *decoration;
+ const char *prefix = " (";
+ struct name_decoration *d;
const char *color_commit =
- diff_get_color_opt(&opt->diffopt, DIFF_COMMIT);
+ diff_get_color(use_color, DIFF_COMMIT);
const char *color_reset =
- decorate_get_color_opt(&opt->diffopt, DECORATION_NONE);
+ decorate_get_color(use_color, DECORATION_NONE);
+
+ load_ref_decorations(DECORATE_SHORT_REFS);
+ d = lookup_decoration(&name_decoration, &commit->object);
+ if (!d)
+ return;
+ while (d) {
+ strbuf_addstr(sb, color_commit);
+ strbuf_addstr(sb, prefix);
+ strbuf_addstr(sb, decorate_get_color(use_color, d->type));
+ if (d->type == DECORATION_REF_TAG)
+ strbuf_addstr(sb, "tag: ");
+ strbuf_addstr(sb, d->name);
+ strbuf_addstr(sb, color_reset);
+ prefix = ", ";
+ d = d->next;
+ }
+ if (prefix[0] == ',') {
+ strbuf_addstr(sb, color_commit);
+ strbuf_addch(sb, ')');
+ strbuf_addstr(sb, color_reset);
+ }
+}
+
+void show_decorations(struct rev_info *opt, struct commit *commit)
+{
+ struct strbuf sb = STRBUF_INIT;
if (opt->show_source && commit->util)
printf("\t%s", (char *) commit->util);
if (!opt->show_decorations)
return;
- decoration = lookup_decoration(&name_decoration, &commit->object);
- if (!decoration)
- return;
- prefix = " (";
- while (decoration) {
- printf("%s", prefix);
- fputs(decorate_get_color_opt(&opt->diffopt, decoration->type),
- stdout);
- if (decoration->type == DECORATION_REF_TAG)
- fputs("tag: ", stdout);
- printf("%s", decoration->name);
- fputs(color_reset, stdout);
- fputs(color_commit, stdout);
- prefix = ", ";
- decoration = decoration->next;
- }
- putchar(')');
+ format_decoration(&sb, commit, opt->diffopt.use_color);
+ fputs(sb.buf, stdout);
+ strbuf_release(&sb);
}
/*
@@ -625,8 +639,8 @@ void show_log(struct rev_info *opt)
printf(" (from %s)",
find_unique_abbrev(parent->object.sha1,
abbrev_commit));
+ fputs(diff_get_color_opt(&opt->diffopt, DIFF_RESET), stdout);
show_decorations(opt, commit);
- printf("%s", diff_get_color_opt(&opt->diffopt, DIFF_RESET));
if (opt->commit_format == CMIT_FMT_ONELINE) {
putchar(' ');
} else {
diff --git a/log-tree.h b/log-tree.h
index 9140f48..e6a2da5 100644
--- a/log-tree.h
+++ b/log-tree.h
@@ -13,6 +13,9 @@ int log_tree_diff_flush(struct rev_info *);
int log_tree_commit(struct rev_info *, struct commit *);
int log_tree_opt_parse(struct rev_info *, const char **, int);
void show_log(struct rev_info *opt);
+void format_decoration(struct strbuf *sb,
+ const struct commit *commit,
+ int use_color);
void show_decorations(struct rev_info *opt, struct commit *commit);
void log_write_email_headers(struct rev_info *opt, struct commit *commit,
const char **subject_p,
diff --git a/pretty.c b/pretty.c
index eae57ad..79784be 100644
--- a/pretty.c
+++ b/pretty.c
@@ -898,23 +898,6 @@ static void parse_commit_message(struct format_commit_context *c)
c->commit_message_parsed = 1;
}
-static void format_decoration(struct strbuf *sb, const struct commit *commit)
-{
- struct name_decoration *d;
- const char *prefix = " (";
-
- load_ref_decorations(DECORATE_SHORT_REFS);
- d = lookup_decoration(&name_decoration, &commit->object);
- while (d) {
- strbuf_addstr(sb, prefix);
- prefix = ", ";
- strbuf_addstr(sb, d->name);
- d = d->next;
- }
- if (prefix[0] == ',')
- strbuf_addch(sb, ')');
-}
-
static void strbuf_wrap(struct strbuf *sb, size_t pos,
size_t width, size_t indent1, size_t indent2)
{
@@ -1146,7 +1129,7 @@ static size_t format_commit_one(struct strbuf *sb, const char *placeholder,
strbuf_addstr(sb, get_revision_mark(NULL, commit));
return 1;
case 'd':
- format_decoration(sb, commit);
+ format_decoration(sb, commit, 0);
return 1;
case 'g': /* reflog info */
switch(placeholder[1]) {
diff --git a/t/t4207-log-decoration-colors.sh b/t/t4207-log-decoration-colors.sh
index bbde31b..925f577 100755
--- a/t/t4207-log-decoration-colors.sh
+++ b/t/t4207-log-decoration-colors.sh
@@ -44,15 +44,15 @@ test_expect_success setup '
'
cat >expected <<EOF
-${c_commit}COMMIT_ID (${c_HEAD}HEAD${c_reset}${c_commit},\
+${c_commit}COMMIT_ID${c_reset}${c_commit} (${c_HEAD}HEAD${c_reset}${c_commit},\
${c_tag}tag: v1.0${c_reset}${c_commit},\
${c_tag}tag: B${c_reset}${c_commit},\
${c_branch}master${c_reset}${c_commit})${c_reset} B
-${c_commit}COMMIT_ID (${c_tag}tag: A1${c_reset}${c_commit},\
+${c_commit}COMMIT_ID${c_reset}${c_commit} (${c_tag}tag: A1${c_reset}${c_commit},\
${c_remoteBranch}other/master${c_reset}${c_commit})${c_reset} A1
-${c_commit}COMMIT_ID (${c_stash}refs/stash${c_reset}${c_commit})${c_reset}\
+${c_commit}COMMIT_ID${c_reset}${c_commit} (${c_stash}refs/stash${c_reset}${c_commit})${c_reset}\
On master: Changes to A.t
-${c_commit}COMMIT_ID (${c_tag}tag: A${c_reset}${c_commit})${c_reset} A
+${c_commit}COMMIT_ID${c_reset}${c_commit} (${c_tag}tag: A${c_reset}${c_commit})${c_reset} A
EOF
# We want log to show all, but the second parent to refs/stash is irrelevant
--
1.8.2.83.gc99314b
^ permalink raw reply related
* [PATCH 01/12] pretty-formats.txt: wrap long lines
From: Nguyễn Thái Ngọc Duy @ 2013-03-16 2:24 UTC (permalink / raw)
To: git; +Cc: Junio C Hamano, Nguyễn Thái Ngọc Duy
In-Reply-To: <1363400683-14813-1-git-send-email-pclouds@gmail.com>
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
Documentation/pretty-formats.txt | 18 ++++++++++++------
1 file changed, 12 insertions(+), 6 deletions(-)
diff --git a/Documentation/pretty-formats.txt b/Documentation/pretty-formats.txt
index 105f18a..66345d1 100644
--- a/Documentation/pretty-formats.txt
+++ b/Documentation/pretty-formats.txt
@@ -106,18 +106,22 @@ The placeholders are:
- '%P': parent hashes
- '%p': abbreviated parent hashes
- '%an': author name
-- '%aN': author name (respecting .mailmap, see linkgit:git-shortlog[1] or linkgit:git-blame[1])
+- '%aN': author name (respecting .mailmap, see linkgit:git-shortlog[1]
+ or linkgit:git-blame[1])
- '%ae': author email
-- '%aE': author email (respecting .mailmap, see linkgit:git-shortlog[1] or linkgit:git-blame[1])
+- '%aE': author email (respecting .mailmap, see
+ linkgit:git-shortlog[1] or linkgit:git-blame[1])
- '%ad': author date (format respects --date= option)
- '%aD': author date, RFC2822 style
- '%ar': author date, relative
- '%at': author date, UNIX timestamp
- '%ai': author date, ISO 8601 format
- '%cn': committer name
-- '%cN': committer name (respecting .mailmap, see linkgit:git-shortlog[1] or linkgit:git-blame[1])
+- '%cN': committer name (respecting .mailmap, see
+ linkgit:git-shortlog[1] or linkgit:git-blame[1])
- '%ce': committer email
-- '%cE': committer email (respecting .mailmap, see linkgit:git-shortlog[1] or linkgit:git-blame[1])
+- '%cE': committer email (respecting .mailmap, see
+ linkgit:git-shortlog[1] or linkgit:git-blame[1])
- '%cd': committer date
- '%cD': committer date, RFC2822 style
- '%cr': committer date, relative
@@ -136,9 +140,11 @@ The placeholders are:
- '%gD': reflog selector, e.g., `refs/stash@{1}`
- '%gd': shortened reflog selector, e.g., `stash@{1}`
- '%gn': reflog identity name
-- '%gN': reflog identity name (respecting .mailmap, see linkgit:git-shortlog[1] or linkgit:git-blame[1])
+- '%gN': reflog identity name (respecting .mailmap, see
+ linkgit:git-shortlog[1] or linkgit:git-blame[1])
- '%ge': reflog identity email
-- '%gE': reflog identity email (respecting .mailmap, see linkgit:git-shortlog[1] or linkgit:git-blame[1])
+- '%gE': reflog identity email (respecting .mailmap, see
+ linkgit:git-shortlog[1] or linkgit:git-blame[1])
- '%gs': reflog subject
- '%Cred': switch color to red
- '%Cgreen': switch color to green
--
1.8.2.83.gc99314b
^ permalink raw reply related
* [PATCH v3+ 1/5] wt-status: move strbuf into read_and_strip_branch()
From: Nguyễn Thái Ngọc Duy @ 2013-03-16 2:12 UTC (permalink / raw)
To: git
Cc: Junio C Hamano, Matthieu Moy, Jonathan Niedier,
Nguyễn Thái Ngọc Duy
In-Reply-To: <1363174973-17597-2-git-send-email-pclouds@gmail.com>
The strbufs are placed outside read_and_strip_branch as a premature
optimization: when it reads "refs/heads/foo" to strbuf and wants to
return just "foo", it could do so without memory movement. In return
the caller must not use the returned pointer after releasing strbufs,
which own the buffers that contain the returned strings. It's a clumsy
design.
By moving strbufs into read_and_strip_branch(), the returned pointer
always points to a malloc'd buffer or NULL. The pointer can be passed
around and freed after use.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
Fixed the commit message. No code change.
wt-status.c | 65 ++++++++++++++++++++++++++++---------------------------------
wt-status.h | 4 ++--
2 files changed, 32 insertions(+), 37 deletions(-)
diff --git a/wt-status.c b/wt-status.c
index ef405d0..6cac27b 100644
--- a/wt-status.c
+++ b/wt-status.c
@@ -969,41 +969,41 @@ static void show_bisect_in_progress(struct wt_status *s,
/*
* Extract branch information from rebase/bisect
*/
-static void read_and_strip_branch(struct strbuf *sb,
- const char **branch,
- const char *path)
+static char *read_and_strip_branch(const char *path)
{
+ struct strbuf sb = STRBUF_INIT;
unsigned char sha1[20];
- strbuf_reset(sb);
- if (strbuf_read_file(sb, git_path("%s", path), 0) <= 0)
- return;
+ if (strbuf_read_file(&sb, git_path("%s", path), 0) <= 0)
+ goto got_nothing;
- while (sb->len && sb->buf[sb->len - 1] == '\n')
- strbuf_setlen(sb, sb->len - 1);
- if (!sb->len)
- return;
- if (!prefixcmp(sb->buf, "refs/heads/"))
- *branch = sb->buf + strlen("refs/heads/");
- else if (!prefixcmp(sb->buf, "refs/"))
- *branch = sb->buf;
- else if (!get_sha1_hex(sb->buf, sha1)) {
+ while (&sb.len && sb.buf[sb.len - 1] == '\n')
+ strbuf_setlen(&sb, sb.len - 1);
+ if (!sb.len)
+ goto got_nothing;
+ if (!prefixcmp(sb.buf, "refs/heads/"))
+ strbuf_remove(&sb,0, strlen("refs/heads/"));
+ else if (!prefixcmp(sb.buf, "refs/"))
+ ;
+ else if (!get_sha1_hex(sb.buf, sha1)) {
const char *abbrev;
abbrev = find_unique_abbrev(sha1, DEFAULT_ABBREV);
- strbuf_reset(sb);
- strbuf_addstr(sb, abbrev);
- *branch = sb->buf;
- } else if (!strcmp(sb->buf, "detached HEAD")) /* rebase */
- ;
+ strbuf_reset(&sb);
+ strbuf_addstr(&sb, abbrev);
+ } else if (!strcmp(sb.buf, "detached HEAD")) /* rebase */
+ goto got_nothing;
else /* bisect */
- *branch = sb->buf;
+ ;
+ return strbuf_detach(&sb, NULL);
+
+got_nothing:
+ strbuf_release(&sb);
+ return NULL;
}
static void wt_status_print_state(struct wt_status *s)
{
const char *state_color = color(WT_STATUS_HEADER, s);
- struct strbuf branch = STRBUF_INIT;
- struct strbuf onto = STRBUF_INIT;
struct wt_status_state state;
struct stat st;
@@ -1018,27 +1018,22 @@ static void wt_status_print_state(struct wt_status *s)
state.am_empty_patch = 1;
} else {
state.rebase_in_progress = 1;
- read_and_strip_branch(&branch, &state.branch,
- "rebase-apply/head-name");
- read_and_strip_branch(&onto, &state.onto,
- "rebase-apply/onto");
+ state.branch = read_and_strip_branch("rebase-apply/head-name");
+ state.onto = read_and_strip_branch("rebase-apply/onto");
}
} else if (!stat(git_path("rebase-merge"), &st)) {
if (!stat(git_path("rebase-merge/interactive"), &st))
state.rebase_interactive_in_progress = 1;
else
state.rebase_in_progress = 1;
- read_and_strip_branch(&branch, &state.branch,
- "rebase-merge/head-name");
- read_and_strip_branch(&onto, &state.onto,
- "rebase-merge/onto");
+ state.branch = read_and_strip_branch("rebase-merge/head-name");
+ state.onto = read_and_strip_branch("rebase-merge/onto");
} else if (!stat(git_path("CHERRY_PICK_HEAD"), &st)) {
state.cherry_pick_in_progress = 1;
}
if (!stat(git_path("BISECT_LOG"), &st)) {
state.bisect_in_progress = 1;
- read_and_strip_branch(&branch, &state.branch,
- "BISECT_START");
+ state.branch = read_and_strip_branch("BISECT_START");
}
if (state.merge_in_progress)
@@ -1051,8 +1046,8 @@ static void wt_status_print_state(struct wt_status *s)
show_cherry_pick_in_progress(s, &state, state_color);
if (state.bisect_in_progress)
show_bisect_in_progress(s, &state, state_color);
- strbuf_release(&branch);
- strbuf_release(&onto);
+ free(state.branch);
+ free(state.onto);
}
void wt_status_print(struct wt_status *s)
diff --git a/wt-status.h b/wt-status.h
index 81e1dcf..b8c3512 100644
--- a/wt-status.h
+++ b/wt-status.h
@@ -79,8 +79,8 @@ struct wt_status_state {
int rebase_interactive_in_progress;
int cherry_pick_in_progress;
int bisect_in_progress;
- const char *branch;
- const char *onto;
+ char *branch;
+ char *onto;
};
void wt_status_prepare(struct wt_status *s);
--
1.8.2.83.gc99314b
^ permalink raw reply related
* Re: [PATCH] status: hint the user about -uno if read_directory takes too long
From: Duy Nguyen @ 2013-03-16 1:51 UTC (permalink / raw)
To: Junio C Hamano, tboegi; +Cc: git, artagnon, robert.allan.zeh, finnag
In-Reply-To: <CACsJy8BixM-9bPB3G_WO+W3cTHBFxLQ=YCU2NDEzHmCYW73ZPQ@mail.gmail.com>
On Thu, Mar 14, 2013 at 5:22 PM, Duy Nguyen <pclouds@gmail.com> wrote:
> On Wed, Mar 13, 2013 at 11:16 PM, Junio C Hamano <gitster@pobox.com> wrote:
>> The noise this introduces to the test suite is a bit irritating and
>> makes us think twice if this really a good change.
>
> I originally thought of two options, this or add an env flag in git
> binary that turns this off in the test suite. The latter did not sound
> good. But I forgot that we set a fake $HOME in the test suite, we
> could disable this in $HOME/.gitconfig, less clutter in individual
> tests.
fwiw, adding to $HOME/.gitconfig by default in test-libs.sh does not
work. Else where we check "git config --list" and the new global
config key will fail them.
--
Duy
^ permalink raw reply
* Re: git svn error "Not a valid object name"
From: Eric Wong @ 2013-03-16 1:45 UTC (permalink / raw)
To: Adam Retter; +Cc: git, Dannes Wessels, Wolfgang Meier, Leif-Jöran Olsson
In-Reply-To: <CAJKLP9ZQBXf5ZZY9FccOAL5QU+q1b5SnAfvP9BpARdqvzPuWeg@mail.gmail.com>
Adam Retter <adam@exist-db.org> wrote:
> Our public SourceForge Subversion repository is here:
> http://svn.code.sf.net/p/exist/code/trunk/eXist
It's asking me for a username/password...
> We cloned that to the local server using rsync and are attempting to
> migrate to git using the following commands:
>
> $ git svn init -t tags -b stable -T trunk
> file:///home/ec2-user/svn-rsync/code new-git-repo
> $ cd new-git-repo
> $ git config svn-remote.svn.preserve-empty-dirs true
> $ git config svn-remote.svn.rewriteRoot https://svn.code.sf.net/p/exist/code
> $ git svn fetch -A /home/ec2-user/.svn2git/authors.txt
>
> It all started well and was running away for quite some hours, when
> the following error occurred:
>
> fatal: Not a valid object name
> ls-tree -z ./webapp/api/: command returned error: 128
>
> I have no idea what this means, or how to fix this.
> We are using Git version 1.8.1.GIT on Amazon EC2 Linux.
>
> Any suggestions please?
You might've hit a bug in branch detection, but I'd have to look at the
repo to be certain and fix it if neded.
--no-follow-parent should work, but you'd lose branch/tag history.
^ permalink raw reply
* [PATCH] index-pack: fix buffer overflow caused by translations
From: Nguyễn Thái Ngọc Duy @ 2013-03-16 1:25 UTC (permalink / raw)
To: git; +Cc: Junio C Hamano, Nguyễn Thái Ngọc Duy
The translation of "completed with %d local objects" is put in a
48-byte buffer, which may be enough for English but not true for any
translations. Convert it to use strbuf (i.e. no hard limit on
translation length).
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
My bad, I should have checked this when I marked this string for
translation. At least recent Vietnamese translation triggers this.
builtin/index-pack.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/builtin/index-pack.c b/builtin/index-pack.c
index 43d364b..ef62124 100644
--- a/builtin/index-pack.c
+++ b/builtin/index-pack.c
@@ -1099,7 +1099,7 @@ static void conclude_pack(int fix_thin_pack, const char *curr_pack, unsigned cha
if (fix_thin_pack) {
struct sha1file *f;
unsigned char read_sha1[20], tail_sha1[20];
- char msg[48];
+ struct strbuf msg = STRBUF_INIT;
int nr_unresolved = nr_deltas - nr_resolved_deltas;
int nr_objects_initial = nr_objects;
if (nr_unresolved <= 0)
@@ -1109,9 +1109,10 @@ static void conclude_pack(int fix_thin_pack, const char *curr_pack, unsigned cha
* sizeof(*objects));
f = sha1fd(output_fd, curr_pack);
fix_unresolved_deltas(f, nr_unresolved);
- sprintf(msg, _("completed with %d local objects"),
- nr_objects - nr_objects_initial);
- stop_progress_msg(&progress, msg);
+ strbuf_addf(&msg, _("completed with %d local objects"),
+ nr_objects - nr_objects_initial);
+ stop_progress_msg(&progress, msg.buf);
+ strbuf_release(&msg);
sha1close(f, tail_sha1, 0);
hashcpy(read_sha1, pack_sha1);
fixup_pack_header_footer(output_fd, pack_sha1,
--
1.8.2.82.gc24b958.dirty
^ permalink raw reply related
* Re: [PATCH v1 22/45] archive: convert to use parse_pathspec
From: Duy Nguyen @ 2013-03-16 1:08 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <7vfvzwv96b.fsf@alter.siamese.dyndns.org>
On Sat, Mar 16, 2013 at 12:56 AM, Junio C Hamano <gitster@pobox.com> wrote:
> Nguyễn Thái Ngọc Duy <pclouds@gmail.com> writes:
>
>> @@ -232,11 +228,18 @@ static int path_exists(struct tree *tree, const char *path)
>> static void parse_pathspec_arg(const char **pathspec,
>> struct archiver_args *ar_args)
>> {
>> - ar_args->pathspec = pathspec = get_pathspec("", pathspec);
>> + /*
>> + * must be consistent with parse_pathspec in path_exists()
>> + * Also if pathspec patterns are dependent, we're in big
>> + * trouble as we test each one separately
>> + */
>> + parse_pathspec(&ar_args->pathspec, 0,
>> + PATHSPEC_PREFER_FULL,
>> + "", pathspec);
>> if (pathspec) {
>> while (*pathspec) {
>> if (!path_exists(ar_args->tree, *pathspec))
>> - die("path not found: %s", *pathspec);
>> + die(_("pathspec '%s' did not match any files"), *pathspec);
>> pathspec++;
>> }
>
> You do not use ar_args->pathspec even though you used parse_pathspec()
> to grok it? What's the point of this change?
parse_pathspec() here is needed because write_archive_entries needs it
later. tree_entry_interesting() has not supported "seen" feature like
match_pathspec_depth() to detect unused pathspecs. For simplicity,
just check each pathspec individually. We can revisit this when we add
"seen" feature to tree_entry_interesting.
--
Duy
^ permalink raw reply
* regression in multi-threaded git-pack-index
From: Stefan Zager @ 2013-03-15 22:42 UTC (permalink / raw)
To: git
We have uncovered a regression in this commit:
b8a2486f1524947f232f657e9f2ebf44e3e7a243
The symptom is that 'git fetch' dies with:
error: index-pack died of signal 10
fatal: index-pack failed
I have only been able to reproduce it on a Mac thus far; will try ubuntu next. We can make it go away by running:
git config pack.threads 1
To reproduce it, download this working copy:
http://commondatastorage.googleapis.com/chromium-browser-snapshots/tmp/src.git.tar.gz
Then:
tar xvfz src.git.tar.gz
cd src.git
git fetch origin refs/heads/lkgr
(That is the shortest reproduction I could come up with; sorry).
Thanks,
Stefan
^ permalink raw reply
* [PATCH] archive-zip: use deflateInit2() to ask for raw compressed data
From: René Scharfe @ 2013-03-15 22:21 UTC (permalink / raw)
To: git discussion list; +Cc: Junio C Hamano
We use the function git_deflate_init() -- which wraps the zlib function
deflateInit() -- to initialize compression of ZIP file entries. This
results in compressed data prefixed with a two-bytes long header and
followed by a four-bytes trailer. ZIP file entries consist of ZIP
headers and raw compressed data instead, so we remove the zlib wrapper
before writing the result.
We can ask zlib for the the raw compressed data without the unwanted
parts in the first place by using deflateInit2() and specifying a
negative number of bits to size the window. For that purpose, factor
out the function do_git_deflate_init() and add git_deflate_init_raw(),
which wraps it. Then use the latter in archive-zip.c and get rid of
the code that stripped the zlib header and trailer.
Also rename the helper function zlib_deflate() to zlib_deflate_raw()
to reflect the change.
Thus we avoid generating data that we throw away anyway, the code
becomes shorter and some magic constants are removed.
Signed-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx>
---
archive-zip.c | 36 ++++++++++++++----------------------
cache.h | 1 +
zlib.c | 25 +++++++++++++++++++------
3 files changed, 34 insertions(+), 28 deletions(-)
diff --git a/archive-zip.c b/archive-zip.c
index d3aef53..e744d77 100644
--- a/archive-zip.c
+++ b/archive-zip.c
@@ -111,8 +111,9 @@ static void copy_le32(unsigned char *dest, unsigned int n)
dest[3] = 0xff & (n >> 030);
}
-static void *zlib_deflate(void *data, unsigned long size,
- int compression_level, unsigned long *compressed_size)
+static void *zlib_deflate_raw(void *data, unsigned long size,
+ int compression_level,
+ unsigned long *compressed_size)
{
git_zstream stream;
unsigned long maxsize;
@@ -120,7 +121,7 @@ static void *zlib_deflate(void *data, unsigned long size,
int result;
memset(&stream, 0, sizeof(stream));
- git_deflate_init(&stream, compression_level);
+ git_deflate_init_raw(&stream, compression_level);
maxsize = git_deflate_bound(&stream, size);
buffer = xmalloc(maxsize);
@@ -265,14 +266,11 @@ static int write_zip_entry(struct archiver_args *args,
}
if (buffer && method == 8) {
- deflated = zlib_deflate(buffer, size, args->compression_level,
- &compressed_size);
- if (deflated && compressed_size - 6 < size) {
- /* ZLIB --> raw compressed data (see RFC 1950) */
- /* CMF and FLG ... */
- out = (unsigned char *)deflated + 2;
- compressed_size -= 6; /* ... and ADLER32 */
- } else {
+ out = deflated = zlib_deflate_raw(buffer, size,
+ args->compression_level,
+ &compressed_size);
+ if (!out || compressed_size >= size) {
+ out = buffer;
method = 0;
compressed_size = size;
}
@@ -353,7 +351,7 @@ static int write_zip_entry(struct archiver_args *args,
unsigned char compressed[STREAM_BUFFER_SIZE * 2];
memset(&zstream, 0, sizeof(zstream));
- git_deflate_init(&zstream, args->compression_level);
+ git_deflate_init_raw(&zstream, args->compression_level);
compressed_size = 0;
zstream.next_out = compressed;
@@ -370,13 +368,10 @@ static int write_zip_entry(struct archiver_args *args,
result = git_deflate(&zstream, 0);
if (result != Z_OK)
die("deflate error (%d)", result);
- out = compressed;
- if (!compressed_size)
- out += 2;
- out_len = zstream.next_out - out;
+ out_len = zstream.next_out - compressed;
if (out_len > 0) {
- write_or_die(1, out, out_len);
+ write_or_die(1, compressed, out_len);
compressed_size += out_len;
zstream.next_out = compressed;
zstream.avail_out = sizeof(compressed);
@@ -394,11 +389,8 @@ static int write_zip_entry(struct archiver_args *args,
die("deflate error (%d)", result);
git_deflate_end(&zstream);
- out = compressed;
- if (!compressed_size)
- out += 2;
- out_len = zstream.next_out - out - 4;
- write_or_die(1, out, out_len);
+ out_len = zstream.next_out - compressed;
+ write_or_die(1, compressed, out_len);
compressed_size += out_len;
zip_offset += compressed_size;
diff --git a/cache.h b/cache.h
index e493563..81a39a2 100644
--- a/cache.h
+++ b/cache.h
@@ -34,6 +34,7 @@ int git_inflate(git_zstream *, int flush);
void git_deflate_init(git_zstream *, int level);
void git_deflate_init_gzip(git_zstream *, int level);
+void git_deflate_init_raw(git_zstream *, int level);
void git_deflate_end(git_zstream *);
int git_deflate_abort(git_zstream *);
int git_deflate_end_gently(git_zstream *);
diff --git a/zlib.c b/zlib.c
index 2b2c0c7..bbaa081 100644
--- a/zlib.c
+++ b/zlib.c
@@ -168,13 +168,8 @@ void git_deflate_init(git_zstream *strm, int level)
strm->z.msg ? strm->z.msg : "no message");
}
-void git_deflate_init_gzip(git_zstream *strm, int level)
+static void do_git_deflate_init(git_zstream *strm, int level, int windowBits)
{
- /*
- * Use default 15 bits, +16 is to generate gzip header/trailer
- * instead of the zlib wrapper.
- */
- const int windowBits = 15 + 16;
int status;
zlib_pre_call(strm);
@@ -188,6 +183,24 @@ void git_deflate_init_gzip(git_zstream *strm, int level)
strm->z.msg ? strm->z.msg : "no message");
}
+void git_deflate_init_gzip(git_zstream *strm, int level)
+{
+ /*
+ * Use default 15 bits, +16 is to generate gzip header/trailer
+ * instead of the zlib wrapper.
+ */
+ return do_git_deflate_init(strm, level, 15 + 16);
+}
+
+void git_deflate_init_raw(git_zstream *strm, int level)
+{
+ /*
+ * Use default 15 bits, negate the value to get raw compressed
+ * data without zlib header and trailer.
+ */
+ return do_git_deflate_init(strm, level, -15);
+}
+
int git_deflate_abort(git_zstream *strm)
{
int status;
--
1.8.2
^ permalink raw reply related
* Re: [PATCH v1 44/45] pathspec: support :(glob) syntax
From: Eric Sunshine @ 2013-03-15 22:11 UTC (permalink / raw)
To: Nguyễn Thái Ngọc Duy; +Cc: git, Junio C Hamano
In-Reply-To: <1363327620-29017-45-git-send-email-pclouds@gmail.com>
On Fri, Mar 15, 2013 at 2:06 AM, Nguyễn Thái Ngọc Duy <pclouds@gmail.com> wrote:
> +GIT_GLOB_PATHSPECS::
> + Setting this variable to `1` will cause git to treat all
> + pathspecs as glob patterns (aka "glob" magic).
Per recent git -> Git normalization, probably: s/git/Git/
> +
> +GIT_NOGLOB_PATHSPECS::
> + Setting this variable to `1` will cause git to treat all
> + pathspecs as literal (aka "literal" magic).
Ditto: s/git/Git/
> @@ -103,6 +105,22 @@ static unsigned prefix_pathspec(struct pathspec_item *item,
> if (literal_global)
> global_magic |= PATHSPEC_LITERAL;
>
> + if (glob_global < 0)
> + glob_global = git_env_bool(GIT_GLOB_PATHSPECS_ENVIRONMENT, 0);
> + if (glob_global)
> + global_magic |= PATHSPEC_GLOB;
> +
> + if (noglob_global < 0)
> + noglob_global = git_env_bool(GIT_NOGLOB_PATHSPECS_ENVIRONMENT, 0);
> +
> + if (glob_global && noglob_global)
> + die(_("global 'glob' and 'noglob' pathspec settings are incompatible"));
> +
> + if ((global_magic & PATHSPEC_LITERAL) &&
> + (global_magic & ~PATHSPEC_LITERAL))
> + die(_("global 'literal' pathspec setting is incompatiable "
> + "with all other global pathspec settings"));
s/incompatiable/incompatible/
-- ES
^ permalink raw reply
* Re: [PATCH v1 40/45] parse_pathspec: preserve prefix length via PATHSPEC_PREFIX_ORIGIN
From: Eric Sunshine @ 2013-03-15 22:00 UTC (permalink / raw)
To: Nguyễn Thái Ngọc Duy; +Cc: git, Junio C Hamano
In-Reply-To: <1363327620-29017-41-git-send-email-pclouds@gmail.com>
On Fri, Mar 15, 2013 at 2:06 AM, Nguyễn Thái Ngọc Duy <pclouds@gmail.com> wrote:
> Prefix length is not preserved across commands when --literal-pathspecs
> is specified (no magic is allowed, including 'prefix'). That's OK
> because we all paths are literal. No magic, no special treatment
s/we all/we know all/
...or...
s/we all/all/
> We could also preserve 'prefix' across commands is quote the prefix
> part, then dequote on receiving. But it may not be 100% accurate, we
s/is quote/by quoting/
s/dequote/dequoting/
> may dequote longer than the original prefix part, for example. That
> may be good or not, but it's not the purpose.
^ permalink raw reply
* Re: [PATCH] status: hint the user about -uno if read_directory takes too long
From: Junio C Hamano @ 2013-03-15 21:59 UTC (permalink / raw)
To: Torsten Bögershausen
Cc: Duy Nguyen, git, artagnon, robert.allan.zeh, finnag
In-Reply-To: <51438F33.3080607@web.de>
Torsten Bögershausen <tboegi@web.de> writes:
> Thanks, that looks good to me:
>
> # It took 2.58 seconds to enumerate untracked files.
> # Consider the -u option for a possible speed-up?
>
> But:
> If I follow the advice as is given and use "git status -u", the result is the same.
Yeah, that was taken from
http://thread.gmane.org/gmane.comp.version-control.git/215820/focus=218125
to which I said something about "more levels of indirections". This
episode shows that even a user who was very well aware of the issue
did not follow a single level of indirection.
> If I think loud, would it be better to say:
>
> # It took 2.58 seconds to search for untracked files.
> # Consider the -uno option for a possible speed-up?
>
> or
>
> # It took 2.58 seconds to search for untracked files.
> # Consider the -u option for a possible speed-up?
> # Please see git help status
The former actively hurts the users, but the latter would be good,
given that your documentation updates clarifies the trade off.
Or we can be more explicit and say
# It took 2.58 seconds to search for untracked files. 'status -uno'
# may speed it up, but you have to be careful not to forget to add
# new files yourself (see 'git help status').
or something.
^ permalink raw reply
* Re: [PATCH v1 10/45] parse_pathspec: a special flag for max_depth feature
From: Eric Sunshine @ 2013-03-15 21:28 UTC (permalink / raw)
To: Nguyễn Thái Ngọc Duy; +Cc: git, Junio C Hamano
In-Reply-To: <1363327620-29017-11-git-send-email-pclouds@gmail.com>
On Fri, Mar 15, 2013 at 2:06 AM, Nguyễn Thái Ngọc Duy <pclouds@gmail.com> wrote:
> match_pathspec_depth() and tree_entry_interesting() check max_depth
> field in order to support "git grep --max-depth". The feature
> activation is tied to "recursive" field, which led to some unwated
s/unwated/unwanted/
> activation, e.g. 5c8eeb8 (diff-index: enable recursive pathspec
> matching in unpack_trees - 2012-01-15).
^ permalink raw reply
* Re: [PATCH] status: hint the user about -uno if read_directory takes too long
From: Torsten Bögershausen @ 2013-03-15 21:14 UTC (permalink / raw)
To: Junio C Hamano
Cc: Torsten Bögershausen, Duy Nguyen, git, artagnon,
robert.allan.zeh, finnag
In-Reply-To: <7v4ngcv35l.fsf@alter.siamese.dyndns.org>
On 15.03.13 21:06, Junio C Hamano wrote:
> Torsten Bögershausen <tboegi@web.de> writes:
>
>> > Thanks, I like that much better than mine
>> > (and expere is probably a word not yet invented)
> OK, then how about redoing Duy's patch like this on top?
>
> I've moved the timing collection from the caller to callee, and I
> think the result is more readable. The message looked easier to see
> with a leading blank line, so I added one.
>
> -- >8 --
> From: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
> Date: Wed, 13 Mar 2013 19:59:16 +0700
> Subject: [PATCH] status: advise to consider use of -u when read_directory takes too long
>
> Introduce advice.statusUoption to suggest considering use of -u to
> strike different trade-off when it took more than 2 seconds to
> enumerate untracked/ignored files.
>
> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
> Signed-off-by: Junio C Hamano <gitster@pobox.com>
> ---
> Documentation/config.txt | 4 ++++
> advice.c | 2 ++
> advice.h | 1 +
> t/t7060-wtstatus.sh | 1 +
> t/t7508-status.sh | 1 +
> t/t7512-status-help.sh | 1 +
> wt-status.c | 21 +++++++++++++++++++++
> wt-status.h | 1 +
> 8 files changed, 32 insertions(+)
>
> diff --git a/Documentation/config.txt b/Documentation/config.txt
> index d1de857..a16eda5 100644
> --- a/Documentation/config.txt
> +++ b/Documentation/config.txt
> @@ -163,6 +163,10 @@ advice.*::
> state in the output of linkgit:git-status[1] and in
> the template shown when writing commit messages in
> linkgit:git-commit[1].
> + statusUoption::
> + Advise to consider using the `-u` option to linkgit:git-status[1]
> + when the command takes more than 2 seconds to enumerate untracked
> + files.
> commitBeforeMerge::
> Advice shown when linkgit:git-merge[1] refuses to
> merge to avoid overwriting local changes.
> diff --git a/advice.c b/advice.c
> index edfbd4a..015011f 100644
> --- a/advice.c
> +++ b/advice.c
> @@ -5,6 +5,7 @@ int advice_push_non_ff_current = 1;
> int advice_push_non_ff_default = 1;
> int advice_push_non_ff_matching = 1;
> int advice_status_hints = 1;
> +int advice_status_u_option = 1;
> int advice_commit_before_merge = 1;
> int advice_resolve_conflict = 1;
> int advice_implicit_identity = 1;
> @@ -19,6 +20,7 @@ static struct {
> { "pushnonffdefault", &advice_push_non_ff_default },
> { "pushnonffmatching", &advice_push_non_ff_matching },
> { "statushints", &advice_status_hints },
> + { "statusuoption", &advice_status_u_option },
> { "commitbeforemerge", &advice_commit_before_merge },
> { "resolveconflict", &advice_resolve_conflict },
> { "implicitidentity", &advice_implicit_identity },
> diff --git a/advice.h b/advice.h
> index f3cdbbf..e3e665d 100644
> --- a/advice.h
> +++ b/advice.h
> @@ -8,6 +8,7 @@ extern int advice_push_non_ff_current;
> extern int advice_push_non_ff_default;
> extern int advice_push_non_ff_matching;
> extern int advice_status_hints;
> +extern int advice_status_u_option;
> extern int advice_commit_before_merge;
> extern int advice_resolve_conflict;
> extern int advice_implicit_identity;
> diff --git a/t/t7060-wtstatus.sh b/t/t7060-wtstatus.sh
> index f4f38a5..52ef06b 100755
> --- a/t/t7060-wtstatus.sh
> +++ b/t/t7060-wtstatus.sh
> @@ -5,6 +5,7 @@ test_description='basic work tree status reporting'
> . ./test-lib.sh
>
> test_expect_success setup '
> + git config --global advice.statusuoption false &&
> test_commit A &&
> test_commit B oneside added &&
> git checkout A^0 &&
> diff --git a/t/t7508-status.sh b/t/t7508-status.sh
> index e313ef1..15e063a 100755
> --- a/t/t7508-status.sh
> +++ b/t/t7508-status.sh
> @@ -8,6 +8,7 @@ test_description='git status'
> . ./test-lib.sh
>
> test_expect_success 'status -h in broken repository' '
> + git config --global advice.statusuoption false &&
> mkdir broken &&
> test_when_finished "rm -fr broken" &&
> (
> diff --git a/t/t7512-status-help.sh b/t/t7512-status-help.sh
> index b3f6eb9..2d53e03 100755
> --- a/t/t7512-status-help.sh
> +++ b/t/t7512-status-help.sh
> @@ -14,6 +14,7 @@ test_description='git status advices'
> set_fake_editor
>
> test_expect_success 'prepare for conflicts' '
> + git config --global advice.statusuoption false &&
> test_commit init main.txt init &&
> git branch conflicts &&
> test_commit on_master main.txt on_master &&
> diff --git a/wt-status.c b/wt-status.c
> index 2a9658b..6e75468 100644
> --- a/wt-status.c
> +++ b/wt-status.c
> @@ -496,9 +496,14 @@ static void wt_status_collect_untracked(struct wt_status *s)
> {
> int i;
> struct dir_struct dir;
> + struct timeval t_begin;
>
> if (!s->show_untracked_files)
> return;
> +
> + if (advice_status_u_option)
> + gettimeofday(&t_begin, NULL);
> +
> memset(&dir, 0, sizeof(dir));
> if (s->show_untracked_files != SHOW_ALL_UNTRACKED_FILES)
> dir.flags |=
> @@ -528,6 +533,14 @@ static void wt_status_collect_untracked(struct wt_status *s)
> }
>
> free(dir.entries);
> +
> + if (advice_status_u_option) {
> + struct timeval t_end;
> + gettimeofday(&t_end, NULL);
> + s->untracked_in_ms =
> + (uint64_t)t_end.tv_sec * 1000 + t_end.tv_usec / 1000 -
> + ((uint64_t)t_begin.tv_sec * 1000 + t_begin.tv_usec / 1000);
> + }
> }
>
> void wt_status_collect(struct wt_status *s)
> @@ -1011,6 +1024,14 @@ void wt_status_print(struct wt_status *s)
> wt_status_print_other(s, &s->untracked, _("Untracked files"), "add");
> if (s->show_ignored_files)
> wt_status_print_other(s, &s->ignored, _("Ignored files"), "add -f");
> + if (advice_status_u_option && 2000 < s->untracked_in_ms) {
> + status_printf_ln(s, GIT_COLOR_NORMAL, "");
> + status_printf_ln(s, GIT_COLOR_NORMAL,
> + _("It took %.2f seconds to enumerate untracked files."),
> + s->untracked_in_ms / 1000.0);
> + status_printf_ln(s, GIT_COLOR_NORMAL,
> + _("Consider the -u option for a possible speed-up?"));
> + }
> } else if (s->commitable)
> status_printf_ln(s, GIT_COLOR_NORMAL, _("Untracked files not listed%s"),
> advice_status_hints
> diff --git a/wt-status.h b/wt-status.h
> index 236b41f..09420d0 100644
> --- a/wt-status.h
> +++ b/wt-status.h
> @@ -69,6 +69,7 @@ struct wt_status {
> struct string_list change;
> struct string_list untracked;
> struct string_list ignored;
> + uint32_t untracked_in_ms;
> };
>
> struct wt_status_state {
> -- 1.8.2-279-g744670c -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
>
Thanks, that looks good to me:
# It took 2.58 seconds to enumerate untracked files.
# Consider the -u option for a possible speed-up?
But:
If I follow the advice as is given and use "git status -u", the result is the same.
If I think loud, would it be better to say:
# It took 2.58 seconds to search for untracked files.
# Consider the -uno option for a possible speed-up?
or
# It took 2.58 seconds to search for untracked files.
# Consider the -u option for a possible speed-up?
# Please see git help status
/Torsten
^ permalink raw reply
* Re: SSH version on Git 1.8.1.2 for Windows is outdated.
From: Joshua Jensen @ 2013-03-15 20:11 UTC (permalink / raw)
To: Konstantin Khomoutov; +Cc: Kristof Mattei, git
In-Reply-To: <20130315210325.7b0a3505ffa4d46e7e716324@domain007.com>
----- Original Message -----
From: Konstantin Khomoutov
Date: 3/15/2013 11:03 AM
> On Fri, 15 Mar 2013 11:05:11 +0100
> Kristof Mattei <kristof@kristofmattei.be> wrote:
>
>> C:\Program Files (x86)\Git\bin>ssh -V
>> OpenSSH_6.1p1, OpenSSL 1.0.1e 11 Feb 2013
>>
>> Is there any way you can incorporate this update in the installer?
> Yes, you should grab the msysGit (the Git for Windows build
> environment) [2], tweak it to include the new OpenSSH binary, ensure it
> builds and works OK and then send a pull request (or post your patchset
> to the msysgit mailing list [3].
>
Wow, we can do that now?
When I brought up the vastly improved performance from a newer SSH
executable, I was told the only way to get it in would be to build from
source [1].
-Josh
[1]
https://groups.google.com/forum/?fromgroups=#!searchin/msysgit/ssh$20josh/msysgit/U3InWruEl88/TAFaw4xJUI0J
^ permalink raw reply
* Re: [PATCH] status: hint the user about -uno if read_directory takes too long
From: Junio C Hamano @ 2013-03-15 20:06 UTC (permalink / raw)
To: Torsten Bögershausen
Cc: Duy Nguyen, git, artagnon, robert.allan.zeh, finnag
In-Reply-To: <51435D49.6040005@web.de>
Torsten Bögershausen <tboegi@web.de> writes:
> Thanks, I like that much better than mine
> (and expere is probably a word not yet invented)
OK, then how about redoing Duy's patch like this on top?
I've moved the timing collection from the caller to callee, and I
think the result is more readable. The message looked easier to see
with a leading blank line, so I added one.
-- >8 --
From: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Date: Wed, 13 Mar 2013 19:59:16 +0700
Subject: [PATCH] status: advise to consider use of -u when read_directory takes too long
Introduce advice.statusUoption to suggest considering use of -u to
strike different trade-off when it took more than 2 seconds to
enumerate untracked/ignored files.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
Documentation/config.txt | 4 ++++
advice.c | 2 ++
advice.h | 1 +
t/t7060-wtstatus.sh | 1 +
t/t7508-status.sh | 1 +
t/t7512-status-help.sh | 1 +
wt-status.c | 21 +++++++++++++++++++++
wt-status.h | 1 +
8 files changed, 32 insertions(+)
diff --git a/Documentation/config.txt b/Documentation/config.txt
index d1de857..a16eda5 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -163,6 +163,10 @@ advice.*::
state in the output of linkgit:git-status[1] and in
the template shown when writing commit messages in
linkgit:git-commit[1].
+ statusUoption::
+ Advise to consider using the `-u` option to linkgit:git-status[1]
+ when the command takes more than 2 seconds to enumerate untracked
+ files.
commitBeforeMerge::
Advice shown when linkgit:git-merge[1] refuses to
merge to avoid overwriting local changes.
diff --git a/advice.c b/advice.c
index edfbd4a..015011f 100644
--- a/advice.c
+++ b/advice.c
@@ -5,6 +5,7 @@ int advice_push_non_ff_current = 1;
int advice_push_non_ff_default = 1;
int advice_push_non_ff_matching = 1;
int advice_status_hints = 1;
+int advice_status_u_option = 1;
int advice_commit_before_merge = 1;
int advice_resolve_conflict = 1;
int advice_implicit_identity = 1;
@@ -19,6 +20,7 @@ static struct {
{ "pushnonffdefault", &advice_push_non_ff_default },
{ "pushnonffmatching", &advice_push_non_ff_matching },
{ "statushints", &advice_status_hints },
+ { "statusuoption", &advice_status_u_option },
{ "commitbeforemerge", &advice_commit_before_merge },
{ "resolveconflict", &advice_resolve_conflict },
{ "implicitidentity", &advice_implicit_identity },
diff --git a/advice.h b/advice.h
index f3cdbbf..e3e665d 100644
--- a/advice.h
+++ b/advice.h
@@ -8,6 +8,7 @@ extern int advice_push_non_ff_current;
extern int advice_push_non_ff_default;
extern int advice_push_non_ff_matching;
extern int advice_status_hints;
+extern int advice_status_u_option;
extern int advice_commit_before_merge;
extern int advice_resolve_conflict;
extern int advice_implicit_identity;
diff --git a/t/t7060-wtstatus.sh b/t/t7060-wtstatus.sh
index f4f38a5..52ef06b 100755
--- a/t/t7060-wtstatus.sh
+++ b/t/t7060-wtstatus.sh
@@ -5,6 +5,7 @@ test_description='basic work tree status reporting'
. ./test-lib.sh
test_expect_success setup '
+ git config --global advice.statusuoption false &&
test_commit A &&
test_commit B oneside added &&
git checkout A^0 &&
diff --git a/t/t7508-status.sh b/t/t7508-status.sh
index e313ef1..15e063a 100755
--- a/t/t7508-status.sh
+++ b/t/t7508-status.sh
@@ -8,6 +8,7 @@ test_description='git status'
. ./test-lib.sh
test_expect_success 'status -h in broken repository' '
+ git config --global advice.statusuoption false &&
mkdir broken &&
test_when_finished "rm -fr broken" &&
(
diff --git a/t/t7512-status-help.sh b/t/t7512-status-help.sh
index b3f6eb9..2d53e03 100755
--- a/t/t7512-status-help.sh
+++ b/t/t7512-status-help.sh
@@ -14,6 +14,7 @@ test_description='git status advices'
set_fake_editor
test_expect_success 'prepare for conflicts' '
+ git config --global advice.statusuoption false &&
test_commit init main.txt init &&
git branch conflicts &&
test_commit on_master main.txt on_master &&
diff --git a/wt-status.c b/wt-status.c
index 2a9658b..6e75468 100644
--- a/wt-status.c
+++ b/wt-status.c
@@ -496,9 +496,14 @@ static void wt_status_collect_untracked(struct wt_status *s)
{
int i;
struct dir_struct dir;
+ struct timeval t_begin;
if (!s->show_untracked_files)
return;
+
+ if (advice_status_u_option)
+ gettimeofday(&t_begin, NULL);
+
memset(&dir, 0, sizeof(dir));
if (s->show_untracked_files != SHOW_ALL_UNTRACKED_FILES)
dir.flags |=
@@ -528,6 +533,14 @@ static void wt_status_collect_untracked(struct wt_status *s)
}
free(dir.entries);
+
+ if (advice_status_u_option) {
+ struct timeval t_end;
+ gettimeofday(&t_end, NULL);
+ s->untracked_in_ms =
+ (uint64_t)t_end.tv_sec * 1000 + t_end.tv_usec / 1000 -
+ ((uint64_t)t_begin.tv_sec * 1000 + t_begin.tv_usec / 1000);
+ }
}
void wt_status_collect(struct wt_status *s)
@@ -1011,6 +1024,14 @@ void wt_status_print(struct wt_status *s)
wt_status_print_other(s, &s->untracked, _("Untracked files"), "add");
if (s->show_ignored_files)
wt_status_print_other(s, &s->ignored, _("Ignored files"), "add -f");
+ if (advice_status_u_option && 2000 < s->untracked_in_ms) {
+ status_printf_ln(s, GIT_COLOR_NORMAL, "");
+ status_printf_ln(s, GIT_COLOR_NORMAL,
+ _("It took %.2f seconds to enumerate untracked files."),
+ s->untracked_in_ms / 1000.0);
+ status_printf_ln(s, GIT_COLOR_NORMAL,
+ _("Consider the -u option for a possible speed-up?"));
+ }
} else if (s->commitable)
status_printf_ln(s, GIT_COLOR_NORMAL, _("Untracked files not listed%s"),
advice_status_hints
diff --git a/wt-status.h b/wt-status.h
index 236b41f..09420d0 100644
--- a/wt-status.h
+++ b/wt-status.h
@@ -69,6 +69,7 @@ struct wt_status {
struct string_list change;
struct string_list untracked;
struct string_list ignored;
+ uint32_t untracked_in_ms;
};
struct wt_status_state {
--
1.8.2-279-g744670c
^ permalink raw reply related
* git branch: multiple --merged and --no-merged options?
From: Jed Brown @ 2013-03-15 19:38 UTC (permalink / raw)
To: git
I find myself frequently running commands like this
$ comm -12 <(git branch --no-merged master) <(git branch --merged next)
when checking for graduation candidates. Of course I first tried
$ git branch --no-merged master --merged next
but this is equivalent to
$ git branch --merged next
Isn't this query common enough to have a nicer interface? What do other
people use?
^ permalink raw reply
* Re: [PATCH v1 22/45] archive: convert to use parse_pathspec
From: Junio C Hamano @ 2013-03-15 17:56 UTC (permalink / raw)
To: Nguyễn Thái Ngọc Duy; +Cc: git
In-Reply-To: <1363327620-29017-23-git-send-email-pclouds@gmail.com>
Nguyễn Thái Ngọc Duy <pclouds@gmail.com> writes:
> @@ -232,11 +228,18 @@ static int path_exists(struct tree *tree, const char *path)
> static void parse_pathspec_arg(const char **pathspec,
> struct archiver_args *ar_args)
> {
> - ar_args->pathspec = pathspec = get_pathspec("", pathspec);
> + /*
> + * must be consistent with parse_pathspec in path_exists()
> + * Also if pathspec patterns are dependent, we're in big
> + * trouble as we test each one separately
> + */
> + parse_pathspec(&ar_args->pathspec, 0,
> + PATHSPEC_PREFER_FULL,
> + "", pathspec);
> if (pathspec) {
> while (*pathspec) {
> if (!path_exists(ar_args->tree, *pathspec))
> - die("path not found: %s", *pathspec);
> + die(_("pathspec '%s' did not match any files"), *pathspec);
> pathspec++;
> }
You do not use ar_args->pathspec even though you used parse_pathspec()
to grok it? What's the point of this change?
> }
> diff --git a/archive.h b/archive.h
> index 895afcd..4a791e1 100644
> --- a/archive.h
> +++ b/archive.h
> @@ -1,6 +1,8 @@
> #ifndef ARCHIVE_H
> #define ARCHIVE_H
>
> +#include "pathspec.h"
> +
> struct archiver_args {
> const char *base;
> size_t baselen;
> @@ -8,7 +10,7 @@ struct archiver_args {
> const unsigned char *commit_sha1;
> const struct commit *commit;
> time_t time;
> - const char **pathspec;
> + struct pathspec pathspec;
> unsigned int verbose : 1;
> unsigned int worktree_attributes : 1;
> unsigned int convert : 1;
^ permalink raw reply
* Re: [PATCH v1 00/45] nd/parse-pathspec and :(glob) pathspec magic
From: Junio C Hamano @ 2013-03-15 17:48 UTC (permalink / raw)
To: Nguyễn Thái Ngọc Duy; +Cc: git
In-Reply-To: <1363327620-29017-1-git-send-email-pclouds@gmail.com>
Nguyễn Thái Ngọc Duy <pclouds@gmail.com> writes:
> Probably not much to say. A big portion of this series is the
> conversion to struct pathspec, which enables more use of pathspec
> magic. :(glob) magic is added to verify that the conversion makes
> sense.
I haven't read any of these patches, but there remains only one user
of the _raw field in dir.c (read_directory) and get_pathspec() is
called by nobody other than builtin/mv.c after this series.
Very encouraging.
> Andrew Wong (1):
> setup.c: check that the pathspec magic ends with ")"
>
> Nguyễn Thái Ngọc Duy (44):
> clean: remove unused variable "seen"
> Move struct pathspec and related functions to pathspec.[ch]
> pathspec: i18n-ize error strings in pathspec parsing code
> pathspec: add copy_pathspec
> Add parse_pathspec() that converts cmdline args to struct pathspec
> parse_pathspec: save original pathspec for reporting
> parse_pathspec: add PATHSPEC_PREFER_{CWD,FULL}
> Convert some get_pathspec() calls to parse_pathspec()
> parse_pathspec: a special flag for max_depth feature
> parse_pathspec: support stripping submodule trailing slashes
> parse_pathspec: support stripping/checking submodule paths
> parse_pathspec: support prefixing original patterns
> Guard against new pathspec magic in pathspec matching code
> clean: convert to use parse_pathspec
> commit: convert to use parse_pathspec
> status: convert to use parse_pathspec
> rerere: convert to use parse_pathspec
> checkout: convert to use parse_pathspec
> rm: convert to use parse_pathspec
> ls-files: convert to use parse_pathspec
> archive: convert to use parse_pathspec
> check-ignore: convert to use parse_pathspec
> add: convert to use parse_pathspec
> reset: convert to use parse_pathspec
> Convert read_cache_preload() to take struct pathspec
> Convert run_add_interactive to use struct pathspec
> Convert unmerge_cache to take struct pathspec
> checkout: convert read_tree_some to take struct pathspec
> Convert report_path_error to take struct pathspec
> Convert refresh_index to take struct pathspec
> Convert {read,fill}_directory to take struct pathspec
> Convert add_files_to_cache to take struct pathspec
> Convert common_prefix() to use struct pathspec
> Remove diff_tree_{setup,release}_paths
> Remove init_pathspec() in favor of parse_pathspec()
> Remove match_pathspec() in favor of match_pathspec_depth()
> tree-diff: remove the use of pathspec's raw[] in follow-rename codepath
> parse_pathspec: make sure the prefix part is wildcard-free
> parse_pathspec: preserve prefix length via PATHSPEC_PREFIX_ORIGIN
> Kill limit_pathspec_to_literal() as it's only used by parse_pathspec()
> pathspec: support :(literal) syntax for noglob pathspec
> pathspec: make --literal-pathspecs disable pathspec magic
> pathspec: support :(glob) syntax
> Rename field "raw" to "_raw" in struct pathspec
>
> Documentation/git.txt | 23 +-
> Documentation/glossary-content.txt | 33 +++
> archive.c | 18 +-
> archive.h | 4 +-
> builtin/add.c | 156 ++++++--------
> builtin/blame.c | 14 +-
> builtin/check-ignore.c | 34 +--
> builtin/checkout.c | 46 ++--
> builtin/clean.c | 24 +--
> builtin/commit.c | 37 ++--
> builtin/diff-files.c | 2 +-
> builtin/diff-index.c | 2 +-
> builtin/diff.c | 6 +-
> builtin/grep.c | 10 +-
> builtin/log.c | 2 +-
> builtin/ls-files.c | 75 +++----
> builtin/ls-tree.c | 13 +-
> builtin/mv.c | 13 +-
> builtin/rerere.c | 8 +-
> builtin/reset.c | 33 +--
> builtin/rm.c | 24 +--
> builtin/update-index.c | 6 +-
> cache.h | 34 +--
> commit.h | 2 +-
> diff-lib.c | 3 +-
> diff.h | 3 +-
> dir.c | 261 +++++-----------------
> dir.h | 18 +-
> git.c | 8 +
> merge-recursive.c | 2 +-
> notes-merge.c | 4 +-
> path.c | 15 +-
> pathspec.c | 431 +++++++++++++++++++++++++++++++++----
> pathspec.h | 59 ++++-
> preload-index.c | 21 +-
> read-cache.c | 5 +-
> rerere.c | 7 +-
> rerere.h | 4 +-
> resolve-undo.c | 4 +-
> resolve-undo.h | 2 +-
> revision.c | 11 +-
> setup.c | 157 +-------------
> t/t0008-ignores.sh | 8 +-
> t/t6130-pathspec-noglob.sh | 18 ++
> tree-diff.c | 48 +++--
> tree-walk.c | 21 +-
> tree.c | 4 +-
> tree.h | 2 +-
> wt-status.c | 18 +-
> wt-status.h | 2 +-
> 50 files changed, 983 insertions(+), 772 deletions(-)
^ 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