¿Cómo cd a la carpeta principal más cercana que tiene una carpeta .git con bash?

Cuando trabajo en proyectos controlados por la versión, a menudo termino en una carpeta anidada. El uso de cd ../../ vuelve un poco engorroso, por lo que me pregunto si hay una forma de definir un alias en bash que cd para el padre hasta que llegue a una carpeta con una carpeta .git , o llegue a ~ .

Entonces digamos que

  • ~/my-project es un repository git
  • my cwd es ~/my-project/deeply/nested/folder/structure
  • Ejecuto el command y me cd'ed a ~/my-project

¿Qué command podría hacer esto? ¿Necesitaría una function bash?

El command que estás buscando es git rev-parse --show-toplevel , puedes hacer una function bash que lo use.

 gr() { cd "$(git rev-parse --show-toplevel)" } 

También tengo en mi ~/.gitconfig :

 [alias] root = rev-parse --show-toplevel 

Lo que hace que este command sea un poco más razonable.

Creo que la respuesta que ya tienes es buena (y posiblemente más eficiente) pero una forma básica de lograr esto sería usar un ciclo:

 until [ -d .git ]; do cd ..; done 

Es decir, vaya al directory padre hasta que exista el directory .git .

Para protegerse contra un bucle infinito si ejecuta el command desde fuera de un repository git, puede agregar una verificación básica:

 until [ -d .git ] || [ "$PWD" = "$p" ]; do p=$PWD; cd ..; done 

No estoy seguro de lo portátil que es, pero en mi sistema tengo una variable $OLDPWD que se puede usar en su lugar:

 until [ -d .git ] || [ "$PWD" = "$OLDPWD" ]; do cd ..; done 

De nuevo, ya respondí, pero tengo un script de la siguiente manera que esencialmente hace eso:

 #!/bin/bash filename=$1 [[ ! ${filename} ]] && echo "no filename" && exit -1 path=$(pwd) while [[ "${path}" != "" && ! -e ${path}/${filename} ]]; do path=${path%/*} done [[ "${path}" == "" ]] && exit -1; cd ${path} 

donde harías findup .git (que a su vez podría convertirse en un alias)