100

在 git 中设置项目很容易,因此即使对于小脚本,我也可以拥有单独的存储库。现在的问题是如何管理它们。

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

所以我有一个目录,里面有很多存储库。

  1. 我怎样才能获取所有这些?
  2. 如何检查其中是否有任何未提交的更改?
  3. 如何检查其中是否有要合并的更改?

如果能够用一个命令来完成这些工作,那就太好了。

输出需要足够安静才能真正注意到要做的事情。

4

24 回答 24

46

我强烈推荐多个存储库工具mr。我曾经使用过一段时间其他人推荐的自定义 shell 脚本,但使用 mr 对我来说有以下好处:

  • 它是通用的:可以使用各种版本控制系统的组合,而不仅仅是 git(例如 Mercurial、SVN 等)。
  • 速度很快:mr 可以并行执行多个作业。我使用许多 git/mercurial 存储库并每天同步它们几次。先生极大地加快了这个过程。
  • 管理存储库签出列表既简单又快捷。只需使用“mr register”而不是修改自定义脚本中的项目列表。

关于您关于静默输出的问题:可以使用命令行开关 -q 修改详细程度。我更喜欢默认输出,它看起来很好地将输出统一在一个简短而清晰的摘要中。

我为 mr 命令使用以下别名,以确保 mr 始终选择存储在 $HOME 中的我的默认项目列表,并使用 5 个并行线程:

alias mr='mr -d ~/ -j 5 '
于 2011-02-28T11:06:47.563 回答
21

我必须说我从当前接受的答案开始(只是一堆迭代存储库的帮助脚本),但总而言之,这对我来说是一种缺乏经验。

所以,在尝试了 mr、repo 和 git-submodules 之后,我发现每个模块都缺少不同的方式,所以,我最终做了自己的变体:http: //fabioz.github.io/mu-repo这是一个成熟的工具这一点 - 它具有允许您执行以下操作的工作流程:

  • 克隆多个仓库
  • 差异(和编辑)多个存储库中的当前更改
  • 预览传入的更改
  • 在多个存储库中并行运行命令
  • 创建回购组
  • 在多个 repos 上运行与 git 无关的命令
  • 等(有关更多信息,请参见主页)。

请注意,它支持任何运行 Python 的操作系统;)

于 2012-07-03T00:27:25.977 回答
16

gr (git-run) 扩展了mr的功能(仅适用于git)。我发现使用它的标签系统组织多个 git 存储库更容易。虽然代码gr维护得不好。如果您使用的是 bash,请确保将其与-t tag使用#tag

于 2014-10-18T22:40:27.760 回答
8

您可以尝试使用带有自定义文件的repomanifest.xml来指定存储库的位置。有一些关于如何执行此操作的文档。

或者,您可以使用git-submodule(1)

于 2009-05-03T09:30:52.157 回答
8

我编写了一个名为“ RepoZ ”的工具,它会在您克隆 git 存储库或更改其中的任何内容(例如切换分支)时自动发现它们。

一旦找到,存储库就会被“跟踪”。这只会在本地存储库列表中显示它们,包括受posh-git启发的密集状态信息。这包含当前分支和其他内容,例如文件编辑和传入或传出提交的计数。

回购用户界面

这有助于跟踪您的本地存储库和未完成的提交或推送工作。此外,您可以使用存储库列表作为导航,从一个存储库切换到另一个存储库。

回购导航

“我怎样才能把它们都拿回来?”

Windows 版本提供了一个上下文菜单来获取或拉取存储库。使用多选,您可以一次在多个存储库上运行操作。

但是,您可能会发现另一个非常有用的功能:

RepoZ 自动获取

使用自动获取,您可以告诉 RepoZ 在后台定期获取所有 git 存储库的远程。当然,这些提取不会与您的本地提交发生冲突。没有像 with 这样的本地合并尝试git pull

于 2019-01-07T11:55:21.867 回答
6

我编写了一个名为gita的命令行工具来管理多个 repos。它并排显示注册回购的状态,例如

在此处输入图像描述

它还可以从任何工作目录委派 git 命令/别名。

现在使用此工具回答您的问题:

我怎样才能获取所有这些?

gita fetch

如何检查其中是否有任何未提交的更改?

gita ll命令在分支名称旁边显示 3 个可能的符号,表示

  • +: 阶段性变化
  • *: 未分级的更改
  • _:未跟踪的文件/文件夹

如何检查其中是否有要合并的更改?

分支名称以 5 种方式着色

  • 白色:本地分支没有远程分支
  • 绿色:本地分支与远程分支相同
  • 红色:本地分支已与远程分支分道扬镳
  • 紫色:本地分支在远程分支之前(适合推送)
  • 黄色:本地分支在远程分支之后(适合合并)

