Git development
 help / color / mirror / Atom feed
* Re: [ANNOUNCE] CGit v0.1-pre
From: Lars Hjemli @ 2006-12-11  8:33 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: git
In-Reply-To: <Pine.LNX.4.64.0612101653420.12500@woody.osdl.org>

On 12/11/06, Linus Torvalds <torvalds@osdl.org> wrote:
> you really want to re-check the existence after you got the lock,
> otherwise you would race with somebody else that got the lock, generated
> the data, and then unlocked (and you got the lock _after_ the data was
> generated, so now you generate it unnecessarily).

Yes, you're right. Thanks for noticing.

But this also applies to the case where the cachefile has expired,
right? In that case, after getting the lock, I have to recheck that
the cachefile is _still_ expired.

Anyway, I must say I find it rather unlikely for these cases to occur
(frequently) in real life. That would seem to imply that the caching
isn't really needed at all.

>
> As a side note: how do you release your caches?
>

Simple timeouts (time()-stat.st_mtime), depending on what kind of page
was requested. If anyone cares about invalid cache content (branch
head moving), relevant cachefiles can be deleted with an update-hook.

-- 

^ permalink raw reply

* Re: kernel.org mirroring (Re: [GIT PULL] MMC update)
From: Jakub Narebski @ 2006-12-11  8:59 UTC (permalink / raw)
  To: Martin Langhoff
  Cc: Jeff Garzik, Git Mailing List, Linus Torvalds, H. Peter Anvin,
	Rogan Dawes, Kernel Org Admin
In-Reply-To: <46a038f90612101816j33870bb1j39182358440aaa40@mail.gmail.com>

Martin Langhoff wrote:
> On 12/11/06, Jakub Narebski <jnareb@gmail.com> wrote:
>>
>> Even if Apache does execute CGI script to completion every time, it might
>> not send the output of the script, but HTTP 304 Not Modified reply. Might.
>> I don't know if it does.
> 
> It is up to the script (CGI or via mod_perl) to set the status to 304
> and finish execution. Just setting the status to 304 does not
> forcefully end execution as you may want to cleanup, log, etc.

I was thinking not about ending execution, but about not sending script
output but sending HTTP 304 Not Modified reply by Apache.

I meant the following sequence of events:
 1. Script sends headers, among those Last-Modified and/or ETag
 2. Apache scans headers (e.g. to add its own), notices that Last-Modified
    is earlier or equal to If-Modified-Since: sent by browser or reverse
    proxy, or ETag matches If-None-Match:, and sends 304 instead of script
    output
 3. Script finishes execution, it's output sent to /dev/null

Again, I don't know if Apache (or any other web server) does that. 
-- 
Jakub Narebski

^ permalink raw reply

* Re: Problems with git-svn authors file
From: Andy Parkins @ 2006-12-11  9:04 UTC (permalink / raw)
  To: git
In-Reply-To: <20061210172604.GA18385@hermes.lan.home.vilz.de>

On Sunday 2006 December 10 17:26, Nicolas Vilz wrote:

> Use of uninitialized value in hash element at /usr/bin/git-svn line
> 2952.
> Use of uninitialized value in concatenation (.) or string at
> /usr/bin/git-svn line 2953.
> Author:  not defined in .git/info/svn-authors file
> 512 at /usr/bin/git-svn line 457
>         main::fetch_lib() called at /usr/bin/git-svn line 328
>         main::fetch() called at /usr/bin/git-svn line 187

I've had errors like this.  For certain repositories (possibly very old ones) 
there is an unusual, empty, revision 0.  I got around the problem by telling 
git-svn to start at revision 1.  Everything seemed fine after that.

$ git-svn fetch -r1

I don't know if that will be your fix, but it's worth a try.


Andy
-- 
Dr Andy Parkins, M Eng (hons), MIEE

^ permalink raw reply

* Re: error: Can't lock ref
From: Andreas Ericsson @ 2006-12-11  9:08 UTC (permalink / raw)
  To: Jon Masters; +Cc: git
In-Reply-To: <457D0F97.6050801@jonmasters.org>

Jon Masters wrote:
> Hi folks,
> 
> I've just pushed up a packed git repo:
> 
> http://www.kerneltools.org/pub/downloads/module-init-tools/devel/module-init-tools.git 
> 
> 
> Attempting to clone this repo using http generates the error in 
> $subject. Brief searching via Google suggests this is an appache 
> permissions problem - anyone got a trivially obvious apache config fix 
> before I go trawling through to figure out what's up?
> 

What does your apache error log say?

-- 
Andreas Ericsson                   andreas.ericsson@op5.se
OP5 AB                             www.op5.se

^ permalink raw reply

* Does pushing to git demon works ?
From: Alexander Litvinov @ 2006-12-11  9:13 UTC (permalink / raw)
  To: git

I tried pushing without success:
> git version
git version 1.4.4.2
> mkdir 1 && cd 1 && git init-db
defaulting to local storage area
> date >> a && git add a && git commit -m "add a" a
Committing initial tree 359e888a2d88e9dfcc9b269bc0b2fb1d9ba0013e
> date >> a && git commit -m "edit a" a
> touch .git/git-daemon-export-ok
> git daemon --verbose --reuseaddr --listen=127.0.0.1
... log here ...
[21607] Extended attributes (16 bytes) exist <host=127.0.0.1>
[21607] Request upload-pack for '/tmp/1'
[21607] Disconnected
[21669] Connection from 127.0.0.1:49875
[21669] Extended attributes (16 bytes) exist <host=127.0.0.1>
[21669] Protocol error: 'git-receive-pack /tmp/1'
[21669] Disconnected (with error)

at another conole:
> git clone git://127.0.0.1/tmp/1 2
remote: Generating pack...
remote: Done counting 6 objects.
remote: Deltifying 6 objects.
remote:  100% (6/6) done
remote: Total 6, written 6 (delta 0), reused 0 (delta 0)
Indexing 6 objects.
 100% (6/6) done
> cd 2
> date >> a && git commit -a -m "2"
> git push
fatal: unexpected EOF
> 

What should I do to make it work ?

Thanks for help,

^ permalink raw reply

* [PATCH] git-add --interactive (wip)
From: Junio C Hamano @ 2006-12-11  9:23 UTC (permalink / raw)
  To: git; +Cc: Josef Weidendorfer
In-Reply-To: <7vd56s8t9w.fsf@assigned-by-dhcp.cox.net>

A script to be driven when the user says "git add --interactive"
is introduced.

When it is run, first it runs its internal 'status' command to
show the current status, and then goes into its internactive
command loop.

The command loop shows the list of subcommands available, and
gives a prompt "What now> ".  In general, when the prompt ends
with a single '>', you can pick only one of the choices given
and type return, like this:

    *** Commands ***
      1: status       2: update       3: revert       4: add untracked
      5: patch        6: diff         7: quit         8: help
    What now> 1

