Git development
 help / color / mirror / Atom feed
* [PATCH 3/9] Add strbuf_printf() to do formatted printing to a strbuf.
From: Kristian Høgsberg @ 2007-09-06  0:23 UTC (permalink / raw)
  To: git; +Cc: Kristian Høgsberg
In-Reply-To: <11890382242333-git-send-email-krh@redhat.com>

Also, expose strbuf_add() and strbuf_add_char() to add raw data to the buffer.

Signed-off-by: Kristian Høgsberg <krh@redhat.com>
---
 strbuf.c |   69 +++++++++++++++++++++++++++++++++++++++++++++++++++++++------
 strbuf.h |    3 ++
 2 files changed, 65 insertions(+), 7 deletions(-)

diff --git a/strbuf.c b/strbuf.c
index e33d06b..2805c11 100644
--- a/strbuf.c
+++ b/strbuf.c
@@ -11,16 +11,26 @@ static void strbuf_begin(struct strbuf *sb) {
 	strbuf_init(sb);
 }
 
-static void inline strbuf_add(struct strbuf *sb, int ch) {
-	if (sb->alloc <= sb->len) {
-		sb->alloc = sb->alloc * 3 / 2 + 16;
-		sb->buf = xrealloc(sb->buf, sb->alloc);
-	}
+static void inline strbuf_grow(struct strbuf *sb, size_t extra)
+{
+	ALLOC_GROW(sb->buf, sb->len + extra, sb->alloc);
+}
+
+void strbuf_add(struct strbuf *sb, const char *data, size_t len)
+{
+	strbuf_grow(sb, len);
+	memcpy(sb->buf + sb->len, data, len);
+	sb->len += len;
+}
+
+void strbuf_add_char(struct strbuf *sb, int ch)
+{
+	strbuf_grow(sb, 1);
 	sb->buf[sb->len++] = ch;
 }
 
 static void strbuf_end(struct strbuf *sb) {
-	strbuf_add(sb, 0);
+	strbuf_add_char(sb, 0);
 }
 
 void read_line(struct strbuf *sb, FILE *fp, int term) {
@@ -33,9 +43,54 @@ void read_line(struct strbuf *sb, FILE *fp, int term) {
 	while ((ch = fgetc(fp)) != EOF) {
 		if (ch == term)
 			break;
-		strbuf_add(sb, ch);
+		strbuf_add_char(sb, ch);
 	}
 	if (ch == EOF && sb->len == 0)
 		sb->eof = 1;
 	strbuf_end(sb);
 }
+
+void strbuf_printf(struct strbuf *sb, const char *fmt, ...)
+{
+	char buffer[2048];
+	va_list args;
+	int len, size = 2 * sizeof buffer;
+
+	va_start(args, fmt);
+	len = vsnprintf(buffer, sizeof(buffer), fmt, args);
+	va_end(args);
+
+	if (len > sizeof(buffer)) {
+		/*
+		 * Didn't fit in the buffer, but this vsnprintf at
+		 * least gives us the required length back.  Grow the
+		 * buffer acccordingly and try again.
+		 */
+		strbuf_grow(sb, len);
+		va_start(args, fmt);
+		len = vsnprintf(sb->buf + sb->len,
+				sb->alloc - sb->len, fmt, args);
+		va_end(args);
+	} else if (len >= 0) {
+		/*
+		 * The initial vsnprintf fit in the temp buffer, just
+		 * copy it to the strbuf.
+		 */
+		strbuf_add(sb, buffer, len);
+	} else {
+		/*
+		 * This vnsprintf sucks and just returns -1 when the
+		 * buffer is too small.  Keep doubling the size until
+		 * it fits.
+		 */
+		while (len < 0) {
+			strbuf_grow(sb, size);
+			va_start(args, fmt);
+			len = vsnprintf(sb->buf + sb->len,
+					sb->alloc - sb->len, fmt, args);
+			va_end(args);
+			size *= 2;
+		}
+	}
+}
+
diff --git a/strbuf.h b/strbuf.h
index 74cc012..1e5d09e 100644
--- a/strbuf.h
+++ b/strbuf.h
@@ -9,5 +9,8 @@ struct strbuf {
 
 extern void strbuf_init(struct strbuf *);
 extern void read_line(struct strbuf *, FILE *, int);
+extern void strbuf_add(struct strbuf *sb, const char *data, size_t len);
+extern void strbuf_add_char(struct strbuf *sb, int ch);
+extern void strbuf_printf(struct strbuf *sb, const char *fmt, ...);
 
 #endif /* STRBUF_H */
-- 
1.5.2.GIT

^ permalink raw reply related

* [PATCH 2/9] Enable wt-status to run against non-standard index file.
From: Kristian Høgsberg @ 2007-09-06  0:23 UTC (permalink / raw)
  To: git; +Cc: Kristian Høgsberg
In-Reply-To: <11890382183913-git-send-email-krh@redhat.com>

We still default to get_index_file(), but this can be overridden
by setting wt_status.index_file after calling wt_status_prepare().

Signed-off-by: Kristian Høgsberg <krh@redhat.com>
---
 wt-status.c |    3 ++-
 wt-status.h |    1 +
 2 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/wt-status.c b/wt-status.c
index 65a7259..0cf9b81 100644
--- a/wt-status.c
+++ b/wt-status.c
@@ -53,6 +53,7 @@ void wt_status_prepare(struct wt_status *s)
 	s->branch = head ? xstrdup(head) : NULL;
 	s->reference = "HEAD";
 	s->fp = stdout;
+	s->index_file = get_index_file();
 }
 
 static void wt_status_print_cached_header(struct wt_status *s)
@@ -198,7 +199,7 @@ static void wt_status_print_changed_cb(struct diff_queue_struct *q,
 static void wt_read_cache(struct wt_status *s)
 {
 	discard_cache();
-	read_cache();
+	read_cache_from(s->index_file);
 }
 
 static void wt_status_print_initial(struct wt_status *s)
diff --git a/wt-status.h b/wt-status.h
index 4f3a615..7744932 100644
--- a/wt-status.h
+++ b/wt-status.h
@@ -21,6 +21,7 @@ struct wt_status {
 	int commitable;
 	int workdir_dirty;
 	int workdir_untracked;
+	const char *index_file;
 	FILE *fp;
 };
 
-- 
1.5.2.GIT

^ permalink raw reply related

* [PATCH 1/9] Enable wt-status output to a given FILE pointer.
From: Kristian Høgsberg @ 2007-09-06  0:23 UTC (permalink / raw)
  To: git; +Cc: Kristian Høgsberg

Still defaults to stdout, but you can now override wt_status.fp after
calling wt_status_prepare().

Signed-off-by: Kristian Høgsberg <krh@redhat.com>
---
 color.c     |   18 ++++++------
 color.h     |    4 +-
 wt-status.c |   85 ++++++++++++++++++++++++++++++----------------------------
 wt-status.h |    3 ++
 4 files changed, 58 insertions(+), 52 deletions(-)

diff --git a/color.c b/color.c
index 09d82ee..124ba33 100644
--- a/color.c
+++ b/color.c
@@ -135,39 +135,39 @@ int git_config_colorbool(const char *var, const char *value)
 	return git_config_bool(var, value);
 }
 
-static int color_vprintf(const char *color, const char *fmt,
+static int color_vfprintf(FILE *fp, const char *color, const char *fmt,
 		va_list args, const char *trail)
 {
 	int r = 0;
 
 	if (*color)
-		r += printf("%s", color);
-	r += vprintf(fmt, args);
+		r += fprintf(fp, "%s", color);
+	r += vfprintf(fp, fmt, args);
 	if (*color)
-		r += printf("%s", COLOR_RESET);
+		r += fprintf(fp, "%s", COLOR_RESET);
 	if (trail)
-		r += printf("%s", trail);
+		r += fprintf(fp, "%s", trail);
 	return r;
 }
 
 
 
-int color_printf(const char *color, const char *fmt, ...)
+int color_fprintf(FILE *fp, const char *color, const char *fmt, ...)
 {
 	va_list args;
 	int r;
 	va_start(args, fmt);
-	r = color_vprintf(color, fmt, args, NULL);
+	r = color_vfprintf(fp, color, fmt, args, NULL);
 	va_end(args);
 	return r;
 }
 
-int color_printf_ln(const char *color, const char *fmt, ...)
+int color_fprintf_ln(FILE *fp, const char *color, const char *fmt, ...)
 {
 	va_list args;
 	int r;
 	va_start(args, fmt);
-	r = color_vprintf(color, fmt, args, "\n");
+	r = color_vfprintf(fp, color, fmt, args, "\n");
 	va_end(args);
 	return r;
 }
diff --git a/color.h b/color.h
index 88bb8ff..6809800 100644
--- a/color.h
+++ b/color.h
@@ -6,7 +6,7 @@
 
 int git_config_colorbool(const char *var, const char *value);
 void color_parse(const char *var, const char *value, char *dst);
-int color_printf(const char *color, const char *fmt, ...);
-int color_printf_ln(const char *color, const char *fmt, ...);
+int color_fprintf(FILE *fp, const char *color, const char *fmt, ...);
+int color_fprintf_ln(FILE *fp, const char *color, const char *fmt, ...);
 
 #endif /* COLOR_H */
diff --git a/wt-status.c b/wt-status.c
index 5205420..65a7259 100644
--- a/wt-status.c
+++ b/wt-status.c
@@ -52,31 +52,33 @@ void wt_status_prepare(struct wt_status *s)
 	head = resolve_ref("HEAD", sha1, 0, NULL);
 	s->branch = head ? xstrdup(head) : NULL;
 	s->reference = "HEAD";
+	s->fp = stdout;
 }
 
-static void wt_status_print_cached_header(const char *reference)
+static void wt_status_print_cached_header(struct wt_status *s)
 {
 	const char *c = color(WT_STATUS_HEADER);
-	color_printf_ln(c, "# Changes to be committed:");
-	if (reference) {
-		color_printf_ln(c, "#   (use \"git reset %s <file>...\" to unstage)", reference);
+	color_fprintf_ln(s->fp, c, "# Changes to be committed:");
+	if (s->reference) {
+		color_fprintf_ln(s->fp, c, "#   (use \"git reset %s <file>...\" to unstage)", s->reference);
 	} else {
-		color_printf_ln(c, "#   (use \"git rm --cached <file>...\" to unstage)");
+		color_fprintf_ln(s->fp, c, "#   (use \"git rm --cached <file>...\" to unstage)");
 	}
-	color_printf_ln(c, "#");
+	color_fprintf_ln(s->fp, c, "#");
 }
 
-static void wt_status_print_header(const char *main, const char *sub)
+static void wt_status_print_header(struct wt_status *s,
+				   const char *main, const char *sub)
 {
 	const char *c = color(WT_STATUS_HEADER);
-	color_printf_ln(c, "# %s:", main);
-	color_printf_ln(c, "#   (%s)", sub);
-	color_printf_ln(c, "#");
+	color_fprintf_ln(s->fp, c, "# %s:", main);
+	color_fprintf_ln(s->fp, c, "#   (%s)", sub);
+	color_fprintf_ln(s->fp, c, "#");
 }
 
-static void wt_status_print_trailer(void)
+static void wt_status_print_trailer(struct wt_status *s)
 {
-	color_printf_ln(color(WT_STATUS_HEADER), "#");
+	color_fprintf_ln(s->fp, color(WT_STATUS_HEADER), "#");
 }
 
 static const char *quote_crlf(const char *in, char *buf, size_t sz)
@@ -108,7 +110,8 @@ static const char *quote_crlf(const char *in, char *buf, size_t sz)
 	return ret;
 }
 
-static void wt_status_print_filepair(int t, struct diff_filepair *p)
+static void wt_status_print_filepair(struct wt_status *s,
+				     int t, struct diff_filepair *p)
 {
 	const char *c = color(t);
 	const char *one, *two;
@@ -117,36 +120,36 @@ static void wt_status_print_filepair(int t, struct diff_filepair *p)
 	one = quote_crlf(p->one->path, onebuf, sizeof(onebuf));
 	two = quote_crlf(p->two->path, twobuf, sizeof(twobuf));
 
-	color_printf(color(WT_STATUS_HEADER), "#\t");
+	color_fprintf(s->fp, color(WT_STATUS_HEADER), "#\t");
 	switch (p->status) {
 	case DIFF_STATUS_ADDED:
-		color_printf(c, "new file:   %s", one);
+		color_fprintf(s->fp, c, "new file:   %s", one);
 		break;
 	case DIFF_STATUS_COPIED:
-		color_printf(c, "copied:     %s -> %s", one, two);
+		color_fprintf(s->fp, c, "copied:     %s -> %s", one, two);
 		break;
 	case DIFF_STATUS_DELETED:
-		color_printf(c, "deleted:    %s", one);
+		color_fprintf(s->fp, c, "deleted:    %s", one);
 		break;
 	case DIFF_STATUS_MODIFIED:
-		color_printf(c, "modified:   %s", one);
+		color_fprintf(s->fp, c, "modified:   %s", one);
 		break;
 	case DIFF_STATUS_RENAMED:
-		color_printf(c, "renamed:    %s -> %s", one, two);
+		color_fprintf(s->fp, c, "renamed:    %s -> %s", one, two);
 		break;
 	case DIFF_STATUS_TYPE_CHANGED:
-		color_printf(c, "typechange: %s", one);
+		color_fprintf(s->fp, c, "typechange: %s", one);
 		break;
 	case DIFF_STATUS_UNKNOWN:
-		color_printf(c, "unknown:    %s", one);
+		color_fprintf(s->fp, c, "unknown:    %s", one);
 		break;
 	case DIFF_STATUS_UNMERGED:
-		color_printf(c, "unmerged:   %s", one);
+		color_fprintf(s->fp, c, "unmerged:   %s", one);
 		break;
 	default:
 		die("bug: unhandled diff status %c", p->status);
 	}
-	printf("\n");
+	fprintf(s->fp, "\n");
 }
 
 static void wt_status_print_updated_cb(struct diff_queue_struct *q,
@@ -160,14 +163,14 @@ static void wt_status_print_updated_cb(struct diff_queue_struct *q,
 		if (q->queue[i]->status == 'U')
 			continue;
 		if (!shown_header) {
-			wt_status_print_cached_header(s->reference);
+			wt_status_print_cached_header(s);
 			s->commitable = 1;
 			shown_header = 1;
 		}
-		wt_status_print_filepair(WT_STATUS_UPDATED, q->queue[i]);
+		wt_status_print_filepair(s, WT_STATUS_UPDATED, q->queue[i]);
 	}
 	if (shown_header)
-		wt_status_print_trailer();
+		wt_status_print_trailer(s);
 }
 
 static void wt_status_print_changed_cb(struct diff_queue_struct *q,
@@ -184,12 +187,12 @@ static void wt_status_print_changed_cb(struct diff_queue_struct *q,
 				msg = use_add_rm_msg;
 				break;
 			}
-		wt_status_print_header("Changed but not updated", msg);
+		wt_status_print_header(s, "Changed but not updated", msg);
 	}
 	for (i = 0; i < q->nr; i++)
-		wt_status_print_filepair(WT_STATUS_CHANGED, q->queue[i]);
+		wt_status_print_filepair(s, WT_STATUS_CHANGED, q->queue[i]);
 	if (q->nr)
-		wt_status_print_trailer();
+		wt_status_print_trailer(s);
 }
 
 static void wt_read_cache(struct wt_status *s)
@@ -206,16 +209,16 @@ static void wt_status_print_initial(struct wt_status *s)
 	wt_read_cache(s);
 	if (active_nr) {
 		s->commitable = 1;
-		wt_status_print_cached_header(NULL);
+		wt_status_print_cached_header(s);
 	}
 	for (i = 0; i < active_nr; i++) {
-		color_printf(color(WT_STATUS_HEADER), "#\t");
-		color_printf_ln(color(WT_STATUS_UPDATED), "new file: %s",
+		color_fprintf(s->fp, color(WT_STATUS_HEADER), "#\t");
+		color_fprintf_ln(s->fp, color(WT_STATUS_UPDATED), "new file: %s",
 				quote_crlf(active_cache[i]->name,
 					   buf, sizeof(buf)));
 	}
 	if (active_nr)
-		wt_status_print_trailer();
+		wt_status_print_trailer(s);
 }
 
 static void wt_status_print_updated(struct wt_status *s)
@@ -281,12 +284,12 @@ static void wt_status_print_untracked(struct wt_status *s)
 		}
 		if (!shown_header) {
 			s->workdir_untracked = 1;
-			wt_status_print_header("Untracked files",
+			wt_status_print_header(s, "Untracked files",
 					       use_add_to_include_msg);
 			shown_header = 1;
 		}
-		color_printf(color(WT_STATUS_HEADER), "#\t");
-		color_printf_ln(color(WT_STATUS_UNTRACKED), "%.*s",
+		color_fprintf(s->fp, color(WT_STATUS_HEADER), "#\t");
+		color_fprintf_ln(s->fp, color(WT_STATUS_UNTRACKED), "%.*s",
 				ent->len, ent->name);
 	}
 }
