git --git-dir não está funcionando como esperado

209

Estou tentando executar o git a partir de um diretório diferente do que estou. Por exemplo, se estou em:

cd /home/domain/
git status << runs perfect ie
# On branch master
# Your branch is ahead of 'origin/master' by 6 commits.

Então agora eu quero executar este comando de um diretório diferente usando a --git-diropção

Então, digamos que estou dentro root/e tente o seguinte:

git --git-dir="/home/domain/" status
## Error 
fatal: Not a git repository: '/home/domain/'

Eu também tentei incluir a .gitpasta ie

git --git-dir="/home/domain/.git/" status

Mas parece que ele está tentando executar o git a partir da raiz, ou seja, excluindo tudo da minha pasta de domínio e adicionando tudo na raiz.

Espero que alguém possa aconselhar sobre o que estou fazendo de errado.

Lee
fonte
4
Agora eu tenho o status funcionando perfeitamente, mas o pull está dando erros. root @ erx [/] # git --git-dir = / home / domínio / .git --work-tree = / home / domain / pull mestre mestre de origem fatal: / usr / local / libexec / git-core / git -pull não pode ser usado sem uma árvore de trabalho. Mas o status funciona? quaisquer ideias Jon
Lee
4
Este é o maior bug do git no momento. Não respeitando os parâmetros --work-tree e / ou --git-dir.
Adam Dymitruk
5
Iniciando o git 1.8.5, você terá a opção de não definir --git-dire, --work-treepara um comando simples: veja minha resposta abaixo
VonC:

Respostas:

314

Você também precisa definir o diretório de trabalho. Confuso, eu sei, mas é uma coisa de flexibilidade.

git --git-dir=/mycode/.git --work-tree=/mycode status

Você pode ler um pouco mais aqui

Jon Gretar
fonte
3
Graças isso funcionou! Concordou que isso é confuso. É chamado de Keep It Simple Stupid. Você quase sempre pode permitir flexibilidade e, ao mesmo tempo, fornecer padrões que fazem mais sentido que o VS ter um comando não funcione.
Não
3
@ Nick concordou, você pensaria que se --git-dirnão fosse especificado, iria verificar se /mycode/.gitexistia e usá-lo antes de gerar um erro.
GP89
4
@NickYeates destacado! Também eu tive um problema ao utilizar ~ para se referir ao meu diretório home, por exemplo git --git-dir=~/src/s3cmd/.git --work-tree=~/src/s3cmd pullnão funcionou, mas git --git-dir=/home/username/src/s3cmd/.git --work-tree=/home/username/src/s3cmd pullfez
Jamie Cook
1
Observe que nem todos os comandos requerem a árvore de trabalho, por exemplo, "git --git-dir = / mycode / .git log" funciona bem. Concordou que isso é confuso!
yoyo
4
Pouco esclarecimento: git --git-dir="$HOME/foo/.git" --work-tree="$HOME/foo" status
Haris Krajina
136

Iniciando o git 1.8.5 (que deve sair na próxima semana), será ainda mais simples:

 git -C "/home/domain/" status

Não há necessidade de definir --git-dire --work-treemais!


Veja commit 44e1e4 de Nazri Ramliy :

É necessário mais pressionamentos de tecla para chamar o comando git em um diretório diferente sem sair do diretório atual:

  1. (cd ~/foo && git status)
    git --git-dir=~/foo/.git --work-dir=~/foo status
    GIT_DIR=~/foo/.git GIT_WORK_TREE=~/foo git status
  2. (cd ../..; git grep foo)
  3. for d in d1 d2 d3; do (cd $d && git svn rebase); done

Os métodos mostrados acima são aceitáveis ​​para scripts, mas são muito pesados ​​para chamadas rápidas da linha de comando.

Com esta nova opção, o acima pode ser feito com menos pressionamentos de tecla:

  1. git -C ~/foo status
  2. git -C ../.. grep foo
  3. for d in d1 d2 d3; do git -C $d svn rebase; done
VonC
fonte
4
Eu tenho tropeçou tentando usar a bandeira -C após o comando git (por exemplo, git status -C <path>não vai funcionar!)
Kedar Paranjape
42

Com base no seu comentário acima, parece que você ainda está com um problema:

root @ erx [/] # git --git-dir = / home / domínio / .git --work-tree = / home / domínio / pull mestre de origem
fatal: / usr / local / libexec / git-core / git-pull não pode ser usado sem uma árvore de trabalho

Parece que você pretende executar isso crontabou algo assim. Pode ser melhor usar cdpara alternar primeiro para o seu diretório de trabalho. Por exemplo:

root @ erx [/] # (cd / home / domain && git pull mestre de origem)

Isso temporariamente (em um subshell, que é o que os parênteses fazem) altera o diretório atual para /home/domaine depois é executado git pull origin master. Após a conclusão do comando, seu diretório atual permanece o que era antes do comando.

Greg Hewgill
fonte
Usar um subshell é simples e elegante. Não sei por que não pensei nisso antes!
Ehtesh Choudhury
Desculpe @Greg, votou na outra resposta de Jon, pois respondeu à pergunta - mas acho que você está no ponto de identificar e responder à intenção e à sua percepção, ou seja, o () s, é exatamente o que eu estava procurando +10
Darren Bishop
1
git --git-dir="/home/domain/" status
## Error 
fatal: Not a git repository: '/home/domain/'

Com o Git 2.26 (primeiro trimestre de 2020), a documentação é mais clara.

Um efeito de especificar onde GIT_DIRestá (com a variável de ambiente ou com a git --git-dir=<where> cmdopção " ") é desativar a descoberta do repositório .

Isso causou um pouco mais de estresse na documentação, pois os novos usuários geralmente ficam confusos.

Veja commit d82ad54 (30 de janeiro de 2020) por Heba Waly ( HebaWaly) .
(Mesclado por Junio ​​C Hamano - gitster- no commit 17e4a1b , 12 de fevereiro de 2020)

git: atualizar documentação para --git-dir

Assinado por: Heba Waly
Ajudado por: Junio ​​C Hamano

git --git-dir <path> é um pouco confuso e às vezes não funciona como o usuário esperaria.

Por exemplo, se o usuário executar git --git-dir=<path> status, o git ignorará o algoritmo de descoberta do repositório e atribuirá a árvore de trabalho ao diretório de trabalho atual do usuário, a menos que especificado de outra forma.
Quando essa atribuição está errada, a saída não corresponde às expectativas do usuário.

Este patch atualiza a documentação para torná-la mais clara.

Portanto, a documentação dogit --git-dir momento inclui:

--git-dir=<path>:

Defina o caminho para o repositório (".git " diretório).
Isso também pode ser controlado pela configuração da GIT_DIRvariável de ambiente.
Pode ser um caminho absoluto ou relativo ao diretório de trabalho atual.

Especificando a localização do ".git diretório " usando esta opção (ou GIT_DIRvariável de ambiente) desativa a descoberta do repositório que tenta encontrar um diretório com o .gitsubdiretório " " (como é descoberto o repositório e o nível superior da árvore de trabalho), e diz ao Git que você está no nível superior da árvore de trabalho.

Se você não estiver no diretório de nível superior da árvore de trabalho, informe ao Git onde está o nível superior da árvore de trabalho, com a --work-tree=<path>opção (ou GIT_WORK_TREEvariável de ambiente)

VonC
fonte