Mercurial有一种打印根目录(包含.hg)的方法

hg root

git中是否有等价的东西来获取包含.git目录的目录?


当前回答

Yes:

git rev-parse --show-toplevel

如果你想更直接地复制Mercurial命令,你可以创建一个别名:

git config --global alias.root 'rev-parse --show-toplevel'

现在git根和hg根一样。


注意:在子模块中,这将显示子模块的根目录,而不是父存储库。如果您使用的是Git >=2.13或更高版本,有一种方法可以让子模块显示超级项目的根目录。如果你的git比这更老,请参阅另一个答案。

其他回答

要计算当前git根目录的绝对路径,比如在shell脚本中使用,使用readlink和git rev-parse的组合:

gitroot=$(readlink -f ./$(git rev-parse --show-cdup))

Git-rev-parse——show-cdup给出正确的“..”’s to get 从你的cwd到根目录,如果你在根目录,则返回空字符串。 然后“prepend”。/"来处理空字符串大小写并使用 Readlink -f转换为完整路径。

你也可以在PATH中创建一个git-root命令作为shell脚本来应用这个技术:

cat > ~/bin/git-root << EOF
#!/bin/sh -e
cdup=$(git rev-parse --show-cdup)
exec readlink -f ./$cdup
EOF
chmod 755 ~/bin/git-root

(上面的代码可以粘贴到终端中创建git-root并设置执行位;实际的脚本在第2、3和4行。)

然后你可以运行git root来获得当前树的根。 注意,在shell脚本中,使用“-e”使shell在rev-parse失败时退出,这样如果不在git目录中,就可以正确地获得退出状态和错误消息。

Yes:

git rev-parse --show-toplevel

如果你想更直接地复制Mercurial命令,你可以创建一个别名:

git config --global alias.root 'rev-parse --show-toplevel'

现在git根和hg根一样。


注意:在子模块中,这将显示子模块的根目录,而不是父存储库。如果您使用的是Git >=2.13或更高版本,有一种方法可以让子模块显示超级项目的根目录。如果你的git比这更老,请参阅另一个答案。

修改一下“git配置”的答案:

git config --global --add alias.root '!pwd -P'

把道路清理干净。很好。

我想进一步阐述丹尼尔·布罗克曼的精彩评论。

定义git配置全局别名。exec”!Exec '允许你做像git Exec make这样的事情,因为man git-config说:

如果别名展开以感叹号作为前缀,则它将被视为shell命令。[…注意,shell命令将从存储库的顶级目录执行,而不一定是当前目录。

知道$GIT_PREFIX将是相对于存储库的顶级目录的当前目录的路径也很方便。但是,知道这只是战斗的一半。Shell变量展开使得它很难使用。所以我建议像这样使用bash -c:

git exec bash -c 'ls -l $GIT_PREFIX'

其他命令包括:

git exec pwd
git exec make

在钩子和.git目录中使用子模块的简短解决方案

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

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

这将在git工作树中的任何地方工作(包括在.git目录中),但假设存储库目录被称为.git(这是默认的)。对于子模块,这将转到包含最外层存储库的根。

如果你想获得当前子模块的根,使用:

echo $(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"
}

通过输入git_root来执行它(在重新启动shell后:exec bash)