Git development
 help / color / mirror / Atom feed
* Re: git-gui messes up the diff view on non ASCII characters
From: Shawn O. Pearce @ 2007-11-11  5:59 UTC (permalink / raw)
  To: Michele Ballabio; +Cc: git, Peter Baumann
In-Reply-To: <200711092230.37905.barra_cuda@katamail.com>

Michele Ballabio <barra_cuda@katamail.com> wrote:
> On Friday 09 November 2007, Peter Baumann wrote:
> > I'm managing some UTF-8 encoded LaTeX files in git, which include some
> > non ASCII characters like the german ä,ö and ü. If I view the diff with
> > git-diff on an UTF8 enabled terminal, all looks nice. So does the diff
> > view in gitk after I commited my changes. Only git-gui shows some
> > "strange" characters, so I assume it is an encoding problem.
> > 
> > I have to admit that I'm totally unaware how this should work, but at
> > least I think my configuration is correct here, because otherwise git-diff
> > or gitk would show the same behaviour. Is there anything which could be
> > done to make git-gui happy, too?
> 
> It's a known issue, and already on Shawn's ToDo list. I have to add that
> viewing untracked UTF8 files in git-gui works just fine. Weird.

Cute.  That's because in the untracked case we open the file and
let the platform's chosen encoding be used to convert it into the
text viewer.  In the tracked diff case we force the encoding to
be in binary.

Now gitk works because it assumes the diff is in the same character
encoding as the commit message itself.  Since commit messages are
typically in UTF-8 (as that is the Git default encoding) then a
UTF-8 encoded file shows correctly in gitk.

What's the right behavior here?  Just assume the platform encoding
is correct for the file we are showing and show it?  Assume the
commit encoding configured in i18n.commitencoding is the correct
one for the file content?  Something else?

-- 
Shawn.

^ permalink raw reply

* [PATCH 0/3] git-svn log fixes
From: David D Kilzer @ 2007-11-11  6:10 UTC (permalink / raw)
  To: git; +Cc: gitster, David D Kilzer

This patch series contains varies fixes for the "git-svn log" command:

[PATCH 1/3] git-svn log: fix ascending revision ranges
[PATCH 2/3] git-svn log: include commit log for the smallest revision in a range
[PATCH 3/3] git-svn log: handle unreachable revisions like "svn log"

I am looking for feedback since this is my first significant patch series
for git.  (I posted a couple of documentation fixes and Makefile tweaks
previously.)

Thanks!

Dave
--
 git-svn.perl           |   60 ++++++++++++++++++++++++------------
 t/t9116-git-svn-log.sh |   80 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 120 insertions(+), 20 deletions(-)
--

^ permalink raw reply

* [PATCH 2/3] git-svn log: include commit log for the smallest revision in a range
From: David D Kilzer @ 2007-11-11  6:10 UTC (permalink / raw)
  To: git; +Cc: gitster, David D Kilzer
In-Reply-To: <1194761435-7286-2-git-send-email-ddkilzer@kilzer.net>

The "svn log -rM:N" command shows commit logs inclusive in the range [M,N].
Previously "git-svn log" always excluded the commit log for the smallest
revision in a range, whether the range was ascending or descending.  With
this patch, the smallest revision in a range is always shown.

Updated tests for ascending and descending revision ranges.