@@ -316,14 +319,14 @@ void wt_status_print(struct wt_status *s)
 			branch_name = "";
 			on_what = "Not currently on any branch.";
 		}
-		color_printf_ln(color(WT_STATUS_HEADER),
+		color_fprintf_ln(s->fp, color(WT_STATUS_HEADER),
 			"# %s%s", on_what, branch_name);
 	}
 
 	if (s->is_initial) {
-		color_printf_ln(color(WT_STATUS_HEADER), "#");
-		color_printf_ln(color(WT_STATUS_HEADER), "# Initial commit");
-		color_printf_ln(color(WT_STATUS_HEADER), "#");
+		color_fprintf_ln(s->fp, color(WT_STATUS_HEADER), "#");
+		color_fprintf_ln(s->fp, color(WT_STATUS_HEADER), "# Initial commit");
+		color_fprintf_ln(s->fp, color(WT_STATUS_HEADER), "#");
 		wt_status_print_initial(s);
 	}
 	else {
@@ -337,7 +340,7 @@ void wt_status_print(struct wt_status *s)
 		wt_status_print_verbose(s);
 	if (!s->commitable) {
 		if (s->amend)
-			printf("# No changes\n");
+			fprintf(s->fp, "# No changes\n");
 		else if (s->workdir_dirty)
 			printf("no changes added to commit (use \"git add\" and/or \"git commit -a\")\n");
 		else if (s->workdir_untracked)
diff --git a/wt-status.h b/wt-status.h
index cfea4ae..4f3a615 100644
--- a/wt-status.h
+++ b/wt-status.h
@@ -1,6 +1,8 @@
 #ifndef STATUS_H
 #define STATUS_H
 
+#include <stdio.h>
+
 enum color_wt_status {
 	WT_STATUS_HEADER,
 	WT_STATUS_UPDATED,
@@ -19,6 +21,7 @@ struct wt_status {
 	int commitable;
 	int workdir_dirty;
 	int workdir_untracked;
+	FILE *fp;
 };
 
 int git_status_config(const char *var, const char *value);
-- 
1.5.2.GIT

^ permalink raw reply related

* Re: People unaware of the importance of "git gc"?
From: Carlos Rica @ 2007-09-06  0:27 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Nicolas Pitre, Nix, Steven Grimm, Linus Torvalds,
	Git Mailing List
In-Reply-To: <7v3axshe6q.fsf@gitster.siamese.dyndns.org>

2007/9/6, Junio C Hamano <gitster@pobox.com>:
> Nicolas Pitre <nico@cam.org> writes:
> > The more I think of it, the less I like automatic repack.  There is
> > always a bad case for it somewhere.
>
> I tend to agree, but at the same time, I think the long term
> goal should be not to have bad cases.

The best solution is make "git gc" unnecessary.
At the long term, and without loss of efficiency.

^ permalink raw reply

* Re: [PATCH 3/3] Makefile: Add cache-tree.h to the public headers list
From: Junio C Hamano @ 2007-09-06  0:16 UTC (permalink / raw)
  To: Dmitry V. Levin; +Cc: Git Mailing List
In-Reply-To: <20070905232251.GC331@nomad.office.altlinux.org>

"Dmitry V. Levin" <ldv@altlinux.org> writes:

> Some external projects (e.g. parsecvs) need cache-tree.h file.

Your patch shows that our Makefile has been lacking a necessary
dependency for a long time.  LIB_H is not "public headers list",
but more like "the headers everybody depends on", and the header
file should have been on that list.  Thanks.

I am however not convinced it is a good idea to treat libgit.a
as if it is a library.  It is not a library in the usual sense
of the word.  Originally we did libgit.a primarily so that we do
not have to list all the *.o dependencies in the Makefile out of
laziness ;-)

^ permalink raw reply

* Re: People unaware of the importance of "git gc"?
From: Jeff King @ 2007-09-05 23:56 UTC (permalink / raw)
  To: Matthieu Moy; +Cc: Git Mailing List
In-Reply-To: <vpq1wddkohr.fsf@bauges.imag.fr>

On Wed, Sep 05, 2007 at 07:31:44PM +0200, Matthieu Moy wrote:

> I have ~/teaching/some-course/.git (well, almost) and ~/etc/.git which
> are two unrelated projects, and to "git gc" both of them, I need
> either a script, or two manual invocations.
>
> (yes, I'm really talking about something trivial)

I tend to have a lot of small projects, so I have on the order of 80 git
repositories on each machine I use, most of which have a 'mothership'
origin on a central, backed-up machine.

When I sit down to work, I want to see which repositories
have changes that need to be pulled. And when I get up to leave, I want
to see which repositories have changes that need to be pushed. Not to
mention files that need committed, loose objects that need packed, etc.

So I wrote the 'git-stale' script, included below. It's not especially
user-friendly, but you might find it useful, as it solves the exact
problem you are talking about (and much more).

It reads 'repository specifications' from ~/.gitstale, one per line,
which are either of the form:

  /path/to/repo

which specifies a repo to check, or:

  r:/path/to/many/repos

which specifies a hierarchy in which to recursively find repos.

My .gitstale looks something like this:

  /home/peff/compile/git
  /home/peff/compile/tig
  r:/home/peff/work

and I get output something like this (edited for brevity):

Checking (1/77) /home/peff/compile/git...
Checking (2/77) /home/peff/compile/tig...
[...]
Checking (77/77) /home/peff/work/foo...
MERGE:next /home/peff/compile/git
COMMIT: /home/peff/work/foo
PACK: /home/peff/work/foo
PUSH:master /home/peff/work/bar

which translates to:
  - the git repo has commits in 'origin/next' that are not in 'next'
    (and you might want to merge them in)
  - there are uncommitted files in 'foo'
  - 'foo' needs packing
  - in the 'bar' repo there are commits in master that are not in origin
    (and you might want to push)

Hopefully it will be useful to you, though I think it is probably too
specific to my workflow to be part of git.

-Peff

-- >8 --
#!/usr/bin/perl

use strict;
use Getopt::Long;

my $CONFIG_FILE = "$ENV{HOME}/.gitstale";

my $nofetch = $ENV{GITSTALE_NOFETCH};
Getopt::Long::Configure(qw(bundling));
GetOptions('nofetch|n!' => \$nofetch) or exit 100;

my @projects = process_spec(@ARGV ? @ARGV : cat($CONFIG_FILE));

my $n = 1;
my $total = @projects;
my %errors;
foreach my $p (@projects) {
  print "Checking ($n/$total) $p...\n";
  $errors{$p} = [check_git($p)];
  $n++;
}

my $errcount;
foreach my $p (@projects) {
  foreach my $e (@{$errors{$p}}) {
    print "$e: $p\n";
  }
}

exit $errcount ? 1 : 0;

sub cat {
  my $fn = shift;
  open(my $fh, '<', $fn)
    or die "unable to open $fn: $!\n";
  return map { chomp; length($_) ? $_ : () } <$fh>;
}

sub process_spec {
  my @dirs;
  my @roots;
  my @exclude;

  foreach (@_) {
    if(/^r:(.*)/) { push @roots, $1 }
    elsif(/^d:(.*)/) { push @dirs, $1 }
    elsif(/^-(.*)/) { push @exclude, qr#(^|/)$1($|/)# }
    else { push @dirs, $_ }
  }

  use File::Find;
  find({
      no_chdir => 1,
      preprocess => sub { sort @_ },
      wanted => sub {
        return unless -d $_ && $_ =~ m#/.git$#;
        foreach my $e (@exclude) { return if $_ =~ $e }
        my $d = $_;
        $d =~ s#/\.git$##;
        push @dirs, $d;
      }
    }, @roots) if @roots;
  return @dirs;
}

sub count_zero {
  open(my $fh, '-|', @_) or die "unable to fork: $!\n";
  my $line = <$fh>;
  return length($line) == 0;
}

sub check_git {
  my $d = shift;

  chdir($d) or return 'CHDIR';

  my @r;
  count_zero(qw(
        git-ls-files -m -o -d --exclude-per-directory=.gitignore
        --directory --no-empty-directory
  )) or push @r, 'COMMIT';

  if(has_origin()) {
    push @r, 'FETCH' if !$nofetch && system('git-fetch');

    foreach my $p (branch_pairs()) {
      count_zero('git-rev-list', "$p->[0]..$p->[1]")
        or push @r, "MERGE:$p->[0]";
      count_zero('git-rev-list', "$p->[1]..$p->[0]")
        or push @r, "PUSH:$p->[0]";
    }
  }
  else {
    push @r, 'ORIGIN';
  }

  push @r, 'PACK' if unpacked_objects() > 1000;

  return @r;
}

sub unpacked_objects {
  my $objects = `git-count-objects`;
  $objects =~ /^(\d+)/;
  return $1;
}

sub branch_pairs {
  my %config;
  foreach my $line (`git-repo-config --get-regexp 'branch..*..*'`) {
    $line =~ m#^branch\.([^.]+)\.([^ ]+) (?:refs/heads/)?(.*)#
      or die "confusing git-repo-config output: $line\n";
    $config{$1}{$2} = $3;
  }

  return [qw(master origin)] if -e '.git/refs/heads/origin';

  return
    (-e '.git/refs/heads/origin' ? [qw(master origin)] : ()),
    map {
      $config{$_}{remote} && $config{$_}{merge} ?
        [$_, $config{$_}{remote} . '/' . $config{$_}{merge}] :
        ()
    } sort keys(%config);
}

sub has_origin {
  return
    -e '.git/branches/origin' ||
    -e '.git/remotes/origin' ||
    !count_zero(qw(git-repo-config --get remote.origin.url));
}
__END__

^ permalink raw reply

* [PATCH 1/3] git-gui/Makefile: Replace libdir with gitgui_libdir
From: Dmitry V. Levin @ 2007-09-05 23:21 UTC (permalink / raw)
  To: Git Mailing List; +Cc: Junio C Hamano

On GNU/Linux, libdir is used to mean "/usr/lib or /usr/lib64"
depending on architecture.  Different libdir meaning breaks
idiomatic expressions like rpm specfile "make libdir=%_libdir".

Signed-off-by: Dmitry V. Levin <ldv@altlinux.org>
---
 git-gui/Makefile |   16 ++++++++--------
 1 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/git-gui/Makefile b/git-gui/Makefile
index 1bac6fe..f143b2c 100644
--- a/git-gui/Makefile
+++ b/git-gui/Makefile
@@ -76,8 +76,8 @@ SHELL_PATH_SQ = $(subst ','\'',$(SHELL_PATH))
 TCL_PATH_SQ = $(subst ','\'',$(TCL_PATH))
 TCLTK_PATH_SQ = $(subst ','\'',$(TCLTK_PATH))
 
-libdir   ?= $(sharedir)/git-gui/lib
-libdir_SQ = $(subst ','\'',$(libdir))
+gitgui_libdir   ?= $(sharedir)/git-gui/lib
+gitgui_libdir_SQ = $(subst ','\'',$(gitgui_libdir))
 
 exedir    = $(dir $(gitexecdir))share/git-gui/lib
 exedir_SQ = $(subst ','\'',$(exedir))
@@ -85,7 +85,7 @@ exedir_SQ = $(subst ','\'',$(exedir))
 $(patsubst %.sh,%,$(SCRIPT_SH)) : % : %.sh
 	$(QUIET_GEN)rm -f $@ $@+ && \
 	GITGUI_RELATIVE= && \
-	if test '$(exedir_SQ)' = '$(libdir_SQ)'; then \
+	if test '$(exedir_SQ)' = '$(gitgui_libdir_SQ)'; then \
 		if test "$(uname_O)" = Cygwin; \
 		then GITGUI_RELATIVE= ; \
 		else GITGUI_RELATIVE=1; \
@@ -95,7 +95,7 @@ $(patsubst %.sh,%,$(SCRIPT_SH)) : % : %.sh
 		-e 's|^ exec wish "$$0"| exec $(subst |,'\|',$(TCLTK_PATH_SQ)) "$$0"|' \
 		-e 's/@@GITGUI_VERSION@@/$(GITGUI_VERSION)/g' \
 		-e 's|@@GITGUI_RELATIVE@@|'$$GITGUI_RELATIVE'|' \
-		-e $$GITGUI_RELATIVE's|@@GITGUI_LIBDIR@@|$(libdir_SQ)|' \
+		-e $$GITGUI_RELATIVE's|@@GITGUI_LIBDIR@@|$(gitgui_libdir_SQ)|' \
 		$@.sh >$@+ && \
 	chmod +x $@+ && \
 	mv $@+ $@
@@ -126,7 +126,7 @@ TRACK_VARS = \
 	$(subst ','\'',TCL_PATH='$(TCL_PATH_SQ)') \
 	$(subst ','\'',TCLTK_PATH='$(TCLTK_PATH_SQ)') \
 	$(subst ','\'',gitexecdir='$(gitexecdir_SQ)') \
-	$(subst ','\'',libdir='$(libdir_SQ)') \
+	$(subst ','\'',gitgui_libdir='$(gitgui_libdir_SQ)') \
 #end TRACK_VARS
 
 GIT-GUI-VARS: .FORCE-GIT-GUI-VARS
@@ -142,9 +142,9 @@ install: all
 	$(QUIET)$(INSTALL_D0)'$(DESTDIR_SQ)$(gitexecdir_SQ)' $(INSTALL_D1)
 	$(QUIET)$(INSTALL_X0)git-gui $(INSTALL_X1) '$(DESTDIR_SQ)$(gitexecdir_SQ)'
 	$(QUIET)$(foreach p,$(GITGUI_BUILT_INS), $(INSTALL_L0)'$(DESTDIR_SQ)$(gitexecdir_SQ)/$p' $(INSTALL_L1)'$(DESTDIR_SQ)$(gitexecdir_SQ)/git-gui' $(INSTALL_L2)'$(DESTDIR_SQ)$(gitexecdir_SQ)/$p' $(INSTALL_L3) &&) true
-	$(QUIET)$(INSTALL_D0)'$(DESTDIR_SQ)$(libdir_SQ)' $(INSTALL_D1)
-	$(QUIET)$(INSTALL_R0)lib/tclIndex $(INSTALL_R1) '$(DESTDIR_SQ)$(libdir_SQ)'
-	$(QUIET)$(foreach p,$(ALL_LIBFILES), $(INSTALL_R0)$p $(INSTALL_R1) '$(DESTDIR_SQ)$(libdir_SQ)' &&) true
+	$(QUIET)$(INSTALL_D0)'$(DESTDIR_SQ)$(gitgui_libdir_SQ)' $(INSTALL_D1)
+	$(QUIET)$(INSTALL_R0)lib/tclIndex $(INSTALL_R1) '$(DESTDIR_SQ)$(gitgui_libdir_SQ)'
+	$(QUIET)$(foreach p,$(ALL_LIBFILES), $(INSTALL_R0)$p $(INSTALL_R1) '$(DESTDIR_SQ)$(gitgui_libdir_SQ)' &&) true
 
 dist-version:
 	@mkdir -p $(TARDIR)
-- 
ldv

^ permalink raw reply related

* [PATCH 2/3] Makefile: Add install-lib and install-include targets
From: Dmitry V. Levin @ 2007-09-05 23:22 UTC (permalink / raw)
  To: Git Mailing List; +Cc: Junio C Hamano

Several external projects (e.g. parsecvs) need libgit library
and related header files.

Signed-off-by: Dmitry V. Levin <ldv@altlinux.org>
---
 Makefile |   11 +++++++++++
 1 files changed, 11 insertions(+), 0 deletions(-)

diff --git a/Makefile b/Makefile
index 51af531..d50e30b 100644
--- a/Makefile
+++ b/Makefile
@@ -143,6 +143,8 @@ STRIP ?= strip
 
 prefix = $(HOME)
 bindir = $(prefix)/bin
+libdir = $(prefix)/lib
+includedir = $(prefix)/include
 gitexecdir = $(bindir)
 sharedir = $(prefix)/share
 template_dir = $(sharedir)/git-core/templates
@@ -702,6 +704,8 @@ ETC_GITCONFIG_SQ = $(subst ','\'',$(ETC_GITCONFIG))
 
 DESTDIR_SQ = $(subst ','\'',$(DESTDIR))
 bindir_SQ = $(subst ','\'',$(bindir))
+libdir_SQ = $(subst ','\'',$(libdir))
+includedir_SQ = $(subst ','\'',$(includedir))
 gitexecdir_SQ = $(subst ','\'',$(gitexecdir))
 template_dir_SQ = $(subst ','\'',$(template_dir))
 prefix_SQ = $(subst ','\'',$(prefix))
@@ -1017,6 +1021,13 @@ install-info:
 quick-install-doc:
 	$(MAKE) -C Documentation quick-install
 
+install-lib: $(LIB_FILE)
+	$(INSTALL) -d -m755 '$(DESTDIR_SQ)$(libdir_SQ)'
+	$(INSTALL) -p -m644 $(LIB_FILE) '$(DESTDIR_SQ)$(libdir_SQ)/'
+
+install-include: $(LIB_H)
+	$(INSTALL) -d -m755 '$(DESTDIR_SQ)$(includedir_SQ)/git'
+	$(INSTALL) -p -m644 $(LIB_H) '$(DESTDIR_SQ)$(includedir_SQ)/git/'
 
 
 ### Maintainer's dist rules
-- 
ldv

^ permalink raw reply related

* [PATCH 3/3] Makefile: Add cache-tree.h to the public headers list
From: Dmitry V. Levin @ 2007-09-05 23:22 UTC (permalink / raw)
  To: Git Mailing List; +Cc: Junio C Hamano

Some external projects (e.g. parsecvs) need cache-tree.h file.

Signed-off-by: Dmitry V. Levin <ldv@altlinux.org>
---
 Makefile |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/Makefile b/Makefile
index d50e30b..2b04829 100644
--- a/Makefile
+++ b/Makefile
@@ -283,7 +283,7 @@ LIB_FILE=libgit.a
 XDIFF_LIB=xdiff/lib.a
 
 LIB_H = \
-	archive.h blob.h cache.h commit.h csum-file.h delta.h grep.h \
+	archive.h blob.h cache.h cache-tree.h commit.h csum-file.h delta.h grep.h \
 	diff.h object.h pack.h pkt-line.h quote.h refs.h list-objects.h sideband.h \
 	run-command.h strbuf.h tag.h tree.h git-compat-util.h revision.h \
 	tree-walk.h log-tree.h dir.h path-list.h unpack-trees.h builtin.h \
-- 
ldv

^ permalink raw reply related

* [PATCH 1/2] git-commit: Disallow unchanged tree in non-merge mode
From: Dmitry V. Levin @ 2007-09-05 23:49 UTC (permalink / raw)
  To: Git Mailing List; +Cc: Junio C Hamano

Do not commit an unchanged tree in non-merge mode.

While regular mode is already handled by git-runstatus, this cheap check
allows to avoid costly git-runstatus later.  Also, amend mode needs
special attention, because git-runstatus return value is ignored.
The idea is that amend should not commit an unchanged tree,
one should just remove the top commit using git-reset instead.

Signed-off-by: Dmitry V. Levin <ldv@altlinux.org>
---
 git-commit.sh |   10 ++++++++++
 1 files changed, 10 insertions(+), 0 deletions(-)

diff --git a/git-commit.sh b/git-commit.sh
index 1d04f1f..800f96c 100755
--- a/git-commit.sh
+++ b/git-commit.sh
@@ -629,6 +629,16 @@ then
 		tree=$(GIT_INDEX_FILE="$TMP_INDEX" git write-tree) &&
 		rm -f "$TMP_INDEX"
 	fi &&
+	if test -n "$current" -a ! -f "$GIT_DIR/MERGE_HEAD"
+	then
+		current_tree="$(git cat-file commit "$current${amend:+^}" 2>/dev/null |
+				sed -e '/^tree \+/!d' -e 's///' -e q)"
+		if test "$tree" = "$current_tree"
+		then
+			echo >&2 "nothing to commit${amend:+ (use \"git reset HEAD^\" to remove the top commit)}"
+			false
+		fi
+	fi &&
 	commit=$(git commit-tree $tree $PARENTS <"$GIT_DIR/COMMIT_MSG") &&
 	rlogm=$(sed -e 1q "$GIT_DIR"/COMMIT_MSG) &&
 	git update-ref -m "$GIT_REFLOG_ACTION: $rlogm" HEAD $commit "$current" &&
-- 
ldv

^ permalink raw reply related

* [PATCH 2/2] git-commit: Add --no-status option
From: Dmitry V. Levin @ 2007-09-05 23:49 UTC (permalink / raw)
  To: Git Mailing List; +Cc: Junio C Hamano

By default, git-commit runs git-runstatus to print changes between
the index and the working tree.  This operation is very costly and
is not always necessary.  New option allows user to commit without
running git-runstatus when appropriate.

Signed-off-by: Dmitry V. Levin <ldv@altlinux.org>
---
 Documentation/git-commit.txt |    7 ++++++-
 git-commit.sh                |   11 ++++++++++-
 2 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/Documentation/git-commit.txt b/Documentation/git-commit.txt
index e54fb12..177e7cd 100644
--- a/Documentation/git-commit.txt
+++ b/Documentation/git-commit.txt
@@ -10,7 +10,7 @@ SYNOPSIS
 [verse]
 'git-commit' [-a | --interactive] [-s] [-v] [-u]
 	   [(-c | -C) <commit> | -F <file> | -m <msg> | --amend]
-	   [--no-verify] [-e] [--author <author>]
+	   [--no-status] [--no-verify] [-e] [--author <author>]
 	   [--] [[-i | -o ]<file>...]
 
 DESCRIPTION
@@ -85,6 +85,11 @@ OPTIONS
 -s|--signoff::
 	Add Signed-off-by line at the end of the commit message.
 
+--no-status::
+	Do not examine paths in the working tree that has changes
+	unrecorded to the index file, and changes between the
+	index file and the current commit.
+
 --no-verify::
 	This option bypasses the pre-commit hook.
 	See also link:hooks.html[hooks].
diff --git a/git-commit.sh b/git-commit.sh
index 800f96c..75126f1 100755
--- a/git-commit.sh
+++ b/git-commit.sh
@@ -3,7 +3,7 @@
 # Copyright (c) 2005 Linus Torvalds
 # Copyright (c) 2006 Junio C Hamano
 
-USAGE='[-a | --interactive] [-s] [-v] [--no-verify] [-m <message> | -F <logfile> | (-C|-c) <commit> | --amend] [-u] [-e] [--author <author>] [--template <file>] [[-i | -o] <path>...]'
+USAGE='[-a | --interactive] [-s] [-v] [--no-status] [--no-verify] [-m <message> | -F <logfile> | (-C|-c) <commit> | --amend] [-u] [-e] [--author <author>] [--template <file>] [[-i | -o] <path>...]'
 SUBDIRECTORY_OK=Yes
 . git-sh-setup
 require_work_tree
@@ -54,6 +54,7 @@ run_status () {
 	else
 		color=--nocolor
 	fi
+	test t = "$status" || return 0
 	git runstatus ${color} \
 		${verbose:+--verbose} \
 		${amend:+--amend} \
@@ -81,6 +82,7 @@ edit_flag=
 no_edit=
 log_given=
 log_message=
+status=t
 verify=t
 quiet=
 verbose=
@@ -184,6 +186,13 @@ $1"
 		no_edit=t
 		shift
 		;;
+	--no-s|--no-st|--no-sta|--no-stat|--no-statu|\
+	--no-status)
+		test "$status_only" = t &&
+			die "Option $1 does not make sense with ${0##*/}."
+		status=
+		shift
+		;;
 	-n|--n|--no|--no-|--no-v|--no-ve|--no-ver|--no-veri|--no-verif|\
 	--no-verify)
 		verify=
-- 
ldv

^ permalink raw reply related

* Re: People unaware of the importance of "git gc"?
From: Junio C Hamano @ 2007-09-05 23:42 UTC (permalink / raw)
  To: Nicolas Pitre; +Cc: Nix, Steven Grimm, Linus Torvalds, Git Mailing List
In-Reply-To: <alpine.LFD.0.9999.0709051858060.21186@xanadu.home>

Nicolas Pitre <nico@cam.org> writes:

> On Wed, 5 Sep 2007, Junio C Hamano wrote:
>
>> Nicolas Pitre <nico@cam.org> writes:
>> 
> The index?  What's that?  ;-)

Sorry, my mistake.  You are always more right than I am [tm] ;-)

> The more I think of it, the less I like automatic repack.  There is 
> always a bad case for it somewhere.

I tend to agree, but at the same time, I think the long term
goal should be not to have bad cases.

Old timers like ourselves learned to run "repack -a -d" when not
doing real work (i.e. beginning of the day while fetching
coffee, before leaving to lunch break, end of the day before
leaving) and we have been _trained_ not to feel that a choir,
but I think that is wrong.  "Sync freezes I/O for and causes my
real-time databasy job undue latency --- I would want to disable
swapper/bdflush/whatever machine-wide and prefer typing 'sync'
from the command line when it is convenient for me" is fine for
an experienced user working on a single user machine, but it
still feels wrong (we do not have "multi-user" issues in git
repository, so this analogy is not quite right, though).

^ permalink raw reply

* Re: People unaware of the importance of "git gc"?
From: Nicolas Pitre @ 2007-09-05 23:04 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Nix, Steven Grimm, Linus Torvalds, Git Mailing List
In-Reply-To: <7v1wdciy3w.fsf@gitster.siamese.dyndns.org>

On Wed, 5 Sep 2007, Junio C Hamano wrote:

> Nicolas Pitre <nico@cam.org> writes:
> 
> >> This patch does not add invocation of the "auto repacking".  It
> >> is left to key Porcelain commands that could produce tons of
> >> loose objects to add a call to "git gc --auto" after they are
> >> done their work.  Obvious candidates are:
> >> 
> >> 	git add
> >
> > Nope!  'git add' creates loose objects which are not yet reachable from 
> > anywhere.  They won't get repacked until a commit is made.
> 
> Bzzt, I am releaved to see you are sometimes wrong ;-)
> 
> They are reachable from the index and are not subject to
> pruning.

