Re: problem with git worktree and git svn

2016-10-13 Thread Eric Wong
Duy Nguyen  wrote:
> On Thu, Oct 13, 2016 at 8:52 AM, Eric Wong  wrote:
> > +sub svn_dir {
> > +   my $git_dir = scalar @_ ? $_[0] : $ENV{GIT_DIR};
> > +   my $common = $ENV{GIT_COMMON_DIR} || "$git_dir/commondir";
> > +   $git_dir .= '/'.::file_to_s($common) if -e $common;
> > +   my $svn_dir = $git_dir . '/svn';
> > +   $svn_dir =~ tr!/!/!s;
> > +   $svn_dir;
> > +}
> 
> 
> If this is shell script, this function could be just
> 
> svn_dir() {
> git rev-parse --git-path svn
> }

Ah, thanks; I missed --git-path.  I will do this in Git/SVN.pm:

--- a/perl/Git/SVN.pm
+++ b/perl/Git/SVN.pm
@@ -808,12 +808,7 @@ sub get_fetch_range {
 }
 
 sub svn_dir {
-   my $git_dir = scalar @_ ? $_[0] : $ENV{GIT_DIR};
-   my $common = $ENV{GIT_COMMON_DIR} || "$git_dir/commondir";
-   $git_dir .= '/'.::file_to_s($common) if -e $common;
-   my $svn_dir = $git_dir . '/svn';
-   $svn_dir =~ tr!/!/!s;
-   $svn_dir;
+   command_oneline(qw(rev-parse --git-path svn));
 }
 
 sub tmp_config {

> which should give you correct path in either single or multi-worktree
> context and you don't need to bother with details like
> $GIT_COMMON_DIR. But I don't know how Perl bindings are implemented, I
> don't know if we have something similar (or easy to add it, like
> Git::git_path()).

I'm not sure it's necessary given the convenience of command_oneline,
and I'd rather avoid the overhead of documenting+supporting a new API
for Git.pm

> I don't know much about git-svn, but from the look of it I agree
> replacing $ENV{GIT_DIR}/svn with svn_dir() should fix it, assuming
> that you don't hard code $ENV{GIT_DIR}/blahblah somewhere else. I
> don't see any other potential problems (from multi-worktree
> perspective).

I think there was a place where $GIT_DIR/config was used, but
only for documentation purposes.


Re: problem with git worktree and git svn

2016-10-13 Thread Duy Nguyen
On Thu, Oct 13, 2016 at 8:52 AM, Eric Wong  wrote:
> +sub svn_dir {
> +   my $git_dir = scalar @_ ? $_[0] : $ENV{GIT_DIR};
> +   my $common = $ENV{GIT_COMMON_DIR} || "$git_dir/commondir";
> +   $git_dir .= '/'.::file_to_s($common) if -e $common;
> +   my $svn_dir = $git_dir . '/svn';
> +   $svn_dir =~ tr!/!/!s;
> +   $svn_dir;
> +}


If this is shell script, this function could be just

svn_dir() {
git rev-parse --git-path svn
}

which should give you correct path in either single or multi-worktree
context and you don't need to bother with details like
$GIT_COMMON_DIR. But I don't know how Perl bindings are implemented, I
don't know if we have something similar (or easy to add it, like
Git::git_path()).

I don't know much about git-svn, but from the look of it I agree
replacing $ENV{GIT_DIR}/svn with svn_dir() should fix it, assuming
that you don't hard code $ENV{GIT_DIR}/blahblah somewhere else. I
don't see any other potential problems (from multi-worktree
perspective).
-- 
Duy


Re: problem with git worktree and git svn

2016-10-12 Thread Eric Wong
Stefan Beller  wrote:
> On Wed, Oct 12, 2016 at 7:45 AM, Mathieu Arnold  wrote:
> 
> > I discovered git worktree earlier this week, and I found it a great
> > asset to be able to have more than one branch of my worktree accessible
> > at the same time...
> >
> > Anyway, back to my problem, the way git-svn works, is that it looks for
> > a directory named "svn" in its gitdir and if it is not present, decide
> > the repository is using git-svn version 1 (whatever that is) and goes to
> > parse all the revisions to recreate the svn directory.
> > So I can only use git svn commands in my main worktree, the one with the
> > real gitdir.

Right, I haven't updated git-svn to be worktree-aware, yet, but
a work-in-progress is below

> > To fix that, all I had to do is to add a symlink named svn in each
> > worktree's gitdir and pointing to ../../svn.
> 
> For some definition of fix. ;)
> Sure it fixes your local setup now, but would we want to use that as well 
> here?
> My gut reaction:
> 
> * not all platforms know symlinks
> * IIRC there is some worktree magic that tells you the "main" dir,
>   so if that was used in git-svn instead it should "just work".
> 
> >
> > I think all that needs to happen is that when adding a new worktree, if
> > the main git directory has a "svn" directory, add a symlink to it in the
> > worktree's gitdir.

I'm fairly sure the worktree C code should not care about how
git-svn works, but rather git-svn should be made aware of
worktree bits...

I haven't studied worktrees much nor do I use git-svn much,
but the following seems to work for fetch/rebase/dcommit:

8<---
Subject: [PATCH] git-svn: WIP worktree awareness

