{"thread":{"id":"35561","subject":"git-mv-submodule","startedAt":"2013-12-21T09:48:33Z","lastAt":"2013-12-21T16:23:32Z","messageCount":3,"participants":["fREW Schmidt","Jens Lehmann"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"232300","messageId":"20131221094833.GA7917@wanderlust","threadId":"35561","inReplyTo":null,"subject":"git-mv-submodule","fromName":"fREW Schmidt","fromEmail":"frioux@gmail.com","sentAt":"2013-12-21T09:48:33Z","receivedAt":"2013-12-21T09:48:33Z","isPatch":false,"sender":{"key":"frioux@gmail.com","avatar":"https://gravatar.com/avatar/639ef3cc221c7f2c225568697bc9d42be4d4e3bada6b4a3b9c32685548f3c105?d=mp&s=160"},"body":"Hello all,\n\nI was on a plane, moving around some of the many (30ish) submodules in\nmy dotfiles and got really annoyed at how much work it is (move the\ndir, remove old from git, add new to git, fix .gitmodules, fix\n.git/config, fix all the parts of the submodule config) so I wrote a\nperl script to work for the most common case.\n\nAs far as I know it should work for anyone not doing Something Weird,\nie manually fiddling with their submodules.  The main case it does not\nsupport that I'd like to in the future is submodules containing\nsubmodules, and also at some point I'd like to wrap git mv to invoke\nthis script on demand automatically.\n\nNote that this script requires perl 5.10.1, released in 2009.  If you\nare stuck with something inferior to that you can comment out the\nversion at the top and the autodie usage and it should work further\nback, but won't be quite as robust.\n\nEnjoy!\n-- \nfREW Schmidt\nhttp://blog.afoolishmanifesto.com\n\n\n#!/usr/bin/env perl\n\nuse 5.10.1;\nuse strict;\nuse warnings;\n\nuse autodie;\nuse File::Basename 'dirname';\nuse File::Path 'make_path';\n\ndie \"you must pass both a from and a to\" unless @ARGV == 2;\n\nmy ($from, $to) = @ARGV;\n\ndie \"you have changes in your working copy!\"\n   unless is_clean();\n\n# move the real dir\nmake_path(dirname($to));\nsafe_system('mv', $from, $to);\n\n# move the git dir (not really that important)\nmake_path(dirname(\".git/modules/$to\"));\nsafe_system('mv', \".git/modules/$from\", \".git/modules/$to\");\n\n# update .gitmodules and .git/config book keeping\nspew($_, slurp($_) =~ s/\\Q$from\\E/$to/gr)\n   for qw( .gitmodules .git/config );\n\nmy $dir_count = scalar split qr(/), $to =~ s(/$)()r;\n\nmy $derp = ('../' x (2 + $dir_count)) . $to;\n\n# update .git/modules/$to/config book keeping\nspew(\n   \".git/modules/$to/config\",\n   slurp(\".git/modules/$to/config\") =~ s/worktree.*/worktree = $derp/gr\n);\n\n# update $to book keeping\nspew(\n   \"$to/.git\",\n   'gitdir: ' . ('../' x $dir_count) . \".git/modules/$to\"\n);\n\nsafe_system(qw( git add -A ), $from, $to, '.gitmodules' );\n\nsub safe_system {\n   system(@_);\n\n   die \"@_ exited poorly :(\"\n      if $? >> 8;\n}\n\nsub safe_capture {\n   my $ret = qx(@_);\n\n   die \"@_ exited poorly :(\"\n      if $? >> 8;\n\n   return $ret;\n}\n\nsub slurp {\n   open my $fh, '<', $_[0];\n   local $/ = undef;\n   scalar <$fh>\n}\n\nsub spew {\n   open my $fh, '>', $_[0];\n   print {$fh} $_[1]\n}\n\nsub is_clean { !safe_capture(qw(git status --porcelain)) }\n"},{"id":"232335","messageId":"52B5BD1B.5090705@web.de","threadId":"35561","inReplyTo":"20131221094833.GA7917@wanderlust","subject":"Re: git-mv-submodule","fromName":"Jens Lehmann","fromEmail":"jens.lehmann@web.de","sentAt":"2013-12-21T16:08:59Z","receivedAt":"2013-12-21T16:08:59Z","isPatch":false,"sender":{"key":"jens.lehmann@web.de","avatar":"https://avatars.githubusercontent.com/u/135220?v=4"},"body":"Am 21.12.2013 10:48, schrieb fREW Schmidt:\n> Hello all,\n> \n> I was on a plane, moving around some of the many (30ish) submodules in\n> my dotfiles and got really annoyed at how much work it is (move the\n> dir, remove old from git, add new to git, fix .gitmodules, fix\n> .git/config, fix all the parts of the submodule config) so I wrote a\n> perl script to work for the most common case.\n> \n> As far as I know it should work for anyone not doing Something Weird,\n> ie manually fiddling with their submodules.  The main case it does not\n> support that I'd like to in the future is submodules containing\n> submodules, and also at some point I'd like to wrap git mv to invoke\n> this script on demand automatically.\n\nThanks for sharing! Form a cursory look over your perl script it\nlooks like it does what stock \"git mv\" will do since 1.8.5 (except\nfor changing the name of the submodule, which I would not advise\nto do when only moving the submodule location in the work tree).\n"},{"id":"232336","messageId":"20131221162332.GB7917@wanderlust","threadId":"35561","inReplyTo":"52B5BD1B.5090705@web.de","subject":"Re: git-mv-submodule","fromName":"fREW Schmidt","fromEmail":"frioux@gmail.com","sentAt":"2013-12-21T16:23:32Z","receivedAt":"2013-12-21T16:23:32Z","isPatch":false,"sender":{"key":"frioux@gmail.com","avatar":"https://gravatar.com/avatar/639ef3cc221c7f2c225568697bc9d42be4d4e3bada6b4a3b9c32685548f3c105?d=mp&s=160"},"body":"On Sat, Dec 21, 2013 at 05:08:59PM +0100, Jens Lehmann wrote:\n> Am 21.12.2013 10:48, schrieb fREW Schmidt:\n> Thanks for sharing! Form a cursory look over your perl script it\n> looks like it does what stock \"git mv\" will do since 1.8.5 (except\n> for changing the name of the submodule, which I would not advise\n> to do when only moving the submodule location in the work tree).\n\nSee, I thought I read that in the changelog; unfortunately I don'g\nthing it does the final set of book-keeping (changing the .git file if\nyou changed the depth of the submodule in the mv and changing the path\nof the worktree in the actual git repo in .git/modules)\n\nI'd love to be wrong on that as this script is clearly not perfect.  I\nthink my second little script in my previous email re git submodule\nbugs shows the issue.  I'll include it here for simplicity though:\n\n mkdir -p test/a test/b\n cd test/a\n git init\n touch a.txt\n git add a.txt\n git ci -m 'initial commit'\n cd ../b\n git init\n mkdir c\n touch c/c.txt\n git submodule add ../a c/a\n git ci -m 'initial commit'\n git mv c d\n git status\n\n-- \nfREW Schmidt\nhttp://blog.afoolishmanifesto.com\n"}]}