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

hg root

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


当前回答

在钩子和.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)

其他回答

下面是我编写的处理这两种情况的脚本:1)带工作区的存储库,2)裸存储库。

https://gist.github.com/jdsumsion/6282953

Git-root(可执行文件在你的路径):

#!/bin/bash
GIT_DIR=`git rev-parse --git-dir` &&
(
  if [ `basename $GIT_DIR` = ".git" ]; then
    # handle normal git repos (with a .git dir)
    cd $GIT_DIR/..
  else
    # handle bare git repos (the repo IS a xxx.git dir)
    cd $GIT_DIR
  fi
  pwd
)

希望这对你们有帮助。

不管你是否已经在git仓库的顶层,cd $(git rev-parse——show-cdup)将带你回家(只是cd)。CD ./$(git rev-parse——show-cdup)是解决这个问题的一种方法。

$ git config alias.root '!pwd'
# then you have:
$ git root

今天必须自己解决这个问题。在c#中解决了它,因为我需要它的程序,但我猜它可以轻松重写。考虑到这是公共领域。

public static string GetGitRoot (string file_path) {

    file_path = System.IO.Path.GetDirectoryName (file_path);

    while (file_path != null) {

        if (Directory.Exists (System.IO.Path.Combine (file_path, ".git")))
            return file_path;

        file_path = Directory.GetParent (file_path).FullName;

    }

    return null;

}

git-extras

添加$ git根目录 看到https://github.com/tj/git-extras/blob/master/Commands.md git-root

$ pwd
.../very-deep-from-root-directory
$ cd `git root`
$ git add . && git commit

git-extra的可用性

Homebrew (osx)/linuxbrew(linux) $ brew安装git-extras Debian /ubuntu repos (https://packages.debian.org/sid/git-extras) $ apt-get安装git-extras