Подтвердить что ты не робот

Git: быстрая команда для перехода к корню рабочего дерева

Мне нужна простая команда 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
}

У вас есть лучшее решение? (функция была написана быстро, предложения приветствуются)

4b9b3361

Ответ 3

Ответ Питера выше отлично работает, если вы находитесь в подкаталоге корня 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'

Ответ 4

$ git config alias.root '!pwd'
$ git root

Ответ 5

К сожалению, изменение текущего каталога может выполняться только оболочкой, а не подпроцессом. К моменту, когда git обойдется в синтаксическом анализе вашей команды, уже слишком поздно - git уже был создан в отдельном процессе.

Здесь действительно грубая, непроверенная функция оболочки, которая просто может сделать то, что вы хотите:

function git() {
    if [ "$1" == "root" ]; then
        git-root
    else
        git "[email protected]"
    fi
}

Ответ 6

Короткие решения, которые работают с подмодулями, в хуках и внутри директории .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)

Ответ 7

Лучший псевдоним, работающий в bash и zsh:

alias git-root='cd "$(git rev-parse --show-cdup)"'