Ответ 1
Об этом уже спрашивали, Есть ли способ получить корневой каталог git за одну команду? Копируя ответ @docgnome, он пишет
cd $(git rev-parse --show-cdup)
Сделайте псевдоним, если хотите:
alias git-root='cd $(git rev-parse --show-cdup)'
Мне нужна простая команда git, чтобы перейти к "корню" репозитория.
Я начал с script, но понял, что я не могу изменить активный каталог оболочки, мне пришлось выполнять функцию. К сожалению, я не могу назвать это напрямую с помощью нечерной формы "git root", например.
function git-root() {
if [ -d .git ]; then
return 0
fi
A=..
while ! [ -d $A/.git ]; do
A="$A/.."
done
cd $A
}
У вас есть лучшее решение? (функция была написана быстро, предложения приветствуются)
Об этом уже спрашивали, Есть ли способ получить корневой каталог git за одну команду? Копируя ответ @docgnome, он пишет
cd $(git rev-parse --show-cdup)
Сделайте псевдоним, если хотите:
alias git-root='cd $(git rev-parse --show-cdup)'
Проще говоря, украсть у Есть ли способ получить корневой каталог git одной командой? и создать псевдоним (как предложил Питер) из
cd "$(git rev-parse --show-toplevel)"
Это работает независимо от того, находитесь ли вы в корневом каталоге или нет.
Ответ Питера выше отлично работает, если вы находитесь в подкаталоге корня git. Если вы уже находитесь в корневом каталоге git, он вернет вас к $HOME. Чтобы предотвратить это, мы можем использовать некоторые условные условия bash.
if [ "`git rev-parse --show-cdup`" != "" ]; then cd `git rev-parse --show-cdup`; fi
чтобы псевдоним стал:
alias git-root='if [ "`git rev-parse --show-cdup`" != "" ]; then cd `git rev-parse --show-cdup`; fi'
$ git config alias.root '!pwd'
$ git root
К сожалению, изменение текущего каталога может выполняться только оболочкой, а не подпроцессом. К моменту, когда git обойдется в синтаксическом анализе вашей команды, уже слишком поздно - git уже был создан в отдельном процессе.
Здесь действительно грубая, непроверенная функция оболочки, которая просто может сделать то, что вы хотите:
function git() {
if [ "$1" == "root" ]; then
git-root
else
git "[email protected]"
fi
}
Короткие решения, которые работают с подмодулями, в хуках и внутри директории .git
Вот краткий ответ, который больше всего захочется:
r=$(git rev-parse --git-dir) && r=$(cd "$r" && pwd)/ && cd "${r%%/.git/*}"
Это будет работать в любом месте рабочего дерева git (в том числе внутри каталога .git
), но предполагает, что каталог хранилища называются .git
(который используется по умолчанию). С подмодулями это пойдет в корень самого внешнего содержащего репозитория.
Если вы хотите получить доступ к корню текущего субмодуля, используйте:
cd ''$(r=$(git rev-parse --show-toplevel) && [[ -n $r ]] && echo "$r" || (cd $(git rev-parse --git-dir)/.. && pwd) )
Чтобы легко выполнить команду в корневом каталоге подмодуля, в разделе [alias]
в вашем .gitconfig
добавьте:
sh = "!f() { root=$(pwd)/ && cd ${root%%/.git/*} && git rev-parse && exec \"[email protected]\"; }; f"
Это позволяет вам легко делать такие вещи, как git sh ag <string>
Надежное решение, которое поддерживает каталоги .git
или $GIT_DIR
с разными именами.
Обратите внимание, что $GIT_DIR
может указывать на что-то внешнее (и не называться .git
), поэтому необходима дополнительная проверка.
Поместите это в свой .bashrc
:
# Print the name of the git working tree root directory
function git_root() {
local root first_commit
# git displays its own error if not in a repository
root=$(git rev-parse --show-toplevel) || return
if [[ -n $root ]]; then
echo $root
return
elif [[ $(git rev-parse --is-inside-git-dir) = true ]]; then
# We're inside the .git directory
# Store the commit id of the first commit to compare later
# It possible that $GIT_DIR points somewhere not inside the repo
first_commit=$(git rev-list --parents HEAD | tail -1) ||
echo "$0: Can't get initial commit" 2>&1 && false && return
root=$(git rev-parse --git-dir)/.. &&
# subshell so we don't change the user 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 1 # git_root will print any errors
cd "$root"
}
Выполните его, набрав cd_git_root
(после перезапуска вашей оболочки: exec bash
)
Лучший псевдоним, работающий в bash и zsh:
alias git-root='cd "$(git rev-parse --show-cdup)"'