Git - 如何查找目录中所有项目的所有“未删除”提交?

时间:2012-09-19 16:44:33

标签: git bash

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

到目前为止一切顺利,我可以很容易地“玩弄”它们,我会定期更改等等。问题是,几个小时后,我不记得我推送到远程存储库的项目。当然,我可以“cd”到每个项目的目录并发出push命令,但这很乏味。我想知道是否会有一种方法,使用bash,运行像 git find all unpushed commits in all projects in this directory 这样的东西。这样的命令将从 Git存储库的目录运行,但包含所有项目的树。

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

  • 项目目录
    • 客户X
    • project1 (Git repo)
    • 客户U
    • project2 (Git repo)
    • 项目3
      • somelibrary (Git repo)
      • 主题(Git repo)

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

欢迎任何帮助,谢谢。

7 个答案:

答案 0 :(得分:6)

您可以使用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命令,以查看您所在的文件/目录...

答案 1 :(得分:6)

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

clustergit允许您一次在多个存储库上运行git命令。在一个文件夹上递归运行git status特别有用。 clustergit支持git statusgit pullgit push等。

enter image description here

答案 2 :(得分:5)

将顶级作为git repo并使每个项目成为子模块。现在你可以运行

git submodule foreach --recursive git status # or any other command
如果您的项目中没有任何子模块,则不需要递归。

答案 3 :(得分:4)

您可以使用以下单行程序,您可以根据请求从不是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以获取“is ahead of”短语。如果这是真的,那么&&&执行,在这种情况下是'pwd'命令。在这里,您可以插入自己的命令(例如,显示未提交的提交)。

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

答案 4 :(得分: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"

另见this post

答案 5 :(得分:1)

以下命令也支持带空格的路径,并且只打印其中包含.git子目录的目录。

每个仓库的未按下更改数量(适用于所有分支):

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)

注意git cherry如果尚未设置上游(-u),则git log不起作用。

答案 6 :(得分:1)

以下是使用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