Silence is Foo Mental notes on Ruby, Git, Rails and whatever geeky thing

21Aug/10Off

git submodules statistics in the terminal prompt

When I'm working in projects with submodules and I make a change in one of the submodules I have to go to every submodule directory to review the changes, some times I didn't make any change in a submodule but my memory is not that smart to know that and it's a waste of time.

The solution I found was to add some aliases to my ~/.gitconfig that help me to know the status of the submodules and to add the stats (amount of modified files) to my terminal prompt.


We'd need to add the aliases to the ~/.gitconfig file, if you don't have it, create it

$ mkdir ~/.gitconfig

now we'll need a [alias] key to add our aliases, we'll add them all just below it.

[alias]
   alias_1=...
   alias_2=...
   alias_n=...

Let's say we have 3 submodules in our project: Silence, Foo and Bar.


1. Alias to show the modified files in each submodule
    substatus = "!git submodule foreach git ls-files -m"

the output would be somewhat like this:

$ git substatus
Entering 'Silence'
     src/com/vo/LoremVO.as
Entering 'Foo'
Entering 'Bar'
     bar.rb
     baz.rb

NOTE: substatus is not a git status, it won't show either untracked nor staged files, it will only show modified files, please see the ls-files command help (git ls-files -h)

2. Alias to show the amount of modified files in all the submodules
    substat = "!git submodule --quiet foreach 'echo $path: `git ls-files -m | wc -l`'"

the output would be somewhat like this:

$ git substat
Silence: 1
Foo: 0
Bar: 2

if you see the output of git substatus you'll see that the amount of files matches.

3. Show the amount of modified files in all the submodules in the prompt

Add the following function to your ~/.bash_profile or ~/.bashrc (if you want to know what's the difference click here)

function __git_submodule_stat
{
    if [ -d .git ]; then
        stat=`git submodule --quiet foreach git ls-files -m | wc -l | tr -d ' '`
        if [ $stat -eq 0 ]; then return; fi
        echo "["$stat"]"
    fi
}

then set your PS1

PS1="[\u:\h \W ] $(__git_ps1)$(__git_submodule_stat) $ "

and your prompt would be shown this way:

[user:host folder ] (master)[3] $ _

which would mean you are in the master branch of your repository and that there are 3 modified files in the submodules.

In this case I don't care about what submodule have been modified, I only want to know if there are modified files in any of the submodules, if so, then I use git substatus to know exactly which ones are the modified files.

The foreach argument to git submodule command is pretty interesting, it executes every command you pass it as parameter, such parameter might be a bash or ruby script with any amount of commands as well.

$ git submodule foreach ~/my_script.sh
$ git submodule foreach ~/my_script.rb

If you know a better solution I'd thank you if you'd let me know.

Please make a comment, thanks for reading!

Filed under: git Leave a comment
12Aug/10Off

Reddit is down, it was probably an accident

Nice 404s

Nice 404s

Filed under: off-topic Leave a comment