管理许多 git 存储库

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/816619/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 06:25:08  来源:igfitidea点击:

Managing many git repositories

gitmultiple-repositories

提问by iny

Setting up a project is easy in git and so I can have separate repository even for small script. Now the problem is how to manage them.

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

I work in multiple places with these repositories. When I have done changes to some repository, I want to be able to update the repositories in other places.

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

So I have a directory with many repositories in it.

所以我有一个包含许多存储库的目录。

  1. How can I fetch all of them?
  2. How can I check whether any of them have uncommitted changes?
  3. How can I check whether any of them have changes to merge?
  1. 我怎样才能获取所有这些?
  2. 如何检查其中是否有任何未提交的更改?
  3. 如何检查它们中的任何一个是否有要合并的更改?

And it would be nice to be able to do these with one command.

能够用一个命令完成这些会很好。

The output needs to be silent enough to actually notice the things to do.

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

采纳答案by iny

Looks like writing a script to do it is quite easy. Essentially it needs to iterate over the repositories and then use commands like git ls-files, git diff and git log.

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

回答by Sandro Giessl

I highly recommend the multiple repositories tool mr. I used to use a custom shell script as recommended by others for some time, but using mr has the following benefits for me:

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

  • It's generic: A conjunction of various version control systems can be used, not only git (e.g. Mercurial, SVN, etc.).
  • It's fast: mr can execute multiple jobs in parallel. I use a number of git/mercurial repositories and sync them several times a day. Mr tremendously speeds up this process.
  • It's easy and quick to manage the list of repository checkouts. Just use 'mr register' rather than modifying the list of projects in your custom script.
  • 它是通用的:可以使用各种版本控制系统的结合,而不仅仅是 git(例如 Mercurial、SVN 等)。
  • 速度很快:mr 可以并行执行多个作业。我使用了许多 git/mercurial 存储库并每天同步几次。Mr 极大地加快了这个过程。
  • 管理存储库检出列表既简单又快捷。只需使用 'mr register' 而不是修改自定义脚本中的项目列表。

Regarding to your question about silent output: The level of verbosity can be modified using the command line switch -q. I prefer the default output which appears to nicely unify the output in a short and clear summary.

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

I use the following alias for the mr command to ensure that mr always picks up my default project list stored in $HOME, and uses 5 parallel threads:

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

alias mr='mr -d ~/ -j 5 '

回答by Fabio Zadrozny

I must say I started with the currently accepted answer (just a bunch of helpers scripts that iterate over the repositories), but all in all, it was a lacking experience for me.

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

So, after trying mr, repo and git-submodules, I found each lacking in a different way, so, I ended up doing my own variant: http://fabioz.github.io/mu-repowhich is a mature tool at this point -- it has workflows which allow you to:

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

  • clone multiple repos
  • diff (and edit) current changes in multiple repos
  • preview incoming changes
  • run commands in multiple repos in parallel
  • create groups of repos
  • run non git-related commands over multiple repos
  • etc (see homepagefor more info).
  • 克隆多个仓库
  • 差异(和编辑)多个存储库中的当前更改
  • 预览传入的更改
  • 在多个存储库中并行运行命令
  • 创建回购组
  • 在多个 repos 上运行与 git 无关的命令
  • 等(有关更多信息,请参阅主页)。

Note that it supports any OS where Python runs ;)

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

回答by Memming

gr(git-run) extends mr's functionality (only for git). I find it easier to organize multiple git repos using its tag system. The code for gris not well maintained though. If you are using bash, make sure you use it with the -t taginstead of #tagform.

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

回答by Spoike

You could try using repowith a custom manifest.xmlfile to specify where your repositories are. There is some documentationon how to do this.

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

Alternatively you could use git-submodule(1).

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

回答by Seth Robertson

gitslaveis a tool which can run the same command over many repositories by creating a superproject/subproject relationship between the super and the subs. This (by default) provides output summarization so you can concentrate on the repositories which provide unique output (useful for git status, not so useful for git ls-files).

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

This is typically used for projects where you need to assemble several repositories together and keep them on the same branch or tag at the same time or whatever. For my directory of (bare) repositories I just have a little makefile which lets me run arbitrary git commands, which as you see I primarily use for fsck and gc:

这通常用于需要将多个存储库组装在一起并将它们同时保存在同一分支或标签上的项目。对于我的(裸)存储库目录,我只有一个小的 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

回答by Waescher

I wrote a tool called "RepoZ" which automatically discovers git repositories as soon as you clone them or change anything in them like switching a branch, for example.

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

Once found, the repositories are "tracked". That will simply show them in a list of local repositories including a dense status information inspired by posh-git. This contains the current branch and further stuff like file edits and the count of incoming or outgoing commits.

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

RepoZ UI

回购用户界面

This helps to keep track of your local repositories and unfinished work to commit or push. In addition, you can use the repository list as navigation to switch from one repository to another.

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

RepoZ Navigation

回购导航

"How can I fetch all of them?"

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

The version for Windows offers a context menu to fetch or pull a repository. With multi-select you can run actions on multiple repositories at once.

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

However, you might find another feature very useful:

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

RepoZ Auto-Fetch

RepoZ 自动获取

With Auto fetch, you can tell RepoZ to fetch the remotes of all your git repositories periodically in the background. These fetches won't collide with your local commits, of course. There are no local merge attempts like with git pull.

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

回答by Nathan

You can use the git-status-allgem for this: https://github.com/reednj/git-status-all

您可以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

There is also a fetch option that will fetch from origin for all the repositories before displaying the status:

还有一个 fetch 选项,可以在显示状​​态之前从所有存储库的 origin 中获取:

git status-all --fetch

git status all

git 状态全部

回答by Scotts

I use this script to easily execute git commands in all of my repositories.

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

#!/bin/sh
if [ ! "" = "" ] ; 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 "
            cd $GITREPO/$dir ; git $@
            echo
         fi

      done
   else

      echo "Git repositories not found."

   fi
fi

By default the script will look for git repositories in ~/cm/src but you can override this by setting the GITREPO environment variable to your liking.

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

This script is based on this script.

此脚本基于此脚本

回答by jaguililla

I've made an alias and a function to run any git command on all repositories available in a directory (recursively). You can find it here: https://github.com/jaguililla/dotfiles/git

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

This is the code:

这是代码:

#!/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 "$@" \;
}

Hope it helps :)

希望能帮助到你 :)

回答by RobBenz

If anyone is still looking at this thread please checkout my shell script called gitme

如果有人仍在查看此线程,请查看我的名为 gitme 的 shell 脚本

you will need to manually input your local git repos but i use this tool everyday to collaborate multiple git projects on multiple computers.

您需要手动输入本地 git 存储库,但我每天都使用此工具在多台计算机上协作多个 git 项目。

you can run git clone https://github.com/robbenz/gitme.git

你可以跑 git clone https://github.com/robbenz/gitme.git

also the script is posted below

脚本也发布在下面

#!/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

I setup an alias in my ~/.bash_profile so alias gitme='sh /path/to/gitme.sh'

我在 ~/.bash_profile 中设置了一个别名 alias gitme='sh /path/to/gitme.sh'