Git development
 help / color / mirror / Atom feed
* [PATCH 2/2] gitview: run blame with -C -C
From: Aneesh Kumar K.V @ 2007-06-13  8:46 UTC (permalink / raw)
  To: git; +Cc: gitster, Aneesh Kumar K.V
In-Reply-To: <142a3f15cd43680e0d7a02f09ffdd93864d13871.1181724308.git.aneesh.kumar@linux.vnet.ibm.com>

From: Aneesh Kumar K.V <aneesh.kumar@gmail.com>

pass -C -C option to git-blame so that blame browsing
works when the data is copied over from other files.

Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@gmail.com>
---
 contrib/gitview/gitview |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/contrib/gitview/gitview b/contrib/gitview/gitview
index 93ecfc1..5931766 100755
--- a/contrib/gitview/gitview
+++ b/contrib/gitview/gitview
@@ -533,7 +533,7 @@ class AnnotateWindow(object):
 
 		self.add_file_data(filename, commit_sha1, line_num)
 
-		fp = os.popen("git blame --incremental -- " + filename + " " + commit_sha1)
+		fp = os.popen("git blame --incremental -C -C -- " + filename + " " + commit_sha1)
 		flags = fcntl.fcntl(fp.fileno(), fcntl.F_GETFL)
 		fcntl.fcntl(fp.fileno(), fcntl.F_SETFL, flags | os.O_NONBLOCK)
 		self.io_watch_tag = gobject.io_add_watch(fp, gobject.IO_IN, self.data_ready)
-- 
1.5.2.1.255.gca6c0-dirty

^ permalink raw reply related

* /usr/bin/cg-log: line 361: echo: write error: Broken pipe
From: MichaelTiloDressel @ 2007-06-13  8:29 UTC (permalink / raw)
  To: git

Hi,

I'm using git version 1.5.2.1 and cogito-0.18.1.
Running cg-log gives a different list of logs than running git log.
After quitting cg-log the following error appears:
/usr/bin/cg-log: line 361: echo: write error: Broken pipe.

The lists are:

cg-log:
Commit: 0ca0ed8941002db1d1c241311b144a52f6c36547 
...
Commit: 68ba6cbe612f302aab41aab9ac224cce815d0449 
...
Commit: 62b3728663ed8ab46700adeb6b23624ec7fac405 
...

git log:
commit 0ca0ed8941002db1d1c241311b144a52f6c36547
...
commit dd41b67c15eccaf3e8b0db84bdd67f37cee67d3d
Merge: acd940c... 68ba6cb...
...
commit 68ba6cbe612f302aab41aab9ac224cce815d0449
...


On the previous commit (dd41b67c15eccaf3e8b0db84bdd67f37cee67d3d)
cg-log didn't show that one as first commit but the one before 
(68ba6cbe612f302aab41aab9ac224cce815d0449).
While cg-status showed dd41b67c15eccaf3e8b0db84bdd67f37cee67d3d.

Is this due to the merge?

Best regards,
Michael

^ permalink raw reply

* unexpected git-cherry-pick conflict
From: Gerrit Pape @ 2007-06-13  9:16 UTC (permalink / raw)
  To: git; +Cc: 417885
In-Reply-To: <6b8a91420706070252y3fd581a3w427d91e5b982d29d@mail.gmail.com>

On Thu, Jun 07, 2007 at 11:52:19AM +0200, Remi Vanicat wrote:
> how to reproduce :
> create a repos with a link in it, then in a branch, remove the link,
> and add a directory in place of the link (same name).
> 
> Then try to cherry pick a commit from a branch where there is the
> directory into a branch where there is the link : it failed even if
> the modification ave nothing to do with said link/directory.

Hi, please see http://bugs.debian.org/417885

This is how I can reproduce the conflict, and I too didn't expect that.
The link/dir that conflicts is not changed in the commit that's
cherry-pick'ed:

 $ mkdir repo && cd repo
 $ git init
 Initialized empty Git repository in .git/
 $ echo foo >file
 $ ln -s dangling link
 $ git add .
 $ git commit -mfoo
 Created initial commit c6a9189: foo
  2 files changed, 2 insertions(+), 0 deletions(-)
  create mode 100644 file
  create mode 120000 link
 $ git checkout -b branch
 Switched to a new branch "branch"
 $ git rm link
 rm 'link'
 $ git commit -mremovelink
 Created commit 2c60f15: removelink
  1 files changed, 0 insertions(+), 1 deletions(-)
  delete mode 120000 link
 $ mkdir link
 $ echo bar >link/file
 $ git add link
 $ git commit -m adddir
 Created commit d3b30b5: adddir
  1 files changed, 1 insertions(+), 0 deletions(-)
  create mode 100644 link/file
 $ echo bar >>file
 $ git commit -mfile file
 Created commit 8ddc4d5: file
  1 files changed, 1 insertions(+), 0 deletions(-)
 $ git checkout master
 Switched to branch "master"
 $ git cherry-pick 8ddc4d5
 CONFLICT (file/directory): There is a directory with name link in
 8ddc4d5... file. Added link as link~HEAD
 Automatic cherry-pick failed.  After resolving the conflicts,
 mark the corrected paths with 'git-add <paths>'
 and commit the result.
 When commiting, use the option '-c 8ddc4d5' to retain authorship and
 message.
 $ 

Thanks, Gerrit.

^ permalink raw reply

* [PATCH] git-svn: allow dcommit to retain local merge information
From: Eric Wong @ 2007-06-13  9:23 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Joakim Tjernlund, Steven Grimm, git
In-Reply-To: <20070612083910.GA28369@muzzle>