---
 perl/Git/SVN.pm   | 29 -
 perl/Git/SVN/Migration.pm | 23 ---
 2 files changed, 32 insertions(+), 20 deletions(-)

diff --git a/perl/Git/SVN.pm b/perl/Git/SVN.pm
index 018beb8..267cc09 100644
--- a/perl/Git/SVN.pm
+++ b/perl/Git/SVN.pm
@@ -807,10 +807,20 @@ sub get_fetch_range {
(++$min, $max);
 }
 
+sub svn_dir {
+   my $git_dir = scalar @_ ? $_[0] : $ENV{GIT_DIR};
+   my $common = $ENV{GIT_COMMON_DIR} || "$git_dir/commondir";
+   $git_dir .= '/'.::file_to_s($common) if -e $common;
+   my $svn_dir = $git_dir . '/svn';
+   $svn_dir =~ tr!/!/!s;
+   $svn_dir;
+}
+
 sub tmp_config {
my (@args) = @_;
-   my $old_def_config = "$ENV{GIT_DIR}/svn/config";
-   my $config = "$ENV{GIT_DIR}/svn/.metadata";
+   my $svn_dir = svn_dir();
+   my $old_def_config = "$svn_dir/config";
+   my $config = "$svn_dir/.metadata";
if (! -f $config && -f $old_def_config) {
rename $old_def_config, $config or
   die "Failed rename $old_def_config => $config: $!\n";
@@ -1671,7 +1681,7 @@ sub tie_for_persistent_memoization {
return if $memoized;
$memoized = 1;
 
-   my $cache_path = "$ENV{GIT_DIR}/svn/.caches/";
+   my $cache_path = svn_dir() . '/.caches/';
mkpath([$cache_path]) unless -d $cache_path;
 
my %lookup_svn_merge_cache;
@@ -1712,7 +1722,7 @@ sub tie_for_persistent_memoization {
sub clear_memoized_mergeinfo_caches {
die "Only call this method in non-memoized context" if 
($memoized);
 
-   my $cache_path = "$ENV{GIT_DIR}/svn/.caches/";
+   my $cache_path = svn_dir() . '/.caches/';
return unless -d $cache_path;
 
for my $cache_file (("$cache_path/lookup_svn_merge",
@@ -2446,12 +2456,13 @@ sub _new {
 "refs/remotes/$prefix$default_ref_id";
}
$_[1] = $repo_id;
-   my $dir = "$ENV{GIT_DIR}/svn/$ref_id";
+   my $svn_dir = svn_dir();
+   my $dir = "$svn_dir/$ref_id";
 
-   # Older repos imported by us used $GIT_DIR/svn/foo instead of
-   # $GIT_DIR/svn/refs/remotes/foo when tracking refs/remotes/foo
+   # Older repos imported by us used $svn_dir/foo instead of
+   # $svn_dir/refs/remotes/foo when tracking refs/remotes/foo
if ($ref_id =~ m{^refs/remotes/(.+)}) {
-   my $old_dir = "$ENV{GIT_DIR}/svn/$1";
+   my $old_dir = "$svn_dir/$1";
if (-d $old_dir && ! -d $dir) {
$dir = $old_dir;
}
@@ -2461,7 +2472,7 @@ sub _new {
mkpath([$dir]);
my $obj = bless {
ref_id => $ref_id, dir => $dir, index => "$dir/index",
-   config => "$ENV{GIT_DIR}/svn/config",
+   config => "$svn_dir/config",
map_root => "$dir/.rev_map", repo_id => $repo_id }, $class;
 
# Ensure it gets canonicalized
diff --git a/perl/Git/SVN/Migration.pm b/perl/Git/SVN/Migration.pm
index cf6ffa7..887fd93 100644
--- a/perl/Git/SVN/Migration.pm
+++ b/perl/Git/SVN/Migration.pm
@@ -45,6 +45,7 @@ use Git qw(

Re: problem with git worktree and git svn

2016-10-12 Thread Stefan Beller
+cc Duy who knows about worktree,
+cc Eric Wong, who knows about git-svn



On Wed, Oct 12, 2016 at 7:45 AM, Mathieu Arnold  wrote:
> Hi,
>
> I'm a FreeBSD ports developer, and while our main repository is in
> Subversion, some of us use git-svn a lot for development.
>
> I discovered git worktree earlier this week, and I found it a great
> asset to be able to have more than one branch of my worktree accessible
> at the same time...
>
> Anyway, back to my problem, the way git-svn works, is that it looks for
> a directory named "svn" in its gitdir and if it is not present, decide
> the repository is using git-svn version 1 (whatever that is) and goes to
> parse all the revisions to recreate the svn directory.
> So I can only use git svn commands in my main worktree, the one with the
> real gitdir.
> To fix that, all I had to do is to add a symlink named svn in each
> worktree's gitdir and pointing to ../../svn.

For some definition of fix. ;)
Sure it fixes your local setup now, but would we want to use that as well here?
My gut reaction:

* not all platforms know symlinks
* IIRC there is some worktree magic that tells you the "main" dir,
  so if that was used in git-svn instead it should "just work".

>
> I think all that needs to happen is that when adding a new worktree, if
> the main git directory has a "svn" directory, add a symlink to it in the
> worktree's gitdir.
>
> --
> Mathieu Arnold
>
>