O Mercurial tem uma maneira de imprimir o diretório raiz (que contém .hg) via
hg root
Existe algo equivalente no git para obter o diretório que contém o diretório .git?
git
version-control
wojo
fonte
fonte
bzr root
foi usado muito em Bazaargit rev-parse --git-dir
, conforme explicado neste comentárioRespostas:
Sim:
Se você deseja replicar o comando Git mais diretamente, é possível criar um alias :
e agora
git root
funcionará exatamente comohg root
.Nota : Em um submódulo, isso exibirá o diretório raiz do submódulo e não o repositório pai. Se você estiver usando Git> = 2.13 ou superior, existe uma maneira de os submódulos mostrarem o diretório raiz do superprojeto. Se o seu git for mais antigo que isso, veja esta outra resposta.
fonte
git config --global alias.exec '!exec '
para que eu possa fazer coisas comogit exec make
. Isso funciona porque os aliases do shell são sempre executados no diretório de nível superior.hg root
faz. Ele imprime o diretório de nível superior do seu repositório com check-out. Ele não muda para você (e na verdade não podia fazê-lo por causa de como todo o conceito de diretório atual e seu shell interagem).~/my.proj/foo/bar
e~/my.proj
estiver vinculado a~/src/my.proj
, o comando acima o levará a~/src/my.proj
. Pode ser um problema, se o que você quiser fazer depois disso não for independente da árvore..git
diretório do projeto .A
man
página paragit-config
(em Alias ) diz:Portanto, no UNIX, você pode:
fonte
.zshrc
e definir `alias cg =" cd $ (git root) ", a parte $ () é avaliada no momento da fonte e sempre aponta para ~ / dotfiles, pois é onde meu zshrc está .Foi
--show-toplevel
adicionado recentementegit rev-parse
ou por que ninguém menciona isso?Na
git rev-parse
página do manual:fonte
git-rev-parse
- por causa do nome que sugere que se trata do processamento de especificações de revisão. Aliás, ficaria feliz em ver umgit --work-tree
trabalho semelhante agit --exec-path[=<path>]
: "Se nenhum caminho for fornecido, o git imprimirá a configuração atual"; pelo menos, na IMO, seria um lugar lógico para procurar esse recurso.root = rev-parse --show-toplevel
criar um alias no seu gitconfig.git config --global alias.root "rev-parse --show-toplevel"
e, em seguida,git root
será capaz de fazer o trabalhogit rev-parse --show-toplevel
funciona quando eu tentei em um submódulo. Ele imprime o diretório raiz do submódulo git. O que é impresso para você?--show-cdup
até--show-top-level
fevereiro de 2011 (após o envio dessa resposta).Que tal "
git rev-parse --git-dir
"?o
--git-dir
opção parece funcionar.Na página de manual do git rev-parse :
Você pode vê-lo em ação neste
git setup-sh
script .Se você estiver em uma pasta de submódulo, com Git> = 2.13 , use :
Se você estiver usando
git rev-parse --show-toplevel
, verifique se está com o Git 2.25+ (primeiro trimestre de 2020) .fonte
.git
se você já estiver no diretório raiz. (Pelo menos, ele faz sobre msysgit.)Para escrever uma resposta simples aqui, para que possamos usar
para fazer o trabalho, basta configurar seu git usando
e você pode adicionar o seguinte ao seu
~/.bashrc
:para que você possa usar apenas
cdroot
para ir para o topo do seu repo.fonte
Se você já está no nível superior ou não em um repositório git
cd $(git rev-parse --show-cdup)
, você será levado para casa (apenas cd).cd ./$(git rev-parse --show-cdup)
é uma maneira de consertar isso.fonte
cd "$(git rev-parse --show-cdup)"
. Isso funciona porquecd ""
você não leva a lugar algum, em vez de voltar$HOME
. E é uma boa prática citar invocações $ () de qualquer maneira, caso elas produzam algo com espaços (embora não seja esse comando nesse caso).$PWD
. Este exemplo resolverá a raiz do git em relação a em$PWD
vez derealpath $PWD
.Para calcular o caminho absoluto do diretório raiz atual do git, digamos para uso em um script de shell, use esta combinação de readlink e git rev-parse:
git-rev-parse --show-cdup
fornece o número certo de ".." s para obter a raiz do seu cwd ou a string vazia, se você estiver na raiz. Em seguida, acrescente "./" para lidar com a caixa de cordas vazia e usereadlink -f
para traduzir para um caminho completo.Você também pode criar um
git-root
comando no seu PATH como um script de shell para aplicar esta técnica:(O acima pode ser colado em um terminal para criar git-root e definir bits de execução; o script real está nas linhas 2, 3 e 4.)
E então você poderá executar
git root
para obter a raiz da sua árvore atual. Observe que, no script do shell, use "-e" para fazer com que o shell seja encerrado se a análise de revisão falhar, para que você possa obter corretamente o status de saída e a mensagem de erro se não estiver em um diretório git.fonte
"$(git rev-parse ...)"
vez de hacks como./$(git rev-parse ...)
.readlink -f
não funciona da mesma maneira no BSD. Veja este SO para soluções alternativas. A resposta Python provavelmente irá funcionar sem instalar nada:python -c 'import os, sys; print(os.path.realpath(sys.argv[1]))' "$(git rev-parse --show-cdup)"
.Como outros observaram, o núcleo da solução é usar
git rev-parse --show-cdup
. No entanto, existem alguns casos extremos a serem abordados:Quando o cwd já é a raiz da árvore de trabalho, o comando gera uma sequência vazia.
Na verdade, ele produz uma linha vazia, mas a substituição de comando retira a quebra de linha à direita. O resultado final é uma sequência vazia.
A maioria das respostas sugere anexar a saída de
./
forma que uma saída vazia se torne"./"
antes de ser alimentadacd
.Quando GIT_WORK_TREE é definido como um local que não é o pai do cwd, a saída pode ser um nome de caminho absoluto.
Anexar
./
está errado nessa situação. Se a./
é anexado a um caminho absoluto, ele se torna um caminho relativo (e eles se referem apenas ao mesmo local se o cwd for o diretório raiz do sistema).A saída pode conter espaço em branco.
Isso realmente se aplica apenas no segundo caso, mas tem uma solução fácil: use aspas duplas em torno da substituição do comando (e qualquer uso subsequente do valor).
Como outras respostas observaram, podemos fazê-lo
cd "./$(git rev-parse --show-cdup)"
, mas isso ocorre no segundo caso de aresta (e no terceiro caso de aresta se deixarmos de aspas duplas).Muitos shells são tratados
cd ""
como não-op, portanto, para aqueles shells que poderíamos fazercd "$(git rev-parse --show-cdup)"
(as aspas duplas protegem a string vazia como argumento no primeiro caso de aresta e preservam espaço em branco no terceiro caso de aresta). POSIX diz que o resultado decd ""
não é especificado, portanto, é melhor evitar fazer essa suposição.Uma solução que funcione em todos os casos acima requer algum tipo de teste. Feito explicitamente, pode ser assim:
Não
cd
é feito o primeiro caso de borda.Se for aceitável executar
cd .
para o primeiro caso de borda, o condicional poderá ser feito na expansão do parâmetro:fonte
git root
' que a resposta acima usa?Caso você esteja alimentando esse caminho para o próprio Git, use
:/
fonte
Soluções curtas que funcionam com submódulos, em ganchos e dentro do
.git
diretórioAqui está a resposta curta que a maioria deseja:
Isso funcionará em qualquer lugar da árvore de trabalho do git (inclusive dentro do
.git
diretório), mas pressupõe que os diretórios do repositório sejam chamados.git
(que é o padrão). Com os submódulos, isso irá para a raiz do repositório externo.Se você deseja chegar à raiz do submódulo atual, use:
Para executar facilmente um comando em sua raiz do submódulo,
[alias]
em sua.gitconfig
, adicione:Isso permite que você faça facilmente coisas como
git sh ag <string>
Solução robusta que suporta diretórios
.git
ou nomes diferentes ou externos$GIT_DIR
.Observe que
$GIT_DIR
pode apontar para algum lugar externo (e não ser chamado.git
), daí a necessidade de uma verificação adicional.Coloque isso no seu
.bashrc
:Executá-lo digitando
git_root
(depois de reiniciar o shell:exec bash
)fonte
(root=$(git rev-parse --git-dir)/ && cd ${root%%/.git/*} && git rev-parse && pwd)
mas isso não cobre$GIT_DIR
s externos com nomes diferentes de.git
Para alterar a resposta "git config" um pouco:
e limpe o caminho. Muito agradável.
fonte
Se você está procurando um bom alias para fazer isso e não exploda
cd
se não estiver em um dir git:fonte
git-extras
adiciona
$ git root
consulte https://github.com/tj/git-extras/blob/master/Commands.md#git-root
Disponibilidade de git-extras
$ brew install git-extras
$ apt-get install git-extras
fonte
Esse alias do shell funciona se você estiver em um subdiretório git ou no nível superior:
atualizado para usar a sintaxe moderna em vez de backticks:
fonte
Todo o resto falha em algum momento, quer ir para o diretório inicial ou apenas falhar miseravelmente. Esta é a maneira mais rápida e mais curta de voltar ao GIT_DIR.
fonte
$GIT_DIR
é desanexado da.git
árvore de trabalho usando -Files egitdir: SOMEPATH
. Consequentemente, isso também falha nos submódulos, onde$GIT_DIR
contém.git/modules/SUBMODULEPATH
.Aqui está um script que eu escrevi que lida com os dois casos: 1) repositório com uma área de trabalho, 2) repositório vazio.
https://gist.github.com/jdsumsion/6282953
git-root
(arquivo executável no seu caminho):Espero que isso seja útil.
fonte
git exec
idéia é mais útil em repositórios não-nua. No entanto, esse script na minha resposta lida corretamente com o caso simples versus o não básico, o que pode ser útil para alguém, então estou deixando essa resposta aqui.git submodule
s onde$GIT_DIR
contém algo parecido/.git/modules/SUBMODULE
. Além disso, você assume que o.git
diretório faz parte da árvore de trabalho no caso não vazio.fonte
[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. Não consegui identificar nenhum caso em que ele atue de maneira diferente da variante não global. (Unix, git 1.7.10.4) BTW: Vocêfindroot
requer a/.git
para evitar uma recursão sem fim.Desde o Git 2.13.0 , ele suporta uma nova opção para mostrar o caminho do projeto raiz, que funciona mesmo quando usado dentro de um submódulo:
fonte
Aliases de shell pré-configurados em estruturas de shell
Se você usar uma estrutura de shell, talvez já exista um alias de shell disponível:
$ grt
em oh-my-zsh (68k) (cd $(git rev-parse --show-toplevel || echo ".")
)$ git-root
no prezto (8,8k) (exibe o caminho para a raiz da árvore de trabalho)$ g..
zimfw (1k) (altera o diretório atual para o nível superior da árvore de trabalho.)fonte
Eu queria expandir o excelente comentário de Daniel Brockman.
A definição
git config --global alias.exec '!exec '
permite fazer coisas comogit exec make
porque, comoman git-config
afirma:Também é útil saber que esse
$GIT_PREFIX
será o caminho para o diretório atual em relação ao diretório de nível superior de um repositório. Mas, sabendo que é apenas metade da batalha ™. A expansão de variáveis do Shell torna bastante difícil de usar. Então, eu sugiro usarbash -c
assim:outros comandos incluem:
fonte
Caso alguém precise de uma maneira compatível com POSIX, sem a necessidade de
git
executável:git-root
:Se você deseja apenas a funcionalidade como parte de um script, remova o shebang e substitua a última
git_root_recurse_parent
linha por:fonte
if
statement deveria verificar se você alterou o diretório na recursão. Se ele permanecer no mesmo diretório, assume que você está preso em algum lugar (por exemplo/
) e freia a recursão. O bug foi corrigido e agora deve funcionar como esperado. Obrigado por apontar isso.Hoje tive que resolver isso sozinho. Resolvi em C # conforme eu precisava para um programa, mas acho que ele pode ser reescrito. Considere este domínio público.
fonte