【问题标题】:How do I execute a Git command without being in the repository?如何在不进入存储库的情况下执行 Git 命令?
【发布时间】:2021-10-11 21:05:49
【问题描述】:

有没有一种方法可以在不进入该存储库的情况下对存储库执行 Git 命令?

例如这样的:git /home/repo log?

请不要告诉我cd 给它。我正在通过exec 电话进行此操作。

【问题讨论】:

标签: git


【解决方案1】:

使用-C 作为 git 的第一个参数:

git -C /home/repo log

根据the docs,这样做的效果是:

-C <path>

就像 git 在 <path> 而不是当前工作目录中启动一样运行。 ...

几乎等同于 --git-dir--work-tree 而不附加通常的 .git 文件夹。但是,选项--git-dir--work-tree 不存在从工作树外部访问存储库;它们用于将.git 移动到其他地方,并且在某些情况下使用起来要复杂得多。

比如只获取/home/repo/subdir的日志:

git -C /home/repo/subdir log .

git -C /home/repo log subdir

不能将log .--git-dir--work-tree 一起使用。必须处理路径以提取相对于工作树顶部的子路径,即使在这种情况下,如果您不使用 -- 选项,git 也不会将其识别为路径,因此唯一可能的方法是:

git --git-dir /home/repo/.git log -- subdir

此外,--work-tree 在我的版本 (git 1.9.1) 中根本无法使用 log 子命令。它只是被忽略了:

git --git-dir /home/repo/.git --work-tree /home/repo/subdir log -- subdir
git --git-dir /home/repo/.git --work-tree /home/repo/whatever log -- subdir

我什至不明白这是一个错误还是一个功能......像往常一样有许多 git 设计选择。

【讨论】:

  • 感谢您添加更多解释。
  • git stash 是另一个子命令示例,如果使用了--git-dir--work-tree,则会失败。
  • 2013年发布的git 1.8.5版本增加了-C选项。
  • -C 对我来说比 --git-dir 工作得更好...... -C 尊重 repo 的 git config 设置。我正在运行 git 版本 1.9.5.msysgit.1
  • 注意:您需要将 -C 选项传递给 git 而不是子命令(正如@calandoa 在此答案中正确完成的那样)。调用 git -C /some/dir add . 将按预期工作,而 git add -C /some/dir . 将引发错误。只是需要注意一些事情,以防止混淆结果。
【解决方案2】:

试试:

git --git-dir=/home/repo/.git log

提供一直到存储库的 .git 目录的路径很重要。否则,您只会收到一条错误消息,内容如下:

fatal: Not a git repository

【讨论】:

  • 这对我不起作用,因为它显示提交的所有文件都已删除。似乎它正在检查提交而不是文件夹内容。请参阅@calandoa 的答案以获得更好的性能。
  • 使用最新的 git 对我不起作用,但是使用 -C 选项它起作用了,例如:git -C /home/repo/.git log
  • 这实际上并没有像 po 预期的那样工作。为什么这是任何公认的答案?这将使用当前目录作为工作树并使用指定的 .git 作为历史记录,这是完全错误的。如果您不只显示日志,例如git status-C 是正确的方法。
  • 它不像以前的 cmet 中的人已经说过的那样工作
【解决方案3】:

实际上你需要同时使用--git-dir 和--work-tree。这是一个例子:

local [] Desktop: mkdir git
local [] Desktop: cd git
local [] git: touch README.txt
local [] git: git init
Initialized empty Git repository in /Users/albert/Desktop/git/.git/
local [] git: cd ..
local [] Desktop: git --work-tree=git --git-dir=git/.git add .
local [] Desktop: git --work-tree=git --git-dir=git/.git commit -a -m 'initial commit, called from outside the git directory'
[master (root-commit) ee951b1] initial commit, called from outside the git directory
0 files changed, 0 insertions(+), 0 deletions(-)
create mode 100644 README.txt
local [] Desktop: cd git
local [] git: git log --pretty=oneline
ee951b161053e0e0948f9e2a36bfbb60f9c87abe initial commit, called from outside the git di

【讨论】:

【解决方案4】:

我试过很多次了! 我终于明白了!

git -C dir --no-pager log --format='%an' -1 filename

请记住,请不要将 .git 添加到您的

-C 目录

【讨论】:

    【解决方案5】:

    对于任何 git 命令,你都可以这样做:

    git --git-dir=<PATH-TO-REPO>/.git --work-tree=<PATH-TO-REPO> <git-command>
    

    例如,如果你想做一个 git status:

     git --git-dir=/home/myrepo/.git --work-tree=/home/myrepo/  status
    

    或者如果你想检查 repo 所在的分支:

    git --git-dir=/home/myrepo/.git --work-tree=/home/myrepo/  rev-parse --abbrev-ref HEAD
    

    【讨论】:

    • 嘿谷歌用户,stackoverflow.com/a/35899275/1277898 是更好的答案 ;)
    • @Git.Coach,如果你有 v1.8.5 或更高版本。
    • 即使 2 年,这个答案仍然是最好的!谢谢
    【解决方案6】:

    这类似于@max 的回答。不幸的是, --git-dir 没有做我需要的。 edit 回想起来,我没有读过的另一个 [previous] 答案建议使用--work-tree。我不确定使用环境或标志是否更合适,所以我会留下我的答案,以防有人发现它有用,但我会改用--work-tree / --git-dir


    有两个 repos,一个在另一个内部,但不是子模块;外部仓库忽略它:

    tools (outer repo)
      gcc/4.9.2 (inner repo)
    

    我想要的是git rev-parse --show-prefix 相对于外部仓库的输出。以下是我想出的(bash 语法;为了便于阅读,分行分隔):

    prefix_dir=$(cd ..; git rev-parse --show-toplevel)
    prefix_dir=$(GIT_WORK_TREE=${prefix_dir} git rev-parse --show-prefix)
    

    在 4.9.2 中执行时,它会生成字符串 gcc/4.9.2

    【讨论】:

      猜你喜欢
      • 2013-07-21
      • 1970-01-01
      • 1970-01-01
      • 2011-09-13
      • 2021-01-18
      • 2016-07-10
      • 2012-07-09
      • 2014-06-13
      • 1970-01-01
      相关资源
      最近更新 更多