The index?  What's that?  ;-)

> >> 	git fetch
> >
> > I think that would be a much better idea to simply decrease the 
> > fetch.unpackLimit default value.
> 
> One thing that I find lacking in that auto patch is actually
> that we should sometimes consolidate multiple small packs into a
> single larger one.  Any behaviour change to encourage creation
> of many tiny packs should be avoided until it materializes.
> 
> Probably we should introduce a built-in minimum value for a
> positive gc.auto, somewhere around 1000 or so, for this reason.

Why not just let the default value take care of it?  If someone really 
wants to set gc.auto to 50, why prevent it?

The more I think of it, the less I like automatic repack.  There is 
always a bad case for it somewhere.


Nicolas

^ permalink raw reply

* Invoke "git gc --auto" from commit, merge, am and rebase.
From: Junio C Hamano @ 2007-09-05 21:59 UTC (permalink / raw)
  To: Nicolas Pitre; +Cc: Nix, Steven Grimm, Linus Torvalds, Git Mailing List
In-Reply-To: <7vwsv4hjfi.fsf@gitster.siamese.dyndns.org>

The point of auto gc is to pack new objects created in loose
format, so a good rule of thumb is where we do update-ref after
creating a new commit.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
  Let's chuck the previous "git add/git fetch" one, and replace it
  with this.

  Also I realize I misread your earlier comment about "git add".
  You are still among the only few people on the list that I
  consider are always more right than I am ;-).

 git-am.sh                  |    2 ++
 git-commit.sh              |    1 +
 git-merge.sh               |    1 +
 git-rebase--interactive.sh |    2 ++
 4 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/git-am.sh b/git-am.sh
