Re: git-mv-submodule

2013-12-21 Thread fREW Schmidt
On Sat, Dec 21, 2013 at 05:08:59PM +0100, Jens Lehmann wrote:
 Am 21.12.2013 10:48, schrieb fREW Schmidt:
 Thanks for sharing! Form a cursory look over your perl script it
 looks like it does what stock git mv will do since 1.8.5 (except
 for changing the name of the submodule, which I would not advise
 to do when only moving the submodule location in the work tree).

See, I thought I read that in the changelog; unfortunately I don'g
thing it does the final set of book-keeping (changing the .git file if
you changed the depth of the submodule in the mv and changing the path
of the worktree in the actual git repo in .git/modules)

I'd love to be wrong on that as this script is clearly not perfect.  I
think my second little script in my previous email re git submodule
bugs shows the issue.  I'll include it here for simplicity though:

 mkdir -p test/a test/b
 cd test/a
 git init
 touch a.txt
 git add a.txt
 git ci -m 'initial commit'
 cd ../b
 git init
 mkdir c
 touch c/c.txt
 git submodule add ../a c/a
 git ci -m 'initial commit'
 git mv c d
 git status

-- 
fREW Schmidt
http://blog.afoolishmanifesto.com


pgpZne3BJMPSW.pgp
Description: PGP signature


git-mv-submodule

2013-12-21 Thread fREW Schmidt
Hello all,

I was on a plane, moving around some of the many (30ish) submodules in
my dotfiles and got really annoyed at how much work it is (move the
dir, remove old from git, add new to git, fix .gitmodules, fix
.git/config, fix all the parts of the submodule config) so I wrote a
perl script to work for the most common case.

As far as I know it should work for anyone not doing Something Weird,
ie manually fiddling with their submodules.  The main case it does not
support that I'd like to in the future is submodules containing
submodules, and also at some point I'd like to wrap git mv to invoke
this script on demand automatically.

Note that this script requires perl 5.10.1, released in 2009.  If you
are stuck with something inferior to that you can comment out the
version at the top and the autodie usage and it should work further
back, but won't be quite as robust.

Enjoy!
-- 
fREW Schmidt
http://blog.afoolishmanifesto.com
#!/usr/bin/env perl

use 5.10.1;
use strict;
use warnings;

use autodie;
use File::Basename 'dirname';
use File::Path 'make_path';

die you must pass both a from and a to unless @ARGV == 2;

my ($from, $to) = @ARGV;

die you have changes in your working copy!
   unless is_clean();

# move the real dir
make_path(dirname($to));
safe_system('mv', $from, $to);

# move the git dir (not really that important)
make_path(dirname(.git/modules/$to));
safe_system('mv', .git/modules/$from, .git/modules/$to);

# update .gitmodules and .git/config book keeping
spew($_, slurp($_) =~ s/\Q$from\E/$to/gr)
   for qw( .gitmodules .git/config );

my $dir_count = scalar split qr(/), $to =~ s(/$)()r;

my $derp = ('../' x (2 + $dir_count)) . $to;

# update .git/modules/$to/config book keeping
spew(
   .git/modules/$to/config,
   slurp(.git/modules/$to/config) =~ s/worktree.*/worktree = $derp/gr
);

# update $to book keeping
spew(
   $to/.git,
   'gitdir: ' . ('../' x $dir_count) . .git/modules/$to
);

safe_system(qw( git add -A ), $from, $to, '.gitmodules' );

sub safe_system {
   system(@_);

   die @_ exited poorly :(
  if $?  8;
}

sub safe_capture {
   my $ret = qx(@_);

   die @_ exited poorly :(
  if $?  8;

   return $ret;
}

sub slurp {
   open my $fh, '', $_[0];
   local $/ = undef;
   scalar $fh
}

sub spew {
   open my $fh, '', $_[0];
   print {$fh} $_[1]
}

sub is_clean { !safe_capture(qw(git status --porcelain)) }


pgpEyJW_kdh5r.pgp
Description: PGP signature


Bug when moving submodules (I think?)

2013-12-18 Thread fREW Schmidt
I tried to make a script to repro this from scratch but ran into other
issues, which may or may not be a bug.  I'll put that at the end.

To repro all you have to do is: 

 git checkout git://github.com/frioux/dotfiles
 git reset --hard 92c85161ceec9e52b0b2d2de893ba11f49c80198
 git mv zsh .zsh

(sha included so this email continues to be valid in the future)

You can now see that .git/index.lock has been left behind.  On a
non-fresh checkout (I'm not sure why my old checkout is special) I get
the following error:

 git: builtin/mv.c:248: cmd_mv: Assertion `pos = 0' failed.

I assumed this was just related to moving submodules that are in
subdirectories, but when I do that from a fresh repo I get a different
error.

 mkdir -p test/a test/b
 cd test/a
 git init
 touch a.txt
 git add a.txt
 git ci -m 'initial commit'
 cd ../b
 git init
 mkdir c
 touch c/c.txt
 git submodule add ../a c/a
 git ci -m 'initial commit'
 git mv c d
 git status

And the error:

 fatal: Could not chdir to '../../../../c/a': No such file or directory
 fatal: 'git status --porcelain' failed in submodule d/a

I am using git v1.8.5.1 built from source on the latest ubuntu.  If
there is anything else I can do to help repro this please do not
hesitate to ask.
-- 
fREW Schmidt
http://blog.afoolishmanifesto.com


pgpgI6eNDJFpI.pgp
Description: PGP signature