Updated bash/zsh function that cd to the root of git tree here's the updated version of the code for being reviewed. Fixes:

&quot;private&quot; _cg function
functions definition as cg() {}
general clean-up

#!/bin/bash

# cd to the root of the current git directory
# If $PWD is submodule, will cd to the root of the top ancestor
# It requires to stay in the current directory, if the root is . or unknown,
# and use cd only once, to have a way to do `cd -`
cg() {
  _cg() {
    local top; top=&quot;$(git rev-parse --show-cdup)&quot;
    top=&quot;${top:-./}&quot;
    local super_root; super_root=&quot;$(git rev-parse --show-superproject-working-tree)&quot;
    if [[ &quot;$super_root&quot; ]]; then
      printf '%s' &quot;$top../&quot;
      ( cd &quot;$top../&quot; &amp;&amp; _cg || return )
    fi
    printf '%s' &quot;$top&quot;
  }
  local git_root
  git_root=&quot;$(_cg)&quot;
  [[ &quot;x${git_root}&quot; != &quot;x./&quot; ]] &amp;&amp; cd &quot;${git_root}&quot; &amp;&amp; return || return 0
}
This is looking great.  Thanks for incorporating the previous improvements and coming back for another round of review.  I noticed a few new things this time:

What does printf '%s' do for you that echo -n wouldn't?  Using printf when you're just passing through a string seems a little odd to me.  It should work either way, but printf would be more idiomatic for C where echo is much more common in shell scripts.
Adding the x constants in the comparison [[ &quot;x${git_root}&quot; != &quot;x./&quot; ]] are not needed.  Using the double square brackets deals with the disappearing variables.  You would need the extra x for [ comparisons because empty arguments become non-existant arguments which causes an error when you try to compare the non-existant to something.
I would use -n in the if [[ &quot;$super_root&quot; ]]; then line like so: if [[ -n &quot;$super_root&quot; ]]; then to make clear what you're trying to do there.