bash git:转到工作树根的快速命令

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1571461/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 18:36:33  来源:igfitidea点击:

git: a quick command to go to root of the working tree

gitbashscripting

提问by elmarco

I wanted a simple git command to go up to the "root" of the repository.

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

I started with a script, but figured that I cannot change active directory of the shell, I had to do a function. Unfortunately, I cannot call it directly with the non-dash form "git root", for instance.

我从一个脚本开始,但认为我无法更改 shell 的活动目录,我必须执行一个函数。不幸的是,例如,我不能用非破折号形式“git root”直接调用它。

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

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

Do you have a better solution? (the function has been written quickly, suggestions are welcome)

你有更好的解决方案吗?(功能写得很快,欢迎提出建议)

回答by Peter

This has been asked before, Is there a way to get the git root directory in one command?Copying @docgnome's answer, he writes

之前有人问过这个问题,有没有办法在一个命令中获取 git 根目录?复制@docgnome 的回答,他写道

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

Make an alias if you like:

如果您愿意,请创建别名:

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

回答by Chris Westin

Simpler still, steal from Is there a way to get the git root directory in one command?, and make an alias (as suggested by Peter) from

更简单的是,从有没有办法在一个命令中获取 git 根目录?,并从

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

This works whether you're in the root directory or not.

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

回答by William Budington

Peter's answer above works great if you're in a subdirectory of the git root. If you're already in the git root, it'll throw you back to $HOME. To prevent this, we can use some bash conditionals.

如果您位于 git root 的子目录中,则上述 Peter 的回答非常有效。如果您已经在 git root 中,它会将您扔回 $HOME。为了防止这种情况,我们可以使用一些 bash 条件。

if [ "`git rev-parse --show-cdup`" != "" ]; then cd `git rev-parse --show-cdup`; fi

so the alias becomes:

所以别名变成:

alias git-root='if [ "`git rev-parse --show-cdup`" != "" ]; then cd `git rev-parse --show-cdup`; fi'

回答by FractalSpace

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

回答by Tom Hale

Short solutions that work with submodules, in hooks, and inside the .gitdirectory

适用于子模块、钩子和.git目录内部的简短解决方案

Here's the short answer that most will want:

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

r=$(git rev-parse --git-dir) && r=$(cd "$r" && pwd)/ && cd "${r%%/.git/*}"

This will work anywhere in a git working tree (including inside the .gitdirectory), but assumes that repository directory(s) are called .git(which is the default). With submodules, this will go to the root of the outermost containing repository.

这将适用于 git 工作树中的任何位置(包括.git目录内部),但假设调用了存储库目录.git(这是默认值)。对于子模块,这将转到最外层包含存储库的根目录。

If you want to get to the root of the current submodule use:

如果要访问当前子模块的根目录,请使用:

cd ''$(r=$(git rev-parse --show-toplevel) && [[ -n $r ]] && echo "$r" || (cd $(git rev-parse --git-dir)/.. && pwd) )

To easily execute a command in your submodule root, under [alias]in your .gitconfig, add:

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

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

This allows you to easily do things like git sh ag <string>

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

Robust solution that supports differently named or external .gitor $GIT_DIRdirectories.

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

Note that $GIT_DIRmay point somewhere external (and not be called .git), hence the need for further checking.

请注意,$GIT_DIR可能指向外部某个地方(而不是被调用.git),因此需要进一步检查。

Put this in your .bashrc:

把它放在你的.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 "
function git() {
    if [ "" == "root" ]; then
        git-root
    else
        git "$@"
    fi
}
: 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" }

Execute it by typing cd_git_root(after restarting your shell: exec bash)

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

回答by Josh Lee

Unfortunately, changing your current directory can only be done by the shell, not by any subprocess. By the time git gets around to parsing your command, it's already too late -- git has already been spawned in a separate process.

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

Here's a really gross, untested shell function that just might do what you want:

这是一个非常粗糙的、未经测试的 shell 函数,它可能会做你想做的事:

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

回答by tasmo

A better alias working in bash and zsh is:

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

##代码##