2016-09-27 1 views
0

J'ai un fichier que je pense être dans un repo git. Je suis actuellement dans mon répertoire personnel. Comment puis-je obtenir le répertoire de premier niveau du repo sans changer mon répertoire de travail actuel?Obtenez le plus haut niveau d'un repo git, seulement en connaissant un seul fichier dans le repo?

Si je suis dans le repo, je peux courir pour obtenir le répertoire racine. Effectivement, je veux pouvoir utiliser un fichier pour trouver directement la racine du répertoire git.

(~) $ find . -name "specific_file.py" 

Lorsque les parties importantes de l'arbre sont:

~/code/dir1/.git 
~/code/dir1/files/more_files/specific_file.py 

est-il un moyen git de le faire, ou manipulations shell générique la meilleure façon de le faire?

Je sais que je peux faire:

(~) $ cd $(dirname $(find . -name "specific_file.py")) 
(~/code/dir1/files/more_files) $ git rev-parse --show-toplevel 
~/code/dir1 
(~/code/dir1/files/more_files) $ cd - 

Si je tente sans être à l'intérieur du repo, je reçois le message:

Fatal '~/code/dir1/files/more_file/specific_file.py' is outside repository 

Si je tente de définir le répertoire git à être plus bas dans la tree:

git --git-dir=$(dirname $(find . -name "specific_file.py")) rev-parse --show-toplevel 

Il me dit que je ne travaille pas dans un répertoire git.

J'ai également essayé de jouer avec l'arbre de travail, mais cela ne semble pas être ce que je cherche après avoir cherché directement un répertoire /.git directement sur le chemin.

+0

Je ne suis pas sûr de comprendre le besoin de faire cela. Est-ce que 'find 'ne vous montrera pas le chemin complet du fichier, à partir duquel il devrait être évident s'il se trouve ou non dans un repo Git? –

+0

Sur quelle plateforme êtes-vous? – pneumatics

+0

@TimBiegeleisen oui, parce que je connais la structure du repo sur ma machine, mais il ne semble pas y avoir un moyen facile de trouver le chemin racine afin qu'il puisse localiser d'autres scripts d'aide en cours de construction depuis la source. Je pourrais bien sûr juste prendre le chemin comme paramètre, mais je voudrais éviter cela s'il y a une solution facile intégrée dans git. –

Répondre

2

Après avoir lu la page de manuel en détail, il était le drapeau -C je n'avais pas besoin les --git-dir ou --work-dir drapeaux.

git -C $(dirname $(find . -name "specific_file.py")) rev-parse --show-toplevel 

Mon interprétation est que plusieurs indicateurs -C pourraient être utiles si vous travaillez avec/sous-modules sous-arbres.

De la page man git:

Run comme si git a été lancé à la place du répertoire travail actuel. Lorsque plusieurs options -C sont données, chaque non-absolu C est interprété par rapport au précédent -C .

Cette option affecte les options qui attendent un nom de chemin comme --git-dir et --work-tree en ce sens que leurs interprétations des noms de chemin seront effectuées par rapport au répertoire de travail provoqué par l'option -C. Pour exemple les invocations suivantes sont équivalentes:

+0

oh voilà! – pneumatics

1

Essayez de changer de répertoire dans un sous-shell, puis appelez git rev-parse --show-toplevel. Tu seras de retour là où tu as commencé, avec les informations que tu veux!

Remarque: les girations $OSTYPE sont dues à l'absence de l'indicateur -f|--canonicalize dans la version BSD de readlink fournie avec OSX. Une alternative sur osx serait brew install greadlink et définir une variable locale comme readlink=$(command -v greadlink readlink | head -n 1), puis appelez ${readlink} -f.

abspath() 
{ 
    case $OSTYPE in 
     darwin*) python -c 'import sys, os.path; print os.path.abspath(sys.argv[1])' $1;; 
     linux*) readlink -f $1;; 
    esac 
} 

topgit() 
{ 
    [ -e "$1" ] || { echo >&2 "$1 does not exist"; return 1; } 
    abspath=`abspath $1` 
    (
    [ -f "$abspath" ] && cd `dirname $abspath` || cd $abspath 
    git rev-parse --show-toplevel 
    ) 
} 
+0

Et je ne pense pas que l'installation du 'greadlink' est une dépendance juste pour quelque chose d'aussi mineur. Le composant sous-shell signifie que je suis moins préoccupé par le changement de répertoire. Il n'y a pas de git intégré/flag/env_var pour le faire directement? –

+1

Oui, l'absence de 'readlink -f' est assez un pincement sur osx. Vous pouvez forcer les appelants à donner des chemins absolus, mais ce n'est pas amusant. J'ai utilisé un doublure Python ou Perl comme solution de rechange, comme une solution portable qui ne nécessite pas l'installation de 'greadlink', mais d'une certaine façon c'est encore plus bête. Mais cela fonctionnerait, veut cette solution? – pneumatics

+1

Nah ça va, j'ai souvent juste utilisé 'python -c" import os.path comme p; print (p.realpath ($ 1)) "' comme alternative. –