10

我终于习惯了 Git,在经历了最初陡峭的学习曲线之后,我必须说它非常好(我只是想念单个文件的外部文件,但那是另一回事了)。然而,我有一个无法解决的问题:我目前正在同时处理十几个项目。它们都是相互关联的,我必须从一个跳到另一个,在这里和那里进行更改。

到目前为止一切都很好,我可以很容易地“处理”它们,我会定期提交更改等等。问题是,几个小时后,我不记得我将哪些项目推送到远程存储库。当然,我可以“cd”到每个项目的目录并发出 push 命令,但这很乏味。我想知道是否有办法使用 bash 来运行类似git find all unpushed commits in all projects in this directory. 这样的命令将从不是Git 存储库但包含所有项目的树的目录中运行。

逻辑很简单,但实现看起来相当复杂,另外一个原因是,虽然根目录包含所有项目,但实际的 Git 存储库可以在起始目录的任何级别找到。例如:

  • 项目目录
    • 客户 X
    • 项目 1(Git 存储库)
    • 客户 U
    • 项目 2(Git 存储库)
    • 项目3
      • 某个库(Git 存储库)
      • 主题(Git 仓库)

在此示例中,只有粗体目录是 Git 存储库,因此应在其中运行检查。我知道结构看起来有点乱,但实际上很容易处理。

欢迎任何帮助,谢谢。

4

7 回答 7

11

您可以使用 找到未推送的提交git cherry,因此您应该能够编写一个 bash 脚本,例如

#!/bin/bash
for file in `find ./ -type d -maxdepth 3` ; do
    cd $file
    git cherry -v
    cd -
done

它将找到 3 层子目录,但看起来可能不是很好。

编辑

正如 Evan 建议的那样,您可以使用子shell 来避免cd返回目录,就像这样

#!/bin/bash
for file in `find ./ -type d -maxdepth 3` ; do
    (cd $file && git cherry -v)
done

您可能想pwd在此处放置一个命令以查看您所在的文件/目录...

于 2012-09-19T17:02:45.990 回答
6

你可以看看 git 子模块,但我个人觉得使用它们并不愉快。前段时间我创建了一个脚本来处理 git repos 的集合:https ://github.com/mnagel/clustergit

clustergit允许您一次在多个存储库上运行 git 命令。在一个文件夹上递归运行 git status 尤其有用。clustergit支持git status, git pull,git push等。

在此处输入图像描述

于 2016-06-29T08:20:33.347 回答
5

将顶层设为 git repo 并将每个项目设为子模块。现在你可以运行

git submodule foreach --recursive git status # or any other command

如果您的项目中没有任何子模块,则不需要递归。

于 2012-09-19T17:21:42.437 回答
5

您可以使用以下单行代码,您可以根据您的要求使用它从不是 Git 存储库的目录中进行搜索。这将列出具有未推送提交的 git 存储库的绝对路径:

find . -type d -iname '.git' -exec sh -c 'cd "${0}/../" && git status | grep -q "is ahead of" && pwd' "{}" \;

这通过递归搜索 .git 目录来工作,当找到时 cd 到父目录,即 git 项目根目录。然后运行 ​​git status 和 grep 以获得“领先于”短语。如果这是真的,则执行 && 之后的命令,在这种情况下是“pwd”命令。在这里您可以插入自己的命令(例如显示未推送的提交)。

注意:仅适用于活动分支上的未推送提交

于 2015-10-28T13:03:26.013 回答
3

以下命令也支持带空格的路径,并且只会检查包含子目录的目录.git

每个 repo 的未推送更改数(对于所有分支):

while IFS= read -r -d '' dir; 
    do 
        ([ -d "$dir/.git" ] && cd "$dir" && echo -n `pwd`\
        && echo " [ UNPUSHED: "`git log --branches --not --remotes | grep "^commit" | wc -l`" ]" ); 
    done < <(find -type d -print0)

每个 repo 的未提交文件数(暂存和未暂存):

while IFS= read -r -d '' dir; 
    do 
        ([ -d "$dir/.git" ] && cd "$dir" && echo -n `pwd`\
         && echo " [ UNCOMMITTED: "`git status -s | wc -l`" ]"); 
    done < <(find -type d -print0)

如果没有设置上游 (-u),则注释git cherry不起作用,而git log上面的设置。

于 2017-06-14T20:23:08.607 回答
2

对于那些使用fish. 基于 JKirchartz 的回答并进行了一些调整:

for file in (find . -type d -maxdepth 3)
  if test -d "$file/.git"
    fish -c "cd $file; and git cherry -v; and pwd"
  end
end
于 2018-06-08T07:55:18.133 回答
2

将此别名添加到您的.gitconfig文件中,然后您可以git status-all从父目录运行以递归方式获取所有 git 存储库的状态。

[alias]
status-all = "!for d in `find . -name \".git\"`; do echo \"\n*** Repository: $d ***\" && git --git-dir=$d --work-tree=$d/.. status; done"

另见这篇文章

于 2015-11-18T15:35:44.980 回答