管理多个Git仓库

118

在 Git 中设置项目非常容易,因此我甚至可以为小脚本设置单独的存储库。现在的问题是如何管理它们。

我在多个地方使用这些存储库。当我对某些存储库进行更改时,我希望能够更新其他位置的存储库。

因此,我有一个包含许多存储库的目录。

  1. 如何获取所有存储库?
  2. 如何检查它们中是否有任何未提交的更改?
  3. 如何检查它们中是否有需要合并的更改?

最好能够用一个命令完成这些操作。

输出需要足够简洁,以便注意到需要处理的事项。


相同的问题已经为 hg mercurial 回答 - Serge Stroobandt
2
注意:自Git 2.30(2020年第四季度)起,您现在可以使用新的git for-each-repo命令。 - VonC
1
@sesm 你应该能够在 git for-each-repo 循环中运行 git rev-parse --git-dir 命令序列:这将显示每个存储库的根文件夹。 - VonC
1
@sesm 你可以运行 git for-each-repo --config=<config> -- xxx args:这将在 $PATH 中查找 git-xxx 可执行文件,其中你可以放置任意数量的逗号。 - VonC
@sesm 很棒,干得好! - VonC
显示剩余5条评论
26个回答

3

为此,您可以使用every工具,在多个目录中运行cli命令,遵循以下模式:every <command>

安装: npm i -g every-cli

用法示例: every git branch

- repo-1
  master
- repo-2
  develop

2
如果仍有人关注这个帖子,请查看我的Shell脚本gitme。
你需要手动输入本地的git repos,但我每天都使用这个工具来在多台电脑上协作多个git项目。
你可以运行“git clone https://github.com/robbenz/gitme.git”
此外,该脚本已发布如下。
#!/bin/bash -e

REPOS=( 
/Users/you/gitrepo1
/Users/you/gitrepo2
/Users/you/gitrepo3
/Users/you/gitrepo4
)

MOVE="Moving to next REPO... \n" 

tput setaf 2;echo "What ya wanna do? You can say push, pull, commit, ftp push, or status"; tput sgr0

read input

if [ $input =  "commit" ]
then
    tput setaf 2;echo "Do you want a unique commit message? [y/n]";tput sgr0
    read ans
    if [ $ans = "y" ]
    then 
        for i in "${REPOS[@]}"
        do
            cd "$i"
            tput setaf 6;pwd;tput sgr0 
            git add . -A
            read -p "Commit description: " desc  
            git commit -m "$desc"
            tput setaf 2;echo  $MOVE;tput sgr0 
            sleep 1
        done 
    else 
        for i in "${REPOS[@]}"
        do
            cd "$i"
            tput setaf 6;pwd;tput sgr0 
            git add . -A
            git commit -m "autocommit backup point"
            tput setaf 2;echo  $MOVE;tput sgr0 
            sleep 1
        done
    fi 
elif [ $input = "push" ] || [ $input = "pull" ] || [ $input = "ftp push" ] || [ $input = "status" ]
    then
        for i in "${REPOS[@]}"
do
    cd "$i"
    tput setaf 6;pwd;tput sgr0 
    git $input 
    tput setaf 2;echo  $MOVE;tput sgr0 
    sleep 1
    done 
else tput setaf 1;echo "You have zero friends";tput sgr0 
fi

我在我的~/.bash_profile中设置了一个别名,如下所示:alias gitme='sh /path/to/gitme.sh'


2
我为此编写了一个CLI工具,请参见https://manicli.com/。它还具有一些不错的附加功能:
  • 在许多仓库上运行命令
  • 声明式配置
  • 灵活的过滤,选择一个项目、具有标签的项目或子路径

2
我找到了一个很好的解决方案,可以从所有具有.git文件夹的子目录中拉取当前分支,即使每个仓库都检出了不同的分支。 这个命令只有一行,足够灵活,可以修改为不同的git命令,并且可以设置别名。 只需复制并粘贴以下内容:
find . -type d -maxdepth 2 -name .git -exec sh -c 'cd "$0" && cd .. && git pull origin $(git rev-parse --abbrev-ref HEAD)' {} \;

分解:

find . -type d -maxdepth 2 -name .git 

在当前目录中查找所有名称为".git"的目录(-name .git)(查找.),最多查找两个目录深度(2而不是1,因为我们正在寻找git repo文件夹中的git文件夹)。

-exec sh -c 

运行以下shell命令(exec sh -c)

'cd "$0" && cd .. && git pull origin $(git rev-parse --abbrev-ref HEAD)'

