git:一个快速命令,用于转到工作树的根目录

5vf7fwbs  于 2022-12-10  发布在  Git
关注(0)|答案(9)|浏览(138)

我想用一个简单的git命令来访问仓库的“根目录”。
我从一个脚本开始,但我发现我不能改变shell的活动目录,我必须做一个函数。不幸的是,我不能直接用非破折号形式“git root”调用它,例如。

function git-root() {
 if [ -d .git ]; then
  return 0
 fi

 A=..
 while ! [ -d $A/.git ]; do 
  A="$A/.."
 done
 cd $A
}

你有更好的解决方案吗?(函数已写快,欢迎建议)

bogh5gae

bogh5gae1#

他写道:“这个问题以前也有人问过,Is there a way to get the git root directory in one command?

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

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

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

4ktjp1zp2#

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

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

无论您是否在根目录中,此操作都有效。

relj7zay

relj7zay3#

如果你在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'
kpbpu008

kpbpu0084#

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

tkclm6bt5#

不幸的是,更改当前目录只能由shell完成,而不是由任何子进程完成。当git开始解析命令时,已经太晚了-- git已经在一个单独的进程中产生了。
下面是一个非常粗糙的、未经测试的shell函数,它可能会完成您想要的任务:

function git() {
    if [ "$1" == "root" ]; then
        git-root
    else
        git "$@"
    fi
}
0g0grzrc

0g0grzrc6#

与子模块一起使用的简短解决方案,位于挂接和.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) )

要轻松执行子模块根中的命令,请在.gitconfig中的[alias]下添加:

sh = "!f() { root=$(pwd)/ && cd ${root%%/.git/*} && git rev-parse && exec \"$@\"; }; f"

这使您可以轻松地执行git sh ag <string>等操作

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

注意,$GIT_DIR可能指向外部的某个地方(并且不被称为.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 1  # git_root will print any errors
  cd "$root"
}

通过键入cd_git_root执行该命令(重新启动shell后:(一个月12个月1x个月)

oxalkeyp

oxalkeyp7#

在bash和zsh中使用的更好的别名是:

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

643ylb088#

Peter的回答是最好的回答。很多人都认为如果你已经在git根目录下,这个方法就不起作用了,不幸的是他们的解决方案太复杂了。
下面是我的一句俏皮话:

alias cd-gitroot='cd $(git rev-parse --show-cdup)/.'
cig3rfwq

cig3rfwq9#

如果您使用的是oh-my-zsh,并且您已在

plugins+=(git)

.zshrc配置文件,则以下命令(别名)起作用:

grt

此别名的定义方式如下:

grt='cd "$(git rev-parse --show-toplevel \|\| echo .)"'

相关问题