public
Last active

git submodule-rm

  • Download Gist
git-submodule-rm.sh
Shell
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
#!/bin/bash
 
function actual_path() {
if [ [ -z "$1" ] -a [ -d $1 ] ]; then
echo $(cd $1 && test `pwd` = `pwd -P`)
return 0
else
return 1
fi
}
 
function is_submodule() {
local top_level parent_git module_name
 
if [ -d "$1" ]; then
cd $1
else
return 1
fi
 
# Find the root of this git repo, then check if its parent dir is also a repo
top_level="$(git rev-parse --show-toplevel)"
if [ ! actual_path $toplevel ]; then
top_level="$(cd $top_level && pwd -P)"
fi
 
module_name="$(basename "$top_level")"
parent_git="$(cd "$top_level/.." && git rev-parse --show-toplevel 2> /dev/null)"
 
if [[ -n $parent_git ]]; then
return 0
else
return 1
fi
}
 
function is_gitroot() {
if [ "$(pwd -P)" = "$(git rev-parse --show-toplevel)" ]; then
return 0
else
return 1
fi
}
 
# first check if it's a valid path
if [ ! -d "$1" ]; then
echo "Usage: git submodule rm <path>"
exit
fi
 
# then check whether we're at git root
if is_gitroot; then
# finally check whether the given path is a submodule
if $(is_submodule "${1}"); then
echo "let's remove those submodules"
# using ${1%/} to remove trailing slashes
git config -f .gitmodules --remove-section submodule.${1%/}
git config -f .git/config --remove-section submodule.${1%/}
git rm --cached ${1%/}
else
echo "git submodule rm is not recursive yet, aborting."
fi
else
echo "You need to run this command from the toplevel of the working tree."
fi

unfortunately, git aliases can't have spaces in it...
so I'm stuck with git submodule-rm

git config is more reliable and readable than sed ;)

You can't have an alias with a space, but you can fake it with a function. Check out my fork: https://gist.github.com/2642691

My fork fixes a "bad substitution" error and says "submodule-rm" with the dash. I don't mind it :)

merged @henrik's fix :)

Is it wise to also remove the untracked submodule files (as per my fork) or is this considered dangerous?

@tlvince To my knowledge it should be safe. I suppose some instructions don't have you removing the files from your working directory because you may have made changes to the submodule that you want to keep, or something.

You should be able to do just:

git rm ${1%/}

Instead of:

git rm --cached ${1%/}
rm -rf ${1%/}

Regarding .git/modules, I don't have any such directory in my repo (with several submodules). Maybe only older versions of Git use it? Or maybe those files are only created when you do something fancy with the modules. Either way, I suppose it's a good idea to have this script remove them. Leaving them can apparently cause problems; removing them shouldn't.

Oops, tried git rm ${1%/} and that didn't work, even with -rf. So both lines are needed.

@henrik I guess those files only show up if you clone and git init.

Great. I've added a test to see if .git/modules exists and quoted the paths. Feel free to merge.

@henrik @tlvince @zaius btw, how did you find this gist?

Yep, same here.

I'm getting "fatal: No such section!" from lines 57 and 58. In my files, there is no trailing slash!

Oh, the problem is that this script doesn't work when the submodule is not at the top level of the super-module! Back to "doing it manually," I guess :-P

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.