tener - git: un comando rápido para ir a la raíz del árbol de trabajo
¿qué hace git log-oneline? (7)
Desafortunadamente, cambiar el directorio actual solo puede ser realizado por el shell, no por ningún subproceso. Para cuando Git comienza a analizar tu comando, ya es demasiado tarde: ya se ha generado git en un proceso separado.
Aquí hay una función de shell realmente no comprobada que puede hacer lo que quiera:
function git() {
if [ "$1" == "root" ]; then
git-root
else
git "$@"
fi
}
Quería un comando simple de git para ir a la "raíz" del repositorio.
Empecé con un script, pero pensé que no podía cambiar el directorio activo del shell, tenía que hacer una función. Desafortunadamente, no puedo llamarlo directamente con el formulario "git root" que no es un tablero, por ejemplo.
function git-root() {
if [ -d .git ]; then
return 0
fi
A=..
while ! [ -d $A/.git ]; do
A="$A/.."
done
cd $A
}
¿Tienes una mejor solución? (la función se ha escrito rápidamente, las sugerencias son bienvenidas)
Esto se ha preguntado antes, ¿hay alguna manera de obtener el directorio raíz de git en un comando? Copiando la respuesta de @ docgnome y modificando ligeramente usando la sugerencia de @George (para ocuparse de Edge Case cuando se encuentre en el directorio raíz):
cd $(git rev-parse --show-toplevel)
Haga un alias si lo desea:
alias git-root=''cd $(git rev-parse --show-toplevel)''
La respuesta de Pedro arriba funciona muy bien si estás en un subdirectorio de la raíz de git. Si ya estás en la raíz de git, te devolverá a $ HOME. Para evitar esto, podemos usar algunos condicionales de bash.
if [ "`git rev-parse --show-cdup`" != "" ]; then cd `git rev-parse --show-cdup`; fi
entonces el alias se convierte en:
alias git-root=''if [ "`git rev-parse --show-cdup`" != "" ]; then cd `git rev-parse --show-cdup`; fi''
Más simple aún, robar de ¿Hay alguna manera de obtener el directorio raíz de git en un comando? y crea un alias (como sugiere Peter) de
cd "$ (git rev-parse --show-toplevel)"
Esto funciona ya sea que estés en el directorio raíz o no.
Un mejor alias que trabaja en bash y zsh es:
alias git-root=''cd "$(git rev-parse --show-cdup)"''
Soluciones breves que funcionan con submódulos, en ganchos y dentro del directorio .git
Aquí está la respuesta corta que la mayoría querrá:
r=$(git rev-parse --git-dir) && r=$(cd "$r" && pwd)/ && cd "${r%%/.git/*}"
Esto funcionará en cualquier parte de un árbol de trabajo de git (incluso dentro del directorio .git
), pero supone que los directorios del repositorio se llaman .git
(que es el predeterminado). Con los submódulos, esto irá a la raíz del depósito que contiene más externo.
Si desea llegar a la raíz del submódulo actual, use:
cd ''''$(r=$(git rev-parse --show-toplevel) && [[ -n $r ]] && echo "$r" || (cd $(git rev-parse --git-dir)/.. && pwd) )
Para ejecutar fácilmente un comando en la raíz de su submódulo, debajo de [alias]
en su .gitconfig
, agregue:
sh = "!f() { root=$(pwd)/ && cd ${root%%/.git/*} && git rev-parse && exec /"$@/"; }; f"
Esto le permite hacer cosas fácilmente como git sh ag <string>
Solución robusta que admite directorios .git
o $GIT_DIR
nombre diferente o externos.
Tenga en cuenta que $GIT_DIR
puede apuntar a un lugar externo (y no llamarse .git
), de ahí la necesidad de una verificación posterior.
Pon esto en tu .bashrc
:
# Print the name of the git working tree''s root directory
function git_root() {
local root first_commit
# git displays its own error if not in a repository
root=$(git rev-parse --show-toplevel) || return
if [[ -n $root ]]; then
echo $root
return
elif [[ $(git rev-parse --is-inside-git-dir) = true ]]; then
# We''re inside the .git directory
# Store the commit id of the first commit to compare later
# It''s possible that $GIT_DIR points somewhere not inside the repo
first_commit=$(git rev-list --parents HEAD | tail -1) ||
echo "$0: Can''t get initial commit" 2>&1 && false && return
root=$(git rev-parse --git-dir)/.. &&
# subshell so we don''t change the user''s working directory
( cd "$root" &&
if [[ $(git rev-list --parents HEAD | tail -1) = $first_commit ]]; then
pwd
else
echo "$FUNCNAME: git directory is not inside its repository" 2>&1
false
fi
)
else
echo "$FUNCNAME: Can''t determine repository root" 2>&1
false
fi
}
# Change working directory to git repository root
function cd_git_root() {
local root
root=$(git_root) || return # git_root will print any errors
cd "$root"
}
cd_git_root
escribiendo cd_git_root
(después de reiniciar su shell: exec bash
)
$ git config alias.root ''!pwd''
$ git root