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

hg root

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


当前回答

正如其他人所注意到的,解决方案的核心是使用git rev-parse——show-cdup。然而,也有一些边缘情况需要解决:

When the cwd already is the root of the working tree, the command yields an empty string. Actually it produces an empty line, but command substitution strip off the trailing line break. The final result is an empty string. Most answers suggest prepending the output with ./ so that an empty output becomes "./" before it is fed to cd. When GIT_WORK_TREE is set to a location that is not the parent of the cwd, the output may be an absolute pathname. Prepending ./ is wrong in this situation. If a ./ is prepended to an absolute path, it becomes a relative path (and they only refer to the same location if the cwd is the root directory of the system). The output may contain whitespace. This really only applies in the second case, but it has an easy fix: use double quotes around the command substitution (and any subsequent uses of the value).

正如其他答案所指出的,我们可以做cd”。/$(git rev-parse——show-cdup))”,但这会在第二个边缘大小写中中断(如果去掉双引号,则会在第三个边缘大小写中中断)。

许多shell将cd ""视为无操作,因此对于这些shell,我们可以执行cd "$(git rev-parse——show-cdup)"(双引号保护第一个边大小写中的空字符串作为参数,并在第三个边大小写中保留空白)。POSIX说cd ""的结果是未指定的,所以最好避免做这种假设。

在上述所有情况下工作的解决方案需要某种类型的测试。显式完成后,它可能是这样的:

cdup="$(git rev-parse --show-cdup)" && test -n "$cdup" && cd "$cdup"

第一个边不做cd操作。

如果运行cd可以接受。对于第一个边情况,则条件可以在参数展开中执行:

cdup="$(git rev-parse --show-cdup)" && cd "${cdup:-.}"

其他回答

在这里写一个简单的答案,这样我们就可以用

git root

要完成这项工作,只需使用

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

然后你可能想在~/.bashrc中添加以下内容:

alias cdroot='cd $(git root)'

这样你就可以用croot到回购的顶部。

以防万一,如果您要将此路径提供给Git本身,请使用:/

# this adds the whole working tree from any directory in the repo
git add :/

# and is equal to
git add $(git rev-parse --show-toplevel)

下面是我编写的处理这两种情况的脚本: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目录中使用子模块的简短解决方案

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

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)

“git rev-parse——git-dir”怎么样?

F:\prog\git\test\copyMerge\dirWithConflicts>git rev-parse --git-dir
F:/prog/git/test/copyMerge/.git

——git-dir选项似乎可以工作。

它甚至可以在裸库中工作,而git rev-parse——show- topllevel会触发(在裸库中)“致命:此操作必须在工作树中运行”。

从git rev-parse手册页:

--git-dir

    Show $GIT_DIR if defined else show the path to the .git directory.

您可以在这个git setup-sh脚本中看到它的作用。

如果你在子模块文件夹中,Git >=2.13,使用:

git rev-parse --show-superproject-working-tree

如果你正在使用git rev-parse——show-toplevel,请确保使用的是git 2.25+ (Q1 2020)。