【问题标题】:Git - How to find all "unpushed" commits for all projects in a directory?Git - 如何查找目录中所有项目的所有“未推送”提交?
【发布时间】:2012-09-19 16:44:32
【问题描述】:

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

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

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

  • 项目目录
    • 客户 X
    • project1(Git 代码库)
    • 客户U
    • project2(Git 存储库)
    • 项目3
      • somelibrary(Git 存储库)
      • 主题(Git 代码库)

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

欢迎任何帮助,谢谢。

【问题讨论】:

    标签: git bash


    【解决方案1】:

    您可以使用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-ing 回到目录,就像这样

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

    你可能想在这里的某个地方放一个pwd 命令来查看你所在的文件/目录...

    【讨论】:

    • 不要使用cd - 切换到上一个目录,您可以将循环的主体设置为子shell。
    • 只使用find + git,不需要shell:find . -name .git -type d -print -exec git --git-dir={} --work-tree={}/.. cherry -v \;
    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

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

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

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

      【讨论】:

        【解决方案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 以获得“领先于”短语。如果这是真的,则执行 && 之后的命令,在这种情况下是“pwd”命令。在这里您可以插入自己的命令(例如显示未推送的提交)。

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

        【讨论】:

        • 这适用于所有分支还是只适用于活动分支?
        • @DanStevens 不幸的是没有,刚刚测试过。试图找到一种仅在远程跟踪分支上显示未推送提交的方法,但尚未找到正确的方法。
        【解决方案5】:

        以下命令也支持带空格的路径,并且只会检查包含.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)
        

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

        【讨论】:

          【解决方案6】:

          将此别名添加到您的 .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

          【讨论】:

            【解决方案7】:

            这里是给那些使用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
            

            【讨论】:

              猜你喜欢
              • 2010-10-31
              • 1970-01-01
              • 1970-01-01
              • 2015-02-18
              • 2020-05-30
              • 1970-01-01
              • 2013-05-13
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多