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)) }
Attachment:
pgpbloLs7F_ZQ.pgp
Description: PGP signature