git --git-dir ne fonctionne pas comme prévu

209

J'essaie d'exécuter git à partir d'un répertoire différent de celui dans lequel je suis. Donc, par exemple, si je suis dans:

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

Alors maintenant, je veux exécuter cette commande à partir d'un répertoire différent en utilisant l' --git-diroption.

Disons donc que je suis dedans root/et essayez ceci:

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

J'ai aussi essayé d'inclure le .gitdossier ie

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

Mais cela ressemble à essayer de lancer git à partir de la racine, c'est-à-dire tout supprimer de mon dossier de domaine et ajouter tout à la racine.

J'espère que quelqu'un pourra vous conseiller sur ce que je fais mal.

Lee
la source
4
Maintenant, mon statut fonctionne parfaitement, mais tirer donne des erreurs. ie root @ erx [/] # git --git-dir = / home / domain / .git --work-tree = / home / domain / pull origin master fatal: / usr / local / libexec / git-core / git -pull ne peut pas être utilisé sans un arbre de travail. Mais le statut fonctionne ?? des idées Jon
Lee
4
C'est le plus gros bug de git en ce moment. Ne respecte pas les paramètres --work-tree et / ou --git-dir.
Adam Dymitruk
5
À partir de git 1.8.5, vous aurez le choix de ne pas définir --git-diret --work-treepour une commande simple: voir ma réponse ci
VonC

Réponses:

315

Vous devez également définir le répertoire de travail. Je suis confus, mais c'est une question de flexibilité.

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

Vous pouvez en lire un peu plus ici

Jon Gretar
la source
3
Merci, cela a fonctionné! Convient que cela prête à confusion. Son appelé Keep It Simple Stupid. Vous pouvez presque toujours permettre la flexibilité tout en donnant des valeurs par défaut qui ont le plus de sens VS ayant une commande ne fonctionne pas du tout.
Nay
3
@Nick a accepté, vous penseriez que s'il --git-dirn'était pas spécifié, il vérifierait s'il /mycode/.gitexistait et l'utiliserait avant de générer une erreur.
GP89
4
@NickYeates a appuyé! J'ai également eu un problème lors de l'utilisation de ~ pour faire référence à mon répertoire personnel, par exemple, git --git-dir=~/src/s3cmd/.git --work-tree=~/src/s3cmd pulln'a pas fonctionné mais l'a git --git-dir=/home/username/src/s3cmd/.git --work-tree=/home/username/src/s3cmd pullfait
Jamie Cook
1
Notez que toutes les commandes ne nécessitent pas l'arborescence de travail, par exemple, "git --git-dir = / mycode / .git log" fonctionne correctement. D'accord sur le fait que cela soit déroutant!
yoyo
4
Petite précision: git --git-dir="$HOME/foo/.git" --work-tree="$HOME/foo" status
Haris Krajina
136

À partir de git 1.8.5 (qui devrait sortir la semaine prochaine), ce sera encore plus simple:

 git -C "/home/domain/" status

Plus besoin de régler --git-diret --work-treeplus!


Voir commit 44e1e4 de Nazri Ramliy :

Il faut plus de touches pour appeler la commande git dans un répertoire différent sans quitter le répertoire courant:

  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

Les méthodes indiquées ci-dessus sont acceptables pour les scripts mais sont trop lourdes pour des appels rapides en ligne de commande.

Avec cette nouvelle option, ce qui précède peut être fait avec moins de frappes:

  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
la source
4
J'ai fait trébucher en essayant d'utiliser le drapeau -C après la commande git (par exemple, ça git status -C <path>ne fonctionnera pas!)
Kedar Paranjape
42

Sur la base de votre commentaire ci-dessus, il semble que vous rencontrez toujours un problème:

root @ erx [/] # git --git-dir = / home / domain / .git --work-tree = / home / domain / pull origin master
fatal: / usr / local / libexec / git-core / git-pull ne peut pas être utilisé sans une arborescence de travail

Il semble que vous ayez l'intention d'exécuter ceci à partir de crontabquelque chose. Il vaut mieux utiliser d'abord cdpour basculer vers votre répertoire de travail. Par exemple:

root @ erx [/] # (cd / home / domain && git pull origin master)

Cela va temporairement (dans un sous-shell, ce que font les parenthèses) changer le répertoire en cours /home/domain, puis exécuter git pull origin master. Une fois la commande terminée, votre répertoire actuel reste ce qu'il était avant la commande.

Greg Hewgill
la source
L'utilisation d'un sous-shell est simple et élégante. Je ne sais pas pourquoi je n'y avais pas pensé avant!
Ehtesh Choudhury
Désolé @Greg, a voté l'autre réponse de Jon car elle a répondu à la question posée - mais je pense que vous êtes sur le point de repérer et de répondre à l'intention et à votre perspicacité, c'est-à-dire les () s, c'est exactement ce que je cherchais +10
Darren Bishop
1
git --git-dir="/home/domain/" status
## Error 
fatal: Not a git repository: '/home/domain/'

Avec Git 2.26 (T1 2020), la documentation est plus claire.

L'un des effets de la spécification de l'emplacement GIT_DIR(avec la variable d'environnement ou l' git --git-dir=<where> cmdoption " ") est de désactiver la découverte du référentiel .

Cela a été placé un peu plus de stress dans la documentation, car les nouveaux utilisateurs sont souvent confus.

Voir commit d82ad54 (30 janvier 2020) par Heba Waly (HebaWaly ) .
(Fusionné par Junio ​​C Hamano - gitster- en commit 17e4a1b , 12 fév 2020)

git: mise à jour de la documentation de --git-dir

Signé par: Heba Waly
Aidé par: Junio ​​C Hamano

git --git-dir <path> est un peu déroutant et parfois ne fonctionne pas comme l'utilisateur s'y attendrait.

Par exemple, si l'utilisateur s'exécute git --git-dir=<path> status, git ignorera l'algorithme de découverte du référentiel et affectera l'arborescence de travail au répertoire de travail actuel de l'utilisateur, sauf indication contraire.
Lorsque cette affectation est incorrecte, la sortie ne correspondra pas aux attentes de l'utilisateur.

Ce correctif met à jour la documentation pour la rendre plus claire.

Alors le documentation pour l'git --git-dir instant comprend:

--git-dir=<path>:

Définissez le chemin d'accès au référentiel (".git ").
Cela peut également être contrôlé en définissant la GIT_DIRvariable d'environnement.
Il peut s'agir d'un chemin absolu ou d'un chemin relatif vers le répertoire de travail actuel.

Spécification de l'emplacement du ".git répertoire " à l' aide de cette option (ou GIT_DIRvariable d'environnement) désactive la découverte du référentiel qui essaie de trouver un répertoire avec le .gitsous-répertoire " " (c'est ainsi que le référentiel et le niveau supérieur de l'arborescence de travail sont découverts), et indique à Git que vous êtes au niveau supérieur de l'arborescence de travail.

Si vous n'êtes pas dans le répertoire de niveau supérieur de l'arborescence de travail, vous devez indiquer à Git où se trouve le niveau supérieur de l'arborescence de travail, avec l' --work-tree=<path>option (ou GIT_WORK_TREEla variable d'environnement)

VonC
la source