index 6809aa0..4db4701 100755
--- a/git-am.sh
+++ b/git-am.sh
@@ -466,6 +466,8 @@ do
 		"$GIT_DIR"/hooks/post-applypatch
 	fi
 
+	git gc --auto
+
 	go_next
 done
 
diff --git a/git-commit.sh b/git-commit.sh
index 1d04f1f..d22d35e 100755
--- a/git-commit.sh
+++ b/git-commit.sh
@@ -652,6 +652,7 @@ git rerere
 
 if test "$ret" = 0
 then
+	git gc --auto
 	if test -x "$GIT_DIR"/hooks/post-commit
 	then
 		"$GIT_DIR"/hooks/post-commit
diff --git a/git-merge.sh b/git-merge.sh
index 3a01db0..697bec2 100755
--- a/git-merge.sh
+++ b/git-merge.sh
@@ -82,6 +82,7 @@ finish () {
 			;;
 		*)
 			git update-ref -m "$rlogm" HEAD "$1" "$head" || exit 1
+			git gc --auto
 			;;
 		esac
 		;;
diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh
index abc2b1c..8258b7a 100755
--- a/git-rebase--interactive.sh
+++ b/git-rebase--interactive.sh
@@ -307,6 +307,8 @@ do_next () {
 	rm -rf "$DOTEST" &&
 	warn "Successfully rebased and updated $HEADNAME."
 
+	git gc --auto
+
 	exit
 }
 

