有没有办法列出终端中的所有 git 存储库?

Posted

技术标签:

【中文标题】有没有办法列出终端中的所有 git 存储库?【英文标题】:Is there any way to list all git repositories in terminal? 【发布时间】:2011-07-03 08:33:01 【问题描述】:

我的系统上有几个 git 存储库,我想在终端中列出它们。

我正在寻找的是这样的:

/path/to/my/git/repo/1/ REPONAME1  
/path/to/my/git/repo/2/ REPONAME2  
/path/to/my/git/repo/3/ REPONAME3

如果你能想出如何显示分支名称和 repo 的状态,例如。 [master] c:0 u:1 d:0,那太好了。

【问题讨论】:

这有点类似于***.com/questions/2765253/…,在这里你也可以找到有用的想法。 是的,它确实帮助了我很多。感谢您指出这一点。 【参考方案1】:

要列出您系统上的所有 git 存储库,您可以在 bash shell 终端(在命令行)中运行以下命令并找到它们。

find / -name .git -type d -exec dirname  \;

【讨论】:

这是一个合理的第一个近似值,但遗漏了很多。裸存储库将丢失,任何使用名为 .git 的常规文件指定 git 目录的存储库也将丢失。 C:\xampp\htdocs\rimedit> find / -name .git -type d -exec dirname ` "C:/Users/Jakub/AppData/Local/GitHub/PortableGit_fed20eba68b3e238e49a47cdfed0a45 783d93651/bin/find.exe":` @ 987654324@-exec'`【参考方案2】:

我发现这比 find 命令更准确,也更快。我确信它可以改进,但这是一个好的开始。显然,在运行此命令之前,您的文件数据库需要是最新的。在 linux 系统上,您可以通过运行 sudo updatedb 来执行此操作。

locate -br '\.git$' | rev | cut -c 6- | rev

【讨论】:

【参考方案3】:

如果你能想出如何显示分支名称和 repo 的状态

这个想法是:

(首先)查找并注册存储库, 然后使用新的(Git 2.30,2020 年第四季度)git for-each-repo command。

首先,选择您想要的任何配置键名称。 例如:“list.repos

使用git config --unset-all(在全局配置文件中)重新初始化列表:

git config --global --unset-all list.repos

然后使用:

nrbray/find_gits(Perl 脚本,它使用 find,而不是 locateuncommitted/(Python,默认使用find,如果需要,使用locate

将结果重定向到文件“list-repos.txt”中,然后注册这些存储库,reading each line of the file:

while IFS="" read -r repo || [ -n "$repo" ]
do
  git config --global --add list.repos $repo
done < list-repos.txt

一旦您的存储库被注册(作为全局 git 配置值),使用新命令 git for-each-repo 循环它们是微不足道的,执行您需要的任何命令。

在 Git 2.30(2020 年第四季度)中引入了一个新命令,最初用于管理“git maintenance(man) 的部分内容并简化 crontab 条目(以及其他调度系统)的编写配置)。

请参阅commit 0016b61、commit 61f7a38、commit a4cb1a2(2020 年 10 月 15 日)、commit 2fec604、commit 0c18b70、commit 4950b2a、commit b08ff1f(2020 年 9 月 11 日)和commit 1942d48(2020 年 8 月 28 日) ) by Derrick Stolee (derrickstolee)。(由 Junio C Hamano -- gitster -- 合并于 commit 7660da1,2020 年 11 月 18 日)

for-each-repo:在配置的 repos 上运行子命令

签字人:Derrick Stolee

将存储库列表存储在全局或系统配置中,然后在该列表上迭代 Git 命令会很有帮助。 创建一个新的内置插件,让专家的这个过程变得简单。 在未来的更改中,我们将使用此内置函数对所有已配置的存储库运行定期维护。

测试非常简单,但强调“--”参数是可选的。

git for-each-repo 现在包含在其man page 中:

git-for-each-repo(1)

姓名

git-for-each-repo - 在存储库列表上运行 Git 命令

概要

[verse]
'git for-each-repo' --config=<config> [--] <arguments>

说明

在存储库列表上运行 Git 命令。之后的争论 已知选项或-- 指示符用作 Git 的参数 子进程。

此命令是实验性的。行为可能会改变。

例如,我们可以对存储库列表中的每一个运行维护 存储在 maintenance.repo 配置变量中使用


git for-each-repo --config=maintenance.repo 维护运行

