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 rootse 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 rootfuncionará 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 roothace. 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/bary~/my.projtiene 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..gitdirectorio del proyecto .La
manpá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-toplevelha agregado recientementegit rev-parseo por qué nadie lo menciona?Desde la
git rev-parsepá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-treetrabajo 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-toplevelen su gitconfig.git config --global alias.root "rev-parse --show-toplevel"y luegogit rootpodrá hacer el trabajogit rev-parse --show-toplevelfunciona cuando lo probé en un submódulo. Imprime el directorio raíz del submódulo git. ¿Qué imprime para ti?--show-cdupa--show-top-levelen febrero de 2011 (después de que se envió esta respuesta).¿Qué tal "
git rev-parse --git-dir"?los
--git-diropción parece funcionar.Desde la página del manual de git rev-parse :
Puedes verlo en acción en este
git setup-shscript .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
.gitsi 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
cdrootpara 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$PWDlugar 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-cduple 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 -fpara traducir a una ruta completa.También puede crear un
git-rootcomando 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 rootpara 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 -fno 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
cdse 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
.gitdirectorioAquí está la respuesta corta que la mayoría querrá:
Esto funcionará en cualquier parte de un árbol de trabajo de git (incluso dentro del
.gitdirectorio), 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
.gito nombres diferentes o externos$GIT_DIR.Tenga en cuenta que
$GIT_DIRpuede 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_DIRque se nombran de otra manera.gitPara 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
cdsi no está en un directorio git:fuente
git-extrasagrega
$ git rootver https://github.com/tj/git-extras/blob/master/Commands.md#git-root
Disponibilidad de git-extras
$ brew install git-extras$ apt-get install git-extrasfuente
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_DIRse separa del.gitárbol de trabajo usando -Files ygitdir: SOMEPATH. En consecuencia, esto también falla para los submódulos, donde$GIT_DIRcontiene.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 execidea 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 submodules donde$GIT_DIRcontiene algo como/.git/modules/SUBMODULE. También supone que el.gitdirectorio 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 "INpwd" && 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: sefindrootrequiere/.gitpara 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:
$ grten oh-my-zsh (68k) (cd $(git rev-parse --show-toplevel || echo "."))$ git-rooten 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 makeporque, comoman git-configdice:También es útil saber que
$GIT_PREFIXserá 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 -casí:Otros comandos incluyen:
fuente
En caso de que alguien necesite una forma de hacer esto compatible con POSIX, sin necesidad de
gitejecutable:git-root:Si solo desea la funcionalidad como parte de un script, elimine el shebang y reemplace la última
git_root_recurse_parentlínea con:fuente
ifSe 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