^ permalink raw reply related

* Re: People unaware of the importance of "git gc"?
From: Junio C Hamano @ 2007-09-05 21:49 UTC (permalink / raw)
  To: Nicolas Pitre; +Cc: Nix, Steven Grimm, Linus Torvalds, Git Mailing List
In-Reply-To: <alpine.LFD.0.9999.0709051634190.21186@xanadu.home>

Nicolas Pitre <nico@cam.org> writes:

> and git commit.  Which resumes it to commit creating operation.

Good point.  I think that makes sense.

^ permalink raw reply

* Re: People unaware of the importance of "git gc"?
From: Junio C Hamano @ 2007-09-05 21:46 UTC (permalink / raw)
  To: Nicolas Pitre; +Cc: Nix, Steven Grimm, Linus Torvalds, Git Mailing List
In-Reply-To: <alpine.LFD.0.9999.0709051634190.21186@xanadu.home>

Nicolas Pitre <nico@cam.org> writes:

>> This patch does not add invocation of the "auto repacking".  It
>> is left to key Porcelain commands that could produce tons of
>> loose objects to add a call to "git gc --auto" after they are
>> done their work.  Obvious candidates are:
>> 
>> 	git add
>
> Nope!  'git add' creates loose objects which are not yet reachable from 
> anywhere.  They won't get repacked until a commit is made.