要安装它,只需运行

pip3 install -U gita
于 2019-02-07T04:29:22.863 回答
5

gitslave是一个工具,它可以通过在 super 和 subs 之间创建超级项目/子项目关系来在许多存储库上运行相同的命令。这(默认情况下)提供输出摘要,因此您可以专注于提供唯一输出的存储库(对 git status 有用,对 git ls-files 不太有用)。

这通常用于需要将多个存储库组合在一起并将它们同时保存在同一个分支或标签上的项目。对于我的(裸)存储库目录,我只有一个小的 makefile,它可以让我运行任意 git 命令,如您所见,我主要用于 fsck 和 gc:

full: fsck-full gc-aggressive
        @:

fsck-full:
        for f in */.; do (cd $$f; echo $$f; git fsck --full || echo $$f FAILED); done

gc-aggressive:
        for f in */.; do (cd $$f; echo $$f; git gc --aggressive || echo $$f FAILED); done

%:
        for f in */.; do (cd $$f; git $@ || echo $$f FAILED); done
于 2012-03-15T16:11:42.003 回答
5

您可以git-status-all为此使用 gem:https ://github.com/reednj/git-status-all

# install the gem    
gem install git-status-all

# use the status-all subcommand to scan the directory
git status-all

还有一个 fetch 选项,它将在显示状态之前从所有存储库的源中获取:

git status-all --fetch

git状态全部

于 2016-12-22T02:32:43.343 回答
5

我已经创建了一个别名和一个函数,可以在目录中的所有可用存储库上运行任何 git 命令(递归)。你可以在这里找到它:https ://github.com/jaguililla/dotfiles/git

这是代码:

#!/bin/sh
# To use it: source git_aliases

# Example: rgita remote \;
alias rgita='find . -type d -name .git -execdir git'

# Example: rgit remote -vv
rgit() {
  rgita "$@" \;
}

希望能帮助到你 :)

于 2018-08-25T10:45:42.327 回答
4

我使用这个脚本在我的所有存储库中轻松执行 git 命令。

#!/bin/sh
if [ ! "$1" = "" ] ; then

   if [ "$GITREPO" = "" -a -d "$HOME/cm/src" ] ; then
      GITREPO="$HOME/cm/src"
   fi

   if [ "$GITREPO" != "" ] ; then

      echo "Git repositories found in $GITREPO"
      echo "-=-=-=-=-=-=-=-=-=-=-=-=-=-"

      DIRS="`/bin/ls -1 $GITREPO`"

      for dir in $DIRS ; do

         if [ -d $GITREPO/$dir/.git ] ; then
            echo "$dir -> git $1"
            cd $GITREPO/$dir ; git $@
            echo
         fi

      done
   else

      echo "Git repositories not found."

   fi
fi

默认情况下,脚本将在 ~/cm/src 中查找 git 存储库,但您可以根据自己的喜好设置 GITREPO 环境变量来覆盖它。

此脚本基于此脚本

于 2009-05-07T19:51:48.620 回答
2

如果有人还在看这个帖子,请查看我的名为 gitme 的 shell 脚本

您将需要手动输入本地 git 存储库,但我每天都使用此工具在多台计算机上协作多个 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'

于 2015-12-18T15:59:32.847 回答
2

为此,您可以使用everywhich 可以按照此模式在多个目录中运行 cli 命令every <command>

安装: npm i -g every-cli

使用示例: every git branch

- repo-1
  master
- repo-2
  develop
于 2021-02-07T17:06:53.133 回答
1

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

从文档:

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

于 2009-05-03T13:22:34.580 回答
1

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

  1. 我怎样才能获取所有这些?gmaster fetch
  2. 如何检查其中是否有任何未提交的更改?gmaster status
  3. 如何检查其中是否有要合并的更改?gmaster status

它被称为 gitmaster:https ://github.com/francoiscabrol/gitmaster

于 2016-10-22T16:02:00.890 回答
1

我将这个简单的 bash 函数写入我的 .bash_profile 中,以便能够仅在所有 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.
于 2018-04-25T14:45:40.580 回答
1

有一个方便的工具可以获取所有多个存储库。 git-pull-all是一个在多个 git 存储库上异步执行的命令行工具。

安装

npm install -g git-pull-all

用法

假设您有这些文件和目录:

~/Projects/
  cool-examples/
    .git/
  funny-movies/
  my-todos.txt
  super-express/
    .git/

