代码之家  ›  专栏  ›  技术社区  ›  elmarco

转到工作树根目录的快速命令

  •  38
  • elmarco  · 技术社区  · 15 年前

    我需要一个简单的git命令来访问存储库的“根”。

    我从一个脚本开始,但我发现无法更改shell的Active Directory,所以我必须执行一个函数。不幸的是,我不能用非破折号形式直接调用它,例如“git root”。

    function git-root() {
     if [ -d .git ]; then
      return 0
     fi
    
     A=..
     while ! [ -d $A/.git ]; do 
      A="$A/.."
     done
     cd $A
    }
    

    你有更好的解决方案吗?(功能编写迅速,欢迎提出建议)

    7 回复  |  直到 6 年前
        1
  •  54
  •   wisbucky Ishan    6 年前

    以前有人问过这个问题, Is there a way to get the git root directory in one command? 他写道,抄袭@docgnome的答案

    cd $(git rev-parse --show-cdup)
    

    如果愿意,可以创建别名:

    alias git-root='cd $(git rev-parse --show-cdup)'
    
        2
  •  38
  •   wisbucky Ishan    6 年前

    更简单的是,从 Is there a way to get the git root directory in one command? ,并在

    cd "$(git rev-parse --show-toplevel)"
    

    无论您是否在根目录中,这都有效。

        3
  •  14
  •   William Budington    13 年前

    如果您在git根目录的子目录中,那么上面的Peter的答案非常有效。如果你已经在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
  •  4
  •   FractalSpace    12 年前
    $ git config alias.root '!pwd'
    $ git root
    
        5
  •  3
  •   Josh Lee ZZ Coder    15 年前

    不幸的是,更改当前目录只能由shell完成,而不能由任何子进程完成。当Git开始解析您的命令时,已经太迟了——Git已经在单独的进程中生成了。

    下面是一个非常粗俗的未经测试的shell函数,它可以满足您的需要:

    function git() {
        if [ "$1" == "root" ]; then
            git-root
        else
            git "$@"
        fi
    }
    
        6
  •  3
  •   Tom Hale    8 年前

    与子模块、钩子和 .git 目录

    以下是大多数人想要的简短答案:

    r=$(git rev-parse --git-dir) && r=$(cd "$r" && pwd)/ && cd "${r%%/.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 \"$@\"; }; f"
    

    这样你就可以轻松地做 git sh ag <string>

    支持不同名称或外部的强大解决方案 Git $GIT_DIR 目录。

    注意 $git_目录 可能指向外部(而不是 Git ,因此需要进一步检查。

    把这个放进你的 .bashrc :

    # Print the name of the git working tree's 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's 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'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"
    }
    

    通过键入来执行 cd_git_root (重新启动外壳后: exec bash )

        7
  •  1
  •   tasmo    9 年前

    在bash和zsh中工作的一个更好的别名是:

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