轻松获取所有git子模块的最新版本

轻松获取所有git子模块的最新版本,git,git-submodules,Git,Git Submodules,我们使用git子模块来管理几个大型项目,这些项目依赖于我们开发的许多其他库。每个库都是作为子模块引入从属项目的独立repo。在开发过程中,我们通常只想获取每个依赖子模块的最新版本 git是否有内置的命令来执行此操作?如果没有,那么Windows批处理文件或类似的文件可以吗?注意:这是从2009年开始的,当时可能很好,但现在有更好的选择。 我们用这个。它被称为git pup: #!/bin/bash # Exists to fully update the git repo that you ar

我们使用git子模块来管理几个大型项目,这些项目依赖于我们开发的许多其他库。每个库都是作为子模块引入从属项目的独立repo。在开发过程中,我们通常只想获取每个依赖子模块的最新版本


git是否有内置的命令来执行此操作?如果没有,那么Windows批处理文件或类似的文件可以吗?

注意:这是从2009年开始的,当时可能很好,但现在有更好的选择。

我们用这个。它被称为
git pup

#!/bin/bash
# Exists to fully update the git repo that you are sitting in...

git pull && git submodule init && git submodule update && git submodule status
只需将其放入一个合适的bin目录(/usr/local/bin)。如果在Windows上,您可能需要修改语法以使其正常工作:)

更新:

作为对原作者关于引入所有子模块的所有头的评论的回应,这是一个好问题

我很确定,
git
内部没有用于此的命令。为此,您需要确定子模块的真正头部。这可以简单地说,
master
是最新的分支,等等