这将为每个值 &lt;repo&gt; 运行 git -C &lt;repo&gt; maintenance run 在多值配置变量maintenance.repo中。

选项

--config=&lt;config&gt;

使用给定的配置变量作为多值列表存储 绝对路径名。迭代要运行的路径列表 给定的参数。

这些配置值是从系统、全局和本地 Git 配置加载的, 可用。如果 git for-each-repo 在不是 Git 仓库,则只使用系统和全局配置。

子进程行为

如果任何git -C &lt;repo&gt; &lt;arguments&gt; 子进程返回非零退出代码, 然后git for-each-repo 进程返回退出代码而不运行 更多子流程。

每个git -C &lt;repo&gt; &lt;arguments&gt;子进程都继承标准文件 描述符stdinstdoutstderr


对于 Git 2.30.1(2021 年第一季度),即使未定义配置变量 &lt;var&gt;,“git for-each-repo --config=&lt;var&gt; &lt;cmd&gt;(man) 也不应为任何存储库运行 &lt;cmd&gt;一次。

参见 Derrick Stolee (derrickstolee) 的 commit 6c62f01(2021 年 1 月 8 日)。(由 Junio C Hamano -- gitster -- 合并到 commit aa08688,2021 年 1 月 15 日)

for-each-repo: 空配置什么都不做

报告人:Andreas Bühmann帮助人:Eric Sunshine帮助人:Junio C Hamano签字人:Derrick Stolee

当配置键 'X' 没有值时,

'git for-each-repo --config=X'(man) 应该返回成功而不调用任何子命令。 当前的实现是段错误。

如果用户使用 'git maintenance start'(man) 使用 'git for-each-repo --config=maintenance.repo ...'(man) 但随后使用 'git maintenance unregister'(man) 删除配置选项。 (注意:'git maintenance stop'(man) 将删除配置删除 cron 计划。)

添加一个简单的测试以确保它有效。 使用 'git help --no-such-option'(man) 作为潜在的子命令,以确保在运行子命令时我们将失败。

【讨论】:

perl 和 python repo-finders 对于 oneliner 来说有点重,至少 perl 有点错误,它会错过有效的 repos。 find -name HEAD -execdir test -d refs -a -d objects \; -printf %h\\n 会做到的,在 Mac 上你需要 brew find 我想。您可以使用(IFS=$'\n'; find `locate */HEAD`…) 等来加快定位自上次更新后未克隆或初始化的存储库。 @jthill 同意。这个答案不是关于单线方法。这是为了说明新的命令。【参考方案4】:

lsgit 是执行此操作的脚本。它本质上是locate -br '^HEAD$' 的包装。

如果本地机器上有同一个repo的多个克隆,则表明这些repo是相关的。

【讨论】:

【参考方案5】:

使用 Powershell,您可以使用如下脚本将所有存储库添加到全局 git 变量:

$dirName = Split-Path -Path ./ -Leaf
$repoProp = "$dirName.repos"

$repos = Get-ChildItem . `
    -Attributes Directory+Hidden `
    -ErrorAction SilentlyContinue `
    -Filter ".git" `
    -Recurse

git config --global --unset-all $repoProp
$repos | ForEach-Object  git config --global --add $repoProp $_.Parent.FullName 

复制根文件夹中的脚本,然后运行它。 然后你可以使用git for-each-repo 命令,正如 VonC 解释的那样。

【讨论】:

【参考方案6】:

包装器:locate -br '^HEAD$' 由 Dee Newcum https://github.com/DeeNewcum/dotfiles/blob/master/bin/lsgit 或 find . -name 'HEAD' 完成,在 https://gist.github.com/nrbray/a0ae8ec59d1fd1ae03e2947368096d2e 中修改

提供了一种仅通过文件夹或文件名搜索 gits 的替代方法。

[没有足够的声誉来评论 Dee 的回答,但我使用了他的解决方案并且对我有用]

【讨论】:

请赢得声誉,然后评论添加评论作为答案误导。

以上是关于有没有办法列出终端中的所有 git 存储库?的主要内容,如果未能解决你的问题,请参考以下文章

有没有办法将外部文件提交到当前存储库?

有没有办法配置 git 存储库以拒绝“git push --force”?

Git 存储库克隆错误(终端提示已禁用)

有没有办法检查远程 git repo 是不是有更改,而无需实际获取更改?

有没有办法用 maven 签出 git 存储库到某个文件夹?

有没有办法将多模块 Maven 项目拆分为不同的 Git 存储库?