Bzzt, I am releaved to see you are sometimes wrong ;-)

They are reachable from the index and are not subject to
pruning.

>> 	git fetch
>
> I think that would be a much better idea to simply decrease the 
> fetch.unpackLimit default value.

One thing that I find lacking in that auto patch is actually
that we should sometimes consolidate multiple small packs into a
single larger one.  Any behaviour change to encourage creation
of many tiny packs should be avoided until it materializes.

Probably we should introduce a built-in minimum value for a
positive gc.auto, somewhere around 1000 or so, for this reason.

^ permalink raw reply

* Re: [PATCH] Fix "cvs log" to use UTC timezone instead of local
From: Jonas Berlin @ 2007-09-05 21:45 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: git
In-Reply-To: <46DF2058.7060405@outerspace.dyndns.org>

Quoting Jonas Berlin on 09/05/2007 09:32 PM UTC:
> Quoting Linus Torvalds on 09/04/2007 01:22 PM UTC:
>> That can be done various ways:
>>
>>  - use the "raw log format" which has dates as seconds-since-UTC (and with 
>>    an *informational* timezone thing that should then just be ignored).
>>
>>    This is likely the best approach, since anything but this will 
> 
> This seems straightforward to implement, so I will go with this.

I just realized that since git-cvsserver creates a SQLite database (assumably for keeping track of what cvs revision numbers map to which git commits) AND the "timezonized" timestamps are stored as strings in there, switching to UTC timestamps would either break current SQLite databases or then require backwards compatibility code to handle the pretty-printed timestamp (with the UTC unrolling code from the patch I sent).