dcommit will still rewrite the HEAD commit and the history of the first
parents of each HEAD~1, HEAD~2, HEAD~3 as it always has.

However, any merge parents (HEAD^2, HEAD^^2, HEAD~2^2) will now be
preserved when the new HEAD and HEAD~[0-9]+ commits are rewritten to SVN
with dcommit.  Commits written to SVN will still not have any merge
information besides anything in the commit message.

Thanks to Joakim Tjernlund, Junio C Hamano and Steven Grimm
for explanations, feedback, examples and test case.

Signed-off-by: Eric Wong <normalperson@yhbt.net>
---

 This is a better patch that replaces the previous one.

 Junio:
   This one is a big change and should probably sit in pu or next
   for a bit.  Double-checking the logic in linearize_history()
   would be greatly appreciated, too.
   
   I don't think there are any regressions for the
   already-linear-history case besides slightly reduced performance for
   new calls to cat-file.

 Joakim/Steven:
   Any further testing and test cases would be appreciated.  Be very
   careful with real-world repositories, and run dcommit with the
   '-n' flag before actually committing to verify the diffs are sane.

  Thanks

 git-svn.perl                     |   72 +++++++++++++++++++++++++++----
 t/t9114-git-svn-dcommit-merge.sh |   89 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 152 insertions(+), 9 deletions(-)
 create mode 100755 t/t9114-git-svn-dcommit-merge.sh

diff --git a/git-svn.perl b/git-svn.perl
index 0ae8d70..4290676 100755
--- a/git-svn.perl
+++ b/git-svn.perl
@@ -372,16 +372,9 @@ sub cmd_dcommit {
 		die "Unable to determine upstream SVN information from ",
 		    "$head history\n";
 	}
-	my $c = $refs[-1];
 	my $last_rev;
-	foreach my $d (@refs) {
-		if (!verify_ref("$d~1")) {
-			fatal "Commit $d\n",
-			      "has no parent commit, and therefore ",
-			      "nothing to diff against.\n",
-			      "You should be working from a repository ",
-			      "originally created by git-svn\n";
-		}
+	my ($linear_refs, $parents) = linearize_history($gs, \@refs);
+	foreach my $d (@$linear_refs) {
 		unless (defined $last_rev) {
 			(undef, $last_rev, undef) = cmt_metadata("$d~1");
 			unless (defined $last_rev) {
@@ -403,6 +396,9 @@ sub cmd_dcommit {
 			                svn_path => '');
 			if (!SVN::Git::Editor->new(\%ed_opts)->apply_diff) {
 				print "No changes\n$d~1 == $d\n";
+			} elsif ($parents->{$d} && @{$parents->{$d}}) {
+				$gs->{inject_parents_dcommit}->{$last_rev} =
+				                               $parents->{$d};
 			}
 		}
 	}
@@ -821,6 +817,59 @@ sub working_head_info {
 	(undef, undef, undef, undef);
 }
 
+sub read_commit_parents {
+	my ($parents, $c) = @_;
+	my ($fh, $ctx) = command_output_pipe(qw/cat-file commit/, $c);
+	while (<$fh>) {
+		chomp;
+		last if '';
+		/^parent ($sha1)/ or next;
+		push @{$parents->{$c}}, $1;
+	}
+	close $fh; # break the pipe
+}
+
+sub linearize_history {
+	my ($gs, $refs) = @_;
+	my %parents;
+	foreach my $c (@$refs) {
+		read_commit_parents(\%parents, $c);
+	}
+
+	my @linear_refs;
+	my %skip = ();
+	my $last_svn_commit = $gs->last_commit;
+	foreach my $c (reverse @$refs) {
+		next if $c eq $last_svn_commit;
+		last if $skip{$c};
+
+		unshift @linear_refs, $c;
+		$skip{$c} = 1;
+
+		# we only want the first parent to diff against for linear
+		# history, we save the rest to inject when we finalize the
+		# svn commit
+		my $fp_a = verify_ref("$c~1");
+		my $fp_b = shift @{$parents{$c}} if $parents{$c};
+		if (!$fp_a || !$fp_b) {
+			die "Commit $c\n",
+			    "has no parent commit, and therefore ",
+			    "nothing to diff against.\n",
+			    "You should be working from a repository ",
+			    "originally created by git-svn\n";
+		}
+		if ($fp_a ne $fp_b) {
+			die "$c~1 = $fp_a, however parsing commit $c ",
+			    "revealed that:\n$c~1 = $fp_b\nBUG!\n";
+		}
+
+		foreach my $p (@{$parents{$c}}) {
+			$skip{$p} = 1;
+		}
+	}
+	(\@linear_refs, \%parents);
+}
+
 package Git::SVN;
 use strict;
 use warnings;
@@ -1541,6 +1590,11 @@ sub get_commit_parents {
 	if (my $cur = ::verify_ref($self->refname.'^0')) {
 		push @tmp, $cur;
 	}
+	if (my $ipd = $self->{inject_parents_dcommit}) {
+		if (my $commit = delete $ipd->{$log_entry->{revision}}) {
+			push @tmp, @$commit;
+		}
+	}
 	push @tmp, $_ foreach (@{$log_entry->{parents}}, @tmp);
 	while (my $p = shift @tmp) {
 		next if $seen{$p};
diff --git a/t/t9114-git-svn-dcommit-merge.sh b/t/t9114-git-svn-dcommit-merge.sh
new file mode 100755
index 0000000..d6ca955
--- /dev/null
+++ b/t/t9114-git-svn-dcommit-merge.sh
@@ -0,0 +1,89 @@
+#!/bin/sh
+#
+# Copyright (c) 2007 Eric Wong
+# Based on a script by Joakim Tjernlund <joakim.tjernlund@transmode.se>
+
+test_description='git-svn dcommit handles merges'
+
+. ./lib-git-svn.sh
+
+big_text_block () {
+cat << EOF
+#
+# (C) Copyright 2000 - 2005
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+EOF
+}
+
+test_expect_success 'setup svn repository' "
+	svn co $svnrepo mysvnwork &&
+	mkdir -p mysvnwork/trunk &&
+	cd mysvnwork &&
+		big_text_block >> trunk/README &&
+		svn add trunk &&
+		svn ci -m 'first commit' trunk &&
+		cd ..
+	"
+
+test_expect_success 'setup git mirror and merge' "
+	git svn init $svnrepo -t tags -T trunk -b branches &&
+	git svn fetch &&
+	git checkout --track -b svn remotes/trunk &&
+	git checkout -b merge &&
+	echo new file > new_file &&
+	git add new_file &&
+	git commit -a -m 'New file' &&
+	echo hello >> README &&
+	git commit -a -m 'hello' &&
+	echo add some stuff >> new_file &&
+	git commit -a -m 'add some stuff' &&
+	git checkout svn &&
+	mv -f README tmp &&
+	echo friend > README &&
+	cat tmp >> README &&
+	git commit -a -m 'friend' &&
+	git pull . merge
+	"
+
+test_debug 'gitk --all & sleep 1'
+
+test_expect_success 'verify pre-merge ancestry' "
+	test x\`git rev-parse --verify refs/heads/svn^2\` = \
+	     x\`git rev-parse --verify refs/heads/merge\` &&
+	git cat-file commit refs/heads/svn^ | grep '^friend$'
+	"
+
+test_expect_success 'git svn dcommit merges' "
+	git svn dcommit
+	"
+
+test_debug 'gitk --all & sleep 1'
+
+test_expect_success 'verify post-merge ancestry' "
+	test x\`git rev-parse --verify refs/heads/svn\` = \
+	     x\`git rev-parse --verify refs/remotes/trunk \` &&
+	test x\`git rev-parse --verify refs/heads/svn^2\` = \
+	     x\`git rev-parse --verify refs/heads/merge\` &&
+	git cat-file commit refs/heads/svn^ | grep '^friend$'
+	"
+
+test_done
-- 
Eric Wong

^ permalink raw reply related

* [PATCH 0/3] git-svn: several house-keeping fixes
From: Eric Wong @ 2007-06-13  9:37 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

[PATCH 1/3] git-svn: cleanup: factor out longest_common_path() function
 - readability

[PATCH 2/3] git-svn: test for creating new directories over svn://
 - The bug is already long fixed, but I'd like to add it for
   documentation/regression testing purposes in case it breaks again.

[PATCH 3/3] git-svn: reduce stat() calls for a backwards compatibility check
 - There's actually a small bugfix in there, too.  This should go to maint.

-- 
Eric Wong

^ permalink raw reply

* [PATCH 1/3] git-svn: cleanup: factor out longest_common_path() function
From: Eric Wong @ 2007-06-13  9:37 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, Eric Wong
In-Reply-To: <11817274254011-git-send-email-normalperson@yhbt.net>

I hadn't looked at this code in a while and had to read this
again to figure out what it did.  To avoid having to do this
again in the future, I just gave gave the hunk a descriptive
name.

Signed-off-by: Eric Wong <normalperson@yhbt.net>
---
 git-svn.perl |   16 +++++++++++-----
 1 files changed, 11 insertions(+), 5 deletions(-)

diff --git a/git-svn.perl b/git-svn.perl
index e350061..58f7dd0 100755
--- a/git-svn.perl
+++ b/git-svn.perl
@@ -3072,11 +3072,8 @@ sub gs_do_switch {
 	$editor->{git_commit_ok};
 }
 
-sub gs_fetch_loop_common {
-	my ($self, $base, $head, $gsv, $globs) = @_;
-	return if ($base > $head);
-	my $inc = $_log_window_size;
-	my ($min, $max) = ($base, $head < $base + $inc ? $head : $base + $inc);
+sub longest_common_path {
+	my ($gsv, $globs) = @_;
 	my %common;
 	my $common_max = scalar @$gsv;
 
@@ -3108,6 +3105,15 @@ sub gs_fetch_loop_common {
 			last;
 		}
 	}
+	$longest_path;
+}
+
+sub gs_fetch_loop_common {
+	my ($self, $base, $head, $gsv, $globs) = @_;
+	return if ($base > $head);
+	my $inc = $_log_window_size;
+	my ($min, $max) = ($base, $head < $base + $inc ? $head : $base + $inc);
+	my $longest_path = longest_common_path($gsv, $globs);
 	while (1) {
 		my %revs;
 		my $err;
-- 
1.5.2.1.243.gbe00

^ permalink raw reply related

* [PATCH 2/3] git-svn: test for creating new directories over svn://
From: Eric Wong @ 2007-06-13  9:37 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, Eric Wong
In-Reply-To: <11817274254011-git-send-email-normalperson@yhbt.net>

As reported by Matthieu Moy, this is causing svnserve to
terminate connections (because it segfaults) segfault.

This test is disabled by default and can be enabled by setting
SVNSERVE_PORT to an unbound (for 127.0.0.1) TCP port in the
environment (in addition to SVN_TESTS=1).  I'm not comfortable
with having a test start a daemon by default and take up a port
that could potentially stay running if the test failed.

Signed-off-by: Eric Wong <normalperson@yhbt.net>
---
 t/t9113-git-svn-dcommit-new-file.sh |   40 +++++++++++++++++++++++++++++++++++
 1 files changed, 40 insertions(+), 0 deletions(-)
 create mode 100755 t/t9113-git-svn-dcommit-new-file.sh

diff --git a/t/t9113-git-svn-dcommit-new-file.sh b/t/t9113-git-svn-dcommit-new-file.sh
new file mode 100755
index 0000000..9ef0db9
--- /dev/null
+++ b/t/t9113-git-svn-dcommit-new-file.sh
@@ -0,0 +1,40 @@
+#!/bin/sh
+#
+# Copyright (c) 2007 Eric Wong
+#
+
+# Don't run this test by default unless the user really wants it
+# I don't like the idea of taking a port and possibly leaving a
+# daemon running on a users system if the test fails.
+# Not all git users will need to interact with SVN.
+test -z "$SVNSERVE_PORT" && exit 0
+
+test_description='git-svn dcommit new files over svn:// test'
+
+. ./lib-git-svn.sh
+
+start_svnserve () {
+	svnserve --listen-port $SVNSERVE_PORT \
+	         --root $rawsvnrepo \
+	         --listen-once \
+	         --listen-host 127.0.0.1 &
+}
+
+test_expect_success 'start tracking an empty repo' "
+	svn mkdir -m 'empty dir' $svnrepo/empty-dir &&
+	echo anon-access = write >> $rawsvnrepo/conf/svnserve.conf &&
+	start_svnserve &&
+	git svn init svn://127.0.0.1:$SVNSERVE_PORT &&
+	git svn fetch
+	"
+
+test_expect_success 'create files in new directory with dcommit' "
+	mkdir git-new-dir &&
+	echo hello > git-new-dir/world &&
+	git update-index --add git-new-dir/world &&
+	git commit -m hello &&
+	start_svnserve &&
+	git svn dcommit
+	"
+
+test_done
-- 
1.5.2.1.243.gbe00

^ permalink raw reply related

* [PATCH 3/3] git-svn: reduce stat() calls for a backwards compatibility check
From: Eric Wong @ 2007-06-13  9:37 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, Eric Wong
In-Reply-To: <11817274254011-git-send-email-normalperson@yhbt.net>

Also, this fixes a bug where in an odd case a remote named
"config" could get renamed to ".metadata".

Signed-off-by: Eric Wong <normalperson@yhbt.net>
---
 git-svn.perl |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/git-svn.perl b/git-svn.perl
index 58f7dd0..0ae8d70 100755
--- a/git-svn.perl
+++ b/git-svn.perl
@@ -1457,7 +1457,7 @@ sub tmp_config {
 	my (@args) = @_;
 	my $old_def_config = "$ENV{GIT_DIR}/svn/config";
 	my $config = "$ENV{GIT_DIR}/svn/.metadata";
-	if (-e $old_def_config && ! -e $config) {
+	if (! -f $config && -f $old_def_config) {
 		rename $old_def_config, $config or
 		       die "Failed rename $old_def_config => $config: $!\n";
 	}
-- 
1.5.2.1.243.gbe00

^ permalink raw reply related

* Re: /usr/bin/cg-log: line 361: echo: write error: Broken pipe
From: MichaelTiloDressel @ 2007-06-13 10:18 UTC (permalink / raw)
  To: git

Hi,

it was just me beeing stupid, not reading the man page. cg-log -M shows
the merge too.
And the pipe error may be due to less.

Cheers,
Michael

^ permalink raw reply

* tags and patches
From: Geoff Russell @ 2007-06-13 10:52 UTC (permalink / raw)
  To: git

Dear gits,

(I'm on 1.5.0.5)

The last tag made seems to be missing from a patch ... eg.

        cd ~ ; mkdir myrepo ; cd myrepo
        git init-db ; echo STUFF > xxx ; git add xxx
        # work, work, work on xxx
        git commit -a
        git tag v1.0
        # work work work on xxx
        # then I clone this repository
        cd /tmp ; git clone ~/myrepo newmyrepo
        # go back and work some more
        cd ~/myrepo
        echo YYY >>xxx
        git commit -a
        git tag v1.1
        # is git commit -a required to commit the tag???
        git format-patch v1.0
        cd /tmp/newmyrepo
        git am ~/myrepo/THEPATCHNAME
        git tag ls

Where is tag v1.1 ?

Cheers,
Geoff Russell

^ permalink raw reply

* Re: That improved git-gui blame viewer..
From: Marco Costalba @ 2007-06-13 11:03 UTC (permalink / raw)
  To: Shawn O. Pearce; +Cc: Junio C Hamano, Linus Torvalds, Git Mailing List
In-Reply-To: <20070612135303.GT6073@spearce.org>

On 6/12/07, Shawn O. Pearce <spearce@spearce.org> wrote:
>
> It is unclear why you aren't just using `git blame --incremental`.
> git-blame running in two passes (with and without -M -C -C) can yield
> some very interesting results on files, like Git's own revision.c.
> And with the new -w flag that Junio just added, there's even more
> interesting possibilities...
>

I will try to explore with git-blame better, thanks.

Marco

^ permalink raw reply

* Re: tags and patches
From: Pierre Habouzit @ 2007-06-13 11:04 UTC (permalink / raw)
  To: Geoff Russell; +Cc: git
In-Reply-To: <93c3eada0706130352h3ad6857eie01e1171fdda3991@mail.gmail.com>

[-- Attachment #1: Type: text/plain, Size: 1174 bytes --]

On Wed, Jun 13, 2007 at 08:22:23PM +0930, Geoff Russell wrote:
> Dear gits,
> 
> (I'm on 1.5.0.5)
> 
> The last tag made seems to be missing from a patch ... eg.
> 
>        cd ~ ; mkdir myrepo ; cd myrepo
>        git init-db ; echo STUFF > xxx ; git add xxx
>        # work, work, work on xxx
>        git commit -a
>        git tag v1.0
>        # work work work on xxx
>        # then I clone this repository
>        cd /tmp ; git clone ~/myrepo newmyrepo
>        # go back and work some more
>        cd ~/myrepo
>        echo YYY >>xxx
>        git commit -a
>        git tag v1.1
>        # is git commit -a required to commit the tag???
>        git format-patch v1.0
>        cd /tmp/newmyrepo
>        git am ~/myrepo/THEPATCHNAME
>        git tag ls

  git tag ls is not the proper way to list tags. Afaict there isn't any
yet, except: ls .git/refs/tags/

  git tag ls just tagged your HEAD with the name 'ls' which is obviously
not what you meant :)

-- 
·O·  Pierre Habouzit
··O                                                madcoder@debian.org
OOO                                                http://www.madism.org

[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply

* Re: That improved git-gui blame viewer..
From: Marco Costalba @ 2007-06-13 11:11 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Shawn O. Pearce, Linus Torvalds, Git Mailing List
In-Reply-To: <7v645thto7.fsf@assigned-by-dhcp.pobox.com>

On 6/12/07, Junio C Hamano <gitster@pobox.com> wrote:
>
> However, adding a new option to "git log" so that you can say
> 'git log --single-follow=$this_file_at_the_tip $branch' is a
> separate matter.  I think it is a sensible thing to do.  But
> even if we do that, I think --single-follow should limit itself
> to the rename following of "diff -M/-C" style.  It is insane to
> include another path only because the result did copy&paste only
> a handful lines out of during its history.
>

Some weeks ago I've started to experiment with git-log as a
replacement for git-rev-list (as suggested by Linus in a thread).

I found some problems and so I stopped, but I think it's time to give
it another look.

Maybe this week-end I'll do some testing.


Marco

^ permalink raw reply

* Re: [PATCH] Interpret :/<pattern> as a regular expression
From: Johannes Schindelin @ 2007-06-13 11:10 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <7vr6ogh2w7.fsf@assigned-by-dhcp.pobox.com>

Hi,

On Tue, 12 Jun 2007, Junio C Hamano wrote:

> Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
> 
> > diff --git a/sha1_name.c b/sha1_name.c
> > index d9188ed..f1ba194 100644
> > --- a/sha1_name.c
> > +++ b/sha1_name.c
> > @@ -611,6 +611,8 @@ static int get_sha1_oneline(const char *prefix, unsigned char *sha1)
> >  {
> >  	struct commit_list *list = NULL, *backup = NULL, *l;
> >  	int retval = -1;
> > +	regex_t regexp;
> > +	regmatch_t regmatch[1];
> >  
> >  	if (prefix[0] == '!') {
> >  		if (prefix[1] != '!')
> 
> Because you are not extracting any match substring, I do not
> think you would need regmatch[] there.

I explicitely want to anchor the match at the beginning of the message 
(otherwise, most of the interesting patterns would match a merge pulling 
that commit in), and therefore I have to check where the match was. Alas, 
that's only possible with regmatch.

> > @@ -622,6 +624,8 @@ static int get_sha1_oneline(const char *prefix, unsigned char *sha1)
> >  	for_each_ref(handle_one_ref, &list);
> >  	for (l = list; l; l = l->next)
> >  		commit_list_insert(l->item, &backup);
> > +	if (regcomp(&regexp, prefix, REG_EXTENDED))
> > +		return error("invalid regexp: %s", prefix);
> >  	while (list) {
> >  		char *p;
> >  		struct commit *commit;
> 
> Why EXTENDED?

Sorry. Old habit. Will fix.

> Also you probably want REG_NEWLINE.

No. If I look for something in the body of the message (like I showed in 
the two examples), I'd like to say ':/.*Blub'. Of course, you could always 
say

	git diff ':/[ -~
]*Blub'

with REG_NEWLINE, to match newlines also. But frankly, it is much more 
often that I want to match something in the whole message than just in the 
oneline. And if I _do_ want the match only in the oneline, I can still go 
and do

	git diff ':/[^
]*Blub'

when REG_NEWLINE is disabled. If you can teach me a better way to do both 
things, matching in the oneline _or_ matching the whole message, _with_ 
REG_NEWLINE, I'll gladly change it, and provide an example in the commit 
message as well as the documentation for equally clueless subjects as me.

> > @@ -630,7 +634,9 @@ static int get_sha1_oneline(const char *prefix, unsigned char *sha1)
> >  		parse_object(commit->object.sha1);
> >  		if (!commit->buffer || !(p = strstr(commit->buffer, "\n\n")))
> >  			continue;
> > -		if (!prefixcmp(p + 2, prefix)) {
> > +		if (!regexec(&regexp, p + 2, 1, regmatch, 0) &&
> > +				printf("match: %d\n", regmatch[0].rm_so) &&
> > +				regmatch[0].rm_so == 0) {
> >  			hashcpy(sha1, commit->object.sha1);
> >  			retval = 0;
> >  			break;
> 
> Do we want to detect return value other than REG_NOMATCH from
> regexec() when it does not return zero?

I am not well versed in the multitude of POSIX and other standards we have 
on this planet, therefore I just read my man page. And it says, quote:

	regexec() returns zero for a successful match or REG_NOMATCH for 
	failure.

Tertium non datur. At least according to my man page here. Am I mistaken 
in my assumption (which seems to be somewhat supported from my limited 
reading of the man page) that all errors should be caught at regcomp() 
time?

> Please lose the debugging printf() before submitting.

Ouch. Sorry.

> > @@ -639,6 +645,7 @@ static int get_sha1_oneline(const char *prefix, unsigned char *sha1)
> >  	free_commit_list(list);
> >  	for (l = backup; l; l = l->next)
> >  		clear_commit_marks(l->item, ONELINE_SEEN);
> > +	regfree(&regexp);
> >  	return retval;
> >  }
> >  
> 
> Also I think you would want to fix get_sha1_oneline() so that it
> not to refuse to work without save_commit_buffer.

You're right, will fix.

I'll resubmit shortly. However, feel free to enlighten me with insights 
into working _with_ REG_NEWLINE, and I'll gladly submit another version of 
the patch with REG_NEWLINE enabled, along with the additions to the 
documentation.

Thanks,
Dscho

^ permalink raw reply

* (unknown)
From: Johannes Schindelin @ 2007-06-13 11:17 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <7vr6ogh2w7.fsf@assigned-by-dhcp.pobox.com>

[PATCH] Interpret :/<pattern> as a regular expression

Earlier, Git interpreted the pattern as a strict prefix, which made
the operator unsuited in many cases.

Now, the pattern is interpreted as a regular expression, on the whole
message, so that you can say

	git diff :/.*^Signed-off-by:.Zack.Brown

to see the diff against the most recent reachable commit which was
signed off by Zack, whose Kernel Cousin I miss very much.

If you want to match just the oneline, but with a regular expression,
say something like

	git diff ':/[^
]*intelligent'

Since it makes more sense to match the beginning of a message (otherwise,
a pattern like ':/git-gui: Improve' would match the _merge_ commit, 
pulling in the commit you are likely to want), the implementation uses the 
regmatch parameter of regexec() to anchor the pattern there.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---

	Anyone who can teach me how to match / not-match a newline
	using a more elegant syntax, please do so, by all means.

 Documentation/git-rev-parse.txt |    6 +++---
 sha1_name.c                     |   31 +++++++++++++++++++++++++------
 2 files changed, 28 insertions(+), 9 deletions(-)

diff --git a/Documentation/git-rev-parse.txt b/Documentation/git-rev-parse.txt
index 6380676..56e1561 100644
--- a/Documentation/git-rev-parse.txt
+++ b/Documentation/git-rev-parse.txt
@@ -194,9 +194,9 @@ blobs contained in a commit.
   found.
 
 * A colon, followed by a slash, followed by a text: this names
-  a commit whose commit message starts with the specified text.
-  This name returns the youngest matching commit which is
-  reachable from any ref.  If the commit message starts with a
+  a commit whose commit message starts with the specified regular
+  expression.  This name returns the youngest matching commit which
+  is reachable from any ref.  If the commit message starts with a
   '!', you have to repeat that;  the special sequence ':/!',
   followed by something else than '!' is reserved for now.
 
diff --git a/sha1_name.c b/sha1_name.c
index d9188ed..988d599 100644
--- a/sha1_name.c
+++ b/sha1_name.c
@@ -599,8 +599,8 @@ static int handle_one_ref(const char *path,
 
 /*
  * This interprets names like ':/Initial revision of "git"' by searching
- * through history and returning the first commit whose message starts
- * with the given string.
+ * through history and returning the first commit whose message matches
+ * the given regular expression.
  *
  * For future extension, ':/!' is reserved. If you want to match a message
  * beginning with a '!', you have to repeat the exclamation mark.
@@ -611,34 +611,53 @@ static int get_sha1_oneline(const char *prefix, unsigned char *sha1)
 {
 	struct commit_list *list = NULL, *backup = NULL, *l;
 	int retval = -1;
+	regex_t regexp;
+	regmatch_t regmatch[1];
+	char *temp_commit_buffer = NULL;
 
 	if (prefix[0] == '!') {
 		if (prefix[1] != '!')
 			die ("Invalid search pattern: %s", prefix);
 		prefix++;
 	}
-	if (!save_commit_buffer)
-		return error("Could not expand oneline-name.");
 	for_each_ref(handle_one_ref, &list);
 	for (l = list; l; l = l->next)
 		commit_list_insert(l->item, &backup);
+	if (regcomp(&regexp, prefix, 0))
+		return error("invalid regexp: %s", prefix);
 	while (list) {
 		char *p;
 		struct commit *commit;
+		enum object_type type;
+		unsigned long size;
 
 		commit = pop_most_recent_commit(&list, ONELINE_SEEN);
 		parse_object(commit->object.sha1);
-		if (!commit->buffer || !(p = strstr(commit->buffer, "\n\n")))
+		if (temp_commit_buffer)
+			free(temp_commit_buffer);
+		if (commit->buffer)
+			p = commit->buffer;
+		else {
+			p = read_sha1_file(commit->object.sha1, &type, &size);
+			if (!p)
+				continue;
+			temp_commit_buffer = p;
+		}
+		if (!(p = strstr(p, "\n\n")))
 			continue;
-		if (!prefixcmp(p + 2, prefix)) {
+		if (!regexec(&regexp, p + 2, 1, regmatch, 0) &&
+				regmatch[0].rm_so == 0) {
 			hashcpy(sha1, commit->object.sha1);
 			retval = 0;
 			break;
 		}
 	}
+	if (temp_commit_buffer)
+		free(temp_commit_buffer);
 	free_commit_list(list);
 	for (l = backup; l; l = l->next)
 		clear_commit_marks(l->item, ONELINE_SEEN);
+	regfree(&regexp);
 	return retval;
 }
 
-- 
1.5.2.1.2827.gba84a8-dirty

^ permalink raw reply related

* Stupid quoting...
From: David Kastrup @ 2007-06-13 11:30 UTC (permalink / raw)
  To: git


Hi,

what is the point in quoting file names and their characters in
git-diff's output?  And what is the recommended way of undoing the
damage?

I have something like

git-diff -M -C --name-status -r master^ master | {
    while read -r flag name
    do
	case "$name" in *\\[0-3][0-7][0-7]*)
		name=$(echo -e $(echo "$name"|sed 's/\\\([0-3][0-7][0-7]\)/\\0\1/g;s/\\\([^0]\)/\\\\\1/g'))
	esac
        [...]

in order to get through the worst with utf-8 file names, and it is a
complete nuisance (double quotemarks are treated later).

Is there any utility or pipe or invocation that can take a sequence of
filenames as printed by git and turn them back into what they actually
were in the first place?

-- 
David Kastrup

^ permalink raw reply

* Re: tags and patches
From: Geoff Russell @ 2007-06-13 12:04 UTC (permalink / raw)
  To: git
In-Reply-To: <20070613110401.GG21684@artemis.intersec.eu>

On 6/13/07, Pierre Habouzit <madcoder@debian.org> wrote:
> On Wed, Jun 13, 2007 at 08:22:23PM +0930, Geoff Russell wrote:
> > Dear gits,
> >
> > (I'm on 1.5.0.5)
> >
> > The last tag made seems to be missing from a patch ... eg.
> >
> >        cd ~ ; mkdir myrepo ; cd myrepo
> >        git init-db ; echo STUFF > xxx ; git add xxx
> >        # work, work, work on xxx
> >        git commit -a
> >        git tag v1.0
> >        # work work work on xxx
> >        # then I clone this repository
> >        cd /tmp ; git clone ~/myrepo newmyrepo
> >        # go back and work some more
> >        cd ~/myrepo
> >        echo YYY >>xxx
> >        git commit -a
> >        git tag v1.1
> >        # is git commit -a required to commit the tag???
> >        git format-patch v1.0
> >        cd /tmp/newmyrepo
> >        git am ~/myrepo/THEPATCHNAME
> >        git tag ls
>
>   git tag ls is not the proper way to list tags. Afaict there isn't any
> yet, except: ls .git/refs/tags/
>
>   git tag ls just tagged your HEAD with the name 'ls' which is obviously
> not what you meant :)

Ooops. Yes, I meant "git tag -l" as the last command, which lists the tags,
but doesn't list v1.1.

Geoff.

>
> --
> ·O·  Pierre Habouzit
> ··O                                                madcoder@debian.org
> OOO                                                http://www.madism.org
>
>

^ permalink raw reply

* Re: Stupid quoting...
From: Alex Riesen @ 2007-06-13 12:06 UTC (permalink / raw)
  To: David Kastrup; +Cc: git
In-Reply-To: <86ir9sw0pi.fsf@lola.quinscape.zz>

On 6/13/07, David Kastrup <dak@gnu.org> wrote:
>
> what is the point in quoting file names and their characters in
> git-diff's output?  And what is the recommended way of undoing the
> damage?
>

Just use "-z". Everything will be unquoted and separated by \0

^ permalink raw reply

* [PATCH] Interpret :/<pattern> as a regular expression
From: Johannes Schindelin @ 2007-06-13 12:11 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <Pine.LNX.4.64.0706131214010.4059@racer.site>

Hi,

I don't know what happened to my subject in the mail I'm replying to... 
Sorry.

Ciao,
Dscho

^ permalink raw reply

* Re: tags and patches
From: Johannes Schindelin @ 2007-06-13 12:14 UTC (permalink / raw)
  To: Geoff Russell; +Cc: git
In-Reply-To: <93c3eada0706130352h3ad6857eie01e1171fdda3991@mail.gmail.com>

Hi,

On Wed, 13 Jun 2007, Geoff Russell wrote:

> Dear gits,

;-)

> [...]
>
>        git tag v1.1
>        git format-patch v1.0
>        cd /tmp/newmyrepo
>        git am ~/myrepo/THEPATCHNAME
> 
> Where is tag v1.1 ?

Tags are not propagated with patches. Sorry.

Ciao,
Dscho

^ permalink raw reply

* Re: Stupid quoting...
From: Johannes Schindelin @ 2007-06-13 12:21 UTC (permalink / raw)
  To: David Kastrup; +Cc: git
In-Reply-To: <86ir9sw0pi.fsf@lola.quinscape.zz>

Hi,

On Wed, 13 Jun 2007, David Kastrup wrote:

> what is the point in quoting file names and their characters in
> git-diff's output?  And what is the recommended way of undoing the
> damage?

The recommended way is not using spaces to begin with. I mean, does 
"David" contain spaces? People seem not to see the problem, and fail to 
blame Microsoft for all the damage they have done, introducing that 
stupid, stupid concept of filenames containing spaces, and _enforcing_ it.

> I have something like
> 
> git-diff -M -C --name-status -r master^ master | {
>     while read -r flag name
>     do
> 	case "$name" in *\\[0-3][0-7][0-7]*)
> 		name=$(echo -e $(echo "$name"|sed 's/\\\([0-3][0-7][0-7]\)/\\0\1/g;s/\\\([^0]\)/\\\\\1/g'))
> 	esac
>         [...]
> 
> in order to get through the worst with utf-8 file names, and it is a
> complete nuisance (double quotemarks are treated later).

Please understand that the quotes are not there for you, but for 
processing by other programs.

However, I _suspect_ that you want to do something like

	name="$(echo $name)"

because "echo" is exactly one of the programs this quoting was invented 
for.

Ciao,
Dscho

^ permalink raw reply

* Re: That improved git-gui blame viewer..
From: Marco Costalba @ 2007-06-13 12:44 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Shawn O. Pearce, Linus Torvalds, Git Mailing List
In-Reply-To: <e5bfff550706130411g151b76e3sa2e351aff5dbb35b@mail.gmail.com>

On 6/13/07, Marco Costalba <mcostalba@gmail.com> wrote:
>
> Some weeks ago I've started to experiment with git-log as a
> replacement for git-rev-list (as suggested by Linus in a thread).
>
> I found some problems and so I stopped

Now I remember why I've quit with git-log: due to a big performance
regression under Windows.

I've made some tests on a git tree copied under Windows:

running:  git rev-list --header --parents --boundary HEAD > tmp.txt

1,38s
1,37s
1,39s

then running: git log --pretty=raw -z --parents --boundary HEAD > tmp.txt

8,87s
8,87s
8,86s
8,86s


So at the end git-log seems 6,4 times slower the git-rev-list !

This would mean the end of the story for me.


Marco

^ permalink raw reply

* Re: That improved git-gui blame viewer..
From: Johannes Schindelin @ 2007-06-13 12:45 UTC (permalink / raw)
  To: Marco Costalba
  Cc: Junio C Hamano, Shawn O. Pearce, Linus Torvalds, Git Mailing List
In-Reply-To: <e5bfff550706130544m40e2f210p2412ef7fde2867a1@mail.gmail.com>

Hi,

On Wed, 13 Jun 2007, Marco Costalba wrote:

> I've made some tests on a git tree copied under Windows:
> 
> running:  git rev-list --header --parents --boundary HEAD > tmp.txt
> 
> [...]
> 
> then running: git log --pretty=raw -z --parents --boundary HEAD > tmp.txt

Isn't that a bit unfair? You should have passed "--pretty=raw" to 
rev-list, too.

Since you already have that tree, could you try rev-list _with_ 
"--pretty=raw", just for comparison?

Thanks,
Dscho

^ permalink raw reply

* Re: unexpected git-cherry-pick conflict
From: Johannes Schindelin @ 2007-06-13 12:58 UTC (permalink / raw)
  To: Gerrit Pape; +Cc: git, 417885
In-Reply-To: <20070613091624.26463.qmail@353090644b4917.315fe32.mid.smarden.org>

Hi,

On Wed, 13 Jun 2007, Gerrit Pape wrote:

>  $ mkdir repo && cd repo
>  $ git init
>  Initialized empty Git repository in .git/
>  $ echo foo >file
>  $ ln -s dangling link
>  $ git add .
>  $ git commit -mfoo
>  Created initial commit c6a9189: foo
>   2 files changed, 2 insertions(+), 0 deletions(-)
>   create mode 100644 file
>   create mode 120000 link

So, basically your master has a file and a symbolic link.

>  $ git checkout -b branch
>  Switched to a new branch "branch"
>  $ git rm link
>  rm 'link'
>  $ git commit -mremovelink
>  Created commit 2c60f15: removelink
>   1 files changed, 0 insertions(+), 1 deletions(-)
>   delete mode 120000 link

Here, you remove the link from the branch.

>  $ mkdir link
>  $ echo bar >link/file
>  $ git add link
>  $ git commit -m adddir
>  Created commit d3b30b5: adddir
>   1 files changed, 1 insertions(+), 0 deletions(-)
>   create mode 100644 link/file

Here you added a directory of the same name as the symbolic link has in 
master.

>  $ git checkout master
>  Switched to branch "master"
>  $ git cherry-pick 8ddc4d5
>  CONFLICT (file/directory): There is a directory with name link in
>  8ddc4d5... file. Added link as link~HEAD

Here you _still_ have the file in master. So that conflict is really 
expected, since a cherry-pick will only do a three-way merge.

I guess you want to use git-rebase instead.

Ciao,
Dscho

^ permalink raw reply

* Re: [PATCH] Interpret :/<pattern> as a regular expression
From: Johannes Schindelin @ 2007-06-13 13:13 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <7v1wggir80.fsf@assigned-by-dhcp.pobox.com>

Hi,

On Tue, 12 Jun 2007, Junio C Hamano wrote:

> Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
> 
> > Earlier, Git interpreted the pattern as a strict prefix, which made
> > the operator unsuited in many cases.
> >
> > Now, the pattern is interpreted as a regular expression (which does not 
> > change the behaviour too much, since few onelines contain special regex 
> > characters), so that you can say
> >
> > 	git diff :/.*^Signed-off-by:.Zack.Brown
> >
> > to see the diff against the most recent reachable commit which was
> > signed off by Zack, whose Kernel Cousin I miss very much.
> >
> > Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
> 
> While this perhaps is an improvement and people who are not
> interested in paying the price have a choice of not using this
> silly syntax, I am moderately annoyed that the syntax does not
> define "the most recent reachable" very well.  It is more like
> "the first one we happened to pick by diffing from reachable
> refs".  It would be more useful if it took "$commit:/$pattern"
> form to limit the search among reachable ones from named commit.

"Unfortunately", $commit:/$pattern is not a good syntax, since it suggests 
that you want to search _in_ $commit, not _from $commit.

How about ':/!commit=$commit:$pattern'?

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