here's the updated version of the code for being reviewed. Fixes:

  • "private" _cg function
  • functions definition as cg() {}
  • general clean-up

# 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="$(git rev-parse --show-cdup)"
    local super_root; super_root="$(git rev-parse --show-superproject-working-tree)"
    if [[ "$super_root" ]]; then
      printf '%s' "$top../"
      ( cd "$top../" && _cg || return )
    printf '%s' "$top"
  local git_root
  [[ "x${git_root}" != "x./" ]] && cd "${git_root}" && return || return 0

1 Answer 1


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 [[ "x${git_root}" != "x./" ]] 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 [[ "$super_root" ]]; then line like so: if [[ -n "$super_root" ]]; then to make clear what you're trying to do there.
  • \$\begingroup\$ I just found that didn't come back with "thank you". Thank you very much for your help! And the objectives behind the implementations: 1) I feel like echo -n is less portable than printf, that's why I stuck to it; 2) Thank you, I've learned something new; 3) perfectly makes sense too! \$\endgroup\$
    – Felixoid
    Jul 18, 2021 at 21:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.