Mercurial a un moyen d'imprimer le répertoire racine (qui contient .hg) via
hg root
Y a-t-il quelque chose d'équivalent dans git pour obtenir le répertoire qui contient le répertoire .git?
git
version-control
wojo
la source
la source
bzr root
été beaucoup utilisée dans Bazaargit rev-parse --git-dir
- dessous , comme expliqué dans ce commentaireRéponses:
Oui:
Si vous souhaitez répliquer la commande Git plus directement, vous pouvez créer un alias :
et
git root
fonctionnera maintenant commehg root
.Remarque : dans un sous-module, cela affichera le répertoire racine du sous - module et non le référentiel parent. Si vous utilisez Git> = 2.13 ou supérieur, il existe un moyen pour les sous - modules d'afficher le répertoire racine du superprojet. Si votre git est plus ancien que cela, consultez cette autre réponse.
la source
git config --global alias.exec '!exec '
pour pouvoir faire des choses commegit exec make
. Cela fonctionne car les alias du shell sont toujours exécutés dans le répertoire de niveau supérieur.hg root
fait. Il imprime le répertoire de niveau supérieur de votre référentiel extrait. Il ne vous y fait pas basculer (et il ne pouvait pas, en fait, le faire en raison de l'interaction de l'ensemble du concept de répertoire actuel et de votre shell).~/my.proj/foo/bar
et~/my.proj
auquel vous avez un lien symbolique~/src/my.proj
, la commande ci-dessus vous amènera~/src/my.proj
. Cela pourrait être un problème si tout ce que vous voulez faire après cela n'est pas indépendant de l'arbre..git
répertoire du projet .La
man
page pourgit-config
(sous Alias ) dit:Donc, sous UNIX, vous pouvez faire:
la source
.zshrc
, et je définis `alias cg =" cd $ (racine git) ", la partie $ () est évaluée au moment de la source, et pointe toujours vers ~ / dotfiles, car c'est là que se trouve mon zshrc .A
--show-toplevel
récemment été ajoutégit rev-parse
ou pourquoi personne ne le mentionne?Depuis la
git rev-parse
page de manuel:la source
git-rev-parse
- en raison de son nom suggérant qu'il s'agit de traiter les spécifications de révision. BTW, je serais heureux de voir ungit --work-tree
travail similaire àgit --exec-path[=<path>]
: "Si aucun chemin n'est donné, git imprimera le paramètre actuel"; au moins, OMI, ce serait un endroit logique pour rechercher une telle fonctionnalité.root = rev-parse --show-toplevel
créer un alias dans votre gitconfig.git config --global alias.root "rev-parse --show-toplevel"
et ensuitegit root
vous pourrez faire le travailgit rev-parse --show-toplevel
fonctionne quand je l'ai essayé dans un sous-module. Il affiche le répertoire racine du sous-module git. Qu'est-ce que cela imprime pour vous?--show-cdup
à--show-top-level
en février 2011 (après la soumission de cette réponse).Et "
git rev-parse --git-dir
"?L'
--git-dir
option semble fonctionner.Depuis la page de manuel de git rev-parse :
Vous pouvez le voir en action dans ce
git setup-sh
script .Si vous êtes dans un dossier de sous-module, avec Git> = 2.13 , utilisez :
Si vous utilisez
git rev-parse --show-toplevel
, assurez-vous que c'est avec Git 2.25+ (Q1 2020) .la source
.git
si vous êtes déjà dans le répertoire racine. (Au moins, il le fait sur msysgit.)Pour écrire une réponse simple ici, afin que nous puissions utiliser
pour faire le travail, configurez simplement votre git en utilisant
et puis vous voudrez peut-être ajouter ce qui suit à votre
~/.bashrc
:afin que vous puissiez simplement utiliser
cdroot
pour aller en haut de votre repo.la source
Si vous êtes déjà au niveau supérieur ou pas dans un référentiel git
cd $(git rev-parse --show-cdup)
vous ramènera à la maison (juste un cd).cd ./$(git rev-parse --show-cdup)
est une façon de résoudre ce problème.la source
cd "$(git rev-parse --show-cdup)"
. Cela fonctionne carcd ""
vous ne mène nulle part, plutôt que de revenir$HOME
. Et il est préférable de citer les invocations $ () de toute façon, au cas où ils produiraient quelque chose avec des espaces (pas que cette commande le fasse dans ce cas, cependant).$PWD
. Cet exemple résoudra la racine de git par rapport à$PWD
au lieu derealpath $PWD
.Pour calculer le chemin absolu du répertoire racine git actuel, par exemple pour une utilisation dans un script shell, utilisez cette combinaison de readlink et git rev-parse:
git-rev-parse --show-cdup
vous donne le bon nombre de ".." pour accéder à la racine depuis votre cwd, ou la chaîne vide si vous êtes à la racine. Ajoutez ensuite "./" pour traiter le cas de chaîne vide et utilisezreadlink -f
pour traduire en un chemin complet.Vous pouvez également créer une
git-root
commande dans votre PATH en tant que script shell pour appliquer cette technique:(Ce qui précède peut être collé dans un terminal pour créer git-root et définir des bits d'exécution; le script réel se trouve aux lignes 2, 3 et 4.)
Et puis vous seriez en mesure d'exécuter
git root
pour obtenir la racine de votre arbre actuel. Notez que dans le script shell, utilisez "-e" pour provoquer la fermeture du shell si le rev-parse échoue afin que vous puissiez correctement obtenir l'état de sortie et le message d'erreur si vous n'êtes pas dans un répertoire git.la source
"$(git rev-parse ...)"
au lieu de hacks comme./$(git rev-parse ...)
.readlink -f
ne fonctionne pas de la même manière sur BSD. Voir cet OS pour des solutions de contournement. La réponse Python fonctionnera probablement sans installer quoi que ce soit:python -c 'import os, sys; print(os.path.realpath(sys.argv[1]))' "$(git rev-parse --show-cdup)"
.Comme d'autres l'ont noté, le cœur de la solution est d'utiliser
git rev-parse --show-cdup
. Cependant, il y a quelques cas marginaux à résoudre:Lorsque le cwd est déjà la racine de l'arborescence de travail, la commande renvoie une chaîne vide.
En fait, il produit une ligne vide, mais la substitution de commande supprime la coupure de ligne de fin. Le résultat final est une chaîne vide.
La plupart des réponses suggèrent d'ajouter la sortie de
./
telle sorte qu'une sortie vide devienne"./"
avant d'être alimentéecd
.Lorsque GIT_WORK_TREE est défini sur un emplacement qui n'est pas le parent du cwd, la sortie peut être un chemin d'accès absolu.
La préparation
./
est incorrecte dans cette situation. Si a./
est ajouté à un chemin absolu, il devient un chemin relatif (et ils ne font référence au même emplacement que si le cwd est le répertoire racine du système).La sortie peut contenir des espaces.
Cela ne s'applique vraiment que dans le deuxième cas, mais il a une solution simple: utilisez des guillemets doubles autour de la substitution de commande (et toute utilisation ultérieure de la valeur).
Comme d'autres réponses l'ont noté, nous pouvons le faire
cd "./$(git rev-parse --show-cdup)"
, mais cela casse dans le deuxième cas de bord (et le troisième cas de bord si nous laissons les guillemets doubles).De nombreux shells traitent
cd ""
comme un no-op, donc pour ces shells, nous pourrions le fairecd "$(git rev-parse --show-cdup)"
(les guillemets doubles protègent la chaîne vide comme argument dans le premier cas de bord et préservent les espaces dans le troisième cas de bord). POSIX indique que le résultat decd ""
n'est pas spécifié, il est donc préférable d'éviter de faire cette hypothèse.Une solution qui fonctionne dans tous les cas ci-dessus nécessite un test quelconque. Fait explicitement, cela pourrait ressembler à ceci:
Aucun
cd
n'est fait pour le premier cas de bord.S'il est acceptable d'exécuter
cd .
pour le premier cas de bord, alors le conditionnel peut être fait dans l'expansion du paramètre:la source
git root
' que la réponse ci-dessus utilise?Au cas où si vous alimentez ce chemin vers le Git lui-même, utilisez
:/
la source
Solutions courtes qui fonctionnent avec des sous-modules, dans des crochets et à l'intérieur du
.git
répertoireVoici la réponse courte que la plupart voudront:
Cela fonctionnera n'importe où dans une arborescence de travail git (y compris à l'intérieur du
.git
répertoire), mais suppose que les répertoires du référentiel sont appelés.git
(ce qui est la valeur par défaut). Avec les sous-modules, cela ira à la racine du référentiel contenant le plus à l'extérieur.Si vous souhaitez accéder à la racine de l'utilisation actuelle du sous-module:
Pour exécuter facilement une commande dans votre racine de sous-module, sous
[alias]
dans votre.gitconfig
, ajoutez:Cela vous permet de faire facilement des choses comme
git sh ag <string>
Solution robuste qui prend en charge des répertoires nommés différemment ou externes
.git
ou$GIT_DIR
.Notez que cela
$GIT_DIR
peut pointer quelque part vers l'extérieur (et ne pas être appelé.git
), d'où la nécessité d'une vérification supplémentaire.Mettez ceci dans votre
.bashrc
:Exécuter en tapant
git_root
(après avoir redémarré votre shell:exec bash
)la source
(root=$(git rev-parse --git-dir)/ && cd ${root%%/.git/*} && git rev-parse && pwd)
mais cela ne couvre pas les$GIT_DIR
s externes qui sont nommés autrement que.git
Pour modifier la "git config" répondez un peu:
et obtenir le chemin nettoyé. Très agréable.
la source
Si vous êtes à la recherche d'un bon alias pour le faire, sans exploser
cd
si vous n'êtes pas dans un répertoire git:la source
git-extras
ajoute
$ git root
voir https://github.com/tj/git-extras/blob/master/Commands.md#git-root
Disponibilité de git-extras
$ brew install git-extras
$ apt-get install git-extras
la source
Cet alias de shell fonctionne que vous soyez dans un sous-répertoire git ou au niveau supérieur:
mis à jour pour utiliser une syntaxe moderne au lieu de backticks:
la source
Tout le reste échoue à un moment donné, soit en allant dans le répertoire personnel, soit en échouant lamentablement. C'est le moyen le plus rapide et le plus court pour revenir au GIT_DIR.
la source
$GIT_DIR
est détaché de l'arbre de travail à l'aide de -Files.git
etgitdir: SOMEPATH
. Par conséquent, cela échoue également pour les sous-modules, où$GIT_DIR
contient.git/modules/SUBMODULEPATH
.Voici un script que j'ai écrit qui gère les deux cas: 1) référentiel avec un espace de travail, 2) référentiel nu.
https://gist.github.com/jdsumsion/6282953
git-root
(fichier exécutable sur votre chemin):J'espère que cela vous sera utile.
la source
git exec
idée est plus utile dans les référentiels non dénudés. Cependant, ce script dans ma réponse gère correctement le cas nu contre non nu, ce qui pourrait être utile à quelqu'un, donc je laisse cette réponse ici.git submodule
s où$GIT_DIR
contient quelque chose comme/.git/modules/SUBMODULE
. Vous supposez également que le.git
répertoire fait partie de l'arbre de travail dans le cas non nu.la source
[alias] findroot = "!f () { [[ -d ".git" ]] && echo "Found git in [
pwd]" && exit 0; cd .. && echo "IN
pwd" && f;}; f"
git config --global alias.root '!pwd'
marche. Je n'ai pu repérer aucun cas où il agit différemment de la variante non globale. (Unix, git 1.7.10.4) BTW: Votrefindroot
requiert un/.git
pour éviter une récursion sans fin.Depuis Git 2.13.0 , il prend en charge une nouvelle option pour afficher le chemin du projet racine, qui fonctionne même lorsqu'il est utilisé depuis l'intérieur d'un sous-module:
la source
Alias de shell préconfigurés dans les cadres de shell
Si vous utilisez un framework shell, un alias shell peut déjà être disponible:
$ grt
en oh-my-zsh (68k) (cd $(git rev-parse --show-toplevel || echo ".")
)$ git-root
dans prezto (8.8k) (affiche le chemin d'accès à la racine de l'arbre de travail)$ g..
zimfw (1k) (change le répertoire courant au niveau supérieur de l'arborescence de travail.)la source
Je voulais développer l'excellent commentaire de Daniel Brockman.
La définition
git config --global alias.exec '!exec '
vous permet de faire des choses commegit exec make
parce que, comme l'man git-config
indique:Il est également utile de savoir que ce
$GIT_PREFIX
sera le chemin d'accès au répertoire actuel par rapport au répertoire de niveau supérieur d'un référentiel. Mais, sachant que ce n'est que la moitié de la bataille ™. L'expansion variable du shell le rend plutôt difficile à utiliser. Je suggère donc d'utiliserbash -c
comme ça:les autres commandes incluent:
la source
Dans le cas où quelqu'un aurait besoin d'une méthode compatible POSIX pour le faire, sans avoir besoin d'un
git
exécutable:git-root
:Si vous souhaitez simplement que la fonctionnalité fasse partie d'un script, supprimez le shebang et remplacez la dernière
git_root_recurse_parent
ligne par:la source
if
instruction était censée vérifier si vous avez changé de répertoire dans la récursivité. S'il reste dans le même répertoire, il suppose que vous êtes coincé quelque part (par exemple/
) et freine la récursivité. Le bogue est corrigé et devrait maintenant fonctionner comme prévu. Merci de l'avoir signalé.J'ai dû résoudre ce problème moi-même aujourd'hui. Résolu en C # comme j'en avais besoin pour un programme, mais je suppose qu'il peut être réécrit en toute simplicité. Considérez ce domaine public.
la source