You also could say "s" or "sta" or "status" above as long as the
choice is unique.

The main command loop has 6 subcommands (plus help and quit).

 * 'status' shows the change between HEAD and index (i.e. what
   will be committed if you say "git commit"), and between index
   and working tree files (i.e. what you could stage further
   before "git commit" using "git-add") for each path.  A sample
   output looks like this:

              staged     unstaged path
     1:       binary      nothing foo.png
     2:     +403/-35        +1/-1 git-add--interactive.perl

   It shows that foo.png has differences from HEAD (but that is
   binary so line count cannot be shown) and there is no
   difference between indexed copy and the working tree
   version (if the working tree version were also different,
   'binary' would have been shown in place of 'nothing').  The
   other file, git-add--interactive.perl, has 403 lines added
   and 35 lines deleted if you commit what is in the index, but
   working tree file has further modifications (one addition and
   one deletion).

 * 'update' shows the status information and gives prompt
   "Update>>".  When the prompt ends with double '>>', you can
   make more than one selection, concatenated with whitespace or
   comma.  Also you can say ranges.  E.g. "2-5 7,9" to choose
   2,3,4,5,7,9 from the list.  You can say '*' to choose
   everything.

   What you chose are then highlighted with '*', like this:

              staged     unstaged path
     1:       binary      nothing foo.png
   * 2:     +403/-35        +1/-1 git-add--interactive.perl

   To remove selection, prefix the input with - like this:

        Update>> -2

   After making the selection, answer with an empty line to
   stage the contents of working tree files for selected paths
   in the index.

 * 'revert' has a very similar UI to 'update', and the staged
   information for selected paths are reverted to that of the
   HEAD version.  Reverting new paths makes them untracked.

 * 'add untracked' has a very similar UI to 'update' and
   'revert', and lets you add untracked paths to the index.

 * 'patch' lets you choose one path out of 'status' like
   selection.  After choosing the path, it presents diff between
   the index and the working tree file and asks you if you want
   to stage the change of each hunk.  You can say:

        y - add the change from that hunk to index
        n - do not add the change from that hunk to index
        a - add the change from that hunk and all the rest to index
        d - do not the change from that hunk nor any of the rest to index
        j - do not decide on this hunk now, and view the next
            undecided hunk
        J - do not decide on this hunk now, and view the next hunk
        k - do not decide on this hunk now, and view the previous
            undecided hunk
        K - do not decide on this hunk now, and view the previous hunk

   After deciding the fate for all hunks, if there is any hunk
   that was chosen, the index is updated with the selected hunks.

 * 'diff' lets you review what will be committed (i.e. between
   HEAD and index).

This is still rough, but does everything except a few things I
think are needed.

 * 'patch' should be able to allow splitting a hunk into
   multiple hunks.

 * 'patch' does not adjust the line offsets @@ -k,l +m,n @@
   in the hunk header.  This does not have major problem in
   practice, but it _should_ do the adjustment.

 * It does not have any explicit support for a merge in
   progress; it may not work at all.

As is any of my initial WIP, the UI of this presents what it
does in a horribly crappy way.  Improvement patches are
appreciated, but wishlist without code are not really...

Signed-off-by: Junio C Hamano <junkio@cox.net>
---
 .gitignore                |    1 +
 Makefile                  |    1 +
 builtin-add.c             |   15 ++
 git-add--interactive.perl |  534 +++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 551 insertions(+), 0 deletions(-)

diff --git a/.gitignore b/.gitignore
index 7f2cd55..edf93a6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,6 +2,7 @@ GIT-CFLAGS
 GIT-VERSION-FILE
 git
 git-add
+git-add--interactive
 git-am
 git-annotate
 git-apply
diff --git a/Makefile b/Makefile
index a1861de..cdd4bf0 100644
--- a/Makefile
+++ b/Makefile
@@ -174,6 +174,7 @@ SCRIPT_SH = \
 	git-lost-found.sh git-quiltimport.sh
 
 SCRIPT_PERL = \
+	git-add--interactive.perl \
 	git-archimport.perl git-cvsimport.perl git-relink.perl \
 	git-rerere.perl \
 	git-cvsserver.perl \
diff --git a/builtin-add.c b/builtin-add.c
index febb75e..37a236e 100644
--- a/builtin-add.c
+++ b/builtin-add.c
@@ -8,6 +8,7 @@
 #include "cache.h"
 #include "builtin.h"
 #include "dir.h"
+#include "exec_cmd.h"
 #include "cache-tree.h"
 
 static const char builtin_add_usage[] =
@@ -89,6 +90,20 @@ int cmd_add(int argc, const char **argv, const char *prefix)
 	int verbose = 0, show_only = 0;
 	const char **pathspec;
 	struct dir_struct dir;
+	int add_interactive = 0;
+
+	for (i = 1; i < argc; i++) {
+		if (!strcmp("--interactive", argv[i]))
+			add_interactive++;
+	}
+	if (add_interactive) {
+		const char *args[] = { "add--interactive", NULL };
+
+		if (add_interactive != 1 || argc != 2)
+			die("add --interactive does not take any parameters");
+		execv_git_cmd(args);
+		exit(1);
+	}
 
 	git_config(git_default_config);
 