Signed-off-by: David D Kilzer <ddkilzer@kilzer.net>
---
 git-svn.perl           |    6 +++---
 t/t9116-git-svn-log.sh |    8 ++++----
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/git-svn.perl b/git-svn.perl
index 3c5a87d..39585d8 100755
--- a/git-svn.perl
+++ b/git-svn.perl
@@ -3592,9 +3592,9 @@ sub git_svn_log_cmd {
 		$c_min = $gs->rev_db_get($r_min);
 		if (defined $c_min && defined $c_max) {
 			if ($r_max > $r_min) {
-				push @cmd, "$c_min..$c_max";
+				push @cmd, "--boundary", "$c_min..$c_max";
 			} else {
-				push @cmd, "$c_max..$c_min";
+				push @cmd, "--boundary", "$c_max..$c_min";
 			}
 		} elsif ($r_max > $r_min) {
 			push @cmd, $c_max;
@@ -3773,7 +3773,7 @@ sub cmd_show_log {
 	my (@k, $c, $d, $stat);
 	my $esc_color = qr/(?:\033\[(?:(?:\d+;)*\d*)?m)*/;
 	while (<$log>) {
-		if (/^${esc_color}commit ($::sha1_short)/o) {
+		if (/^${esc_color}commit -?($::sha1_short)/o) {
 			my $cmt = $1;
 			if ($c && cmt_showable($c) && $c->{r} != $r_last) {
 				$r_last = $c->{r};
diff --git a/t/t9116-git-svn-log.sh b/t/t9116-git-svn-log.sh
index 618d7e9..5000892 100755
--- a/t/t9116-git-svn-log.sh
+++ b/t/t9116-git-svn-log.sh
@@ -45,18 +45,18 @@ test_expect_success 'run log against a from trunk' "
 	git svn log -r3 a | grep ^r3
 	"
 
-printf 'r2 \nr4 \n' > expected-range-r2-r4
+printf 'r1 \nr2 \nr4 \n' > expected-range-r1-r2-r4
 
 test_expect_success 'test ascending revision range' "
 	git reset --hard trunk &&
-	git svn log -r 1:4 | grep '^r[0-9]' | cut -d'|' -f1 | diff -u expected-range-r2-r4 -
+	git svn log -r 1:4 | grep '^r[0-9]' | cut -d'|' -f1 | diff -u expected-range-r1-r2-r4 -
 	"
 
-printf 'r4 \nr2 \n' > expected-range-r4-r2
+printf 'r4 \nr2 \nr1 \n' > expected-range-r4-r2-r1
 
 test_expect_success 'test descending revision range' "
 	git reset --hard trunk &&
-	git svn log -r 4:1 | grep '^r[0-9]' | cut -d'|' -f1 | diff -u expected-range-r4-r2 -
+	git svn log -r 4:1 | grep '^r[0-9]' | cut -d'|' -f1 | diff -u expected-range-r4-r2-r1 -
 	"
 
 test_done
-- 
1.5.3.4

^ permalink raw reply related

* [PATCH 3/3] git-svn log: handle unreachable revisions like "svn log"
From: David D Kilzer @ 2007-11-11  6:10 UTC (permalink / raw)
  To: git; +Cc: gitster, David D Kilzer
In-Reply-To: <1194761435-7286-3-git-send-email-ddkilzer@kilzer.net>

When unreachable revisions are given to "svn log", it displays all commit
logs in the given range that exist in the current tree.  (If no commit
logs are found in the current tree, it simply prints a single commit log
separator.)  This patch makes "git-svn log" behave the same way.

Ten tests added to t/t9116-git-svn-log.sh.

Signed-off-by: David D Kilzer <ddkilzer@kilzer.net>
---
 git-svn.perl           |   58 ++++++++++++++++++++++++++++--------------
 t/t9116-git-svn-log.sh |   66 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 105 insertions(+), 19 deletions(-)

diff --git a/git-svn.perl b/git-svn.perl
index 39585d8..c584715 100755
--- a/git-svn.perl
+++ b/git-svn.perl
@@ -2257,9 +2257,10 @@ sub rev_db_get {
 }
 
 sub find_rev_before {
-	my ($self, $rev, $eq_ok) = @_;
+	my ($self, $rev, $eq_ok, $min_rev) = @_;
 	--$rev unless $eq_ok;
-	while ($rev > 0) {
+	$min_rev ||= 1;
+	while ($rev >= $min_rev) {
 		if (my $c = $self->rev_db_get($rev)) {
 			return ($rev, $c);
 		}
@@ -2268,6 +2269,19 @@ sub find_rev_before {
 	return (undef, undef);
 }
 
+sub find_rev_after {
+	my ($self, $rev, $eq_ok, $max_rev) = @_;
+	++$rev unless $eq_ok;
+	$max_rev ||= $self->rev_db_max();
+	while ($rev <= $max_rev) {
+		if (my $c = $self->rev_db_get($rev)) {
+			return ($rev, $c);
+		}
+		++$rev;
+	}
+	return (undef, undef);
+}
+
 sub _new {
 	my ($class, $repo_id, $ref_id, $path) = @_;
 	unless (defined $repo_id && length $repo_id) {
@@ -3587,19 +3601,19 @@ sub git_svn_log_cmd {
 			push @cmd, $c;
 		}
 	} elsif (defined $r_max) {
-		my ($c_min, $c_max);
-		$c_max = $gs->rev_db_get($r_max);
-		$c_min = $gs->rev_db_get($r_min);
-		if (defined $c_min && defined $c_max) {
-			if ($r_max > $r_min) {
-				push @cmd, "--boundary", "$c_min..$c_max";
-			} else {
-				push @cmd, "--boundary", "$c_max..$c_min";
-			}
-		} elsif ($r_max > $r_min) {
-			push @cmd, $c_max;
+		if ($r_max < $r_min) {
+			($r_min, $r_max) = ($r_max, $r_min);
+		}
+		my (undef, $c_max) = $gs->find_rev_before($r_max, 1, $r_min);
+		my (undef, $c_min) = $gs->find_rev_after($r_min, 1, $r_max);
+		# If there are no commits in the range, both $c_max and $c_min
+		# will be undefined.  If there is at least 1 commit in the
+		# range, both will be defined.
+		return () if !defined $c_min;
+		if ($c_min eq $c_max) {
+			push @cmd, '--max-count=1', $c_min;
 		} else {
-			push @cmd, $c_min;
+			push @cmd, '--boundary', "$c_min..$c_max";
 		}
 	}
 	return (@cmd, @files);
@@ -3705,9 +3719,13 @@ sub show_commit_changed_paths {
 	print "Changed paths:\n", @{$c->{changed}};
 }
 
+sub commit_log_separator {
+    return ('-' x 72) . "\n";
+}
+
 sub show_commit_normal {
 	my ($c) = @_;
-	print '-' x72, "\nr$c->{r} | ";
+	print commit_log_separator(), "r$c->{r} | ";
 	print "$c->{c} | " if $show_commit;
 	print "$c->{a} | ", strftime("%Y-%m-%d %H:%M:%S %z (%a, %d %b %Y)",
 				 localtime($c->{t_utc})), ' | ';
@@ -3768,6 +3786,10 @@ sub cmd_show_log {
 
 	config_pager();
 	@args = git_svn_log_cmd($r_min, $r_max, @args);
+	if (!@args) {
+		print commit_log_separator() unless $incremental || $oneline;
+		return;
+	}
 	my $log = command_output_pipe(@args);
 	run_pager();
 	my (@k, $c, $d, $stat);
@@ -3816,14 +3838,12 @@ sub cmd_show_log {
 		process_commit($c, $r_min, $r_max, \@k);
 	}
 	if (@k) {
-		my $swap = $r_max;
-		$r_max = $r_min;
-		$r_min = $swap;
+		($r_min, $r_max) = ($r_max, $r_min);
 		process_commit($_, $r_min, $r_max) foreach reverse @k;
 	}
 out:
 	close $log;
-	print '-' x72,"\n" unless $incremental || $oneline;
+	print commit_log_separator() unless $incremental || $oneline;
 }
 
 package Git::SVN::Migration;
diff --git a/t/t9116-git-svn-log.sh b/t/t9116-git-svn-log.sh
index 5000892..56dd8fe 100755
--- a/t/t9116-git-svn-log.sh
+++ b/t/t9116-git-svn-log.sh
@@ -30,6 +30,12 @@ test_expect_success 'setup repository and import' "
 	git reset --hard trunk &&
 	echo aye >> README &&
 	git commit -a -m aye &&
+	git svn dcommit &&
+	git reset --hard b &&
+	echo spy >> README &&
+	git commit -a -m spy &&
+	echo try >> README &&
+	git commit -a -m try &&
 	git svn dcommit
 	"
 
@@ -59,4 +65,64 @@ test_expect_success 'test descending revision range' "
 	git svn log -r 4:1 | grep '^r[0-9]' | cut -d'|' -f1 | diff -u expected-range-r4-r2-r1 -
 	"
 
+printf 'r1 \nr2 \n' > expected-range-r1-r2
+
+test_expect_success 'test ascending revision range with unreachable revision' "
+	git reset --hard trunk &&
+	git svn log -r 1:3 | grep '^r[0-9]' | cut -d'|' -f1 | diff -u expected-range-r1-r2 -
+	"
+
+printf 'r2 \nr1 \n' > expected-range-r2-r1
+
+test_expect_success 'test descending revision range with unreachable revision' "
+	git reset --hard trunk &&
+	git svn log -r 3:1 | grep '^r[0-9]' | cut -d'|' -f1 | diff -u expected-range-r2-r1 -
+	"
+
+printf 'r2 \n' > expected-range-r2
+
+test_expect_success 'test ascending revision range with unreachable upper boundary revision and 1 commit' "
+	git reset --hard trunk &&
+	git svn log -r 2:3 | grep '^r[0-9]' | cut -d'|' -f1 | diff -u expected-range-r2 -
+	"
+
+test_expect_success 'test descending revision range with unreachable upper boundary revision and 1 commit' "
+	git reset --hard trunk &&
+	git svn log -r 3:2 | grep '^r[0-9]' | cut -d'|' -f1 | diff -u expected-range-r2 -
+	"
+
+printf 'r4 \n' > expected-range-r4
+
+test_expect_success 'test ascending revision range with unreachable lower boundary revision and 1 commit' "
+	git reset --hard trunk &&
+	git svn log -r 3:4 | grep '^r[0-9]' | cut -d'|' -f1 | diff -u expected-range-r4 -
+	"
+
+test_expect_success 'test descending revision range with unreachable lower boundary revision and 1 commit' "
+	git reset --hard trunk &&
+	git svn log -r 4:3 | grep '^r[0-9]' | cut -d'|' -f1 | diff -u expected-range-r4 -
+	"
+
+echo ------------------------------------------------------------------------ > expected-separator
+
+test_expect_success 'test ascending revision range with unreachable boundary revisions and no commits' "
+	git reset --hard trunk &&
+	git svn log -r 5:6 | diff -u expected-separator -
+	"
+
+test_expect_success 'test descending revision range with unreachable boundary revisions and no commits' "
+	git reset --hard trunk &&
+	git svn log -r 6:5 | diff -u expected-separator -
+	"
+
+test_expect_success 'test ascending revision range with unreachable boundary revisions and 1 commit' "
+	git reset --hard trunk &&
+	git svn log -r 3:5 | grep '^r[0-9]' | cut -d'|' -f1 | diff -u expected-range-r4 -
+	"
+
+test_expect_success 'test descending revision range with unreachable boundary revisions and 1 commit' "
+	git reset --hard trunk &&
+	git svn log -r 5:3 | grep '^r[0-9]' | cut -d'|' -f1 | diff -u expected-range-r4 -
+	"
+
 test_done
-- 
1.5.3.4

^ permalink raw reply related

* [PATCH 1/3] git-svn log: fix ascending revision ranges
From: David D Kilzer @ 2007-11-11  6:10 UTC (permalink / raw)
  To: git; +Cc: gitster, David D Kilzer
In-Reply-To: <1194761435-7286-1-git-send-email-ddkilzer@kilzer.net>

Fixed typo in Git::SVN::Log::git_svn_log_cmd().  Previously a command like
"git-svn log -r1:4" would only show a commit log separator.

Added tests for ascending and descending revision ranges.

Signed-off-by: David D Kilzer <ddkilzer@kilzer.net>
---
 git-svn.perl           |    2 +-
 t/t9116-git-svn-log.sh |   14 ++++++++++++++
 2 files changed, 15 insertions(+), 1 deletions(-)

diff --git a/git-svn.perl b/git-svn.perl
index ec25ea4..3c5a87d 100755
--- a/git-svn.perl
+++ b/git-svn.perl
@@ -3591,7 +3591,7 @@ sub git_svn_log_cmd {
 		$c_max = $gs->rev_db_get($r_max);
 		$c_min = $gs->rev_db_get($r_min);
 		if (defined $c_min && defined $c_max) {
-			if ($r_max > $r_max) {
+			if ($r_max > $r_min) {
 				push @cmd, "$c_min..$c_max";
 			} else {
 				push @cmd, "$c_max..$c_min";
diff --git a/t/t9116-git-svn-log.sh b/t/t9116-git-svn-log.sh
index 0d4e6b3..618d7e9 100755
--- a/t/t9116-git-svn-log.sh
+++ b/t/t9116-git-svn-log.sh
@@ -45,4 +45,18 @@ test_expect_success 'run log against a from trunk' "
 	git svn log -r3 a | grep ^r3
 	"
 
+printf 'r2 \nr4 \n' > expected-range-r2-r4
+
+test_expect_success 'test ascending revision range' "
+	git reset --hard trunk &&
+	git svn log -r 1:4 | grep '^r[0-9]' | cut -d'|' -f1 | diff -u expected-range-r2-r4 -
+	"
+
+printf 'r4 \nr2 \n' > expected-range-r4-r2
+
+test_expect_success 'test descending revision range' "
+	git reset --hard trunk &&
+	git svn log -r 4:1 | grep '^r[0-9]' | cut -d'|' -f1 | diff -u expected-range-r4-r2 -
+	"
+
 test_done
-- 
1.5.3.4

^ permalink raw reply related

* Re: [PATCH] status&commit: Teach them to show commits of modified submodules.
From: Yin Ping @ 2007-11-11  6:18 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <7vabpliz13.fsf@gitster.siamese.dyndns.org>

On Nov 11, 2007 5:14 AM, Junio C Hamano <gitster@pobox.com> wrote:
>  * I think everbody preferes to have "On branch master" at the
>    very beginning

Reasonable.

>
>  * As I understand it, in the real life use,
>    the superproject can stay behind from the tip of subproject
>    and rebind it to a different commit only when there are
>    significant changes of the subproject that need to be there
>    to allow the other parts of the superproject (either
>    superproject itself or another submodule) to use the features
>    and/or fixes the submodule updates provides.

I think it's this kind of case in most open-source project. However,
in a company environment, superprojects may be not so super. A
superproject may bind very tightly with submodules (such as the html
template files which change very frequently) and the developer of a superproject
and its submodules may be the same guy(s). In these cases, a long list
of commits
for submodules are expected be reviewed when commiting the superproject.
>
>    And I think it is more important to give the birds-eye view
>    of the supermodule itself first, when you are helping to
>    prepare a commit message for the supermodule.
>    and then continue "Notable changes in submodule A are ...".
>    And the new part you are adding would help the user to write
>    the latter description.
I agree.
>
> I also find "<<< lines then >>> other lines" format very hard to
> read.  Maybe formatting it like this would make it a bit more
> readable and more space efficient?
>
>         # * sm1 354cd45...3f751e5:
>         #   - one line message for C
>         #   - one line message for B
>         #   + one line message for D
>         #   + one line message for E
>         # * sm2 5c8bfb5...ac46d84:
>         #   - msg
>
I have struggled between these two kinds of presentation and finally
choose the '<<<' one.
IMHO, '-/+' one each line will distract and less space/size efficient
(100 '+/-' for 100 lines of messages).

However, it's not a big matter. I'll change the presentation if
everyone prefers the
patch-like one.

> Note that if you swap the order and move this at the tail
> (perhaps before "Untracked files:" section, if you do not have a
> decent .gitignore set up), you can also lose the "submodules
> modified: sm1 sm2" line and the blank line before it, which
> would make the output even shorter without losing any useful
> information.
>
So following is ok?
        # On branch master
        # Changes to be committed:
        #   (use "git reset HEAD <file>..." to unstage)
        #
        #       modified:   sm1
        #       modified:   sm2
        #       modified:   sm3
        #
        # Changed but not updated:
        #   (use "git add/rm <file>..." to update what will be committed)
        #
        #       modified:   file1
        #
        # Submodules modifiled: sm1 sm2 sm3
        #
        # * sm1 354cd45...3f751e5:
        #   - one line message for C
        #   - one line message for B
        #   + one line message for D
        #   + one line message for E
        # * sm2 354cd46...3f751e7:
        #   - one line message
        # * sm3 354cd47...3f751e8:
        #   Warn: sm1 doesn't contains commit 354cd45
        #
        # Untracked files:
        #   (use "git add <file>..." to include in what will be committed)
        #
        #       file2
        #



-- 
Ping Yin

^ permalink raw reply

* Re: [PATCH] status&commit: Teach them to show commits of modified submodules.
From: Yin Ping @ 2007-11-11  6:24 UTC (permalink / raw)
  To: Lars Hjemli; +Cc: git
In-Reply-To: <8c5c35580711101607l7c45d6f5ge0f40ac6e447031a@mail.gmail.com>

On Nov 11, 2007 8:07 AM, Lars Hjemli <hjemli@gmail.com> wrote:
> On Nov 10, 2007 8:27 PM, Ping Yin <pkufranky@gmail.com> wrote:
> > This commit teaches git status/commit to also show commits of user-cared
> > modified submodules since HEAD (or HEAD^ if --amend option is on).
>
> Some nitpicks:
> -we'll need a config option to enable/disable this output in git-status
agree. default off?
> -the feature should probably be implemented in git-submodule.sh
>
I'll want to see the commits of submodules when editing commit msg. So
i implemented
this in git-commit.sh. May be a configuration/option can added to turn
this on or off.

> --
> larsh
>



-- 
Ping Yin

^ permalink raw reply

* [PATCH 0/5] Return of 'quickfetch' version 3
From: Shawn O. Pearce @ 2007-11-11  7:29 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

OK, attempt #3.  Much shorter series as I've taken out the (messy)
object memory management change.  Its now unrelated to this series
and may return in the near future.

 1) Fix memory leak in traverse_commit_list

The memory leak we talked about in traverse_commit_list.  Its still
valid for pack-objects but is unnecessary for fetch.

 2) git-fetch: Always fetch tags if the object they reference exists

I think I figured out why I said "random behavior" earlier.
Please see the commit message for an updated description.

 3) run-command: Support sending stderr to /dev/null
 4) rev-list: Introduce --quiet to avoid /dev/null redirects
 5) git-fetch: avoid local fetching from alternate (again)

Pretty much the original quickfetch series, but updated with list
comments and moved to builtin-fetch where it works for all types
of transports and not just the native git one.

-- 
Shawn.

^ permalink raw reply

* [PATCH 1/5] Fix memory leak in traverse_commit_list
From: Shawn O. Pearce @ 2007-11-11  7:29 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

If we were listing objects too then the objects were buffered in an
array only reachable from a stack allocated structure.  When this
function returns that array would be leaked as nobody would have
a reference to it anymore.

Historically this hasn't been a problem as the primary user of
traverse_commit_list() (the noble git-rev-list) would terminate
as soon as the function was finished, thus allowing the operating
system to cleanup memory.  However we have been leaking this data
in git-pack-objects ever since that program learned how to run the
revision listing internally, rather than relying on reading object
names from git-rev-list.

To better facilitate reuse of traverse_commit_list during other
builtin tools we shouldn't leak temporary memory like this and
instead we need to clean up properly after ourselves.

Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
---
 list-objects.c |    7 +++++++
 1 files changed, 7 insertions(+), 0 deletions(-)

diff --git a/list-objects.c b/list-objects.c
index e5c88c2..4ef58e7 100644
--- a/list-objects.c
+++ b/list-objects.c
@@ -170,4 +170,11 @@ void traverse_commit_list(struct rev_info *revs,
 	}
 	for (i = 0; i < objects.nr; i++)
 		show_object(&objects.objects[i]);
+	free(objects.objects);
+	if (revs->pending.nr) {
+		free(revs->pending.objects);
+		revs->pending.nr = 0;
+		revs->pending.alloc = 0;
+		revs->pending.objects = NULL;
+	}
 }
-- 
1.5.3.5.1661.gcbf0

^ permalink raw reply related

* [PATCH 2/5] git-fetch: Always fetch tags if the object they reference exists
From: Shawn O. Pearce @ 2007-11-11  7:29 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

Previously git-fetch.sh used `git cat-file -t` to determine if an
object referenced by a tag exists, and if so fetch that tag locally.
This was subtly broken during the port to C based builtin-fetch as
lookup_object() only works to locate an object if it was previously
accessed by the transport.  Not all transports will access all
objects in this way, so tags were not always being fetched.

The rsync transport never loads objects into the internal object
table so automated tag following didn't work if rsync was used.
Automated tag following also didn't work on the native transport
if the new tag was behind the common point(s) negotiated between
the two ends of the connection as the tag's referrant would not
be loaded into the internal object table.  Further the automated
tag following was broken with the HTTP commit walker if the new
tag's referrant was behind an existing ref, as the walker would
stop before loading the tag's referrant into the object table.

Switching to has_sha1_file() restores the original behavior from
the shell script by checking if the object exists in the ODB,
without relying on the state left behind by a transport.

Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
---
 builtin-fetch.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/builtin-fetch.c b/builtin-fetch.c
index 847db73..a935b5a 100644
--- a/builtin-fetch.c
+++ b/builtin-fetch.c
@@ -389,7 +389,7 @@ static struct ref *find_non_local_tags(struct transport *transport,
 
 		if (!path_list_has_path(&existing_refs, ref_name) &&
 		    !path_list_has_path(&new_refs, ref_name) &&
-		    lookup_object(ref->old_sha1)) {
+		    has_sha1_file(ref->old_sha1)) {
 			path_list_insert(ref_name, &new_refs);
 
 			rm = alloc_ref(strlen(ref_name) + 1);
-- 
1.5.3.5.1661.gcbf0

^ permalink raw reply related

* [PATCH 3/5] run-command: Support sending stderr to /dev/null
From: Shawn O. Pearce @ 2007-11-11  7:29 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

Some callers may wish to redirect stderr to /dev/null in some
contexts, such as if they are executing a command only to get
the exit status and don't want users to see whatever output it
may produce as a side-effect of computing that exit status.

Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
---
 run-command.c |    6 ++++--
 run-command.h |    1 +
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/run-command.c b/run-command.c
index d99a6c4..476d00c 100644
--- a/run-command.c
+++ b/run-command.c
@@ -41,7 +41,7 @@ int start_command(struct child_process *cmd)
 		cmd->close_out = 1;
 	}
 
-	need_err = cmd->err < 0;
+	need_err = !cmd->no_stderr && cmd->err < 0;
 	if (need_err) {
 		if (pipe(fderr) < 0) {
 			if (need_in)
@@ -87,7 +87,9 @@ int start_command(struct child_process *cmd)
 			close(cmd->out);
 		}
 
-		if (need_err) {
+		if (cmd->no_stderr)
+			dup_devnull(2);
+		else if (need_err) {
 			dup2(fderr[1], 2);
 			close_pair(fderr);
 		}
diff --git a/run-command.h b/run-command.h
index 94e1e9d..1fc781d 100644
--- a/run-command.h
+++ b/run-command.h
@@ -23,6 +23,7 @@ struct child_process {
 	unsigned close_out:1;
 	unsigned no_stdin:1;
 	unsigned no_stdout:1;
+	unsigned no_stderr:1;
 	unsigned git_cmd:1; /* if this is to be git sub-command */
 	unsigned stdout_to_stderr:1;
 };
-- 
1.5.3.5.1661.gcbf0

^ permalink raw reply related

* [PATCH 4/5] rev-list: Introduce --quiet to avoid /dev/null redirects
From: Shawn O. Pearce @ 2007-11-11  7:29 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

Some uses of git-rev-list are to run it with --objects to see if
a range of objects between two or more commits is fully connected
or not.  In such a case the caller doesn't care about the actual
object names or hash hints so formatting this data only for it to
be dumped to /dev/null by a redirect is a waste of CPU time.  If
all the caller needs is the exit status then --quiet can be used
to bypass the commit and object formatting.

Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
---
 Documentation/git-rev-list.txt |    9 +++++++++
 builtin-rev-list.c             |   26 ++++++++++++++++++++++----
 2 files changed, 31 insertions(+), 4 deletions(-)

diff --git a/Documentation/git-rev-list.txt b/Documentation/git-rev-list.txt
index 4852804..989fbf3 100644
--- a/Documentation/git-rev-list.txt
+++ b/Documentation/git-rev-list.txt
@@ -20,6 +20,7 @@ SYNOPSIS
 	     [ \--not ]
 	     [ \--all ]
 	     [ \--stdin ]
+	     [ \--quiet ]
 	     [ \--topo-order ]
 	     [ \--parents ]
 	     [ \--timestamp ]
@@ -270,6 +271,14 @@ limiting may be applied.
 	In addition to the '<commit>' listed on the command
 	line, read them from the standard input.
 
+--quiet::
+
+	Don't print anything to standard output.  This form of
+	git-rev-list is primarly meant to allow the caller to
+	test the exit status to see if a range of objects is fully
+	connected (or not).  It is faster than redirecting stdout
+	to /dev/null as the output does not have to be formatted.
+
 --cherry-pick::
 
 	Omit any commit that introduces the same change as
diff --git a/builtin-rev-list.c b/builtin-rev-list.c
index 2dec887..d67724c 100644
--- a/builtin-rev-list.c
+++ b/builtin-rev-list.c
@@ -26,6 +26,7 @@ static const char rev_list_usage[] =
 "    --remove-empty\n"
 "    --all\n"
 "    --stdin\n"
+"    --quiet\n"
 "  ordering output:\n"
 "    --topo-order\n"
 "    --date-order\n"
@@ -50,6 +51,7 @@ static int show_timestamp;
 static int hdr_termination;
 static const char *header_prefix;
 
+static void finish_commit(struct commit *commit);
 static void show_commit(struct commit *commit)
 {
 	if (show_timestamp)
@@ -93,6 +95,11 @@ static void show_commit(struct commit *commit)
 		strbuf_release(&buf);
 	}
 	maybe_flush_or_die(stdout, "stdout");
+	finish_commit(commit);
+}
+
+static void finish_commit(struct commit *commit)
+{
 	if (commit->parents) {
 		free_commit_list(commit->parents);
 		commit->parents = NULL;
@@ -101,6 +108,12 @@ static void show_commit(struct commit *commit)
 	commit->buffer = NULL;
 }
 
+static void finish_object(struct object_array_entry *p)
+{
+	if (p->item->type == OBJ_BLOB && !has_sha1_file(p->item->sha1))
+		die("missing blob object '%s'", sha1_to_hex(p->item->sha1));
+}
+
 static void show_object(struct object_array_entry *p)
 {
 	/* An object with name "foo\n0000000..." can be used to
@@ -108,9 +121,7 @@ static void show_object(struct object_array_entry *p)
 	 */
 	const char *ep = strchr(p->name, '\n');
 
-	if (p->item->type == OBJ_BLOB && !has_sha1_file(p->item->sha1))
-		die("missing blob object '%s'", sha1_to_hex(p->item->sha1));
-
+	finish_object(p);
 	if (ep) {
 		printf("%s %.*s\n", sha1_to_hex(p->item->sha1),
 		       (int) (ep - p->name),
@@ -527,6 +538,7 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix)
 	int read_from_stdin = 0;
 	int bisect_show_vars = 0;
 	int bisect_find_all = 0;
+	int quiet = 0;
 
 	git_config(git_default_config);
 	init_revisions(&revs, prefix);
@@ -565,6 +577,10 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix)
 			read_revisions_from_stdin(&revs);
 			continue;
 		}
+		if (!strcmp(arg, "--quiet")) {
+			quiet = 1;
+			continue;
+		}
 		usage(rev_list_usage);
 
 	}
@@ -640,7 +656,9 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix)
 		}
 	}
 
-	traverse_commit_list(&revs, show_commit, show_object);
+	traverse_commit_list(&revs,
+		quiet ? finish_commit : show_commit,
+		quiet ? finish_object : show_object);
 
 	return 0;
 }
-- 
1.5.3.5.1661.gcbf0

^ permalink raw reply related

* [PATCH 5/5] git-fetch: avoid local fetching from alternate (again)
From: Shawn O. Pearce @ 2007-11-11  7:29 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

Back in e3c6f240fd9c5bdeb33f2d47adc859f37935e2df Junio taught
git-fetch to avoid copying objects when we are fetching from
a repository that is already registered as an alternate object
database.  In such a case there is no reason to copy any objects
as we can already obtain them through the alternate.

However we need to ensure the objects are all reachable, so we
run `git rev-list --objects $theirs --not --all` to verify this.
If any object is missing or unreadable then we need to fetch/copy
the objects from the remote.  When a missing object is detected
the git-rev-list process will exit with a non-zero exit status,
making this condition quite easy to detect.

Although git-fetch is currently a builtin (and so is rev-list)
we cannot invoke the traverse_objects() API at this point in the
transport code.  The object walker within traverse_objects() calls
die() as soon as it finds an object it cannot read.  If that happens
we want to resume the fetch process by calling do_fetch_pack().
To get around this we spawn git-rev-list into a background process
to prevent a die() from killing the foreground fetch process,
thus allowing the fetch process to resume into do_fetch_pack()
if copying is necessary.

We aren't interested in the output of rev-list (a list of SHA-1
object names that are reachable) or its errors (a "spurious" error
about an object not being found as we need to copy it) so we redirect
both stdout and stderr to /dev/null.

We run this git-rev-list based check before any fetch as we may
already have the necessary objects local from a prior fetch.  If we
don't then its very likely the first $theirs object listed on the
command line won't exist locally and git-rev-list will die very
quickly, allowing us to start the network transfer.  This test even
on remote URLs may save bandwidth if someone runs `git pull origin`,
sees a merge conflict, resets out, then redoes the same pull just
a short time later.  If the remote hasn't changed between the two
pulls and the local repository hasn't had git-gc run in it then
there is probably no need to perform network transfer as all of
the objects are local.

Documentation for the new quickfetch function was suggested and
written by Junio, based on his original comment in git-fetch.sh.

Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
---
 builtin-fetch.c       |   69 +++++++++++++++++++++++++++++++++++++++++++++++-
 t/t5502-quickfetch.sh |   33 +++++++++++++++++++++++
 2 files changed, 100 insertions(+), 2 deletions(-)

diff --git a/builtin-fetch.c b/builtin-fetch.c
index a935b5a..31e138e 100644
--- a/builtin-fetch.c
+++ b/builtin-fetch.c
@@ -8,10 +8,12 @@
 #include "path-list.h"
 #include "remote.h"
 #include "transport.h"
+#include "run-command.h"
 
 static const char fetch_usage[] = "git-fetch [-a | --append] [--upload-pack <upload-pack>] [-f | --force] [--no-tags] [-t | --tags] [-k | --keep] [-u | --update-head-ok] [--depth <depth>] [-v | --verbose] [<repository> <refspec>...]";
 
 static int append, force, tags, no_tags, update_head_ok, verbose, quiet;
+static const char *depth;
 static char *default_rla = NULL;
 static struct transport *transport;
 
@@ -335,9 +337,72 @@ static void store_updated_refs(const char *url, struct ref *ref_map)
 	fclose(fp);
 }
 
+/*
+ * We would want to bypass the object transfer altogether if
+ * everything we are going to fetch already exists and connected
+ * locally.
+ *
+ * The refs we are going to fetch are in to_fetch (nr_heads in
+ * total).  If running
+ *
+ *  $ git-rev-list --objects to_fetch[0] to_fetch[1] ... --not --all
+ *
+ * does not error out, that means everything reachable from the
+ * refs we are going to fetch exists and is connected to some of
+ * our existing refs.
+ */
+static int quickfetch(struct ref *ref_map)
+{
+	struct child_process revlist;
+	struct ref *ref;
+	char **argv;
+	int i, err;
+
+	/*
+	 * If we are deepening a shallow clone we already have these
+	 * objects reachable.  Running rev-list here will return with
+	 * a good (0) exit status and we'll bypass the fetch that we
+	 * really need to perform.  Claiming failure now will ensure
+	 * we perform the network exchange to deepen our history.
+	 */
+	if (depth)
+		return -1;
+
+	for (i = 0, ref = ref_map; ref; ref = ref->next)
+		i++;
+	if (!i)
+		return 0;
+
+	argv = xmalloc(sizeof(*argv) * (i + 6));
+	i = 0;
+	argv[i++] = xstrdup("rev-list");
+	argv[i++] = xstrdup("--quiet");
+	argv[i++] = xstrdup("--objects");
+	for (ref = ref_map; ref; ref = ref->next)
+		argv[i++] = xstrdup(sha1_to_hex(ref->old_sha1));
+	argv[i++] = xstrdup("--not");
+	argv[i++] = xstrdup("--all");
+	argv[i++] = NULL;
+
+	memset(&revlist, 0, sizeof(revlist));
+	revlist.argv = (const char**)argv;
+	revlist.git_cmd = 1;
+	revlist.no_stdin = 1;
+	revlist.no_stdout = 1;
+	revlist.no_stderr = 1;
+	err = run_command(&revlist);
+
+	for (i = 0; argv[i]; i++)
+		free(argv[i]);
+	free(argv);
+	return err;
+}
+
 static int fetch_refs(struct transport *transport, struct ref *ref_map)
 {
-	int ret = transport_fetch_refs(transport, ref_map);
+	int ret = quickfetch(ref_map);
+	if (ret)
+		ret = transport_fetch_refs(transport, ref_map);
 	if (!ret)
 		store_updated_refs(transport->url, ref_map);
 	transport_unlock_pack(transport);
@@ -473,7 +538,7 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
 	static const char **refs = NULL;
 	int ref_nr = 0;
 	int cmd_len = 0;
-	const char *depth = NULL, *upload_pack = NULL;
+	const char *upload_pack = NULL;
 	int keep = 0;
 
 	for (i = 1; i < argc; i++) {
diff --git a/t/t5502-quickfetch.sh b/t/t5502-quickfetch.sh
index b4760f2..16eadd6 100755
--- a/t/t5502-quickfetch.sh
+++ b/t/t5502-quickfetch.sh
@@ -86,4 +86,37 @@ test_expect_success 'quickfetch should not leave a corrupted repository' '
 
 '
 
+test_expect_success 'quickfetch should not copy from alternate' '
+
+	(
+		mkdir quickclone &&
+		cd quickclone &&
+		git init-db &&
+		(cd ../.git/objects && pwd) >.git/objects/info/alternates &&
+		git remote add origin .. &&
+		git fetch -k -k
+	) &&
+	obj_cnt=$( (
+		cd quickclone &&
+		git count-objects | sed -e "s/ *objects,.*//"
+	) ) &&
+	pck_cnt=$( (
+		cd quickclone &&
+		git count-objects -v | sed -n -e "/packs:/{
+				s/packs://
+				p
+				q
+			}"
+	) ) &&
+	origin_master=$( (
+		cd quickclone &&
+		git rev-parse origin/master
+	) ) &&
+	echo "loose objects: $obj_cnt, packfiles: $pck_cnt" &&
+	test $obj_cnt -eq 0 &&
+	test $pck_cnt -eq 0 &&
+	test z$origin_master = z$(git rev-parse master)
+
+'
+
 test_done
-- 
1.5.3.5.1661.gcbf0

^ permalink raw reply related

* [PATCH 0/3] Adding colors to git-add--interactive
From: Dan Zwell @ 2007-11-11  2:21 UTC (permalink / raw)
  To: Jeff King
  Cc: Junio C Hamano, Shawn O. Pearce, Wincent Colaiuta,
	Git Mailing List, Jonathan del Strother, Johannes Schindelin,
	Frank Lichtenheld
In-Reply-To: <20071104054305.GA13929@sigill.intra.peff.net>

[Note: I'm resending this because it looks like this e-mail didn't go
out properly. Sorry for duplicates.]

A bit of a recap--this feature was
requested by a user a few weeks ago, and I wrote a short patch that
implemented partial coloring. The main criticisms of this patch were:
- The name of the configuration key to turn on interactive coloring
was not well chosen.
- The color attribute synonyms "clear" and "reset" were used
interchangeably, though "reset" is what the rest of git uses.
- The colors were not user-settable.

When the above were fixed, the new patch garnered the following
criticism:
- The color names accepted in .gitconfig were perl color names (to be
fed to Term::ANSIColor), and this was not consistent with the rest
of git. For example, "red blue ul" would have to be written, "red
on_blue underline".

Fixing this (the colors could not be converted by a regex, but had to
be parsed) was very libraryish, and also a little confusing. I was
given a suggestion or two about how to make it more readable. This
parsing also needed to be added to Git.pm instead of
git-add--interactive.perl.

In the next iteration, all of the above were fixed, but as Jeff King
pointed out, I was printing $color before the beginning of a string,
and printing $clear at the end, which allowed ${COLOR}text\n${RESET},
which looks bad on some terminals.

Last iteration, it was pointed out that print_colored must take a
file handle to pave the way for pager support, and Junio Hamano and Jeff
King both gave suggestions as to how, and Junio sent me few changes
that allow printing colored diffs in addition to prompts. I ended up
making changes so that the two color functions can be used with perl's
print():
print colored($color, "some text")
print color_diff_hunk($hunk)

This way, file handles can be added directly to the print calls, when
support for $PAGER is added.

Let me know if other things need correction.

Dan

^ permalink raw reply

* Re: [PATCH 0/3] Adding colors to git-add--interactive
From: Jeff King @ 2007-11-11  7:54 UTC (permalink / raw)
  To: Dan Zwell
  Cc: Junio C Hamano, Shawn O. Pearce, Wincent Colaiuta,
	Git Mailing List, Jonathan del Strother, Johannes Schindelin,
	Frank Lichtenheld
In-Reply-To: <20071110180109.34febc3f@paradox.zwell.net>

On Sat, Nov 10, 2007 at 06:01:09PM -0600, Dan Zwell wrote:

> A bit of a recap--this feature was requested by a user a few weeks

Thanks for the recap; there have been enough iterations of this series
that at least I forgot what was going on. The patches look reasonable,
but I have a few comments (hopefully you have enough "umph" for one more
iteration). I'll just inline them here.

[patch 1/3]:
> +my ($use_color, $prompt_color, $header_color, $help_color, $normal_color);
> +my $color_config = qx(git config --get color.interactive);

Why call git config here manually, but Git::config later (I think the
answer is "because we don't call Git::config until a later patch", but it
is probably best to remain consistent).

> +sub colored {
> +	my $color = shift;
> +	my $string = join("", @_);
> +
> +	if ($use_color) {
> +		# Put a color code at the beginning of each line, a reset at the end
> +		# color after newlines that are not at the end of the string
> +		$string =~ s/(\n+)(.)/$1$color$2/g;
> +		# reset before newlines
> +		$string =~ s/(\n+)/$normal_color$1/g;
> +		# codes at beginning and end (if necessary):
> +		$string =~ s/^/$color/;
> +		$string =~ s/$/$normal_color/ unless $string =~ /\n$/;
> +	}
> +	return $string;
> +}

This also seems like a candidate for lib-ification in Git.pm, alongside
color_to_ansi_code.

> -			print "$opts->{HEADER}\n";
> +			print colored $header_color, "$opts->{HEADER}\n";

I don't know if we have a style policy on calling

  user_defined_function $foo, $bar;

rather than

  user_defined_function($foo, $bar);

In fact, I don't know that we have much perl style policy at all. But I
tend to shy away from the former because then the syntax requires that
"colored" is always defined before the calling spot.

[patch 2/3]:
> +		# Grab the 3 main colors in git color string format, with sane
> +		# (visible) defaults:
> +		my $repo = Git->repository();
> +		$prompt_color = Git::color_to_ansi_code(
> +			Git::config($repo, "color.interactive.prompt") || "bold blue");
> +		$header_color = Git::color_to_ansi_code(
> +			Git::config($repo, "color.interactive.header") || "bold");
> +		$help_color = Git::color_to_ansi_code(
> +			Git::config($repo, "color.interactive.help") || "red bold");
> +		$normal_color = Git::color_to_ansi_code("normal");

It is much more common (and proper OO, in the face of inheritance) to
use

   $repo->config("color.interactive.prompt")

> +=item color_to_ansi_code ( COLOR )
> +
> +Converts a git-style color string, like "underline blue white" to
> +an ANSI color code. The code is generated by Term::ANSIColor,
> +after the string is parsed into the format that is accepted by
> +that module. Used as follows:
> +
> +	print color_to_ansi_code("underline blue white");
> +	print "some text";
> +	print color_to_ansi_code("normal");

Yay, documentation!  It would also be nice to have a test script that
runs this through a few more complex git color specs.

> +	my %attrib_mappings = (
> +		"bold"    => "bold",
> +		"ul"      => "underline",
> +		"blink"   => "blink",
> +		# not supported:
> +		#"dim"     => "",

Why not? I don't especially care about "dim" support, but if there is a
good reason, then you should note it.

> +	foreach $word (split /\s+/, $git_string) {
> +		if ($word =~ /normal/) {
> +			$fg_done = "true";
> +		}

Why a regex instead of 'eq'? Also, should this be case insensitive?

> +		elsif ($word =~ /black|red|green|yellow/ ||
> +			   $word =~ /blue|magenta|cyan|white/) {

It looks like you are doing two regexes here just to meet whitespace
guidelines. Look into the '/x' modifier to make your regex prettier (but
again, consider 'eq').

> +	return Term::ANSIColor::color(join(" ", @ansi_words)||"reset");

Style: whitespace around ||

[patch 3/3]:
> +			# Not implemented:
> +			#$whitespace_color = Git::color_to_ansi_code(
> +				#Git::config($repo, "color.diff.whitespace") || "normal red");

Personally I would have just excluded the parsing, since it isn't
implemented, but I don't think it matters.

> +sub colored_diff_hunk {

Perhaps this should also go in Git.pm? Though right now I don't know
which other perl scripts would actually want to colorize a diff, so I
don't think it matters.

> -	system(qw(git diff-index -p --cached HEAD --),
> -	       map { $_->{VALUE} } @them);
> +	system(qw(git diff -p --cached HEAD --), map { $_->{VALUE} } @them);

Now this was a surprise after reading the commit message.

-Peff

^ permalink raw reply

* Dose git-fetch need --reference option like git-clone?
From: Yin Ping @ 2007-11-11  8:09 UTC (permalink / raw)
  To: git

I want to track remote repsotory (say remoteA) on my local repository
(say localB), so i do the following in directory localB
$ git remote add remoteA git://remoteAUrl
$ git fetch remoteA
This will fetch all objects from git://remoteAUrl if localB and
remoteA don't have common objects.

If I already have a cloned remoteA on local machine (say
/path/to/remoteACloned), I want to do following to reduce the net
traffic as git-clone:
git fetch --reference /path/to/remoteACloned remotedA

Is this reasonable? Or is there already a resolution for this case?

-- 
Ping Yin

^ permalink raw reply

* Re: [PATCH 2/2] --pretty=format: on-demand format expansion
From: Jeff King @ 2007-11-11  8:13 UTC (permalink / raw)
  To: René Scharfe
  Cc: Junio C Hamano, Paul Mackerras, Git Mailing List, Pierre Habouzit,
	Johannes Schindelin
In-Reply-To: <20071110203435.GB20592@sigill.intra.peff.net>

On Sat, Nov 10, 2007 at 03:34:35PM -0500, Jeff King wrote:

> Your solution leaves me partly disgusted at the hackishness, and partly
> delighted at the cleverness. I think the way you have coded it is quite
> clear, though, so I don't think anyone is likely to get confused reading
> it. I haven't read through it carefully yet, but a tentative Ack from
> me.

OK, I had a chance to read through your patches more carefully. Assuming
that the strbuf offset technique is acceptable (and I think it is worth
the increased speed and simplicity), they look great to me. So:

Acked-by: Jeff King <peff@peff.net>

-Peff

^ permalink raw reply

* Re: [PATCH 0/3] Adding colors to git-add--interactive
From: Junio C Hamano @ 2007-11-11  8:23 UTC (permalink / raw)
  To: Jeff King
  Cc: Dan Zwell, Shawn O. Pearce, Wincent Colaiuta, Git Mailing List,
	Jonathan del Strother, Johannes Schindelin, Frank Lichtenheld
In-Reply-To: <20071111075446.GA26985@sigill.intra.peff.net>

Jeff King <peff@peff.net> writes:

>> -	system(qw(git diff-index -p --cached HEAD --),
>> -	       map { $_->{VALUE} } @them);
>> +	system(qw(git diff -p --cached HEAD --), map { $_->{VALUE} } @them);
>
> Now this was a surprise after reading the commit message.

This hunk makes the "show diff" subcommand honor user's external
diff viewer if specified, which is a good change.  But it does
not belong to the "colored add -i" series.

I mildly suspect that this change might have been my fault, but
I think it should be treated in an independent patch anyway.

^ permalink raw reply

* Re: [PATCH] status&commit: Teach them to show commits of modified submodules.
From: Lars Hjemli @ 2007-11-11  8:27 UTC (permalink / raw)
  To: Yin Ping; +Cc: git
In-Reply-To: <46dff0320711102224h7a14329ag27fcfcfcf479823e@mail.gmail.com>

On Nov 11, 2007 7:24 AM, Yin Ping <pkufranky@gmail.com> wrote:
> On Nov 11, 2007 8:07 AM, Lars Hjemli <hjemli@gmail.com> wrote:
> > On Nov 10, 2007 8:27 PM, Ping Yin <pkufranky@gmail.com> wrote:
> > > This commit teaches git status/commit to also show commits of user-cared
> > > modified submodules since HEAD (or HEAD^ if --amend option is on).
> >
> > Some nitpicks:
> > -we'll need a config option to enable/disable this output in git-status
> agree. default off?

That would be nice.

> > -the feature should probably be implemented in git-submodule.sh
> >
> I'll want to see the commits of submodules when editing commit msg.

If git-commit.sh uses git-submodule.sh to get this information, the
feature is still available in git-submodule even if it's disabled for
git-status.

--
larsh

^ permalink raw reply

* Re: `git-send-email' doesn't specify `Content-Type'
From: Jeff King @ 2007-11-11  8:32 UTC (permalink / raw)
  To: Björn Steinbrink
  Cc: Brian Swetland, Johannes Schindelin, Ludovic Courtès, git
In-Reply-To: <20071110125126.GA7261@atjola.homenet>

On Sat, Nov 10, 2007 at 01:51:26PM +0100, Björn Steinbrink wrote:

> On 2007.11.10 04:35:05 -0800, Brian Swetland wrote:
> > The first line of the patch is a From: field with Arve's name, in
> > an (rfc822?) encoded format):
> > From: =?utf-8?q?Arve=20Hj=C3=B8nnev=C3=A5g?= <arve@android.com>

It's rfc2047 (and you can grep for that in git-send-email).

> Ah! Commit author differs from mail sender, didn't think of that. That's
> probably the same problem as with the -s option, ie. that git-send-email
> only looks at the existing text and not add anything it adds itself when
> checking the encoding. Sorry for the noise.

It's not the same problem; the '-s' problem was git-format-patch, and
this is git-send-email. In fact, git-format-patch correctly notes the
encoding in the header. It is git-send-email in this case that takes the
encoded and properly marked header, deciphers it, throws away the
original encoding, and sticks it into the message body without
considering the encoding of the body.

So I think you would want to:
  1. remember the encoding pulled from the rfc2047 header
  2. When prepending the author line to the message, consider the
     body encoding.
  2a. If no encoding, then the body is US-ASCII and we can presumably
      just add
         MIME-Version: 1.0
         Content-Type: text/plain; charset=$enc
  2b. If there is an encoding, we need to Iconv from the name
      encoding to the body encoding.

However, as it stands now, our rfc2047 unquoting _always_ assumes that
we are in utf-8 for the name (which is probably true if the messages
came out of git-format-patch with default-ish settings). So the easy,
hackish way is probably to just add the MIME-Version and 'Content-type:
text/plain; charset=utf-8' headers if we unquoted the author field.

If we want to accept arbitrary messages, below is a patch to at least
have unquote_rfc2047 return the right information (and then on
git-send-email.perl:758, where we prepend $author, the encoding would
need to be taken into account as I described above).

Given that git-send-email is already pretty dependent on
git-format-patch output (and nobody has been complaining about its
rfc2047 handling so far!) the easy, hackish way is probably the best.

-Peff

---
diff --git a/git-send-email.perl b/git-send-email.perl
index f9bd2e5..4f8297f 100755
--- a/git-send-email.perl
+++ b/git-send-email.perl
@@ -514,11 +514,13 @@ $time = time - scalar $#files;
 
 sub unquote_rfc2047 {
 	local ($_) = @_;
-	if (s/=\?utf-8\?q\?(.*)\?=/$1/g) {
+	my $encoding;
+	if (s/=\?([^?])+\?q\?(.*)\?=/$2/g) {
+		$encoding = $1;
 		s/_/ /g;
 		s/=([0-9A-F]{2})/chr(hex($1))/eg;
 	}
-	return "$_";
+	return "$_", $encoding;
 }
 
 # use the simplest quoting being able to handle the recipient
@@ -667,6 +669,7 @@ foreach my $t (@files) {
 	open(F,"<",$t) or die "can't open file $t";
 
 	my $author = undef;
+	my $author_encoding;
 	@cc = @initial_cc;
 	@xh = ();
 	my $input_format = undef;
@@ -692,7 +695,8 @@ foreach my $t (@files) {
 						next if ($suppress_from);
 					}
 					elsif ($1 eq 'From') {
-						$author = unquote_rfc2047($2);
+						($author, $author_encoding)
+						  = unquote_rfc2047($2);
 					}
 					printf("(mbox) Adding cc: %s from line '%s'\n",
 						$2, $_) unless $quiet;

^ permalink raw reply related

* Re: Deprecate git-fetch-pack?
From: Mike Hommey @ 2007-11-11  8:32 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Daniel Barkalow, git
In-Reply-To: <7v4pftip42.fsf@gitster.siamese.dyndns.org>

On Sat, Nov 10, 2007 at 04:48:29PM -0800, Junio C Hamano wrote:
> Daniel Barkalow <barkalow@iabervon.org> writes:
> 
> > Now that git-fetch is in C, built in, and doing the fetch-pack in the same 
> > process, the normal usage patterns don't involve actually executing 
> > git-fetch-pack. Can we deprecate it at this point, or it is plausibly 
> > being used by scripts? As it is now, I'm not entirely confidant that the 
> > tests in t5500 won't be fooled by git-fetch working even with 
> > git-fetch-pack being broken in various ways, which should be fixed if we 
> > want to keep it.
> >
> > We also might as well deprecate peek-remote now that it's a synonym for 
> > ls-remote.
> 
> Especially because git-fetch is no longer as hackable as it used
> to be, and because people may still find special needs that can
> be hacked up with direct access to low level transports from the
> script more easily than going down to the C level, I'd rather
> wait and see for a cycle or two to decide.  There is no strong
> reason to drop it, is there?

Still, if the functionality is needed, i think it would be better if it
were provided by git-fetch --pack. The list of programs is already long
enough, it should be time to shrink it.

Mike

^ permalink raw reply

* Re: `git-send-email' doesn't specify `Content-Type'
From: Jeff King @ 2007-11-11  8:35 UTC (permalink / raw)
  To: Björn Steinbrink
  Cc: Brian Swetland, Johannes Schindelin, Ludovic Courtès, git
In-Reply-To: <20071111083224.GA30299@sigill.intra.peff.net>

On Sun, Nov 11, 2007 at 03:32:24AM -0500, Jeff King wrote:

> -	return "$_";
> +	return "$_", $encoding;

This actually breaks other calls to unquote_rfc2047 which use a scalar
context. So that would have to be fixed if this were to start a real
patch.

-Peff

^ permalink raw reply

* Re: Dose git-fetch need --reference option like git-clone?
From: Junio C Hamano @ 2007-11-11  8:36 UTC (permalink / raw)
  To: Yin Ping; +Cc: git
In-Reply-To: <46dff0320711110009y713c7d38q7b1457c92daecef6@mail.gmail.com>

"Yin Ping" <pkufranky@gmail.com> writes:

> If I already have a cloned remoteA on local machine (say
> /path/to/remoteACloned), I want to do following to reduce the net
> traffic as git-clone:
> git fetch --reference /path/to/remoteACloned remotedA
>
> Is this reasonable? Or is there already a resolution for this case?

Resolution, meaning "No, that's not a good thing and we refuse
to support such an option"?

No, there is no such thing.

I think what you are talking about is a reasonable thing to
want.  It would have been easier to hack in back when git-fetch
was a script, but now you would need to work a bit harder in the
C code.  On the other hand, however, I suspect the resulting
code would be cleaner without having to actually create and
delete temporary refs in refs/reference-tmp/ namespace but fake
them only in-core, with a proper transport API enhancements.

But if you only want a quick-and-dirty workaround, you can
manually do refs/reference-tmp and objects/info/alternates dance
that is done by git-clone before running a git-fetch from such
"nearby" remote.

I strongly suspect that an approach not to use temporary refs on
the filesystem would be needed for robustness if we were to do
this for real inside git-fetch as a real solution, so that we
would not leave them behind when interrupted.  This is not such
a big deal for git-clone which knows it always starts from a
void and cleaning up the mess is not a big issue, but matters
for the use of git-fetch under discussion, which _will_ work
inside an already initialized repository.

^ permalink raw reply

* Re: Dose git-fetch need --reference option like git-clone?
From: Mike Hommey @ 2007-11-11  8:38 UTC (permalink / raw)
  To: Yin Ping; +Cc: git
In-Reply-To: <46dff0320711110009y713c7d38q7b1457c92daecef6@mail.gmail.com>

On Sun, Nov 11, 2007 at 04:09:55PM +0800, Yin Ping wrote:
> I want to track remote repsotory (say remoteA) on my local repository
> (say localB), so i do the following in directory localB
> $ git remote add remoteA git://remoteAUrl
> $ git fetch remoteA
> This will fetch all objects from git://remoteAUrl if localB and
> remoteA don't have common objects.
> 
> If I already have a cloned remoteA on local machine (say
> /path/to/remoteACloned), I want to do following to reduce the net
> traffic as git-clone:
> git fetch --reference /path/to/remoteACloned remotedA
> 
> Is this reasonable? Or is there already a resolution for this case?

It would probably be reasonable to have this on git-remote. Anyways, you
can easily do it yourself by editing .git/objects/info/alternates and
adding /path/to/remoteACloned in it. You can happily git fetch after
that.

Mike

^ permalink raw reply

* Re: `git-send-email' doesn't specify `Content-Type'
From: Brian Swetland @ 2007-11-11  8:39 UTC (permalink / raw)
  To: Jeff King
  Cc: Björn Steinbrink, Johannes Schindelin, Ludovic Courtès,
	git
In-Reply-To: <20071111083224.GA30299@sigill.intra.peff.net>


This issue with the encoding of the author got me thinking...

What happens if the metadata has utf8 content and the patch itself has 
some *other* non-ascii encoding (some iso-latin variant perhaps).

Is there any way to deal with that situation sanely other than indicate
that it's 8bit content and not specify an encoding?  Is that what
happens currently?

Brian

^ 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