git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: John Keeping <john@keeping.me.uk>
To: Christoph Anton Mitterer <mail@christoph.anton.mitterer.name>
Cc: git@vger.kernel.org
Subject: Re: [PATCH] use refnames instead of "left"/"right" in dirdiffs
Date: Wed, 27 Mar 2013 23:07:16 +0000	[thread overview]
Message-ID: <20130327230715.GU2286@serenity.lan> (raw)
In-Reply-To: <1364422397.8091.1.camel@heisenberg.scientia.net>

On Wed, Mar 27, 2013 at 11:13:17PM +0100, Christoph Anton Mitterer wrote:
> Currently, when a dir-diff is made with git-difftool the two revisions are
> stored in two temporary directories ".../left" and ".../right".
> Many difftools show these pathnames in ther UI and therefore it would be helpful
> for users, if actual reference names specified as progam arguments was used
> instead.
> 
> Reference names might contain slash / characters which are not allowed to be
> part of a file name. These must therefore be encoded.
> 
> Also, reference names that would could possibly "break out" of the temporary
> directory (e.g. "/foo", "foo/../bar" or "foo/././bar") must be sanitised.
> * Added a subroutine escape_reference_to_single_directory_name() which encodes a
>   reference name to a valid single directory name.
>   Any occurance of a slash / is replaced by two backslashes \\.
>   Having a backslash \ in a reference name should be forbidden, but just to be
>   save from collisions, any occurance of a backslash \ is replaced by a
>   backslash followed by an underscore \_ at first.
> 
> * Use this new function to construct the pathnames of the temporary directories
>   for the two revisions in dir-diffs.
> 
> Signed-off-by: Christoph Anton Mitterer <mail@christoph.anton.mitterer.name>
> 
> diff --git a/git-difftool.perl b/git-difftool.perl
> index 12231fb..53e756d 100755
> --- a/git-difftool.perl
> +++ b/git-difftool.perl
> @@ -83,6 +83,28 @@ sub exit_cleanup
>         exit($status | ($status >> 8));
>  }
>  
> +sub escape_reference_to_single_directory_name
> +{
> +       # Git allows reference names (see git-check-ref-format(1)) which cannot
> +       # be directly mapped to a single directory name.
> +       #
> +       # This subroutines replaces any occurance of a slash / by two
> +       # backslashes \\.
> +       # Thereby, break-out attempts like "/foo", "foo/../bar" or "foo/././bar"
> +       # are prevented, too.

That's not going to work well on Windows, is it?  Anything with two dots
in is already forbidden so we don't need to worry about that; I'm not
sure we need to remove forward slashes at all, until we consider the
"commit containing" syntax ':/fix nasty bug' or 'master^{/fix bug}'.

I'm more concerned with specifiers containing '^', '@', '{', ':' - see
'SPECIFYING REVISIONS' in git-rev-parse(1) for the full details of
what's acceptable.  At some point I think it may be better to fall back
to the SHA1 of the relevant commit.

> +       #
> +       # Having a backslash \ in a reference name should be forbidden, but just
> +       # to be save from collisions, any occurance of a backslash \ is replaced
> +       # by a backslash followed by an underscore \_ at first.
> +
> +       my ($commit_name)  = @_;
> +
> +       $commit_name =~ s/\\/\\_/g;
> +       $commit_name =~ s/\//\\\\/g;
> +
> +       return $commit_name;
> +}
> +
>  sub setup_dir_diff
>  {
>         my ($repo, $workdir, $symlinks) = @_;
> @@ -169,8 +191,13 @@ EOF
>  
>         # Setup temp directories
>         my $tmpdir = tempdir('git-difftool.XXXXX', CLEANUP => 0, TMPDIR => 1);
> -       my $ldir = "$tmpdir/left";
> -       my $rdir = "$tmpdir/right";
> +       my $ldir = "$tmpdir/" . escape_reference_to_single_directory_name($ARGV[0]);
> +       my $rdir = "$tmpdir/";
> +       if (@ARGV < 2) {
> +               $rdir .= 'HEAD';
> +       } else {
> +               $rdir .= escape_reference_to_single_directory_name($ARGV[1]);
> +       }

I don't think this approach is general enough, since git-difftool
accepts the same range of arguments that git-diff does.

We need to walk over @ARGV here, ignore anything starting with '-', stop
when we reach '--' and handle the arguments found in there including the
three acceptable range forms:

    <commit> <commit>
    <commit>..<commit>
    <commit>...<commit>

replacing missing commits with HEAD.

>         mkpath($ldir) or exit_cleanup($tmpdir, 1);
>         mkpath($rdir) or exit_cleanup($tmpdir, 1);
>  
> 

  reply	other threads:[~2013-03-27 23:08 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-03-27 22:13 [PATCH] use refnames instead of "left"/"right" in dirdiffs Christoph Anton Mitterer
2013-03-27 23:07 ` John Keeping [this message]
2013-03-28 12:46   ` Christoph Anton Mitterer
2013-03-28 14:19     ` John Keeping
2013-03-28 14:38       ` John Keeping

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20130327230715.GU2286@serenity.lan \
    --to=john@keeping.me.uk \
    --cc=git@vger.kernel.org \
    --cc=mail@christoph.anton.mitterer.name \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).