diff --git a/git-add--interactive.perl b/git-add--interactive.perl
new file mode 100755
index 0000000..7b42308
--- /dev/null
+++ b/git-add--interactive.perl
@@ -0,0 +1,534 @@
+#!/usr/bin/perl -w
+
+use strict;
+
+sub run_cmd_pipe {
+	my $fh = undef;
+	open($fh, '-|', @_) or die;
+	return <$fh>;
+}
+
+my ($GIT_DIR) = run_cmd_pipe(qw(git rev-parse --git-dir));
+
+if (!defined $GIT_DIR) {
+	exit(1); # rev-parse would have already said "not a git repo"
+}
+chomp($GIT_DIR);
+
+sub refresh {
+	system('git update-index --refresh 2>/dev/null');
+}
+
+sub list_untracked {
+	map {
+		chomp $_;
+		$_;
+	}
+	run_cmd_pipe(qw(git ls-files --others
+			--exclude-per-directory=.gitignore),
+		     "--exclude-from=$GIT_DIR/info/exclude",
+		     '--', @_);
+}
+
+my $status_fmt = '%12s %12s %s';
+my $status_head = sprintf($status_fmt, 'staged', 'unstaged', 'path');
+
+# Returns list of five tuples:
+# 0: print message
+# 1: pathname
+# 2: add/del between HEAD and index
+# 3: add/del between index and working tree
+# 4: binary
+sub list_modified {
+	my ($only) = @_;
+	my (%data, @return);
+	my ($add, $del, $adddel, $file);
+
+	if (!$only || ($only eq 'index-only')) {
+		for (run_cmd_pipe(qw(git diff-index --cached
+				     --numstat --summary HEAD))) {
+			if (($add, $del, $file) =
+			    /^([-\d]+)	([-\d]+)	(.*)/) {
+				my ($change, $bin);
+				if ($add eq '-' && $del eq '-') {
+					$change = 'binary';
+					$bin = 1;
+				}
+				else {
+					$change = "+$add/-$del";
+				}
+				$data{$file} =
+				    [$change, 'nothing', undef, undef, $bin];
+			}
+			elsif (($adddel, $file) =
+			       /^ (create|delete) mode [0-7]+ (.*)$/) {
+				$data{$file}[2] = $adddel;
+			}
+		}
+	}
+
+	if (!$only || ($only eq 'file-only')) {
+		for (run_cmd_pipe(qw(git diff-files --numstat --summary))) {
+			if (($add, $del, $file) =
+			    /^([-\d]+)	([-\d]+)	(.*)/) {
+				if (!exists $data{$file}) {
+					$data{$file} =
+					    ['unchanged', undef, undef, undef];
+				}
+				my ($change, $bin);
+				if ($add eq '-' && $del eq '-') {
+					$change = 'binary';
+					$bin = 1;
+				}
+				else {
+					$change = "+$add/-$del";
+				}
+				$data{$file}[1] = $change;
+				if ($bin) {
+					$data{$file}[4] = 1;
+				}
+			}
+			elsif (($adddel, $file) =
+			       /^ (create|delete) mode [0-7]+ (.*)$/) {
+				$data{$file}[3] = $adddel;
+			}
+		}
+	}
+
+	for (sort keys %data) {
+		my $it = $data{$_};
+		push @return, [(sprintf $status_fmt, @{$it}[0,1], $_), $_,
+			       @{$it}[2,3,4]];
+	}
+	return @return;
+}
+
+
+sub find_unique {
+	my ($string, @stuff) = @_;
+	my $found = undef;
+	for (my $i = 0; $i < @stuff; $i++) {
+		my $it = $stuff[$i];
+		my $hit = undef;
+		if (ref $it) { $it = $it->[0]; }
+		eval {
+			if ($it =~ /^$string/) {
+				$hit = 1;
+			};
+		};
+		if (defined $hit && defined $found) {
+			return undef;
+		}
+		if ($hit) {
+			$found = $i + 1;
+		}
+	}
+	return $found;
+}
+
+sub list_and_choose {
+	my ($opts, @stuff) = @_;
+	my (@chosen, @return);
+	my $i;
+
+      TOPLOOP:
+	while (1) {
+		my $last_lf = 0;
+
+		if ($opts->{HEADER}) {
+			if (!$opts->{LIST_FLAT}) {
+				print "     ";
+			}
+			print "$opts->{HEADER}\n";
+		}
+		for ($i = 0; $i < @stuff; $i++) {
+			my $chosen = $chosen[$i] ? '*' : ' ';
+			my $print = $stuff[$i];
+			if (ref $print) {
+				$print = $print->[0];
+			}
+			printf("%s%2d: %s", $chosen, $i+1, $print);
+			if (($opts->{LIST_FLAT}) &&
+			    (($i + 1) % ($opts->{LIST_FLAT}))) {
+				print "\t";
+				$last_lf = 0;
+			}
+			else {
+				print "\n";
+				$last_lf = 1;
+			}
+		}
+		if (!$last_lf) {
+			print "\n";
+		}
+
+		return if ($opts->{LIST_ONLY});
+
+		print $opts->{PROMPT};
+		if ($opts->{SINGLETON}) {
+			print "> ";
+		}
+		else {
+			print ">> ";
+		}
+		my $line = <STDIN>;
+		last if (!$line);
+		chomp $line;
+		my $donesomething = 0;
+		for my $choice (split(/[\s,]+/, $line)) {
+			my $choose = 1;
+			my ($bottom, $top);
+
+			# Input that begins with '-'; unchoose
+			if ($choice =~ s/^-//) {
+				$choose = 0;
+			}
+			# A range can be specified like 5-7
+			if ($choice =~ /^(\d+)-(\d+)$/) {
+				($bottom, $top) = ($1, $2);
+			}
+			elsif ($choice =~ /^\d+$/) {
+				$bottom = $top = $choice;
+			}
+			elsif ($choice eq '*') {
+				$bottom = 1;
+				$top = 1 + @stuff;
+			}
+			else {
+				$bottom = $top = find_unique($choice, @stuff);
+				if (!defined $bottom) {
+					print "Huh ($choice)?\n";
+					next TOPLOOP;
+				}
+			}
+			if ($opts->{SINGLETON} && $bottom != $top) {
+				print "Huh ($choice)?\n";
+				next TOPLOOP;
+			}
+			for ($i = $bottom-1; $i <= $top-1; $i++) {
+				next if (@stuff <= $i);
+				$chosen[$i] = $choose;
+				$donesomething++;
+			}
+		}
+		last if (!$donesomething || $opts->{IMMEDIATE});
+	}
+	for ($i = 0; $i < @stuff; $i++) {
+		if ($chosen[$i]) {
+			push @return, $stuff[$i];
+		}
+	}
+	return @return;
+}
+
+sub status_cmd {
+	list_and_choose({ LIST_ONLY => 1, HEADER => $status_head },
+			list_modified());
+	print "\n";
+}
+
+sub say_n_paths {
+	my $did = shift @_;
+	my $cnt = scalar @_;
+	print "$did ";
+	if (1 < $cnt) {
+		print "$cnt paths\n";
+	}
+	else {
+		print "one path\n";
+	}
+}
+
+sub update_cmd {
+	my @mods = list_modified('file-only');
+	return if (!@mods);
+
+	my @update = list_and_choose({ PROMPT => 'Update',
+				       HEADER => $status_head, },
+				     @mods);
+	if (@update) {
+		system(qw(git update-index --add --), map { $_->[1] } @update);
+		say_n_paths('updated', @update);
+	}
+	print "\n";
+}
+
+sub revert_cmd {
+	my @update = list_and_choose({ PROMPT => 'Revert',
+				       HEADER => $status_head, },
+				     list_modified());
+	if (@update) {
+		my @lines = run_cmd_pipe(qw(git ls-tree HEAD --),
+					 map { $_->[1] } @update);
+		my $fh;
+		open $fh, '|-', qw(git update-index --index-info)
+		    or die;
+		for (@lines) {
+			print $fh $_;
+		}
+		close($fh);
+		for (@update) {
+			if ($_->[2] && $_->[2] eq 'create') {
+				system(qw(git update-index --force-remove --),
+				       $_->[1]);
+				print "note: $_->[1] is untracked now.\n";
+			}
+		}
+		refresh();
+		say_n_paths('reverted', @update);
+	}
+	print "\n";
+}
+
+sub add_untracked_cmd {
+	my @add = list_and_choose({ PROMPT => 'Add untracked' },
+				  list_untracked());
+	if (@add) {
+		system(qw(git update-index --add --), @add);
+		say_n_paths('added', @add);
+	}
+	print "\n";
+}
+
+sub parse_diff {
+	my ($path) = @_;
+	my @diff = run_cmd_pipe(qw(git diff-files -p --), $path);
+	my (@hunk) = { TEXT => [] };
+
+	for (@diff) {
+		if (/^@@ /) {
+			push @hunk, { TEXT => [] };
+		}
+		push @{$hunk[-1]{TEXT}}, $_;
+	}
+	return @hunk;
+}
+
+sub help_patch_cmd {
+	print <<\EOF ;
+y - stage this hunk
+n - do not stage this hunk
+a - stage this and all the remaining hunks
+d - do not stage this hunk nor any of the remaining hunks
+j - leave this hunk undecided, see next undecided hunk
+J - leave this hunk undecided, see next hunk
+k - leave this hunk undecided, see previous undecided hunk
+K - leave this hunk undecided, see previous hunk
+EOF
+}
+
+sub patch_update_cmd {
+	my @mods = list_modified('file-only');
+	@mods = grep { !($_->[4]) } @mods;
+	return if (!@mods);
+
+	my ($it) = list_and_choose({ PROMPT => 'Patch update',
+				     SINGLETON => 1,
+				     IMMEDIATE => 1,
+				     HEADER => $status_head, },
+				   @mods);
+	return if (!$it);
+
+	my ($ix, $num);
+	my $path = $it->[1];
+	my ($head, @hunk) = parse_diff($path);
+	for (@{$head->{TEXT}}) {
+		print;
+	}
+	$num = scalar @hunk;
+	$ix = 0;
+
+	while (1) {
+		my ($prev, $next, $other, $undecided);
+		$other = '';
+
+		if ($num <= $ix) {
+			$ix = 0;
+		}
+		for (my $i = 0; $i < $ix; $i++) {
+			if (!defined $hunk[$i]{USE}) {
+				$prev = 1;
+				$other .= '/k';
+				last;
+			}
+		}
+		if ($ix) {
+			$other .= '/K';
+		}
+		for (my $i = $ix + 1; $i < $num; $i++) {
+			if (!defined $hunk[$i]{USE}) {
+				$next = 1;
+				$other .= '/j';
+				last;
+			}
+		}
+		if ($ix < $num - 1) {
+			$other .= '/J';
+		}
+		for (my $i = 0; $i < $num; $i++) {
+			if (!defined $hunk[$i]{USE}) {
+				$undecided = 1;
+				last;
+			}
+		}
+		last if (!$undecided);
+
+		for (@{$hunk[$ix]{TEXT}}) {
+			print;
+		}
+		print "Stage this hunk [y/n/a/d$other/?]? ";
+		my $line = <STDIN>;
+		if ($line) {
+			if ($line =~ /^y/i) {
+				$hunk[$ix]{USE} = 1;
+			}
+			elsif ($line =~ /^n/i) {
+				$hunk[$ix]{USE} = 0;
+			}
+			elsif ($line =~ /^a/i) {
+				while ($ix < $num) {
+					if (!defined $hunk[$ix]{USE}) {
+						$hunk[$ix]{USE} = 1;
+					}
+					$ix++;
+				}
+				next;
+			}
+			elsif ($line =~ /^d/i) {
+				while ($ix < $num) {
+					if (!defined $hunk[$ix]{USE}) {
+						$hunk[$ix]{USE} = 0;
+					}
+					$ix++;
+				}
+				next;
+			}
+			elsif ($other =~ /K/ && $line =~ /^K/) {
+				$ix--;
+				next;
+			}
+			elsif ($other =~ /J/ && $line =~ /^J/) {
+				$ix++;
+				next;
+			}
+			elsif ($other =~ /k/ && $line =~ /^k/) {
+				while (1) {
+					$ix--;
+					last if (!$ix ||
+						 !defined $hunk[$ix]{USE});
+				}
+				next;
+			}
+			elsif ($other =~ /j/ && $line =~ /^j/) {
+				while (1) {
+					$ix++;
+					last if ($ix >= $num ||
+						 !defined $hunk[$ix]{USE});
+				}
+				next;
+			}
+			else {
+				help_patch_cmd($other);
+				next;
+			}
+			# soft increment
+			while (1) {
+				$ix++;
+				last if ($ix >= $num ||
+					 !defined $hunk[$ix]{USE});
+			}
+		}
+	}
+
+	my ($o_lno, $n_lno);
+	my @result = ();
+	for (@hunk) {
+		my $text = $_->{TEXT};
+		my ($o_ofs, $o_cnt, $n_ofs, $n_cnt) =
+		    $text->[0] =~ /^@@ -(\d+)(?:,(\d+)) \+(\d+)(?:,(\d+)) @@/;
+		if (!$_->{USE}) {
+			# Adjust offset here.
+			next;
+		}
+		else {
+			for (@$text) {
+				push @result, $_;
+			}
+		}
+	}
+
+	if (@result) {
+		my $fh;
+
+		open $fh, '|-', qw(git apply --cached);
+		for (@{$head->{TEXT}}, @result) {
+			print $fh $_;
+		}
+		close $fh;
+		refresh();
+	}
+
+	print "\n";
+}
+
+sub diff_cmd {
+	my @mods = list_modified('index-only');
+	@mods = grep { !($_->[4]) } @mods;
+	return if (!@mods);
+	my ($it) = list_and_choose({ PROMPT => 'Review diff',
+				     SINGLETON => 1,
+				     IMMEDIATE => 1,
+				     HEADER => $status_head, },
+				   @mods);
+	return if (!$it);
+	system(qw(git diff-index -p --cc --cached HEAD --), $it->[1]);
+}
+
+sub quit_cmd {
+	print "Bye.\n";
+	exit(0);
+}
+
+sub help_cmd {
+	print <<\EOF ;
+status        - show paths with changes
+update        - add working tree state to the staged set of changes
+revert        - revert staged set of changes back to the HEAD version
+patch         - pick hunks and update selectively
+diff	      - view diff between HEAD and index
+add untracked - add contents of untracked files to the staged set of changes
+EOF
+}
+
+sub main_loop {
+	my @cmd = ([ 'status', \&status_cmd, ],
+		   [ 'update', \&update_cmd, ],
+		   [ 'revert', \&revert_cmd, ],
+		   [ 'add untracked', \&add_untracked_cmd, ],
+		   [ 'patch', \&patch_update_cmd, ],
+		   [ 'diff', \&diff_cmd, ],
+		   [ 'quit', \&quit_cmd, ],
+		   [ 'help', \&help_cmd, ],
+	);
+	while (1) {
+		my ($it) = list_and_choose({ PROMPT => 'What now',
+					     SINGLETON => 1,
+					     LIST_FLAT => 4,
+					     HEADER => '*** Commands ***',
+					     IMMEDIATE => 1 }, @cmd);
+		if ($it) {
+			eval {
+				$it->[1]->();
+			};
+			if ($@) {
+				print "$@";
+			}
+		}
+	}
+}
+
+my @z;
+
+refresh();
+status_cmd();
+main_loop();
-- 
1.4.4.2.gdfd96