> I guess at this point it's good to mention that current cvs implementations (at least 1.12.12) produce timestamps of format "yyyy-mm-dd HH:MM:SS +ZZZZ" (i.e. they do include timezone information) while older versions (at least 1.11.22) produce the UTC-only format "yyyy/mm/dd HH:MM:SS" which is currently used by git-cvsserver. Backwards compatibility generally being a good thing, while at the expense of timezone information, I chose to keep the older UTC-only format. Should you prefer to keep the timezone information, I'll update the cvs log format instead. Heck, I could even support both through some configuration option if you really wanted :)

Another option would be to scrap support for old cvs clients.. I could investigate when the new format was introduced..

-- 
- xkr47

^ permalink raw reply

* Re: [PATCH] Fix "cvs log" to use UTC timezone instead of local
From: Jonas Berlin @ 2007-09-05 21:32 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: git
In-Reply-To: <alpine.LFD.0.999.0709040612260.3088@evo.linux-foundation.org>

Quoting Linus Torvalds on 09/04/2007 01:22 PM UTC:
> So instead of turning it back into UTC here, I think git-cvsserver should 
> be changed to ask for the date in the native git format in the first 
> place.

I agree.

My first patch was a minimal-intrusion one to avoid unnecessarily breaking stuff.

I guess at this point it's good to mention that current cvs implementations (at least 1.12.12) produce timestamps of format "yyyy-mm-dd HH:MM:SS +ZZZZ" (i.e. they do include timezone information) while older versions (at least 1.11.22) produce the UTC-only format "yyyy/mm/dd HH:MM:SS" which is currently used by git-cvsserver. Backwards compatibility generally being a good thing, while at the expense of timezone information, I chose to keep the older UTC-only format. Should you prefer to keep the timezone information, I'll update the cvs log format instead. Heck, I could even support both through some configuration option if you really wanted :)

> That can be done various ways:
> 
>  - use the "raw log format" which has dates as seconds-since-UTC (and with 
>    an *informational* timezone thing that should then just be ignored).
> 
>    This is likely the best approach, since anything but this will 

This seems straightforward to implement, so I will go with this.

> For example, I think your patch may fix "cvs log", but I'm seeing some 
> suspiciously similar code in the "cvs annotate" handling, so I suspect 
> that would need it too.

I will make sure this works as well.

-- 
- xkr47

^ permalink raw reply

* Re: Significant performance waste in git-svn and friends
From: David Kastrup @ 2007-09-05 21:19 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Mike Hommey, git
In-Reply-To: <7vd4wwj16d.fsf@gitster.siamese.dyndns.org>

Junio C Hamano <gitster@pobox.com> writes:

> Mike Hommey <mh@glandium.org> writes:
>
>> The same things obviously apply to git-cvsimport and other scripts
>> calling git-hash-object a lot.
>
> I *obviously* hate this patch, as it makes this Porcelain
> command to be aware of the internal representation too much.
>
> I wonder if letting fast-import handle the object creation is an
> option, though.

I think it would be saner to give git-hash-object an operation mode
that makes it usable as a pipe-controlled daemon, so that one needs
not fork and exec for interning another object.  That way, porcelain
commands could keep one bidirectional pipe (feed object type and
source and whether to use -w into git-hash-project, receive object id)
to git-hash-object around until they finish.

-- 
David Kastrup, Kriemhildstr. 15, 44793 Bochum

^ permalink raw reply

* Re: People unaware of the importance of "git gc"?
From: Alex Riesen @ 2007-09-05 21:18 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Nicolas Pitre, Nix, Steven Grimm, Linus Torvalds,
	Git Mailing List
In-Reply-To: <7vr6lcj2zi.fsf@gitster.siamese.dyndns.org>

Junio C Hamano, Wed, Sep 05, 2007 22:01:37 +0200:
> +	/*
> +	 * Quickly check if a "gc" is needed, by estimating how
> +	 * many loose objects there are.  Because SHA-1 is evenly
> +	 * distributed, we can check only one and get a reasonable
> +	 * estimate.
> +	 */

:))

