21 ответов:
The
manстраницаgit-config(при псевдоним) говорит:если расширение псевдонима сопровождается восклицательным знаком, оно будет рассматриваться как оболочка команда. Например, определение "псевдоним.новый = !gitk --all --not ORIG_HEAD", вызов " git new "эквивалентно выполнению команды оболочки" gitk --all --not ORIG_HEAD". Обратите внимание, что оболочка команды будут выполняться из каталога верхнего уровня репозитория, который может не выполняться обязательно будет текущий каталог.
Итак, на UNIX вы можете сделать:
git config --global --add alias.root '!pwd'
и
--show-toplevelтолько недавно был добавлен вgit rev-parseили почему никто не упоминает об этом?С
git rev-parseman page:--show-toplevel Show the absolute path of the top-level directory.
как насчет "
git rev-parse --git-dir"?F:\prog\git\test\copyMerge\dirWithConflicts>git rev-parse --git-dir F:/prog/git/test/copyMerge/.gitThe
--git-dirопция, кажется, работает.--git-dir Show $GIT_DIR if defined else show the path to the .git directory.вы можете увидеть его в действии в этой
git setup-shскрипт.
Если вы уже находитесь на верхнем уровне или не в репозитории git
cd $(git rev-parse --show-cdup)отвезет вас домой (только cd).cd ./$(git rev-parse --show-cdup)Это один из способов исправить это.
написать простой ответ здесь, так что мы можем использовать
git rootчтобы выполнить эту работу, просто настройте свой git с помощью
git config --global alias.root "rev-parse --show-toplevel"и тогда вы, возможно, захотите, чтобы добавить следующий код
~/.bashrc:alias cdroot='cd $(git root)', так что вы можете просто использовать
cdroot, чтобы перейти к верхней части РЕПО.
чтобы вычислить абсолютный путь текущего корневого каталога git, скажем, для использования в сценарии оболочки, используйте эту комбинацию readlink и Git rev-parse:
gitroot=$(readlink -f ./$(git rev-parse --show-cdup))
git-rev-parse --show-cdupдает вам правильное число ".."с получить в корень из вашего cwd или пустую строку, если вы находитесь в корне. Тогда добавь"./ "чтобы справиться с пустой строкой case и использоватьreadlink -fдля перевода на полный путь.вы также можете создать
git-rootкоманда в вашем пути как сценарий оболочки чтобы применить эту технику:cat > ~/bin/git-root << EOF #!/bin/sh -e cdup=$(git rev-parse --show-cdup) exec readlink -f ./$cdup EOF chmod 755 ~/bin/git-root(вышесказанное может быть вставлено в терминал для создания git-root и установки битов выполнения; фактический скрипт находится в строках 2, 3 и 4.)
и тогда ты сможешь работать
git rootчтобы получить корень текущего дерева. Обратите внимание, что в сценарии оболочки используйте "-e", чтобы заставить оболочку выйти, если rev-parse терпит неудачу, чтобы вы могли правильно получить статус выхода и сообщение об ошибке, если вы не находитесь в каталоге git.
как уже отмечалось, суть решения заключается в использовании
git rev-parse --show-cdup. Тем не менее, есть несколько крайних случаев для решения:
когда cwd уже является корнем рабочего дерева, команда выдает пустую строку.
на самом деле он производит пустую строку, но команда подстановки полосы от конечной линии разрыва. Конечным результатом является пустая строка.большинство ответов предлагают добавить выход с
./так что пустой вывод становится"./"перед подачей кcd.когда GIT_WORK_TREE устанавливается в расположение, которое не является родительским для cwd, выход может быть абсолютным путем.
перед
./ошибается в этой ситуации. Если a./добавляется к абсолютному пути, он становится относительным путем (и они ссылаются только на то же место, если cwd является корневым каталогом системы).в выходные данные могут содержать пробелы.
это действительно применимо только во втором случае, но у него есть простое решение: используйте двойные кавычки вокруг замены команды (и любые последующие использования значения).
как отметили другие ответы, мы можем сделать
cd "./$(git rev-parse --show-cdup)", но это разрывает второй крайний случай (и третий крайний случай, если мы оставим двойные кавычки).многие снаряды лечат
cd ""как no-op, так что для этих снарядов мы могли бы сделатьcd "$(git rev-parse --show-cdup)"(двойные кавычки защищают пустую строку в качестве аргумента в первом граничном случае и сохраняют пробелы в третьем граничном случае). POSIX говорит результатcd ""не указано, поэтому лучше всего избегать этого предположения.решение, которое работает во всех вышеперечисленных случаях, требует какого-то теста. Сделано явно, это может выглядеть так:
cdup="$(git rev-parse --show-cdup)" && test -n "$cdup" && cd "$cdup"нет
cdсделано для первого случая края.если это приемлемо для запуска
cd .для первого реберного случая, то условное может быть сделано в расширении параметра:cdup="$(git rev-parse --show-cdup)" && cd "${cdup:-.}"
короткие решения, которые работают с подмодулями, в крючках и внутри
.gitкаталогвот короткий ответ, который большинство захочет:
r=$(git rev-parse --git-dir) && r=$(cd "$r" && pwd)/ && echo "${r%%/.git/*}"это будет работать в любом месте в рабочем дереве git (в том числе внутри : Can't get initial commit" 2>&1 && false && return root=$(git rev-parse --git-dir)/.. && # subshell so we don't change the user's working directory ( cd "$root" && if [[ $(git rev-list --parents HEAD | tail -1) = $first_commit ]]; then pwd else echo "$FUNCNAME: git directory is not inside its repository" 2>&1 false fi ) else echo "$FUNCNAME: Can't determine repository root" 2>&1 false fi } # Change working directory to git repository root function cd_git_root() { local root root=$(git_root) || return # git_root will print any errors cd "$root" }
выполните его, введя
git_root(после перезагрузки оболочки:exec bash)
на всякий случай, если вы подаете этот путь к самому Git, используйте
:/# this adds the whole working tree from any directory in the repo git add :/ # and is equal to git add $(git rev-parse --show-toplevel)
чтобы изменить "git config" ответ только немного:
git config --global --add alias.root '!pwd -P'и очистите путь. Очень симпатичный.
Если вы ищете хороший псевдоним, чтобы сделать это плюс не взорвать
cdЕсли вы не находитесь в Git dir:alias ..g='git rev-parse && cd "$(git rev-parse --show-cdup)"'
этот псевдоним оболочки работает независимо от того, находитесь ли вы в поддире git или на верхнем уровне:
alias gr='[ ! -z `git rev-parse --show-toplevel` ] && cd `git rev-parse --show-toplevel || pwd`'обновлено для использования современного синтаксиса вместо обратных кавычек:
alias gr='[ ! -z $(git rev-parse --show-toplevel) ] && cd $(git rev-parse --show-toplevel || pwd)'
alias git-root='cd \`git rev-parse --git-dir\`; cd ..'все остальное не удается в какой-то момент либо перейти в домашний каталог, либо просто неудачно. Это самый быстрый и короткий путь, чтобы вернуться к использование переменной git_dir.
вот скрипт, который я написал, который обрабатывает оба случая: 1) репозиторий с рабочей областью, 2) голый репозиторий.
https://gist.github.com/jdsumsion/6282953
git-root(исполняемый файл в вашем пути):#!/bin/bash GIT_DIR=`git rev-parse --git-dir` && ( if [ `basename $GIT_DIR` = ".git" ]; then # handle normal git repos (with a .git dir) cd $GIT_DIR/.. else # handle bare git repos (the repo IS a xxx.git dir) cd $GIT_DIR fi pwd )надеюсь, это полезно.
git-extrasдобавляет
$ git root
смотрите https://github.com/tj/git-extras/blob/master/Commands.md#git-root$ pwd .../very-deep-from-root-directory $ cd `git root` $ git add . && git commitналичие git-экстры
- homebrew (osx) / linuxbrew(linux)
$ brew install git-extras- репозитории debian/ubuntu (https://packages.debian.org/sid/git-extras)
$ apt-get install git-extras
С Git 2.13.0, он поддерживает новую опцию, чтобы показать путь к корневому проекту, который работает даже при использовании внутри подмодуля:
git rev-parse --show-superproject-working-tree
должен был решить это сам сегодня. Решил его в C# , поскольку мне это было нужно для программы, но я думаю, что его можно esily переписать. Рассмотрим это общественное достояние.
public static string GetGitRoot (string file_path) { file_path = System.IO.Path.GetDirectoryName (file_path); while (file_path != null) { if (Directory.Exists (System.IO.Path.Combine (file_path, ".git"))) return file_path; file_path = Directory.GetParent (file_path).FullName; } return null; }
предварительно настроенные псевдонимы оболочки в рамках оболочки
если вы используете фреймворк оболочки, возможно, уже есть псевдоним оболочки:
$ grtна Oh-my-zsh (68k) (cd $(git rev-parse --show-toplevel || echo "."))$ git-rootна prezto (8.8 k) (отображает путь к корню рабочего дерева)$ g..zimfw (1k) (изменяет текущий каталог на верхний уровень рабочего дерева.)
в случае, если кто-то нуждается в POSIX совместимый способ сделать это, без необходимости
gitисполняемый файл:#!/bin/sh #: Path to child directory recurse_parent() { if is_cwd_git_root ; then pwd return 0 fi if [ "" = "$(pwd)" ] ; then return 1 fi cd .. recurse_parent "${CWD}" } is_cwd_git_root() { [ -d .git/branches -a -d .git/objects -a -d .git/refs -a -f .git/HEAD ] } recurse_parent
Comments