将目录更改为第一个参数(cd“$0”),然后向上更改一个级别以离开.git文件夹(cd ..),然后运行git rev-parse...来指定分支以拉取源,以获取当前分支的HEAD提交。

{} \;

"{}"是我们从初始find命令中得到的相对路径结果。;用于结束命令。

在zsh上测试了MacOS 10.14.6。目前只有在远程和本地分支名称相同时才能正常工作。

您可以修改此内容以获取状态。我相信您可能能够添加参数以进一步使其更加灵活,但我尚未尝试过。


1
我在我的.bash_profile中编写了这个简单的bash函数,以便能够在所有git存储库中运行git、maven、gradle或任何其他bash命令:
# usefull function to work with multiple git repositories
all() {
    failed=0
    printf '>>> START RUNNING: "%s" >>>' "$*"
    for d in */; do
        pushd "$d" > /dev/null
        if [ -d ".git" ]
        then
            printf '\n--------------------------------------------\n\n'
            pwd
            eval $@
            if [ $? -ne 0 ]
            then
                failed=1
                break;
            fi
        fi
        popd > /dev/null
    done
    if [ $failed -eq 0 ]
    then
        printf '\n--------------------------------------------\n'
        printf '<<< RAN "%s" WITH SUCCESS!!! <<<' "$*"
    else
        printf '\n<<< FAILED!!! <<<'
    fi
}

这可以这样使用

all git st
all git pull
all ./gradlew clean test
etc.

你也可以使用以下命令并行运行它们:all './gradlew clean test &' - ChaudPain

1
我使用Visual Studio Code。我们的代码库中有大约20个库,它们都是单独的Git仓库,Visual Studio Code中的源代码控制选项卡非常适合快速查看本地仓库的更新情况。还有定期获取设置以保持信息最新状态以及刷新按钮。
虽然这不像脚本那样方便,但对于源代码控制来说,我喜欢自己进行更改。编写非常良好的脚本需要小心不要覆盖更改等。通过VS Code方法,您可以快速获得大量信息,以便自己采取行动。
以下是屏幕截图:

Source control window in VS Code


1

声明:我正在www.repoflow.com上开发此工具。

如何获取它们所有的内容?
如何检查是否有任何更改需要合并?

  • 您可以获取涉及的所有存储库(或推送/拉取/提交它们)。获取后,UI 将使用新的存储库状态进行更新,如果存储库分歧,则可以看到冲突的种类并开始合并它们。

enter image description here

我该如何检查它们中是否有未提交的更改?
  • 在用户界面上,您可以查看每个存储库的文件状态(您可以单独或批量添加/删除它们)。

enter image description here

我正在处理这个问题,但也同时解决了OP的问题,并有助于管理多个存储库,您可以使用UI或基础GraphQL API创建自己的脚本,请将其视为另一种选择。

1

https://dev59.com/DXRA5IYBdhLWcg3wzhbZ#816674 的基础上进行扩展(现在该存储库可在 GitHub 上获得)

我建议您检查一下这个工具 https://github.com/googleapis/github-repo-automation,它是 Google 用来管理多个仓库的。

关于您提出的关于提交更改的问题,更改应该是 PR,这样您就可以对其做出反应。

https://github.com/tj/git-extras 可以帮助您为您的场景编写脚本。

  1. 如何获取它们的所有内容? 在google解决方案中使用 repo sync 命令

  2. 如何检查它们是否有未提交的更改? 您可以使用库功能轻松编写自己的逻辑。

  3. 如何检查它们是否有需要合并的变更? PR 应该是分支需要合并的最终指示,但如果您有其他逻辑 - 使用上述方法。

查看 git extras 命令以获取想法,请参见 https://github.com/tj/git-extras/blob/master/Commands.md#git-show-unmerged-branches


1

我刚刚创建了一个工具,可以做你想要的事情!

  1. 如何获取它们所有?gmaster fetch
  2. 如何检查它们是否有未提交的更改?gmaster status
  3. 如何检查它们是否有需要合并的更改?gmaster status

它叫做 gitmaster: https://github.com/francoiscabrol/gitmaster


1

你应该在 CPAN 上查看 rgit,它可以递归地在目录树中的所有存储库上执行 git 命令。

从文档中可以看到:

此实用程序会在根目录(可能是当前工作目录或 - 如果已设置 - 由 GIT_DIR 环境变量给出的目录)中递归搜索所有 git 存储库,按存储库路径对此列表进行排序,进入每个存储库并执行指定的 git 命令。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接