^ permalink raw reply related

* Re: [RFC \ WISH] Add -o option to git-rev-list
From: Josef Weidendorfer @ 2006-12-11  9:26 UTC (permalink / raw)
  To: Marco Costalba
  Cc: Linus Torvalds, Git Mailing List, Junio C Hamano, Alex Riesen,
	Shawn Pearce
In-Reply-To: <e5bfff550612101615u5f588513n499e3b88ce14a6f6@mail.gmail.com>

On Monday 11 December 2006 01:15, Marco Costalba wrote:
> 		guiUpdateTimer.start(100, true);

What is the result with	"guiUpdateTimer.start(0, true);" ?
There is no need to put in any time interval at all, because
the timeout is a normal event which will be queued in the GUI
event queue.

If there were X events in the mean time, they are queued and handled
before your timeOut function is called again. So the GUI will be
responsive, even if you have a 0 ms timer. 


^ permalink raw reply

* Re: kernel.org mirroring (Re: [GIT PULL] MMC update)
From: Jakub Narebski @ 2006-12-11  9:30 UTC (permalink / raw)
  To: git
In-Reply-To: <20061211034018.16937.qmail@science.horizon.com>

Side note: I wonder why this mail is not attached to the rest of thread in
the gmane.comp.version-control.git news/Usenet GMane mirrot of git mailing
list.