接下来,创建一个简单脚本,执行以下操作:

  • 检查“已修改”存储库的git子模块状态。输出行的第一个字符表示这一点。如果修改了次级回购,您可能不想继续
  • 对于列出的每个回购,将cd放入其目录中并运行
    git checkout master&&git pull
    。检查错误
  • 最后,我建议您向用户打印一个显示,以指示子模块的当前状态——可能会提示他们添加所有和提交
  • 我想说的是,这种风格并不是git子模块设计的真正目的。通常,您会说“LibraryX”的版本是“2.32”,并且会一直这样,直到我告诉它“升级”

    从某种意义上说,这就是您使用所描述的脚本所做的事情,但只是更加自动。需要小心

    更新2:

    如果您在windows平台上,您可能需要考虑使用Python来实现脚本,因为它在这些方面非常强大。如果您使用的是unix/linux,那么我建议只使用bash脚本


    需要澄清吗?只需发表评论。

    我认为您必须编写一个脚本来完成此操作。老实说,我可能会安装python来执行此操作,这样您就可以使用
    os.walk
    To
    cd
    对每个目录执行相应的命令。使用python或批处理以外的其他脚本语言,您可以轻松添加/删除子项目,而无需修改脚本。

    如果是第一次签出回购,您需要首先使用
    --init

    git submodule update --init --recursive
    
    对于git 1.8.2或更高版本,添加了选项
    --remote
    ,以支持更新远程分支的最新提示:

    git submodule update --recursive --remote
    
    这还有一个额外的好处,即尊重
    .gitmodules
    .git/config
    文件中指定的任何“非默认”分支(如果碰巧有,默认值是origin/master,在这种情况下,这里的一些其他答案也可以使用)

    对于git 1.7.3或更高版本,您可以使用(但以下是仍然适用的更新):

    或:

    如果您想将子模块拉到最新提交,而不是repo指向的当前提交


    有关详细信息,请参见

    亨里克走上了正确的道路。“foreach”命令可以执行任意shell脚本。最新的两种选择可能是

    git submodule foreach git pull origin master
    
    以及

    它将遍历所有初始化的子模块并运行给定的命令。

    编辑

    philfreo在评论中指出,需要最新版本。如果有任何嵌套子模块需要在其最新版本中:

    git submodule foreach --recursive git pull
    
    ----下面的过时评论---

    这不是官方的做法吗

    git submodule update --init
    
    我每次都用它。到目前为止没有问题

    编辑:

    我刚刚发现您可以使用:

    git submodule foreach --recursive git submodule update --init 
    

    它还将递归地提取所有子模块,即依赖项。

    以下内容在Windows上适用于我

    git submodule init
    git submodule update
    

    我不知道这是哪个版本的git,但这正是您要搜索的:

    git submodule update --recursive
    
    我也将它与git pull一起使用来更新根存储库:

    git pull && git submodule update --recursive
    
    git在1.8.5中首次学习到的功能。

    在修复之前,您第一次确实需要运行

    git子模块更新--初始化--递归


    由于子模块的默认分支可能是而不是
    master
    ,因此我将自动完成完整Git子模块的升级:

    git submodule init
    git submodule update
    git submodule foreach 'git fetch origin; git checkout $(git rev-parse --abbrev-ref HEAD); git reset --hard origin/$(git rev-parse --abbrev-ref HEAD); git submodule update --recursive; git clean -dfx'
    
    在init上运行以下命令: 在git repo目录中,它最适合我

    这将拉动包括子模块在内的所有最新模块

    解释 在git repo目录中,它最适合我

    这将第一次拉取所有最新的模块,包括子模块。

    克隆和初始化子模块

    git clone git@github.com:speedovation/kiwi-resources.git resources
    git submodule init
    
    休息 在开发过程中,只需拉动和更新子模块

    git pull --recurse-submodules  && git submodule update --recursive
    
    将Git子模块更新为源上的最新提交 首选方式如下
    注意:最后两个命令具有相同的行为

    下面是从所有git存储库中提取的命令行,无论它们是否为子模块:

    ROOT=$(git rev-parse --show-toplevel 2> /dev/null)
    find "$ROOT" -name .git -type d -execdir git pull -v ';'
    

    如果您在顶级git存储库中运行它,您可以将
    “$ROOT”
    替换为

    备注:这不是一种简单的方法,但可行,而且它有自己独特的优点

    如果只想克隆存储库的
    HEAD
    版本,只想克隆其所有子模块的
    HEAD
    s(即签出“trunk”),那么可以使用以下Lua脚本。有时简单的命令
    git子模块更新--init--recursive--remote--no-fetch--depth=1<
    
    git submodule init
    git submodule update
    git submodule foreach 'git fetch origin; git checkout $(git rev-parse --abbrev-ref HEAD); git reset --hard origin/$(git rev-parse --abbrev-ref HEAD); git submodule update --recursive; git clean -dfx'
    
    git submodule update --init --recursive
    
    git - the base command to perform any git command
        submodule - Inspects, updates and manages submodules.
            update - Update the registered submodules to match what the superproject
            expects by cloning missing submodules and updating the working tree of the
            submodules. The "updating" can be done in several ways depending on command
            line options and the value of submodule.<name>.update configuration variable.
                --init without the explicit init step if you do not intend to customize
                any submodule locations.
                --recursive is specified, this command will recurse into the registered
                submodules, and update any nested submodules within.
    
    git submodule update --recursive
    
    git clone git@github.com:speedovation/kiwi-resources.git resources
    git submodule init
    
    git pull --recurse-submodules  && git submodule update --recursive
    
    git submodule foreach git pull origin master
    
    git submodule update --remote --merge
    
    ROOT=$(git rev-parse --show-toplevel 2> /dev/null)
    find "$ROOT" -name .git -type d -execdir git pull -v ';'
    
    -- mkdir boost ; cd boost ; lua ../git-submodules-clone-HEAD.lua https://github.com/boostorg/boost.git .
    local module_url = arg[1] or 'https://github.com/boostorg/boost.git'
    local module = arg[2] or module_url:match('.+/([_%d%a]+)%.git')
    local branch = arg[3] or 'master'
    function execute(command)
        print('# ' .. command)
        return os.execute(command)
    end
    -- execute('rm -rf ' .. module)
    if not execute('git clone --single-branch --branch master --depth=1 ' .. module_url .. ' ' .. module) then
        io.stderr:write('can\'t clone repository from ' .. module_url .. ' to ' .. module .. '\n')
        return 1
    end
    -- cd $module ; git submodule update --init --recursive --remote --no-fetch --depth=1
    execute('mkdir -p ' .. module .. '/.git/modules')
    assert(io.input(module .. '/.gitmodules'))
    local lines = {}
    for line in io.lines() do
        table.insert(lines, line)
    end
    local submodule
    local path
    local submodule_url
    for _, line in ipairs(lines) do
        local submodule_ = line:match('^%[submodule %"([_%d%a]-)%"%]$')
        if submodule_ then
            submodule = submodule_
            path = nil
            submodule_url = nil
        else
            local path_ = line:match('^%s*path = (.+)$')
            if path_ then
                path = path_
            else
                submodule_url = line:match('^%s*url = (.+)$')
            end
            if submodule and path and submodule_url then
                -- execute('rm -rf ' .. path)
                local git_dir = module .. '/.git/modules/' .. path:match('^.-/(.+)$')
                -- execute('rm -rf ' .. git_dir)
                execute('mkdir -p $(dirname "' .. git_dir .. '")')
                if not execute('git clone --depth=1 --single-branch --branch=' .. branch .. ' --separate-git-dir ' .. git_dir .. ' ' .. module_url .. '/' .. submodule_url .. ' ' .. module .. '/' .. path) then
                    io.stderr:write('can\'t clone submodule ' .. submodule .. '\n')
                    return 1
                end
                path = nil
                submodule_url = nil
            end
        end
    end
    
    [submodule "opt/submodules/solarized"]
        path = opt/submodules/solarized
        url = git@github.com:altercation/solarized.git
    [submodule "opt/submodules/intellij-colors-solarized"]
        path = opt/submodules/intellij-colors-solarized
        url = git@github.com:jkaving/intellij-colors-solarized.git
    
    [alias]
        updatesubs = "!sh -c \"git submodule init && git submodule update && git submodule status\" "
    
    git updatesubs
    
    git config submodule.recurse true
    
    git submodule foreach git checkout develop
    git submodule foreach git pull
    
    git pull
    git submodule foreach --recursive git checkout master
    git submodule foreach --recursive git pull