Mercurial tiene una forma de imprimir el directorio raíz (que contiene .hg) a través de
hg root
¿Hay algo equivalente en git para obtener el directorio que contiene el directorio .git?
git
version-control
wojo
fuente
fuente
bzr root
se usaba mucho en Bazargit rev-parse --git-dir
, como se explica en este comentarioRespuestas:
Si:
Si desea replicar el comando Git más directamente, puede crear un alias :
y ahora
git root
funcionará igual quehg root
.Nota : en un submódulo, esto mostrará el directorio raíz del submódulo y no el repositorio principal. Si está utilizando Git> = 2.13 o superior, hay una forma en que los submódulos pueden mostrar el directorio raíz del superproyecto. Si su git es más viejo que eso, vea esta otra respuesta.
fuente
git config --global alias.exec '!exec '
para poder hacer cosas comogit exec make
. Esto funciona porque los alias de shell siempre se ejecutan en el directorio de nivel superior.hg root
hace. Imprime el directorio de nivel superior de su repositorio desprotegido. No lo cambia a él (y, de hecho, no pudo hacerlo debido a cómo interactúa todo el concepto de directorio actual y su shell).~/my.proj/foo/bar
y~/my.proj
tiene un enlace simbólico~/src/my.proj
, el comando anterior lo moverá a~/src/my.proj
. Podría ser un problema, si lo que quiera hacer después de eso no es independiente del árbol..git
directorio del proyecto .La
man
página degit-config
(bajo Alias ) dice:Entonces, en UNIX puedes hacer:
fuente
.zshrc
, y defino `alias cg =" cd $ (git root) ", la parte $ () se evalúa en el tiempo de origen, y siempre apunta a ~ / dotfiles, ya que ahí es donde está mi zshrc .¿Se
--show-toplevel
ha agregado recientementegit rev-parse
o por qué nadie lo menciona?Desde la
git rev-parse
página del manual:fuente
git-rev-parse
, debido a que su nombre sugiere que se trata de procesar especificaciones de revisión. Por cierto, me gustaría ver ungit --work-tree
trabajo similar agit --exec-path[=<path>]
: "Si no se proporciona ninguna ruta, git imprimirá la configuración actual"; al menos, en mi opinión, sería un lugar lógico para buscar esa característica.root = rev-parse --show-toplevel
en su gitconfig.git config --global alias.root "rev-parse --show-toplevel"
y luegogit root
podrá hacer el trabajogit rev-parse --show-toplevel
funciona cuando lo probé en un submódulo. Imprime el directorio raíz del submódulo git. ¿Qué imprime para ti?--show-cdup
a--show-top-level
en febrero de 2011 (después de que se envió esta respuesta).¿Qué tal "
git rev-parse --git-dir
"?los
--git-dir
opción parece funcionar.Desde la página del manual de git rev-parse :
Puedes verlo en acción en este
git setup-sh
script .Si está en una carpeta de submódulos, con Git> = 2.13 , use :
Si está utilizando
git rev-parse --show-toplevel
, asegúrese de que sea con Git 2.25+ (Q1 2020) .fuente
.git
si ya está en el directorio raíz. (Al menos, lo hace en msysgit.)Para escribir una respuesta simple aquí, para que podamos usar
para hacer el trabajo, simplemente configure su git usando
y luego puede agregar lo siguiente a su
~/.bashrc
:para que puedas usar
cdroot
para ir a la parte superior de tu repositorio.fuente
Si ya estás en el nivel superior o no en un repositorio git
cd $(git rev-parse --show-cdup)
te llevará a casa (solo cd).cd ./$(git rev-parse --show-cdup)
es una forma de arreglar eso.fuente
cd "$(git rev-parse --show-cdup)"
. Esto funciona porquecd ""
no te lleva a ningún lado, en lugar de regresar$HOME
. Y es una buena práctica citar las invocaciones de $ () de todos modos, en caso de que generen algo con espacios (sin embargo, este comando no lo hará en este caso).$PWD
. Este ejemplo resolverá la raíz de git en$PWD
lugar derealpath $PWD
.Para calcular la ruta absoluta del directorio raíz git actual, digamos para usar en un script de shell, use esta combinación de readlink y git rev-parse:
git-rev-parse --show-cdup
le da el número correcto de ".." para llegar a la raíz desde su cwd, o la cadena vacía si está en la raíz. Luego anteponga "./" para tratar el caso de cadena vacía y usereadlink -f
para traducir a una ruta completa.También puede crear un
git-root
comando en su RUTA como un script de shell para aplicar esta técnica:(Lo anterior se puede pegar en un terminal para crear git-root y establecer bits de ejecución; el script real está en las líneas 2, 3 y 4.)
Y luego podrás correr
git root
para obtener la raíz de tu árbol actual. Tenga en cuenta que en la secuencia de comandos del shell, use "-e" para hacer que el shell salga si el rev-parse falla, de modo que pueda obtener correctamente el estado de salida y el mensaje de error si no está en un directorio git.fuente
"$(git rev-parse ...)"
lugar de hacks como./$(git rev-parse ...)
.readlink -f
no funciona igual en BSD. Vea este SO para soluciones alternativas. La respuesta Python probablemente funcionará sin instalar nada:python -c 'import os, sys; print(os.path.realpath(sys.argv[1]))' "$(git rev-parse --show-cdup)"
.Como otros han señalado, el núcleo de la solución es usar
git rev-parse --show-cdup
. Sin embargo, hay algunos casos extremos para abordar:Cuando cwd ya es la raíz del árbol de trabajo, el comando produce una cadena vacía.
En realidad, produce una línea vacía, pero la tira de sustitución de comando se separa del salto de línea final. El resultado final es una cadena vacía.
La mayoría de las respuestas sugieren anteponer la salida
./
para que una salida vacía se convierta"./"
antes de alimentarlacd
.Cuando GIT_WORK_TREE se establece en una ubicación que no es la principal del cwd, la salida puede ser una ruta absoluta.
Pretender
./
está mal en esta situación. Si a./
se antepone a una ruta absoluta, se convierte en una ruta relativa (y solo se refieren a la misma ubicación si cwd es el directorio raíz del sistema).La salida puede contener espacios en blanco.
Esto realmente solo se aplica en el segundo caso, pero tiene una solución fácil: use comillas dobles alrededor de la sustitución de comandos (y cualquier uso posterior del valor).
Como han señalado otras respuestas, podemos hacerlo
cd "./$(git rev-parse --show-cdup)"
, pero esto se rompe en el segundo caso de borde (y el tercer caso de borde si dejamos las comillas dobles).Muchos shells se tratan
cd ""
como no operativos, por lo que para esos shells podríamos hacercd "$(git rev-parse --show-cdup)"
(las comillas dobles protegen la cadena vacía como argumento en el primer caso de borde y preservan los espacios en blanco en el tercer caso de borde). POSIX dice el resultado decd ""
no está especificado, por lo que puede ser mejor evitar hacer esta suposición.Una solución que funciona en todos los casos anteriores requiere una prueba de algún tipo. Hecho explícitamente, podría verse así:
No
cd
se hace para el primer caso de borde.Si es aceptable ejecutar
cd .
para el primer caso límite, entonces el condicional se puede hacer en la expansión del parámetro:fuente
git root
' que usa la respuesta anterior?En caso de que si está alimentando este camino al Git en sí, use
:/
fuente
Soluciones cortas que funcionan con submódulos, en ganchos y dentro del
.git
directorioAquí está la respuesta corta que la mayoría querrá:
Esto funcionará en cualquier parte de un árbol de trabajo de git (incluso dentro del
.git
directorio), pero supone que se llama a los directorios del repositorio.git
(que es el valor predeterminado). Con submódulos, esto irá a la raíz del repositorio que contiene más externo.Si desea llegar a la raíz del submódulo actual, use:
Para ejecutar fácilmente un comando en la raíz de su submódulo, debajo
[alias]
de su.gitconfig
, agregue:Esto te permite hacer fácilmente cosas como
git sh ag <string>
Solución robusta que admite directorios
.git
o nombres diferentes o externos$GIT_DIR
.Tenga en cuenta que
$GIT_DIR
puede apuntar a algún lugar externo (y no ser llamado.git
), de ahí la necesidad de una mayor verificación.Pon esto en tu
.bashrc
:Ejecutarlo mediante la tipificación
git_root
(después de reiniciar el shell:exec bash
)fuente
(root=$(git rev-parse --git-dir)/ && cd ${root%%/.git/*} && git rev-parse && pwd)
pero esto no cubre los correos electrónicos externos$GIT_DIR
que se nombran de otra manera.git
Para enmendar la respuesta "git config" solo un poco:
y limpiar el camino. Muy agradable.
fuente
Si está buscando un buen alias para hacer esto y no explotar
cd
si no está en un directorio git:fuente
git-extras
agrega
$ git root
ver https://github.com/tj/git-extras/blob/master/Commands.md#git-root
Disponibilidad de git-extras
$ brew install git-extras
$ apt-get install git-extras
fuente
Este alias de shell funciona tanto si está en un subdirectorio git como en el nivel superior:
actualizado para usar la sintaxis moderna en lugar de backticks:
fuente
Todo lo demás falla en algún momento, ya sea yendo al directorio de inicio o simplemente fallando miserablemente. Esta es la forma más rápida y rápida de volver al GIT_DIR.
fuente
$GIT_DIR
se separa del.git
árbol de trabajo usando -Files ygitdir: SOMEPATH
. En consecuencia, esto también falla para los submódulos, donde$GIT_DIR
contiene.git/modules/SUBMODULEPATH
.Aquí hay un script que he escrito que maneja ambos casos: 1) repositorio con un espacio de trabajo, 2) repositorio desnudo.
https://gist.github.com/jdsumsion/6282953
git-root
(archivo ejecutable en su ruta):Espero que esto sea útil.
fuente
git exec
idea es más útil en repositorios no descubiertos. Sin embargo, este script en mi respuesta maneja el caso desnudo versus no desnudo correctamente, lo que podría ser útil para alguien, así que dejo esta respuesta aquí.git submodule
s donde$GIT_DIR
contiene algo como/.git/modules/SUBMODULE
. También supone que el.git
directorio es parte del árbol de trabajo en el caso no desnudo.fuente
[alias] findroot = "!f () { [[ -d ".git" ]] && echo "Found git in [
pwd]" && exit 0; cd .. && echo "IN
pwd" && f;}; f"
git config --global alias.root '!pwd'
funciona. No pude detectar ningún caso en el que actúe de manera diferente a la variante no global. (Unix, git 1.7.10.4) Por cierto: sefindroot
requiere/.git
para evitar una recursión sin fin.Desde Git 2.13.0 , admite una nueva opción para mostrar la ruta del proyecto raíz, que funciona incluso cuando se utiliza desde un submódulo:
fuente
Alias de Shell preconfigurados en Frameworks de Shell
Si usa un marco de shell, es posible que ya haya un alias de shell disponible:
$ grt
en oh-my-zsh (68k) (cd $(git rev-parse --show-toplevel || echo ".")
)$ git-root
en prezto (8.8k) (muestra la ruta a la raíz del árbol de trabajo)$ g..
zimfw (1k) (cambia el directorio actual al nivel superior del árbol de trabajo).fuente
Quería ampliar el excelente comentario de Daniel Brockman.
La definición le
git config --global alias.exec '!exec '
permite hacer cosas comogit exec make
porque, comoman git-config
dice:También es útil saber que
$GIT_PREFIX
será la ruta al directorio actual en relación con el directorio de nivel superior de un repositorio. Pero, sabiendo que es solo la mitad de la batalla ™. La expansión variable de Shell hace que sea bastante difícil de usar. Entonces sugiero usarbash -c
así:Otros comandos incluyen:
fuente
En caso de que alguien necesite una forma de hacer esto compatible con POSIX, sin necesidad de
git
ejecutable:git-root
:Si solo desea la funcionalidad como parte de un script, elimine el shebang y reemplace la última
git_root_recurse_parent
línea con:fuente
if
Se suponía que declaración verificaría si ha cambiado el directorio en la recursividad. Si permanece en el mismo directorio, se supone que está atascado en algún lugar (p/
. Ej. ) Y frena la recursividad. El error está solucionado y ahora debería funcionar como se esperaba. Gracias por mencionarlo.Tuve que resolver esto yo mismo hoy. Lo resolvió en C # ya que lo necesitaba para un programa, pero supongo que puede reescribirse fácilmente. Considere este dominio público.
fuente