linux@horizon.com wrote:

> Oh!  There is no per-directory shortlog page; that simplifies things.
> But there *should* be.)

There is. It is called "history" (and currently we have only shortlog-like
view for history and no log-like view).

> The only tricky thing is the "n minutes/hours/days ago" timestamps.
> Basically, you want to generate a half-formatted, indefinitely-cacheable
> page that contains them as absolute timestamps, and a have system for
> regenerating the fully-formatted page from that (and the current time).

Or use ECMAScript (JavaScript) for that. I plan (if this feature is
requested) to make it a %feature.

-- 
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git


^ permalink raw reply

* Re: Does pushing to git demon works ?
From: Jakub Narebski @ 2006-12-11  9:38 UTC (permalink / raw)
  To: git
In-Reply-To: <200612111513.05752.litvinov2004@gmail.com>

Alexander Litvinov wrote:

> I tried pushing [to git daemon] without success:

>$ git push
> fatal: unexpected EOF
> 
> What should I do to make it work ?

You cannot make it work. Git by design allow pushing only through
authenticated protocols. You can push via ssh+git:// and local,
you can push via http(s):// but you have to configure WebDAV, perhaps in the
future you would be able to push via ftp(s)://. The git:// and rsync://
protocols are read-only: you can fetch (pull) but you can't push.

P.S. Please send reply also to git mailing list
-- 
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git


^ permalink raw reply

* Re: [RFC \ WISH] Add -o option to git-rev-list
From: Alex Riesen @ 2006-12-11 10:00 UTC (permalink / raw)
  To: Marco Costalba
  Cc: Linus Torvalds, Git Mailing List, Junio C Hamano, Shawn Pearce
In-Reply-To: <e5bfff550612102317w331f3b0fyc3c6b095ff21191a@mail.gmail.com>

On 12/11/06, Marco Costalba <mcostalba@gmail.com> wrote:
>   $ time git rev-list --header --boundary --parents --topo-order HEAD
> /dev/null
> 3.04user 0.05system 0:03.09elapsed 100%CPU (0avgtext+0avgdata 0maxresident)k
> 0inputs+0outputs (0major+10141minor)pagefaults 0swaps

here you filtered output of git-rev-list by /dev/null, which makes no sense

> $ time git rev-list --header --boundary --parents --topo-order HEAD >
> /tmp/tmp.txt; cat /tmp/tmp.txt > /dev/null
> 3.44user 0.28system 0:03.74elapsed 99%CPU (0avgtext+0avgdata 0maxresident)k
> 0inputs+0outputs (0major+18033minor)pagefaults 0swaps

should be: time { git-rev-list >/tmp/tmp; cat /tmp/tmp >/dev/null; }

^ permalink raw reply

* Re: kernel.org mirroring (Re: [GIT PULL] MMC update)
From: Martin Langhoff @ 2006-12-11 10:18 UTC (permalink / raw)
  To: Jakub Narebski
  Cc: Jeff Garzik, Git Mailing List, Linus Torvalds, H. Peter Anvin,
	Rogan Dawes, Kernel Org Admin
In-Reply-To: <200612110959.56492.jnareb@gmail.com>

On 12/11/06, Jakub Narebski <jnareb@gmail.com> wrote:
> I was thinking not about ending execution, but about not sending script
> output but sending HTTP 304 Not Modified reply by Apache.
>
> I meant the following sequence of events:
>  1. Script sends headers, among those Last-Modified and/or ETag
>  2. Apache scans headers (e.g. to add its own), notices that Last-Modified
>     is earlier or equal to If-Modified-Since: sent by browser or reverse
>     proxy, or ETag matches If-None-Match:, and sends 304 instead of script
>     output
>  3. Script finishes execution, it's output sent to /dev/null
>
> Again, I don't know if Apache (or any other web server) does that.

It doesn't. You want to take the decision to send a 304, cleanup and
exit _inside_ the CGI. If it was up to apache, then the CGI script
would end up creating the (potentially expensive to produce) content
just to see it sent to /dev/null OR if apache was to terminate
execution of the CGI more violently, the CGI wouldn't have a chance to
cleanup and release resources.

So it's a matter of setting the header to 304 and exiting.

cheers,


martin


^ permalink raw reply

* Re: Using GIT to store /etc (Or: How to make GIT store all file permission bits)
From: Andreas Ericsson @ 2006-12-11 10:39 UTC (permalink / raw)
  To: Kyle Moffett; +Cc: Jakub Narebski, git
In-Reply-To: <19476830-E30A-42B7-AD9B-4C417D830C8E@mac.com>

Kyle Moffett wrote:
> On Dec 10, 2006, at 13:26:32, Jakub Narebski wrote:
>> The idea is to not store /etc in git directly, but use import/export 
>> scripts, which for example saves permissions and ownership in some 
>> file also tracked by git on import, and restores correct permissions 
>> on export. That is what I remember from this discussion. This of 
>> course means that you would have to write your own porcelain...
>>
>> What about mentioned in other email IsiSetup?
> 
> The real problem I have with that is you literally have to duplicate all 
> sorts of functionality.  I want to run "foo-status" in /etc and get 
> something useful, but if /etc is not a git directory in and of itself 
> then you have to duplicate most of "git-status" anyways.

Make /etc/.git a symlink to where you store your repo and go to the 
other directory when you want to *restore* configuration. The only "own 
porcelain" you need to write is a simple program that understands "save" 
and "restore" (or some such) and tucks away the meta-data in a file 
somewhere inside the git tree. If you make it in the format

octal-mode path/to/file

you can even get decently human-readable permission diffs, which will 
most likely be prettier and easier to read than anything git currently has.

> 
> GIT already has _some_ idea about file permissions, it just discards 
> most of the data before writing to disk.   Of course, adding POSIX ACLs
> and user-extended-attributes requires a new data format, but those are 
> very similar to filesystem permissions; they differ only in amount of 
> data stored, not in purpose.
> 

The amount of data stored is the issue here. The current implementation 
(which works just fine and does The Right Thing(tm) for code-repos) only 
stores what it has to and uses the spare bits to do other things.

> Import/export scripts literally require wrapping every single GIT 
> command with a script that changes directory a few times, reads from a 
> different checked-out tree, and permutes some extended-attribute data 
> slightly before storing it in the underlying GIT tree.  Even without 
> adding any new functionality whatsoever that doubles the amount of code 
> just for finding your repository and checking command-line arguments, 
> and that's a crazy trade-off to make in any situation.
> 

GIT_DIR=/some/where/else/.git git log -p

Why would you want to read from a different checked-out tree? 
Non-committed data is "changes", committed data is "HEAD" (or 
commit-ish) and marked data is "index". I see no reason what so ever for 
a second checked-out tree.

-- 
Andreas Ericsson                   andreas.ericsson@op5.se
OP5 AB                             www.op5.se

^ permalink raw reply

* Re: [PATCH] git-add --interactive (wip)
From: Josef Weidendorfer @ 2006-12-11 10:47 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <7vslfm23co.fsf_-_@assigned-by-dhcp.cox.net>

On Monday 11 December 2006 10:23, Junio C Hamano wrote:
> A script to be driven when the user says "git add --interactive"
> is introduced.

Cool.
Just allowing to unstage files this way makes me happy, thanks.

I just tried to work with this thing to separate my recent
"branch.*.localmerge" changes to the simple version I posted
afterwards.

I noted that I need to manually change a few dependent hunks,
so this "one hunk at a time" and not being able to edit changes
in a hunk does not fit my workflow.
Just as a sidenote: after deciding to not apply hunks, you
lose them in this WIP, as you will find nothing in "unstaged" mode
afterwards :-(

Despite not having a patch for it right now, it would work out
better for me to open the editor with the patch for one
file, and allow to edit it to *replace* the staged version.

Neverless, thanks for this WIP,

^ permalink raw reply

* Re: Using GIT to store /etc (Or: How to make GIT store all file permission bits)
From: Nikolai Weibull @ 2006-12-11 10:50 UTC (permalink / raw)
  To: Kyle Moffett; +Cc: git
In-Reply-To: <787BE48C-1808-4A33-A368-5E8A3F00C787@mac.com>

On 12/10/06, Kyle Moffett <mrmacman_g4@mac.com> wrote:
> I've recently become somewhat interested in the idea of using GIT to
> store the contents of various folders in /etc.  However after a bit
> of playing with this, I discovered that GIT doesn't actually preserve
> all permission bits since that would cause problems with the more
> traditional software development model.  I'm curious if anyone has
> done this before; and if so, how they went about handling the
> permissions and ownership issues.

I keep the files I want to track in a separate folder that I track
with Git and use a Makefile for updating /etc.  I basically have a
rule for checking for differences between the tracked folder and /etc
and a rule for installing changed files (with the correct
permissions).  It works, but it does require some "Makefile magic" to
work right (or the way /I/ want it anyway).


^ permalink raw reply

* Re: Using GIT to store /etc (Or: How to make GIT store all file permission bits)
From: Jeff Garzik @ 2006-12-11 10:55 UTC (permalink / raw)
  To: Kyle Moffett; +Cc: Andreas Ericsson, Jakub Narebski, git
In-Reply-To: <457D3573.2010001@op5.se>

Another option is to have a process that stores your configs in git, and 
script an export from git to rpm|deb.  Packaging systems make it even 
easier to go between config versions.

	Jeff



^ permalink raw reply

* Re: Does pushing to git demon works ?
From: Alexander Litvinov @ 2006-12-11 10:56 UTC (permalink / raw)
  To: Jakub Narebski, git
In-Reply-To: <elj8q6$32n$2@sea.gmane.org>

В сообщении от Monday 11 December 2006 15:38 Jakub Narebski написал(a):
> Alexander Litvinov wrote:
> > I tried pushing [to git daemon] without success:
> >
> >$ git push
> > fatal: unexpected EOF
> >
> > What should I do to make it work ?
>
> You cannot make it work. Git by design allow pushing only through
> authenticated protocols. You can push via ssh+git:// and local,
> you can push via http(s):// but you have to configure WebDAV, perhaps in
> the future you would be able to push via ftp(s)://. The git:// and rsync://
> protocols are read-only: you can fetch (pull) but you can't push.
>
> P.S. Please send reply also to git mailing list


^ permalink raw reply

* Re: [RFC \ WISH] Add -o option to git-rev-list
From: Andreas Ericsson @ 2006-12-11 11:39 UTC (permalink / raw)
  To: Marco Costalba
  Cc: Linus Torvalds, Git Mailing List, Junio C Hamano, Alex Riesen,
	Shawn Pearce
In-Reply-To: <e5bfff550612101151r5e77ddc0w8f61f36fc1f2920e@mail.gmail.com>

Marco Costalba wrote:
> On 12/10/06, Linus Torvalds <torvalds@osdl.org> wrote:
>>
>> Why don't you use the pipe and standard read()?
>>
>> Even if you use "popen()" and get a "FILE *" back, you can still do
>>
>>         int fd = fileno(file);
>>
>> and use the raw IO capabilities.
>>
>> The thing is, temporary files can actually be faster under Linux just
>> because the Linux page-cache simply kicks ass. But it's not going to be
>> _that_ big of a difference, and you need all that crazy "wait for 
>> rev-list
>> to finish" and the "clean up temp-file on errors" etc crap, so there's no
>> way it's a better solution.
>>
> 
> Two things.
> 
> - memory use: the next natural step with files is, instead of loading
> the file content in memory and *keep it there*, we could load one
> chunk at a time, index the chunk and discard. At the end we keep in
> memory only indexing info to quickly get to the data when needed, but
> the big part of data stay on the file.
> 

memory usage vs speed tradeoff. Since qgit is a pure user-app, I think 
it's safe to opt for the memory hungry option. If people run it on too 
lowbie hardware they'll just have to make do with other ways of viewing 
the DAG or shutting down some other programs.

> - This is probably my ignorance, but experimenting with popen() I
> found I could not know *when* git-rev-list ends because both feof()
> and ferror() give 0 after a fread() with git-rev-list already defunct.
> Not having a reference to the process (it is hidden behind popen() ),
> I had to check for 0 bytes read after a successful read (to avoid
> racing in case I ask the pipe before the first data it's ready) to
> know that job is finished and call pclose().
> 

(coding in MUA, so highly untested)

pid_t runcmd(const char **argv, const char **env, int *out, *int err)
{
	int pid;

	pipe(out);
	pipe(err);

	pid = fork();


	/* parent returns upon forking */
	if (pid) {
		/* close childs file-descriptors in our address space */
		close(out[0]);
		close(err[0]);
		return pid;
	}

	/* child */
	/* close parents file-descriptors */
	close(out[0]);
	close(err[0]);

	/* stdout and stderr writes to childs ends of the pipes */
	dup2(out[1], STDOUT_FILENO);
	dup2(err[1], STDERR_FILENO);
	execve(argv[0], argv, NULL);

	_exit(0); /* not reached unless execve() failed */
}

The caller can now read out[0] and err[0] as regular file-descriptors 
and has the pid of the child-process in the return value. The parent 
receives SIGCHILD if the child exits, the child receives EPIPE when 
writing if the parent crashes.

In a prudent implementation, the parent should waitpid(pid_t pid, int 
*status, WNOHANG) for the child every once in a while to collect its 
exit status gracefully.

Do some experimenting and I'm sure you'll find something suitable for you.

-- 
Andreas Ericsson                   andreas.ericsson@op5.se
OP5 AB                             www.op5.se

^ permalink raw reply

* Re: Problems with git-svn authors file
From: Nicolas Vilz @ 2006-12-11 11:44 UTC (permalink / raw)
  To: Andy Parkins; +Cc: git
In-Reply-To: <200612110904.54389.andyparkins@gmail.com>

On Mon, Dec 11, 2006 at 09:04:52AM +0000, Andy Parkins wrote:
> On Sunday 2006 December 10 17:26, Nicolas Vilz wrote:
> 
> > Use of uninitialized value in hash element at /usr/bin/git-svn line
> > 2952.
> > Use of uninitialized value in concatenation (.) or string at
> > /usr/bin/git-svn line 2953.
> > Author:  not defined in .git/info/svn-authors file
> > 512 at /usr/bin/git-svn line 457
> >         main::fetch_lib() called at /usr/bin/git-svn line 328
> >         main::fetch() called at /usr/bin/git-svn line 187
> 
> I've had errors like this.  For certain repositories (possibly very old ones) 
> there is an unusual, empty, revision 0.  I got around the problem by telling 
> git-svn to start at revision 1.  Everything seemed fine after that.
> 

Well it is a fresh repository. And you are right, there is an empty
revision 0. I didn't recognize that is was the revision 0 I got stuck
with. But it is obvious now :)

> $ git-svn fetch -r1
> 
> I don't know if that will be your fix, but it's worth a try.
That fixed it, thx.


^ permalink raw reply

* Re: [ANNOUNCE] CGit v0.1-pre
From: Lars Hjemli @ 2006-12-11 11:59 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: git
In-Reply-To: <8c5c35580612110033y4f6260c9xffeaf4457f4ead21@mail.gmail.com>

On 12/11/06, Lars Hjemli <hjemli@gmail.com> wrote:
> Anyway, I must say I find it rather unlikely for these cases to occur
> (frequently) in real life.

*blush*

Of course this will happen in real life, I just needed to think about
it for a while (it just depends on the _size_ of the thundering hurd,
right?)

Anyway, it's fixed (I think) and pushed out

-- 

^ permalink raw reply

* Re: Using GIT to store /etc (Or: How to make GIT store all file permission bits)
From: Josef Weidendorfer @ 2006-12-11 12:13 UTC (permalink / raw)
  To: Andreas Ericsson; +Cc: Kyle Moffett, Jakub Narebski, git
In-Reply-To: <457D3573.2010001@op5.se>

On Monday 11 December 2006 11:39, Andreas Ericsson wrote:
> > Import/export scripts literally require wrapping every single GIT 
> > command with a script that changes directory a few times, reads from a 
> > different checked-out tree, and permutes some extended-attribute data 
> > slightly before storing it in the underlying GIT tree.  Even without 
> > adding any new functionality whatsoever that doubles the amount of code 
> > just for finding your repository and checking command-line arguments, 
> > and that's a crazy trade-off to make in any situation.
> > 
> 
> GIT_DIR=/some/where/else/.git git log -p

Doing this everytime you want to run a git command *is* a lot of time
wasted for typing.

The .gitlink proposal would come in handy here: you have a simple
file instead of .git/, which links to the real repository.


^ permalink raw reply

* Re: [RFC \ WISH] Add -o option to git-rev-list
From: Marco Costalba @ 2006-12-11 12:52 UTC (permalink / raw)
  To: Josef Weidendorfer
  Cc: Linus Torvalds, Git Mailing List, Junio C Hamano, Alex Riesen,
	Shawn Pearce
In-Reply-To: <200612111026.23656.Josef.Weidendorfer@gmx.de>

On 12/11/06, Josef Weidendorfer <Josef.Weidendorfer@gmx.de> wrote:
> On Monday 11 December 2006 01:15, Marco Costalba wrote:
> >               guiUpdateTimer.start(100, true);
>
> What is the result with "guiUpdateTimer.start(0, true);" ?
> There is no need to put in any time interval at all, because
> the timeout is a normal event which will be queued in the GUI
> event queue.
>
> If there were X events in the mean time, they are queued and handled
> before your timeOut function is called again. So the GUI will be
> responsive, even if you have a 0 ms timer.
>

IOW you suggest to use a brute force polling of the pipe.

I'will try this, just to test the pipe, not the application because I
would really need to read data in big chunks.

Data read from pipe/file or something else is read in an array (char*
[]) and do not touched anymore, no more copies are made. For every
read a new array is allocated on the heap.

With chunks of 64KB, because each rev descriptions is about few
hundered bytes only few revs (about 1% with current linux tree) fall
at the boundary of the chunk, half in one and the rest in the next.
This boundary revs require a special handling that at the end involves
an additional copy.

If I get from the pipe very small data (few KB) probably it would be
better to read always in a local array of fixed size and then copy to
final destination in memory. But this imply that all the data work
copy is duplicated: instead of 30MB of data we'll going to move 60MB
(linux tree)

With big chunks of 64KB only about 1% of data (revs that fall at the
array boundary) is duplicated.


^ permalink raw reply

* Re: Collection of stgit issues and wishes
From: Catalin Marinas @ 2006-12-11 12:59 UTC (permalink / raw)
  To: Jakub Narebski; +Cc: git
In-Reply-To: <200612110037.54309.jnareb@gmail.com>

On 10/12/06, Jakub Narebski <jnareb@gmail.com> wrote:
> BTW. currently I use StGIT to manage a series of commits on feature
> branch which implements step-by-step single feature, and would be
> later send as a patch series. With StGIT I can work on final patch
> in series, notice that underlying feature developed in earlier patch
> (earlier commit) needs modification, so I do refresh, pop until
> given patch, change patch, push all, and work on patch.

Or, if you made a modification but you want it committed to an
underlying patch, use "refresh --patch" or "pop --keep; refresh".

BTW, if it's not clear for me how to initially structure a patch
series, I add everything to a patch and create underlying patches
afterwards and pick hunks from the big one (usually manually, though
native support in StGIT for this would be good, as someone pointed out
on this list). If all the hunks in the big patch were added to other
patches, pushing the big one should result in an empty patch
automatically (because of the three-way merging) and can be safely
removed.

-- 

^ permalink raw reply

* Re: [RFC \ WISH] Add -o option to git-rev-list
From: Marco Costalba @ 2006-12-11 12:59 UTC (permalink / raw)
  To: Andreas Ericsson
  Cc: Linus Torvalds, Git Mailing List, Junio C Hamano, Alex Riesen,
	Shawn Pearce
In-Reply-To: <457D4386.70408@op5.se>

On 12/11/06, Andreas Ericsson <ae@op5.se> wrote:
> Marco Costalba wrote:
> > On 12/10/06, Linus Torvalds <torvalds@osdl.org> wrote:
> >>
> >> Why don't you use the pipe and standard read()?
> >>
> >> Even if you use "popen()" and get a "FILE *" back, you can still do
> >>
> >>         int fd = fileno(file);
> >>
> >> and use the raw IO capabilities.
> >>
> >> The thing is, temporary files can actually be faster under Linux just
> >> because the Linux page-cache simply kicks ass. But it's not going to be
> >> _that_ big of a difference, and you need all that crazy "wait for
> >> rev-list
> >> to finish" and the "clean up temp-file on errors" etc crap, so there's no
> >> way it's a better solution.
> >>
> >
> > Two things.
> >
> > - memory use: the next natural step with files is, instead of loading
> > the file content in memory and *keep it there*, we could load one
> > chunk at a time, index the chunk and discard. At the end we keep in
> > memory only indexing info to quickly get to the data when needed, but
> > the big part of data stay on the file.
> >
>
> memory usage vs speed tradeoff. Since qgit is a pure user-app, I think
> it's safe to opt for the memory hungry option. If people run it on too
> lowbie hardware they'll just have to make do with other ways of viewing
> the DAG or shutting down some other programs.
>
> > - This is probably my ignorance, but experimenting with popen() I
> > found I could not know *when* git-rev-list ends because both feof()
> > and ferror() give 0 after a fread() with git-rev-list already defunct.
> > Not having a reference to the process (it is hidden behind popen() ),
> > I had to check for 0 bytes read after a successful read (to avoid
> > racing in case I ask the pipe before the first data it's ready) to
> > know that job is finished and call pclose().
> >
>
> (coding in MUA, so highly untested)
>

Thanks Andreas, I will do some tests with your code. But at first
sight I fail to see (I'm not an expert on this tough ;-)  ) where is
the difference from using popen() and fileno() to get the file
descriptors.

Thanks

^ permalink raw reply

* Re: [RFC \ WISH] Add -o option to git-rev-list
From: Josef Weidendorfer @ 2006-12-11 13:28 UTC (permalink / raw)
  To: Marco Costalba
  Cc: Linus Torvalds, Git Mailing List, Junio C Hamano, Alex Riesen,
	Shawn Pearce
In-Reply-To: <e5bfff550612110452t5bb18517yc0cf8278d4d9948c@mail.gmail.com>

On Monday 11 December 2006 13:52, Marco Costalba wrote:
> On 12/11/06, Josef Weidendorfer <Josef.Weidendorfer@gmx.de> wrote:
> > On Monday 11 December 2006 01:15, Marco Costalba wrote:
> > >               guiUpdateTimer.start(100, true);
> >
> > What is the result with "guiUpdateTimer.start(0, true);" ?
> ...
> IOW you suggest to use a brute force polling of the pipe.

Ah, yes. That is probably not what you want.

Why did you introduce the timer at all? What was the problem
with QProcess and handling its signal "data available" ?

If you do

	git-rev-list | cat > /dev/null

the consuming "cat" will do a blocking read, and this should have
the same property "handle data as fast as possible when they
come available" as QProcess with handling the data in
the handler of QProcess' signal "data available".

If it is about postprocessing the small data chunks you get (and the
double copy in memory), I do not think this is a problem: a machine
noadays usually should handle 1 GB/s bandwidth to memory. You probably
are loosing more with your 100ms timer.

Or am I missing something?


^ permalink raw reply

* Re: Using GIT to store /etc (Or: How to make GIT store all file permission bits)
From: Johannes Schindelin @ 2006-12-11 13:33 UTC (permalink / raw)
  To: Josef Weidendorfer; +Cc: Andreas Ericsson, Kyle Moffett, Jakub Narebski, git
In-Reply-To: <200612111313.34292.Josef.Weidendorfer@gmx.de>

Hi,

On Mon, 11 Dec 2006, Josef Weidendorfer wrote:

> On Monday 11 December 2006 11:39, Andreas Ericsson wrote:
> > > Import/export scripts literally require wrapping every single GIT 
> > > command with a script that changes directory a few times, reads from a 
> > > different checked-out tree, and permutes some extended-attribute data 
> > > slightly before storing it in the underlying GIT tree.  Even without 
> > > adding any new functionality whatsoever that doubles the amount of code 
> > > just for finding your repository and checking command-line arguments, 
> > > and that's a crazy trade-off to make in any situation.
> > > 
> > 
> > GIT_DIR=/some/where/else/.git git log -p
> 
> Doing this everytime you want to run a git command *is* a lot of time
> wasted for typing.
> 
> The .gitlink proposal would come in handy here: you have a simple
> file instead of .git/, which links to the real repository.

I beg your pardon; I'm just joining in. Why is a symbolic link for .git 
inacceptable?

Ciao,
Dscho

^ permalink raw reply


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