> +	if (sizeof(path) <= snprintf(path, sizeof(path), "%s/17", objdir)) {
> +		warning("insanely long object directory %.*s", 50, objdir);

or a non-POSIX snprintf returning "negative value" (Microsoft)

^ permalink raw reply

* Re: People unaware of the importance of "git gc"?
From: Nix @ 2007-09-05 21:14 UTC (permalink / raw)
  To: Nicolas Pitre
  Cc: Junio C Hamano, Steven Grimm, Linus Torvalds, Git Mailing List
In-Reply-To: <alpine.LFD.0.9999.0709051634190.21186@xanadu.home>

On 5 Sep 2007, Nicolas Pitre stated:

> On Wed, 5 Sep 2007, Junio C Hamano wrote:
>> 	git fetch
>
> I think that would be a much better idea to simply decrease the 
> fetch.unpackLimit default value.

I think `git fetch' works reasonably well as is: unless you're fetching
every five minutes you often find you get packs anyway. There's no point
packing incrementally *too* often, or you replace a lots-of-objects
problem with a lots-of-packs problem, after which you're worse off than
when you started.

^ permalink raw reply

* Re: People unaware of the importance of "git gc"?
From: Alex Riesen @ 2007-09-05 21:07 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Git Mailing List
In-Reply-To: <alpine.LFD.0.999.0709042355030.19879@evo.linux-foundation.org>

Linus Torvalds, Wed, Sep 05, 2007 09:09:27 +0200:
> I personally repack everything way more often than is necessary, and I had 
> kind of assumed that people did it that way, but I was apparently wrong. 
> Comments?

I do it from time to time. Seldom in working repositories, because
they usually come and go before they have a chance to accumulate
enough of loose objects. I do a partial repack (git repack -d) after
every import from p4 repo, because every snapshot of it is an ugly
mess changing files all over the tree. Sometimes, after I merged a big
chunk with the p4 repo and sent it over (the process involves rebase).

It is usually concious decision when to do a repack or gc. The repack
time is seldom a problem: it is fast enough even on windows (and I do
have big repos and binary objects). The gc causes my machines to swap,
though. Some of them heavily, so there my repos stay longer partially
packed. I do use .keep packs for this reason (and because windows or
cygwin or both have more problems with big files the they have with
small).

I used to clone repos with "-s", but quickly stopped after a few
broken histories.  This also tought me to think before running
"git gc" or "git repack -a -d".

On a rare occurance I even use "git repack -a -d -l" and "git
pack-refs" separately.

This was all specific to my day-job. At home, on linux systems I just
run git-gc whenever I please, without even thinking why. It finishes
mostly in less than a minute (the kernel: ~40-50 sec on my P4 2.6GHz, 1Gb).

^ permalink raw reply

* Fwd: [PATCH] Invoke "git gc --auto" from "git add" and "git fetch"
From: Govind Salinas @ 2007-09-05 20:59 UTC (permalink / raw)
  To: Git Mailing List
In-Reply-To: <69b0c0350709051357ifa547aarfe3e0b36cf9be98f@mail.gmail.com>

Forgot to cc the list.

---------- Forwarded message ----------
From: Govind Salinas <govindsalinas@gmail.com>
Date: Sep 5, 2007 3:57 PM
Subject: Re: [PATCH] Invoke "git gc --auto" from "git add" and "git fetch"
To: Junio C Hamano <gitster@pobox.com>


I have a completely uninformed question...

Can git-add/rm/etc create dangling object or objects that would
be cleaned up by git-gc --auto?  I would think (and I could be
completely off base here) that you would only want to call gc
after an operation that could create stuff that needs to be gc'ed,
since only then could the threshold be reached.

Anyways, just curious.  One day I should actually go in and read
some git code.

-Govind

On 9/5/07, Junio C Hamano <gitster@pobox.com> wrote:
> This makes the two commands to call "git gc --auto" when they
> are done.
>
> I earlier said that obvious candidates also include merge and
> rebase, but these are lot less frequent operations compared to
> add, and more importantly, in a normal workflow they would
> almost always happen after "git fetch" is done.
>
> In other words, if you are downstream developer, the automatic
> invocation in "git fetch" will take care of things for you, and
> otherwise if you do not have an upstream, you would be doing
> your own development, so "git add" to add your changes will take
> care of the auto invocation for you.
>
> Signed-off-by: Junio C Hamano <gitster@pobox.com>
> ---
>  * This is obviously a follow-up to the previous one that allows
>    you to say "git gc --auto".  I somewhat feel dirty about
>    calling cmd_gc() bypassing fork & exec from "git add",
>    though...
>
>  builtin-add.c |    2 ++
>  git-fetch.sh  |    1 +
>  2 files changed, 3 insertions(+), 0 deletions(-)
>
> diff --git a/builtin-add.c b/builtin-add.c
> index 105a9f0..8431c16 100644
> --- a/builtin-add.c
> +++ b/builtin-add.c
> @@ -263,9 +263,11 @@ int cmd_add(int argc, const char **argv, const char *prefix)
>
>   finish:
>         if (active_cache_changed) {
> +               const char *args[] = { "gc", "--auto", NULL };
>                 if (write_cache(newfd, active_cache, active_nr) ||
>                     close(newfd) || commit_locked_index(&lock_file))
>                         die("Unable to write new index file");
> +               cmd_gc(2, args, NULL);
>         }
>
>         return 0;
> diff --git a/git-fetch.sh b/git-fetch.sh
> index c3a2001..86050eb 100755
> --- a/git-fetch.sh
> +++ b/git-fetch.sh
> @@ -375,3 +375,4 @@ case "$orig_head" in
>         fi
>         ;;
>  esac
> +git gc --auto
> --
> 1.5.3.1.840.g0fedbc
>
> -
> 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
>

^ permalink raw reply

* Re: Significant performance waste in git-svn and friends
From: Junio C Hamano @ 2007-09-05 20:40 UTC (permalink / raw)
  To: Mike Hommey; +Cc: git
In-Reply-To: <20070905184710.GA3632@glandium.org>

Mike Hommey <mh@glandium.org> writes:

> The same things obviously apply to git-cvsimport and other scripts
> calling git-hash-object a lot.

I *obviously* hate this patch, as it makes this Porcelain
command to be aware of the internal representation too much.

I wonder if letting fast-import handle the object creation is an
option, though.

^ permalink raw reply

* [PATCH] Invoke "git gc --auto" from "git add" and "git fetch"
From: Junio C Hamano @ 2007-09-05 20:37 UTC (permalink / raw)
  To: Nicolas Pitre; +Cc: Nix, Steven Grimm, Linus Torvalds, Git Mailing List
In-Reply-To: <7vr6lcj2zi.fsf@gitster.siamese.dyndns.org>

This makes the two commands to call "git gc --auto" when they
are done.

I earlier said that obvious candidates also include merge and
rebase, but these are lot less frequent operations compared to
add, and more importantly, in a normal workflow they would
almost always happen after "git fetch" is done.

In other words, if you are downstream developer, the automatic
invocation in "git fetch" will take care of things for you, and
otherwise if you do not have an upstream, you would be doing
your own development, so "git add" to add your changes will take
care of the auto invocation for you.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 * This is obviously a follow-up to the previous one that allows
   you to say "git gc --auto".  I somewhat feel dirty about
   calling cmd_gc() bypassing fork & exec from "git add",
   though...

 builtin-add.c |    2 ++
 git-fetch.sh  |    1 +
 2 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/builtin-add.c b/builtin-add.c
index 105a9f0..8431c16 100644
--- a/builtin-add.c
+++ b/builtin-add.c
@@ -263,9 +263,11 @@ int cmd_add(int argc, const char **argv, const char *prefix)
 
  finish:
 	if (active_cache_changed) {
+		const char *args[] = { "gc", "--auto", NULL };
 		if (write_cache(newfd, active_cache, active_nr) ||
 		    close(newfd) || commit_locked_index(&lock_file))
 			die("Unable to write new index file");
+		cmd_gc(2, args, NULL);
 	}
 
 	return 0;
diff --git a/git-fetch.sh b/git-fetch.sh
index c3a2001..86050eb 100755
--- a/git-fetch.sh
+++ b/git-fetch.sh
@@ -375,3 +375,4 @@ case "$orig_head" in
 	fi
 	;;
 esac
+git gc --auto
-- 
1.5.3.1.840.g0fedbc

^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox