Git development
 help / color / mirror / Atom feed
* [PATCH 3/3] gitweb: Output valid utf8 in git_blame_common('data')
From: Jakub Narebski @ 2011-12-17  9:15 UTC (permalink / raw)
  To: git; +Cc: Juergen Kreileder, John Hawley, admin
In-Reply-To: <1324113324-21328-1-git-send-email-jnareb@gmail.com>

From: Jürgen Kreileder <jk@blackdown.de>

Otherwise when javascript-actions are enabled gitweb shown broken
author names in the tooltips on blame pages ('blame_incremental'
view).

Signed-off-by: Jürgen Kreileder <jk@blackdown.de>
Acked-by: Jakub Narębski <jnareb@gmail.com>
---
 gitweb/gitweb.perl |    4 +++-
 1 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index dcf4658..d24763b 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -6244,7 +6244,9 @@ sub git_blame_common {
 			-type=>"text/plain", -charset => "utf-8",
 			-status=> "200 OK");
 		local $| = 1; # output autoflush
-		print while <$fd>;
+		while (my $line = <$fd>) {
+			print to_utf8($line);
+		}
 		close $fd
 			or print "ERROR $!\n";
 
-- 
1.7.6

^ permalink raw reply related

* [PATCH 0/3 (resend)] gitweb: Various to_utf8 / esc_html fixes
From: Jakub Narebski @ 2011-12-17  9:22 UTC (permalink / raw)
  To: git; +Cc: Juergen Kreileder, John Hawley, admin, Jakub Narebski

Sorry for resend of this series, but I forgot to generate patches in
UTF-8 instead of i18n.logoutputencoding=iso-8859-2


This is post-release resend of Jürgen patches (which were sent
during feature-freeze).

I have slightly extended commit messages, and added my ACK.

Jürgen Kreileder (3):
  gitweb: Call to_utf8() on input string in chop_and_escape_str()
  gitweb: esc_html() site name for title in OPML
  gitweb: Output valid utf8 in git_blame_common('data')

 gitweb/gitweb.perl |    8 ++++++--
 1 files changed, 6 insertions(+), 2 deletions(-)

-- 
1.7.6

^ permalink raw reply

* [PATCH 1/3] gitweb: Call to_utf8() on input string in chop_and_escape_str()
From: Jakub Narebski @ 2011-12-17  9:22 UTC (permalink / raw)
  To: git; +Cc: Juergen Kreileder, John Hawley, admin
In-Reply-To: <1324113743-21498-1-git-send-email-jnareb@gmail.com>

From: Jürgen Kreileder <jk@blackdown.de>

a) To fix the comparison with the chopped string,
   otherwise we compare bytes with characters, as
   chop_str() must run to_utf8() for correct operation
b) To give the title attribute correct encoding;
   we need to mark strings as UTF-8 before outpur

Signed-off-by: Jürgen Kreileder <jk@blackdown.de>
Acked-by: Jakub Narębski <jnareb@gmail.com>
---
 gitweb/gitweb.perl |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index f80f259..35126cd 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -1696,6 +1696,7 @@ sub chop_and_escape_str {
 	my ($str) = @_;
 
 	my $chopped = chop_str(@_);
+	$str = to_utf8($str);
 	if ($chopped eq $str) {
 		return esc_html($chopped);
 	} else {
-- 
1.7.6

^ permalink raw reply related

* [PATCH 3/3] gitweb: Output valid utf8 in git_blame_common('data')
From: Jakub Narebski @ 2011-12-17  9:22 UTC (permalink / raw)
  To: git; +Cc: Juergen Kreileder, John Hawley, admin
In-Reply-To: <1324113743-21498-1-git-send-email-jnareb@gmail.com>

From: Jürgen Kreileder <jk@blackdown.de>

Otherwise when javascript-actions are enabled gitweb shown broken
author names in the tooltips on blame pages ('blame_incremental'
view).

Signed-off-by: Jürgen Kreileder <jk@blackdown.de>
Acked-by: Jakub Narębski <jnareb@gmail.com>
---
 gitweb/gitweb.perl |    4 +++-
 1 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index dcf4658..d24763b 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -6244,7 +6244,9 @@ sub git_blame_common {
 			-type=>"text/plain", -charset => "utf-8",
 			-status=> "200 OK");
 		local $| = 1; # output autoflush
-		print while <$fd>;
+		while (my $line = <$fd>) {
+			print to_utf8($line);
+		}
 		close $fd
 			or print "ERROR $!\n";
 
-- 
1.7.6

^ permalink raw reply related

* [PATCH 2/3] gitweb: esc_html() site name for title in OPML
From: Jakub Narebski @ 2011-12-17  9:22 UTC (permalink / raw)
  To: git; +Cc: Juergen Kreileder, John Hawley, admin
In-Reply-To: <1324113743-21498-1-git-send-email-jnareb@gmail.com>

From: Jürgen Kreileder <jk@blackdown.de>

This escapes the site name in OPML (XML uses the same escaping rules
as HTML).  Also fixes encoding issues because esc_html() uses
to_utf8().

Signed-off-by: Jürgen Kreileder <jk@blackdown.de>
Acked-by: Jakub Narębski <jnareb@gmail.com>
---
 gitweb/gitweb.perl |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index 35126cd..dcf4658 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -7863,11 +7863,12 @@ sub git_opml {
 		-charset => 'utf-8',
 		-content_disposition => 'inline; filename="opml.xml"');
 
+	my $title = esc_html($site_name);
 	print <<XML;
 <?xml version="1.0" encoding="utf-8"?>
 <opml version="1.0">
 <head>
-  <title>$site_name OPML Export</title>
+  <title>$title OPML Export</title>
 </head>
 <body>
 <outline text="git RSS feeds">
-- 
1.7.6

^ permalink raw reply related

* [PATCH] make "git push -v" actually verbose
From: Jeff King @ 2011-12-17  9:37 UTC (permalink / raw)
  To: git; +Cc: Tay Ray Chuan, Junio C Hamano

Providing a single "-v" to "git push" currently does
nothing. Giving two flags ("git push -v -v") turns on the
first level of verbosity.

This is caused by a regression introduced in 8afd8dc (push:
support multiple levels of verbosity, 2010-02-24). Before
the series containing 8afd8dc, the verbosity handling for
fetching and pushing was completely separate. Commit bde873c
refactored the verbosity handling out of the fetch side, and
then 8afd8dc converted push to use the refactored code.

However, the fetch and push sides numbered and passed along
their verbosity levels differently. For both, a verbosity
level of "-1" meant "quiet", and "0" meant "default output".
But from there they differed.

For fetch, a verbosity level of "1" indicated to the "fetch"
program that it should make the status table slightly more
verbose, showing up-to-date entries. A verbosity level of
"2" meant that we should pass a verbose flag to the
transport; in the case of fetch-pack, this displays protocol
debugging information.

As a result, the refactored code in bde873c checks for
"verbosity >= 2", and only then passes it on to the
transport. From the transport code's perspective, a
verbosity of 0 or 1 both meant "0".

Push, on the other hand, does not show its own status table;
that is always handled by the transport layer or below
(originally send-pack itself, but these days it is done by
the transport code). So a verbosity level of 1 meant that we
should pass the verbose flag to send-pack, so that it knows
we want a verbose status table. However, once 8afd8dc
switched it to the refactored fetch code, a verbosity level
of 1 was now being ignored.  Thus, you needed to
artificially bump the verbosity to 2 (via "-v -v") to have
any effect.

We can fix this by letting the transport code know about the
true verbosity level (i.e., let it distinguish level 0 or
1).

We then have to also make an adjustment to any transport
methods that assumed "verbose > 0" meant they could spew
lots of debugging information. Before, they could only get
"0" or "2", but now they will also receive "1". They need to
adjust their condition for turning on such spew from
"verbose > 0" to "verbose > 1".

Signed-off-by: Jeff King <peff@peff.net>
---
This is an old bug, obviously, but it has been bugging me
off and on for the past year, so I finally decided to track
it down.

Sorry for the epic-length commit message. It was a subtle
bug, and the actual patch makes it very difficult to
understand why it works and doesn't regress the fetch case.
Hopefully it made sense. :)

 transport.c |   10 +++++-----
 1 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/transport.c b/transport.c
index 51814b5..48002b9 100644
--- a/transport.c
+++ b/transport.c
@@ -215,7 +215,7 @@ static struct ref *get_refs_via_rsync(struct transport *transport, int for_push)
 	rsync.argv = args;
 	rsync.stdout_to_stderr = 1;
 	args[0] = "rsync";
-	args[1] = (transport->verbose > 0) ? "-rv" : "-r";
+	args[1] = (transport->verbose > 1) ? "-rv" : "-r";
 	args[2] = buf.buf;
 	args[3] = temp_dir.buf;
 	args[4] = NULL;
@@ -268,7 +268,7 @@ static int fetch_objs_via_rsync(struct transport *transport,
 	rsync.argv = args;
 	rsync.stdout_to_stderr = 1;
 	args[0] = "rsync";
-	args[1] = (transport->verbose > 0) ? "-rv" : "-r";
+	args[1] = (transport->verbose > 1) ? "-rv" : "-r";
 	args[2] = "--ignore-existing";
 	args[3] = "--exclude";
 	args[4] = "info";
@@ -351,7 +351,7 @@ static int rsync_transport_push(struct transport *transport,
 	args[i++] = "-a";
 	if (flags & TRANSPORT_PUSH_DRY_RUN)
 		args[i++] = "--dry-run";
-	if (transport->verbose > 0)
+	if (transport->verbose > 1)
 		args[i++] = "-v";
 	args[i++] = "--ignore-existing";
 	args[i++] = "--exclude";
@@ -527,7 +527,7 @@ static int fetch_refs_via_pack(struct transport *transport,
 	args.lock_pack = 1;
 	args.use_thin_pack = data->options.thin;
 	args.include_tag = data->options.followtags;
-	args.verbose = (transport->verbose > 0);
+	args.verbose = (transport->verbose > 1);
 	args.quiet = (transport->verbose < 0);
 	args.no_progress = !transport->progress;
 	args.depth = data->options.depth;
@@ -981,7 +981,7 @@ int transport_set_option(struct transport *transport,
 void transport_set_verbosity(struct transport *transport, int verbosity,
 	int force_progress)
 {
-	if (verbosity >= 2)
+	if (verbosity >= 1)
 		transport->verbose = verbosity <= 3 ? verbosity : 3;
 	if (verbosity < 0)
 		transport->verbose = -1;
-- 
1.7.7.4.13.g57bf4

^ permalink raw reply related

* Re: [PATCH] make "git push -v" actually verbose
From: Jeff King @ 2011-12-17  9:41 UTC (permalink / raw)
  To: git; +Cc: Tay Ray Chuan, Junio C Hamano
In-Reply-To: <20111217093713.GA2073@sigill.intra.peff.net>

On Sat, Dec 17, 2011 at 04:37:15AM -0500, Jeff King wrote:

> Providing a single "-v" to "git push" currently does
> nothing. Giving two flags ("git push -v -v") turns on the
> first level of verbosity.

One minor clarification: it is not technically true that "git push -v"
does nothing. It just does not do the interesting "show a verbose status
table" operation, which is almost certainly what the user wants (and
what happened before the commits I mentioned). It does print "Pushing to
$url", since that happens above the transport layer. But I'm pretty sure
that is not what users of "-v" are interested in. :)

-Peff

^ permalink raw reply

* Re: [PATCH] Escape file:// URL's to meet subversion SVN::Ra requirements
From: Jonathan Nieder @ 2011-12-17  9:50 UTC (permalink / raw)
  To: Ben Walton; +Cc: normalperson, git
In-Reply-To: <1320251895-6348-2-git-send-email-bwalton@artsci.utoronto.ca>

Hi again,

Ben Walton wrote:

> Previously only http/https URL's were uri escaped.  When building
> against subversion 1.7, this was causing a segfault in perl after
> an assertion failure in the SVN::Ra bindings during in t9134.

(Not a segfault, just a core dump.)  Thanks.

[....]
> --- a/git-svn.perl
> +++ b/git-svn.perl
> @@ -5366,6 +5366,9 @@ sub escape_url {
>  	if ($url =~ m#^(https?)://([^/]+)(.*)$#) {
>  		my ($scheme, $domain, $uri) = ($1, $2, escape_uri_only($3));
>  		$url = "$scheme://$domain$uri";
> +	} elsif ($url =~ m#^(file)://(.*)$#) {
> +		my ($scheme, $uri) = ($1, escape_uri_only($2));
> +		$url = "$scheme://$uri";

This has two obvious effects, one good and one bad.

The good effect is that it converts spaces to %20.  Both old and new
versions of Subversion seem to be happy to treat %20 as a space, and
new versions of Subversion are not happy to treat a space as a space,
so this conversion can only be a good thing.

The bad effect is that it converts percent signs to %25.  So commands
like "git svn clone file:///path/to/test%20repository" that previously
worked might not work any more, if v1.6.5-rc0~61 (svn: assume URLs
from the command-line are URI-encoded, 2009-08-16) did not do its job
completely.

In other words, it seems to me like you are on the right track. ;-)

Another possible approach: to imitate the svn command line tools, we
could use SVN::Client::url_from_path in some appropriate place. 

Next steps:

 - track down the trouble on svn 1.6.x that Eric mentioned
 - fix any remaining tests that still don't pass

Thanks for getting this started.  Will sleep and play with it a little
more.

Jonathan

^ permalink raw reply

* Re: git-svn: multiple fetch lines
From: Jonathan Nieder @ 2011-12-17 10:05 UTC (permalink / raw)
  To: Nathan Gray; +Cc: git, Eric Wong
In-Reply-To: <CA+7g9Jxd3mhbra34f+MiJRt36Lb6gVHi1nOCP8Zo5y-G9jB3qA@mail.gmail.com>

Hi Nathan,

Nathan Gray wrote:

> I'm in a conversation with the support fellow of the very nice Tower
> git interface for OS X and we need clarification on a point.  Does
> git-svn explicitly support multiple "fetch =" lines in an svn-remote
> section or is it just an accident that it works?  My belief is that
> such support is intended and his is that it is accidental.

It's true that the documentation is not as clear about this as one
might like.  Documentation/git-svn.txt leaves it to the reader to
infer that this is supported by analogy with "fetch =" lines in native
git [remote] sections:

	'git svn' stores [svn-remote] configuration information in the
	repository .git/config file.  It is similar the core git
	[remote] sections except 'fetch' keys do not accept glob
	arguments; but they are instead handled by the 'branches'
	and 'tags' keys.

The change description for the patch that introduced that functionality
is more helpful.

	$ git log -S'Could not find a \"svn-remote.*.fetch\" key' git-svn.perl
	commit 706587fc
	Author: Eric Wong <normalperson@yhbt.net>
	Date:   Thu Jan 18 17:50:01 2007 -0800

	    git-svn: add support for metadata in .git/config
	    
	    Of course, we handle metadata migrations from previous versions
	    and we have added unit tests.
	    
	    The new .git/config remotes resemble non-SVN remotes.  Below
	    is an example with comments:
[example using multiple 'fetch' keys snipped]

Perhaps such an example would be useful for the git-svn(1) manpage,
too.  Any ideas for where to add such a note, and how it should be
worded?  (Of course, if you can phrase such an idea in patch form,
that would be the most convenient.)

Hope that helps,
Jonathan

^ permalink raw reply

* Re: best way to fastforward all tracking branches after a fetch
From: Sitaram Chamarty @ 2011-12-17 10:10 UTC (permalink / raw)
  To: Gelonida N; +Cc: git
In-Reply-To: <jbvj5o$skt$1@dough.gmane.org>

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

On Sat, Dec 10, 2011 at 01:26:32PM +0100, Gelonida N wrote:
> Hi,
> 
> What is the best way to fastforward all fastforwardable tracking
> branches after a git fetch?

I know this is a somewhat closed topic, but I took some time to
clean up a program I have been using for a while, including some
changes based upon ideas elsewhere in this thread.  The program
"git-branch-check" is attached, and requires perl > 5.10.0.

Note that this does a lot more than just fast-forward all
branches, although it can do that as well.

I alias it (in ~/.gitconfig) to 'bc', so I just run "git bc".
Running with "-h" shows usage:

    Usage: /home/sitaram/bin/git-branch-check [options] [branches]

    Check or fast forward branches.  Default: act upon all local branches if no
    arguments supplied, or just the current branch if '-c' is passed.
            -c      act upon current branch only
            -ff     don't just check, try to fast forward also
            -md     max diff (default 100; see below for details)
            -h      help
    'max diff':
        hide output for two branches different by more than so many commits

My usual usage is just "git bc -c", which may give me:

       1        pu...origin/pu
       1        pu...github/pu
      13        pu...master
           5    pu...q
           7    pu...vrs

This quickly tells me my 'pu' is one ahead of both my own
gitolite server as well as github's copy, and that it is 13
commits ahead of master.  The (unreleased and frequently
rebased) feature branches 'q' and 'vrs' are ahead of pu, which
means a rebase is not pending.  Without the "-c" I may see the
status of master versus its own upstream and other remotes,
etc., also.

The purpose of the max diff limit (default 100) is to hide, for
example, the pair 'master' and 'man' from the git.git repo.
Otherwise you'd see something like:

    27249 973    master...man

which is pretty meaningless.  The sum of those two numbers
should be less than the max.

"git bc -ff" will attempt to fast forward all selected branches
that are ancestors of their respective upstreams.  The current
branch will not be ff-ed if the tree is dirty, since you can't
do this by 'git branch -f'; it has to be an actual merge
command.

The output is not (currently) pipable to other programs because
I use colors (obtained from 'git config --get-color') and
currently it is not conditional on STDOUT being a tty.

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

^ permalink raw reply

* Re: best way to fastforward all tracking branches after a fetch
From: Sitaram Chamarty @ 2011-12-17 10:11 UTC (permalink / raw)
  To: Gelonida N; +Cc: git
In-Reply-To: <20111217101009.GA19248@sita-lt.atc.tcs.com>


[-- Attachment #1.1: Type: text/plain, Size: 2703 bytes --]

oops; forgot the program...

On Sat, Dec 17, 2011 at 03:40:09PM +0530, Sitaram Chamarty wrote:
> On Sat, Dec 10, 2011 at 01:26:32PM +0100, Gelonida N wrote:
> > Hi,
> > 
> > What is the best way to fastforward all fastforwardable tracking
> > branches after a git fetch?
> 
> I know this is a somewhat closed topic, but I took some time to
> clean up a program I have been using for a while, including some
> changes based upon ideas elsewhere in this thread.  The program
> "git-branch-check" is attached, and requires perl > 5.10.0.
> 
> Note that this does a lot more than just fast-forward all
> branches, although it can do that as well.
> 
> I alias it (in ~/.gitconfig) to 'bc', so I just run "git bc".
> Running with "-h" shows usage:
> 
>     Usage: /home/sitaram/bin/git-branch-check [options] [branches]
> 
>     Check or fast forward branches.  Default: act upon all local branches if no
>     arguments supplied, or just the current branch if '-c' is passed.
>             -c      act upon current branch only
>             -ff     don't just check, try to fast forward also
>             -md     max diff (default 100; see below for details)
>             -h      help
>     'max diff':
>         hide output for two branches different by more than so many commits
> 
> My usual usage is just "git bc -c", which may give me:
> 
>        1        pu...origin/pu
>        1        pu...github/pu
>       13        pu...master
>            5    pu...q
>            7    pu...vrs
> 
> This quickly tells me my 'pu' is one ahead of both my own
> gitolite server as well as github's copy, and that it is 13
> commits ahead of master.  The (unreleased and frequently
> rebased) feature branches 'q' and 'vrs' are ahead of pu, which
> means a rebase is not pending.  Without the "-c" I may see the
> status of master versus its own upstream and other remotes,
> etc., also.
> 
> The purpose of the max diff limit (default 100) is to hide, for
> example, the pair 'master' and 'man' from the git.git repo.
> Otherwise you'd see something like:
> 
>     27249 973    master...man
> 
> which is pretty meaningless.  The sum of those two numbers
> should be less than the max.
> 
> "git bc -ff" will attempt to fast forward all selected branches
> that are ancestors of their respective upstreams.  The current
> branch will not be ff-ed if the tree is dirty, since you can't
> do this by 'git branch -f'; it has to be an actual merge
> command.
> 
> The output is not (currently) pipable to other programs because
> I use colors (obtained from 'git config --get-color') and
> currently it is not conditional on STDOUT being a tty.



[-- Attachment #1.2: git-branch-check --]
[-- Type: text/plain, Size: 5677 bytes --]

#!/usr/bin/perl -s
use 5.10.0;
use strict;
use warnings;

# ----------------------------------------------------------------------

# bare-minimum subset of 'Tsh' (see github.com/sitaramc/tsh)
{
    my($rc, $text);
    sub rc { return $rc || 0; }
    sub text { return $text || ''; }
    sub lines { return split /\n/, $text; }
    sub try {
        my $cmd = shift; die "try: expects only one argument" if @_;
        $text = `( $cmd ) 2>&1; echo -n RC=\$?`;
        if ($text =~ s/RC=(\d+)$//) {
            $rc = $1;
            return (not $rc);
        }
        die "couldnt find RC= in result; this should not happen:\n$text\n\n...\n";
    }
}

# ----------------------------------------------------------------------

# options; the "-s" above sets one or more of these
# (the format of the lines below is special; it is used by usage() to generate
# help text for the options)
# BEGIN OPTIONS
    our $c;     # act upon current branch only
    our $ff;    # don't just check, try to fast forward also
    our $md;    # max diff (default 100; see below for details)
    our $h;     # help
# END OPTIONS
    $md ||= 100;

# get this over with; usage() exits so don't worry
    usage() if $h;

# get current branch
    my $current = '';
    try "git symbolic-ref HEAD" or die "DETACHED HEAD or no repo";
    ($current = (lines)[0]) =~ s(refs/heads/)();

# get branch names
    # first, all local branches as keys of a hash with upstream name if any, as the value
    my %upstream;
    try "git for-each-ref --perl '--format=\$upstream{%(refname:short)} = %(upstream:short);' refs/heads"
        or die "for-each-ref 1 failed";
    eval text;

    # local branches as a list; keep $current at the top, and the rest sorted
    my @local = ($current, grep { $_ ne $current } sort keys %upstream);

    # remote branches as a list
    try "git for-each-ref '--format=%(refname:short)' refs/remotes"
        or die "for-each-ref 2 failed";
    my @remote = lines;

# decide what branches to act upon.  Default: all local branches.  If any
# arguments are given, then those.  If '-c' is passed, only current branch.
    my @branches = @local;
    @branches = @ARGV if @ARGV;
    @branches = ($current) if $c;

# ----------------------------------------------------------------------

# show the tree state if it's dirty
    print "dirty:\n", text if dirty();

# process selected branches
    for my $b (@branches) {
        # attempt a fast-forward if -ff is passed
        ff($b, $upstream{$b}, $current) if ($ff);
        # check against its own upstream
        check($b, $upstream{$b});
        # then against all remote branches of the same name (I typically have
        # my own gitolite server as 'upstream' but also have github and google
        # code as additional remotes that I push my branches to)
        check($b, grep(m(^[^/]+/$b$), @remote));
    }
    # ...then against all local branches.  We do this in a separate loop
    # so their output is kept separate from the remote compares above.
    for my $b (@branches) {
        check($b, @local);
    }

# DONE...

# ----------------------------------------------------------------------
# subroutines
# ----------------------------------------------------------------------

sub ff {
    # b=branch, u=upstream, c=current
    my ($b, $u, $c) = @_;

    unless ($u) {
        say "$b does not have an upstream";
        return;
    }

    if ($b eq $c and dirty()) {
        say "working tree is dirty; skipping ff for (current branch) $b";
        return;
    }

    # $l = number of commits "l"eft side has over the "r"ight (similarly $r...)
    my($l, $r) = compare($b, $u);
    if ($r and not $l) {
        # there is something to update, and ff is possible
        if ($b eq $c) {
            # current branch; needs an actual merge
            try("git merge --ff-only $u") or die "$b: 'git merge --ff-only $u' failed:\n" .  text;
        } else {
            # other branches can be forced
            try("git branch -f $b $u") or die "$b: 'git branch -f $b $u' failed:\n" .  text;
        }
    }
}

sub check {
    my ($b, @list) = @_;
    state %seen;

    for my $u (@list) {
        next unless $u;
        next if $b eq $u or $seen{$b}{$u};
        # seeing a...b is as good as seeing b...a also
        $seen{$b}{$u} = 1;
        $seen{$u}{$b} = 1;

        my ($l, $r) = compare($b, $u);

        my $abs = $l + $r; next unless $abs;    # if they're equal, don't show it
        next if $abs >= $md;                    # if they're too far apart, don't show it

        print spacepad(4, $l) . color('green') . ($l || ' ');
        print spacepad(4, $r) . color('red')   . ($r || ' ');
        say color('reset') . "    $b...$u";
    }
}

sub compare {
    my ($b, $u) = @_;

    try("git rev-list $u..$b") or die "'git rev-list $u..$b' failed:\n" .  text;
    my $l = lines;

    try("git rev-list $b..$u") or die "'git rev-list $b..$u' failed:\n" .  text;
    my $r = lines;

    return($l, $r);
}

sub dirty {
    try "git status -s -uno | cut -c1-2 | sort | uniq -c; /./";
}

sub color {
    my $color = shift;
    return `git config --get-color "" $color`;
}

sub spacepad {
    return " " x ($_[0] - length($_[1]));
}

sub usage {
    print "
Usage: $0 [options] [branches]

Check or fast forward branches.  Default: act upon all local branches if no
arguments supplied, or just the current branch if '-c' is passed.
";
    @ARGV=($0);
    for ( grep { /BEGIN OPTIONS/../END OPTIONS/ and not /OPTION/ } <> ) {
        s/our \$/\t-/;
        s/; *#/\t/;
        print;
    }
    say "\'max diff':\n    hide output for two branches different by more than so many commits";
    exit 1;
}

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

^ permalink raw reply

* [PATCH 1/3] use struct sha1_array in diff_tree_combined()
From: René Scharfe @ 2011-12-17 10:15 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano, Ævar Arnfjörð Bjarmason,
	Jens Lehmann

Maintaining an array of hashes is easier using sha1_array than
open-coding it.  This patch also fixes a leak of the SHA1 array
in  diff_tree_combined_merge().

---
 builtin/diff.c |   12 ++++++------
 combine-diff.c |   34 +++++++++++++---------------------
 diff.h         |    3 ++-
 submodule.c    |   14 +++++---------
 4 files changed, 26 insertions(+), 37 deletions(-)

diff --git a/builtin/diff.c b/builtin/diff.c
index 0fe638f..387afa7 100644
--- a/builtin/diff.c
+++ b/builtin/diff.c
@@ -14,6 +14,7 @@
 #include "log-tree.h"
 #include "builtin.h"
 #include "submodule.h"
+#include "sha1-array.h"
 
 struct blobinfo {
 	unsigned char sha1[20];
@@ -169,7 +170,7 @@ static int builtin_diff_combined(struct rev_info *revs,
 				 struct object_array_entry *ent,
 				 int ents)
 {
-	const unsigned char (*parent)[20];
+	struct sha1_array parents = SHA1_ARRAY_INIT;
 	int i;
 
 	if (argc > 1)
@@ -177,12 +178,11 @@ static int builtin_diff_combined(struct rev_info *revs,
 
 	if (!revs->dense_combined_merges && !revs->combine_merges)
 		revs->dense_combined_merges = revs->combine_merges = 1;
-	parent = xmalloc(ents * sizeof(*parent));
-	for (i = 0; i < ents; i++)
-		hashcpy((unsigned char *)(parent + i), ent[i].item->sha1);
-	diff_tree_combined(parent[0], parent + 1, ents - 1,
+	for (i = 1; i < ents; i++)
+		sha1_array_append(&parents, ent[i].item->sha1);
+	diff_tree_combined(ent[0].item->sha1, &parents,
 			   revs->dense_combined_merges, revs);
-	free((void *)parent);
+	sha1_array_clear(&parents);
 	return 0;
 }
 
diff --git a/combine-diff.c b/combine-diff.c
index 214014d..cfe6230 100644
--- a/combine-diff.c
+++ b/combine-diff.c
@@ -8,6 +8,7 @@
 #include "log-tree.h"
 #include "refs.h"
 #include "userdiff.h"
+#include "sha1-array.h"
 
 static struct combine_diff_path *intersect_paths(struct combine_diff_path *curr, int n, int num_parent)
 {
@@ -1116,15 +1117,14 @@ static void handle_combined_callback(struct diff_options *opt,
 }
 
 void diff_tree_combined(const unsigned char *sha1,
-			const unsigned char parent[][20],
-			int num_parent,
+			const struct sha1_array *parents,
 			int dense,
 			struct rev_info *rev)
 {
 	struct diff_options *opt = &rev->diffopt;
 	struct diff_options diffopts;
 	struct combine_diff_path *p, *paths = NULL;
-	int i, num_paths, needsep, show_log_first;
+	int i, num_paths, needsep, show_log_first, num_parent = parents->nr;
 
 	diffopts = *opt;
 	diffopts.output_format = DIFF_FORMAT_NO_OUTPUT;
@@ -1144,7 +1144,7 @@ void diff_tree_combined(const unsigned char *sha1,
 			diffopts.output_format = stat_opt;
 		else
 			diffopts.output_format = DIFF_FORMAT_NO_OUTPUT;
-		diff_tree_sha1(parent[i], sha1, "", &diffopts);
+		diff_tree_sha1(parents->sha1[i], sha1, "", &diffopts);
 		diffcore_std(&diffopts);
 		paths = intersect_paths(paths, i, num_parent);
 
@@ -1199,22 +1199,14 @@ void diff_tree_combined(const unsigned char *sha1,
 void diff_tree_combined_merge(const unsigned char *sha1,
 			     int dense, struct rev_info *rev)
 {
-	int num_parent;
-	const unsigned char (*parent)[20];
 	struct commit *commit = lookup_commit(sha1);
-	struct commit_list *parents;
-
-	/* count parents */
-	for (parents = commit->parents, num_parent = 0;
-	     parents;
-	     parents = parents->next, num_parent++)
-		; /* nothing */
-
-	parent = xmalloc(num_parent * sizeof(*parent));
-	for (parents = commit->parents, num_parent = 0;
-	     parents;
-	     parents = parents->next, num_parent++)
-		hashcpy((unsigned char *)(parent + num_parent),
-			parents->item->object.sha1);
-	diff_tree_combined(sha1, parent, num_parent, dense, rev);
+	struct commit_list *parent = commit->parents;
+	struct sha1_array parents = SHA1_ARRAY_INIT;
+
+	while (parent) {
+		sha1_array_append(&parents, parent->item->object.sha1);
+		parent = parent->next;
+	}
+	diff_tree_combined(sha1, &parents, dense, rev);
+	sha1_array_clear(&parents);
 }
diff --git a/diff.h b/diff.h
index 0c51724..96085cb 100644
--- a/diff.h
+++ b/diff.h
@@ -12,6 +12,7 @@ struct diff_queue_struct;
 struct strbuf;
 struct diff_filespec;
 struct userdiff_driver;
+struct sha1_array;
 
 typedef void (*change_fn_t)(struct diff_options *options,
 		 unsigned old_mode, unsigned new_mode,
@@ -195,7 +196,7 @@ struct combine_diff_path {
 extern void show_combined_diff(struct combine_diff_path *elem, int num_parent,
 			      int dense, struct rev_info *);
 
-extern void diff_tree_combined(const unsigned char *sha1, const unsigned char parent[][20], int num_parent, int dense, struct rev_info *rev);
+extern void diff_tree_combined(const unsigned char *sha1, const struct sha1_array *parents, int dense, struct rev_info *rev);
 
 extern void diff_tree_combined_merge(const unsigned char *sha1, int, struct rev_info *);
 
diff --git a/submodule.c b/submodule.c
index 68c1ba9..788d532 100644
--- a/submodule.c
+++ b/submodule.c
@@ -373,15 +373,11 @@ static void collect_submodules_from_diff(struct diff_queue_struct *q,
 
 static void commit_need_pushing(struct commit *commit, struct commit_list *parent, int *needs_pushing)
 {
-	const unsigned char (*parents)[20];
-	unsigned int i, n;
+	struct sha1_array parents = SHA1_ARRAY_INIT;
 	struct rev_info rev;
 
-	n = commit_list_count(parent);
-	parents = xmalloc(n * sizeof(*parents));
-
-	for (i = 0; i < n; i++) {
-		hashcpy((unsigned char *)(parents + i), parent->item->object.sha1);
+	while (parent) {
+		sha1_array_append(&parents, parent->item->object.sha1);
 		parent = parent->next;
 	}
 
@@ -389,9 +385,9 @@ static void commit_need_pushing(struct commit *commit, struct commit_list *paren
 	rev.diffopt.output_format |= DIFF_FORMAT_CALLBACK;
 	rev.diffopt.format_callback = collect_submodules_from_diff;
 	rev.diffopt.format_callback_data = needs_pushing;
-	diff_tree_combined(commit->object.sha1, parents, n, 1, &rev);
+	diff_tree_combined(commit->object.sha1, &parents, 1, &rev);
 
-	free((void *)parents);
+	sha1_array_clear(&parents);
 }
 
 int check_submodule_needs_pushing(unsigned char new_sha1[20], const char *remotes_name)
-- 
1.7.8

^ permalink raw reply related

* [PATCH 2/3] pass struct commit to diff_tree_combined_merge()
From: René Scharfe @ 2011-12-17 10:20 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano, Ævar Arnfjörð Bjarmason,
	Jens Lehmann
In-Reply-To: <4EEC6BD4.4040302@lsrfire.ath.cx>

Instead of passing the hash of a commit and then searching that
same commit in the single caller, simply pass the commit directly.

---
 combine-diff.c |    7 +++----
 diff.h         |    3 ++-
 log-tree.c     |    4 +---
 3 files changed, 6 insertions(+), 8 deletions(-)

diff --git a/combine-diff.c b/combine-diff.c
index cfe6230..a2e8dcf 100644
--- a/combine-diff.c
+++ b/combine-diff.c
@@ -1196,10 +1196,9 @@ void diff_tree_combined(const unsigned char *sha1,
 	}
 }
 
-void diff_tree_combined_merge(const unsigned char *sha1,
-			     int dense, struct rev_info *rev)
+void diff_tree_combined_merge(const struct commit *commit, int dense,
+			      struct rev_info *rev)
 {
-	struct commit *commit = lookup_commit(sha1);
 	struct commit_list *parent = commit->parents;
 	struct sha1_array parents = SHA1_ARRAY_INIT;
 
@@ -1207,6 +1206,6 @@ void diff_tree_combined_merge(const unsigned char *sha1,
 		sha1_array_append(&parents, parent->item->object.sha1);
 		parent = parent->next;
 	}
-	diff_tree_combined(sha1, &parents, dense, rev);
+	diff_tree_combined(commit->object.sha1, &parents, dense, rev);
 	sha1_array_clear(&parents);
 }
diff --git a/diff.h b/diff.h
index 96085cb..ae71f4c 100644
--- a/diff.h
+++ b/diff.h
@@ -13,6 +13,7 @@ struct strbuf;
 struct diff_filespec;
 struct userdiff_driver;
 struct sha1_array;
+struct commit;
 
 typedef void (*change_fn_t)(struct diff_options *options,
 		 unsigned old_mode, unsigned new_mode,
@@ -198,7 +199,7 @@ extern void show_combined_diff(struct combine_diff_path *elem, int num_parent,
 
 extern void diff_tree_combined(const unsigned char *sha1, const struct sha1_array *parents, int dense, struct rev_info *rev);
 
-extern void diff_tree_combined_merge(const unsigned char *sha1, int, struct rev_info *);
+extern void diff_tree_combined_merge(const struct commit *commit, int dense, struct rev_info *rev);
 
 void diff_set_mnemonic_prefix(struct diff_options *options, const char *a, const char *b);
 
diff --git a/log-tree.c b/log-tree.c
index e7694a3..319bd31 100644
--- a/log-tree.c
+++ b/log-tree.c
@@ -599,9 +599,7 @@ int log_tree_diff_flush(struct rev_info *opt)
 
 static int do_diff_combined(struct rev_info *opt, struct commit *commit)
 {
-	unsigned const char *sha1 = commit->object.sha1;
-
-	diff_tree_combined_merge(sha1, opt->dense_combined_merges, opt);
+	diff_tree_combined_merge(commit, opt->dense_combined_merges, opt);
 	return !opt->loginfo;
 }
 
-- 
1.7.8

^ permalink raw reply related

* Re: [PATCH] Fix an "variable might be used uninitialized" gcc warning
From: Andreas Schwab @ 2011-12-17 10:22 UTC (permalink / raw)
  To: Jonathan Nieder; +Cc: Ramsay Jones, Junio C Hamano, GIT Mailing-list
In-Reply-To: <20111216235908.GA5858@elie.hsd1.il.comcast.net>

Jonathan Nieder <jrnieder@gmail.com> writes:

> Ramsay Jones wrote:
>
>>         CC builtin/checkout.o
>>     builtin/checkout.c: In function `cmd_checkout':
>>     builtin/checkout.c:160: warning: 'mode' might be used uninitialized \
>>         in this function
> [...]
>> [Note that only 2 out of the 3 versions of gcc I use issues this
>> warning]
>
> Which version of gcc is that?  Is gcc getting more sane, so we won't
> have to worry about this after a while, or is the false positive a
> new regression that should be reported to them?

The regression is that the function has been changed in a way that makes
it impossible to infer the intended flow.

Andreas.

-- 
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."

^ permalink raw reply

* [PATCH 3/3] submodule: use diff_tree_combined_merge() instead of diff_tree_combined()
From: René Scharfe @ 2011-12-17 10:27 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano, Ævar Arnfjörð Bjarmason,
	Jens Lehmann
In-Reply-To: <4EEC6CD7.2030408@lsrfire.ath.cx>

Use diff_tree_combined_merge() instead of open-coding it.

Signed-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx>
---
 submodule.c |   14 +++-----------
 1 files changed, 3 insertions(+), 11 deletions(-)

diff --git a/submodule.c b/submodule.c
index 788d532..9a28060 100644
--- a/submodule.c
+++ b/submodule.c
@@ -371,23 +371,15 @@ static void collect_submodules_from_diff(struct diff_queue_struct *q,
 }
 
 
-static void commit_need_pushing(struct commit *commit, struct commit_list *parent, int *needs_pushing)
+static void commit_need_pushing(struct commit *commit, int *needs_pushing)
 {
-	struct sha1_array parents = SHA1_ARRAY_INIT;
 	struct rev_info rev;
 
-	while (parent) {
-		sha1_array_append(&parents, parent->item->object.sha1);
-		parent = parent->next;
-	}
-
 	init_revisions(&rev, NULL);
 	rev.diffopt.output_format |= DIFF_FORMAT_CALLBACK;
 	rev.diffopt.format_callback = collect_submodules_from_diff;
 	rev.diffopt.format_callback_data = needs_pushing;
-	diff_tree_combined(commit->object.sha1, &parents, 1, &rev);
-
-	sha1_array_clear(&parents);
+	diff_tree_combined_merge(commit, 1, &rev);
 }
 
 int check_submodule_needs_pushing(unsigned char new_sha1[20], const char *remotes_name)
@@ -410,7 +402,7 @@ int check_submodule_needs_pushing(unsigned char new_sha1[20], const char *remote
 		die("revision walk setup failed");
 
 	while ((commit = get_revision(&rev)) && !needs_pushing)
-		commit_need_pushing(commit, commit->parents, &needs_pushing);
+		commit_need_pushing(commit, &needs_pushing);
 
 	free(sha1_copy);
 	strbuf_release(&remotes_arg);
-- 
1.7.8

^ permalink raw reply related

* Re: [PATCH 1/3] use struct sha1_array in diff_tree_combined()
From: René Scharfe @ 2011-12-17 10:27 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano, Ævar Arnfjörð Bjarmason,
	Jens Lehmann
In-Reply-To: <4EEC6BD4.4040302@lsrfire.ath.cx>

Am 17.12.2011 11:15, schrieb René Scharfe:
> Maintaining an array of hashes is easier using sha1_array than
> open-coding it.  This patch also fixes a leak of the SHA1 array
> in  diff_tree_combined_merge().
>
> ---

Signed-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx>

^ permalink raw reply

* Re: [PATCH 2/3] pass struct commit to diff_tree_combined_merge()
From: René Scharfe @ 2011-12-17 10:27 UTC (permalink / raw)
  Cc: git, Junio C Hamano, Ævar Arnfjörð Bjarmason,
	Jens Lehmann
In-Reply-To: <4EEC6CD7.2030408@lsrfire.ath.cx>

Am 17.12.2011 11:20, schrieb René Scharfe:
> Instead of passing the hash of a commit and then searching that
> same commit in the single caller, simply pass the commit directly.
>
> ---

Signed-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx>

Ugh.  Forgetting it twice is stupid..

^ permalink raw reply

* [PATCH] remote-curl: don't pass back fake refs
From: Jeff King @ 2011-12-17 10:45 UTC (permalink / raw)
  To: git; +Cc: Shawn O. Pearce, Junio C Hamano

When receive-pack advertises its list of refs, it generally
hides the capabilities information after a NUL at the end of
the first ref. However, when we have an empty repository,
there are no refs, and therefore receive-pack writes a fake
ref "capabilities^{}" with the capabilities afterwards.

On the client side, git reads the result with
get_remote_heads. We pick the capabilities from the end of
the line, and then call check_ref to make sure the ref name
is valid. We see that it isn't, and don't bother adding it
to our list of refs.

However, the call to check_ref is enabled by passing the
REF_NORMAL flag to get_remote_heads. For the regular git
transport, we pass REF_NORMAL in get_refs_via_connect if we
are doing a push (since only receive-pack uses this fake
ref).  But in remote-curl, we never use this flag, and we
accept the fake ref as a real one, passing it back from the
helper to the parent git-push.

Most of the time this bug goes unnoticed, as the fake ref
won't match our refspecs. However, if "--mirror" is used,
then we see it as remote cruft to be pruned, and try to pass
along a deletion refspec for it. Of course this refspec has
bogus syntax (because of the ^{}), and the helper complains,
aborting the push.

Let's have remote-curl mirror what the builtin
get_refs_via_connect does (at least for the case of using
git protocol; we can leave the dumb info/refs reader as it
is).

Signed-off-by: Jeff King <peff@peff.net>
---
 remote-curl.c        |    7 ++++---
 t/t5541-http-push.sh |   14 ++++++++++++++
 2 files changed, 18 insertions(+), 3 deletions(-)

diff --git a/remote-curl.c b/remote-curl.c
index 0e720ee..b780ba5 100644
--- a/remote-curl.c
+++ b/remote-curl.c
@@ -188,7 +188,7 @@ static int write_discovery(int in, int out, void *data)
 	return err;
 }
 
-static struct ref *parse_git_refs(struct discovery *heads)
+static struct ref *parse_git_refs(struct discovery *heads, int for_push)
 {
 	struct ref *list = NULL;
 	struct async async;
@@ -200,7 +200,8 @@ static struct ref *parse_git_refs(struct discovery *heads)
 
 	if (start_async(&async))
 		die("cannot start thread to parse advertised refs");
-	get_remote_heads(async.out, &list, 0, NULL, 0, NULL);
+	get_remote_heads(async.out, &list, 0, NULL,
+			for_push ? REF_NORMAL : 0, NULL);
 	close(async.out);
 	if (finish_async(&async))
 		die("ref parsing thread failed");
@@ -268,7 +269,7 @@ static struct ref *get_refs(int for_push)
 		heads = discover_refs("git-upload-pack");
 
 	if (heads->proto_git)
-		return parse_git_refs(heads);
+		return parse_git_refs(heads, for_push);
 	return parse_info_refs(heads);
 }
 
diff --git a/t/t5541-http-push.sh b/t/t5541-http-push.sh
index a73c826..89232b2 100755
--- a/t/t5541-http-push.sh
+++ b/t/t5541-http-push.sh
@@ -154,5 +154,19 @@ test_expect_success 'push (chunked)' '
 	 test $HEAD = $(git rev-parse --verify HEAD))
 '
 
+test_expect_success 'push --all can push to empty repo' '
+	d=$HTTPD_DOCUMENT_ROOT_PATH/empty-all.git &&
+	git init --bare "$d" &&
+	git --git-dir="$d" config http.receivepack true &&
+	git push --all "$HTTPD_URL"/smart/empty-all.git
+'
+
+test_expect_success 'push --mirror can push to empty repo' '
+	d=$HTTPD_DOCUMENT_ROOT_PATH/empty-mirror.git &&
+	git init --bare "$d" &&
+	git --git-dir="$d" config http.receivepack true &&
+	git push --mirror "$HTTPD_URL"/smart/empty-mirror.git
+'
+
 stop_httpd
 test_done
-- 
1.7.7.4.13.g57bf4

^ permalink raw reply related

* Escape character for .gitconfig
From: Erik Blake @ 2011-12-17 10:10 UTC (permalink / raw)
  To: git

I have an editor path that includes "(" and ")". No matter how I try to 
escape this character, I get either variations on:

C:/Program Files (x86)/Notepad++/notepad++.exe: -c: line 0: syntax error 
near unexpected token `('
C:/Program Files (x86)/Notepad++/notepad++.exe: -c: line 0: `C:/Program 
Files (x86)/Notepad++/notepad++.exe \$@\'
error: There was a problem with the editor 'C:/Program Files 
(x86)/Notepad++/notepad++.exe'.
Please supply the message using either -m or -F option.

or:

fatal: bad config file line 5 in C:\Users\xxx/.gitconfig

As you can see, I'm running git on a Win7 64 machine. Is there any way 
to escape the brackets? Or do I need to reinstall notepad++ on a 
different path?

^ permalink raw reply

* Re: [PATCH 1/3] use struct sha1_array in diff_tree_combined()
From: Jeff King @ 2011-12-17 10:53 UTC (permalink / raw)
  To: René Scharfe
  Cc: git, Junio C Hamano, Ævar Arnfjörð Bjarmason,
	Jens Lehmann
In-Reply-To: <4EEC6BD4.4040302@lsrfire.ath.cx>

On Sat, Dec 17, 2011 at 11:15:48AM +0100, René Scharfe wrote:

> Maintaining an array of hashes is easier using sha1_array than
> open-coding it.  This patch also fixes a leak of the SHA1 array
> in  diff_tree_combined_merge().
> 
> ---
>  builtin/diff.c |   12 ++++++------
>  combine-diff.c |   34 +++++++++++++---------------------
>  diff.h         |    3 ++-
>  submodule.c    |   14 +++++---------
>  4 files changed, 26 insertions(+), 37 deletions(-)

Yay. When I refactored sha1_array, I hoped there would be other users,
but I hadn't actually converted any yet. Good to know it is paying off.

> -	parent = xmalloc(ents * sizeof(*parent));
> -	for (i = 0; i < ents; i++)
> -		hashcpy((unsigned char *)(parent + i), ent[i].item->sha1);
> -	diff_tree_combined(parent[0], parent + 1, ents - 1,
> +	for (i = 1; i < ents; i++)
> +		sha1_array_append(&parents, ent[i].item->sha1);
> +	diff_tree_combined(ent[0].item->sha1, &parents,
>  			   revs->dense_combined_merges, revs);
> -	free((void *)parent);
> +	sha1_array_clear(&parents);

The original code is slightly more efficient, as it is able to use a
single malloc (because it knows the number of entries ahead of time).
It probably doesn't make a difference, but we could also add a
sha1_array_grow() for this case.

I think it could be used in all three spots you converted in this patch.

-Peff

^ permalink raw reply

* Re: Escape character for .gitconfig
From: Jeff King @ 2011-12-17 10:58 UTC (permalink / raw)
  To: Erik Blake; +Cc: git
In-Reply-To: <4EEC6A9D.1060005@icefield.yk.ca>

On Sat, Dec 17, 2011 at 11:10:37AM +0100, Erik Blake wrote:

> I have an editor path that includes "(" and ")". No matter how I try
> to escape this character, I get either variations on:
> 
> C:/Program Files (x86)/Notepad++/notepad++.exe: -c: line 0: syntax
> error near unexpected token `('
> C:/Program Files (x86)/Notepad++/notepad++.exe: -c: line 0:
> `C:/Program Files (x86)/Notepad++/notepad++.exe \$@\'
> error: There was a problem with the editor 'C:/Program Files
> (x86)/Notepad++/notepad++.exe'.
> Please supply the message using either -m or -F option.
> 
> or:
> 
> fatal: bad config file line 5 in C:\Users\xxx/.gitconfig

You didn't tell us what you actually tried, so I don't know where you
went wrong.

But you will need to quote the whole value for git to read from your
gitconfig, and then quote any metacharacters in the value so that the
shell doesn't interpret them. I think you want:

  [core]
    editor = "'C:/Program Files (x86)/Notepad++/notepad++.exe'"

-Peff

^ permalink raw reply

* Re: How to automatically correct an almost correct auto-merge?
From: SZEDER Gábor @ 2011-12-17 11:07 UTC (permalink / raw)
  To: Seth Robertson; +Cc: git
In-Reply-To: <201112162039.pBGKdR8H012831@no.baka.org>

On Fri, Dec 16, 2011 at 03:39:27PM -0500, Seth Robertson wrote:
> 
> > How can I teach git to produce the correct merge result when
> > performing the same merge later on?
> 
> Custom merge driver.
> 
> Type `man gitattributes` and search for "custom merge driver"
> 
> Your merge driver can have whatever policy you can program, on a per
> file basis.

Thanks for the pointer, I knew it must be possible with git somehow.

For future reference, here's what I did to handle the minimal receipe
posted in my earlier email:

I stored the diff between the original and semantically almost correct
merge result and the fixed version in the file "patch", then put
together the little script below and configured it as custom merge
driver for the file "file", as described in the documentation.  The
script uses 'git merge-file' to perform the real merge, and then
applies the fixup patch (after rewriting the paths, because during the
merge the patch should be applied to the current file the merge driver
is working with instead of the original "file").  Of course, "file"
might be modified by other merges before or after the problematic
merge, but the fixup patch should not be applied in those cases.  The
two greps and the conditions make sure that the patch is applied only
if both "code blocks" are in the file and they are in the wrong order.

Unfortunately, applying a patch is more sensitive to matching context,
so it will fail easily when there are other changes in the
neighborhood, but at least it will fail loudly, and then I'll know I
have to fix it up manually.  We'll see, how it will cope with real
source code.


Thanks,
Gábor



#!/bin/sh

f="file"

git merge-file "$1" "$2" "$3"

a_line="$(grep -n '^a$' "$1" |cut -d: -f1)"
c_line="$(grep -n '^c$' "$1" |cut -d: -f1)"

if [ -n "$a_line" -a -n "$c_line" ] && [ "$c_line" -lt "$a_line" ]; then 
	echo "Fixing incorrect auto-merge result of '$f'"
	sed -e "s%^diff --git a/$f b/$f%diff --git a/$1 b/$1%" \
		-e "s%^--- a/$f%--- a/$1%" \
		-e "s%^+++ b/$f%+++ b/$1%" patch \
		|git apply
fi

^ permalink raw reply

* Re: [PATCH 1/3] use struct sha1_array in diff_tree_combined()
From: René Scharfe @ 2011-12-17 11:16 UTC (permalink / raw)
  To: Jeff King
  Cc: git, Junio C Hamano, Ævar Arnfjörð Bjarmason,
	Jens Lehmann
In-Reply-To: <20111217105315.GA23935@sigill.intra.peff.net>

Am 17.12.2011 11:53, schrieb Jeff King:
>> -	parent = xmalloc(ents * sizeof(*parent));
>> -	for (i = 0; i<  ents; i++)
>> -		hashcpy((unsigned char *)(parent + i), ent[i].item->sha1);
>> -	diff_tree_combined(parent[0], parent + 1, ents - 1,
>> +	for (i = 1; i<  ents; i++)
>> +		sha1_array_append(&parents, ent[i].item->sha1);
>> +	diff_tree_combined(ent[0].item->sha1,&parents,
>>   			   revs->dense_combined_merges, revs);
>> -	free((void *)parent);
>> +	sha1_array_clear(&parents);
>
> The original code is slightly more efficient, as it is able to use a
> single malloc (because it knows the number of entries ahead of time).
> It probably doesn't make a difference, but we could also add a
> sha1_array_grow() for this case.
>
> I think it could be used in all three spots you converted in this patch.

We coulddo that, yes.  In the case above we have the number already, in 
the other cases we'd have to count.

But I don't think it's worth it here.  ALLOC_GROW gives us 24 entries 
initially, which should be enough in most cases -- I'm not sure I want 
to see combined diff of that many tree.  And 24 times 20 bytes is small 
enough to not cause any memory allocation issues.

Taking out the counting and not having to worry about the number of 
items is a feature in my book.  Simple timings before and after the 
patch didn't show any significant difference.

René

^ permalink raw reply

* Re: [PATCH 1/3] use struct sha1_array in diff_tree_combined()
From: Jeff King @ 2011-12-17 11:19 UTC (permalink / raw)
  To: René Scharfe
  Cc: git, Junio C Hamano, Ævar Arnfjörð Bjarmason,
	Jens Lehmann
In-Reply-To: <4EEC7A10.3080705@lsrfire.ath.cx>

On Sat, Dec 17, 2011 at 12:16:32PM +0100, René Scharfe wrote:

> >The original code is slightly more efficient, as it is able to use a
> >single malloc (because it knows the number of entries ahead of time).
> >It probably doesn't make a difference, but we could also add a
> >sha1_array_grow() for this case.
> [...]
> We coulddo that, yes.  In the case above we have the number already,
> in the other cases we'd have to count.
> 
> But I don't think it's worth it here.  ALLOC_GROW gives us 24 entries
> initially, which should be enough in most cases -- I'm not sure I
> want to see combined diff of that many tree.  And 24 times 20 bytes
> is small enough to not cause any memory allocation issues.

You're right.

I was blindly looking at the conversion without thinking about the
context. Of course if you have just a few items, it's going to be
irrelevant (my initial refactoring of sha1_array was to help speed up a
hundreds-of-thousands of sha1s case, so I think that put me in the
mindset of a large list).

Sorry for the noise.

-Peff

^ permalink raw reply

* Re: [BUG] in rev-parse
From: Jeff King @ 2011-12-17 12:02 UTC (permalink / raw)
  To: Michael Haggerty; +Cc: Junio C Hamano, nathan.panike, git
In-Reply-To: <4EEA7A7E.4070109@alum.mit.edu>

On Thu, Dec 15, 2011 at 11:53:50PM +0100, Michael Haggerty wrote:

> I believe that the OP was more inconvenienced that "git rev-parse
> --short" chokes on multiple objects than by the fact that it insists
> that the objects exist.  (And shortening the SHA1s of non-existent
> objects doesn't sound very useful anyway.)  So I think that a useful
> compromise would be for "git rev-parse --short" to accept multiple args
> but continue to insist that each of the args is a valid object.

Part of the guarantee of "--verify" is that it returns a single object.
I don't know how many callers rely on "--short" implying "--verify"
implying a single object.

I agree in practice it would probably be an OK change, and it's very
easy to do. I just don't think it's an important enough problem to worry
about, given the available workaround. But if you want to write the
patch, be my guest. :)

-Peff

^ 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