当您git-pull-all在目录上运行命令时~/Projects,它应该找到子 git 存储库(在上述情况下为 cool-examplessuper-express)然后git pull在每个存储库上执行。

$ cd ~/Projects
$ git-pull-all
funny-movies/
Not a git repository
cool-examples/
Already up-to-date.
super-express/
Already up-to-date.
Done!
git-pull-all ~/Projects

GitHub链接:https ://github.com/tatsuyaoiw/git-pull-all

于 2019-07-30T06:42:04.137 回答
1

我找到了一个很好的解决方案,可以从所有具有 .git 文件夹的子目录中提取当前分支,即使每个 repo 都签出了不同的分支。该命令是单行的,足够灵活,可以针对不同的 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 

在当前目录 (find .) 中查找名称为 ".git" (-name .git) 的所有目录 (-type d),最多查找两个目录深度(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 pull origin 同时通过为当前分支运行 git rev-parse... 指定分支HEAD 提交。

{} \;

“{}”是我们从初始find命令获得的结果相对路径。这 ; 用于结束命令。

在 zsh 上的 MacOS 10.14.6 上测试。按原样,仅当远程和本地分支命名相同时才有效,AFAIK。

您可以修改它以获取状态。我希望您可以添加参数以进一步使其更加灵活,但我还没有尝试过。

于 2020-10-26T10:04:26.433 回答
1

我为此编写了一个 CLI 工具,请参见https://manicli.com/。它还有一些不错的附加功能:

  • 在许多 repos 上运行命令
  • 声明式配置
  • 灵活过滤,选择1个项目,项目有标签,或子路径
于 2022-02-18T22:37:12.550 回答
0

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

我怎样才能获取所有这些?
如何检查其中是否有要合并的更改?

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

在此处输入图像描述

如何检查其中是否有任何未提交的更改?

  • 在 UI 上,您可以查看每个存储库的文件状态(您可以单独或批量添加/删除它们)。

在此处输入图像描述

我正在研究这个,但这也解决了 OP 问题并帮助管理多个存储库,您可以使用 UI 或底层 GraphQL API 创建自己的脚本,请考虑将其作为另一种选择。

于 2019-06-17T13:12:30.837 回答
0

我使用 Visual Studio 代码。我们的代码库中有大约 20 个库,它们都是独立的 Git 存储库,Visual Studio Code 中的源代码控制选项卡非常适合“一目了然”地查看本地存储库的落后或领先程度。还有一些设置可以定期获取以使该信息保持最新,以及刷新按钮。

它不像脚本那么方便,但是当涉及到源代码控制时,我喜欢做一个做出改变的人。需要一个非常好的脚本来小心不要覆盖更改等。使用 VS Code 方法,您可以快速获得大量信息,您可以自己采取行动。

这是它的截图:

VS Code 中的源代码控制窗口

于 2019-09-24T16:37:30.573 回答
0

我使用我的代码编辑器(VS 代码)的多光标选择/多行编辑功能来创建批处理/shell 脚本并一次性执行它。通过这个简单愚蠢的解决方案,我知道我在做什么以及我可以从执行这些命令中得到什么。无需猜测,无需学习,无需定制。另一个原因是,每次我想对驻留在公共父目录中的不同存储库集执行命令时。

于 2020-11-18T11:52:34.247 回答
0

请按照以下步骤从所有存储库中提取代码:

  1. 使用扩展名为 .bat 创建一个新文件
  2. 将该文件放在您拥有所有存储库文件夹的同一层次结构中
  3. 编辑 .bat 文件并添加下面提到的脚本
FOR /D %%G in (%cd%\*) Do cd %%G & call git branch & call git pull & cd ..
echo All code pulled successfully!!
pause
  1. 保存文件并双击开始拉取代码
于 2021-07-09T21:14:54.360 回答
-1

https://github.com/wwjamieson3/envisionTools有一个名为 gitstat 的 bash 脚本,它可以执行此操作以及更多功能。它与 GNU 和 mac 兼容。如果被要求,它可以从远程执行获取。它显示未跟踪、修改、添加、删除和暂存的文件。它通过在遥控器上显示未合并的提交和未推送的本地提交来与遥控器不同。它还可以以摘要或详细模式甚至 HTML 显示颜色编码的结果。它使用 locate 而不是 find,因为它的速度无限快,并且如果它变得太旧,甚至会提示更新您的 locate 数据库。

于 2012-11-24T10:18:00.047 回答
-6

看起来写一个脚本来做这件事很容易。本质上,它需要遍历存储库,然后使用 git ls-files、git diff 和 git log 等命令。

于 2009-05-03T14:13:28.610 回答