maneira fácil de puxar mais recente de todos os submódulos git
-
06-07-2019 - |
Pergunta
Estamos usando submódulos git para gerenciar um par de grandes projetos que dependem de muitas outras bibliotecas que desenvolvemos. Cada biblioteca é um repo separado trazidos para o projeto dependente como um sub-módulo. Durante o desenvolvimento, que muitas vezes querem apenas ir pegar a versão mais recente de cada sub-módulo dependente.
Git tem construído em um comando para fazer isso? Se não, como sobre um arquivo de lote do Windows ou similar que pode fazê-lo?
Solução
Se é pela primeira vez você check-out um repo que você precisa para uso --init
primeiro:
git submodule update --init --recursive
Para git 1.8.2 ou acima do --remote
opção foi adicionada para atualizar suporte para mais dicas de filiais remotas:
git submodule update --recursive --remote
Este tem a vantagem de respeitar quaisquer ramos "não padrão" especificados nos arquivos .gitmodules
ou .git/config
(se acontecer de você ter qualquer, o padrão é origin / master, caso em que algumas das outras respostas aqui iria funcionar tão bem ).
Para git 1.7.3 ou acima, você pode usar (mas o abaixo armadilhas em torno do que atualização não ainda se aplicam):
git submodule update --recursive
ou
git pull --recurse-submodules
Se você quer puxar seus submódulos os últimos commits intead do que os pontos de reporte para.
git-submódulo (1) para mais detalhes
Outras dicas
Se você precisa de coisas puxar para submódulos em seus repositórios submódulo usar
git pull --recurse-submodules
um git recurso aprendeu pela primeira vez em 1.7.3.
Mas isso vai se compromete a não verificação adequados (os seus repositório principal aponta para) em submódulos
Para conferir commits adequadas em seus submódulos você deve atualizá-los depois de puxar usando
git submodule update --recursive --remote
Na inicialização executando o seguinte comando:
git submodule update --init --recursive
de dentro do diretório repo git, funciona melhor para mim.
Isso vai puxar todos os mais recentes, incluindo sub-módulos.
Explicou
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.
Após isso, você pode simplesmente executar:
git submodule update --recursive
de dentro do diretório repo git, funciona melhor para mim.
Isso vai puxar todos os mais recentes, incluindo sub-módulos.
Nota:. Esta é a partir de 2009 e pode ter sido bom, então, mas há melhores opções agora
Nós usamos isso. É chamado 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
Basta colocá-lo em um diretório bin adequado (/ usr / / bin local). Se no Windows, pode ser necessário modificar a sintaxe para fazê-lo funcionar:)
Update:
Em resposta ao comentário pelo autor original sobre puxar em todas as cabeças de todos os submódulos -. Essa é uma boa pergunta ??p>
Eu tenho quase certeza que git
não tem um comando para isso internamente. A fim de fazer isso, você precisa identificar o que CABEÇA é realmente para um sub-módulo. Isso poderia ser tão simples como dizer master
é a mais até a filial data, etc ...
Em seguida, criar um script simples que faz o seguinte:
-
git submodule status
cheque de repositórios "modificados". O primeiro caractere das linhas de saída indica isso. Se um sub-repo é modificado, você pode não querer prosseguir. - para cada repo listado, cd para ele do diretório e execute
git checkout master && git pull
. Verifique se há erros. - No final, eu sugiro que você imprimir uma tela para o usuário para indicar o estado actual dos submódulos -? Talvez levá-los para adicionar todos e comprometer
Eu gostaria de mencionar que este estilo não é realmente o que submódulos git foram projetados para. Normalmente, você quer dizer "LibraryX" está na versão "2.32" e vai ficar assim até que eu diga a ele para "upgrade".
Isto é, em certo sentido, o que está fazendo com o roteiro descrito, mas apenas mais automaticamente. Cuidado é necessário!
Update 2:
Se você estiver em uma plataforma Windows, você pode querer olhar usando Python para implementar o script, pois é muito capaz nessas áreas. Se você estiver em Unix / Linux, então eu sugiro que apenas um script bash.
Precisa de quaisquer esclarecimentos? Basta postar um comentário.
Henrik está no caminho certo. O comando 'foreach' pode executar qualquer script shell arbitrários. Duas opções para puxar o mais recente pode ser,
git submodule foreach git pull origin master
e,
git submodule foreach /path/to/some/cool/script.sh
Isso vai percorrer todos inicializado submódulos e executar os comandos dados.
A seguir trabalhou para mim no Windows.
git submodule init
git submodule update
Editar :
Nos comentários foi apontado (por philfreo ) que a versão mais recente é necessária. Se não houver nenhum submódulos aninhados que precisam estar em sua versão mais recente:
git submodule foreach --recursive git pull
----- comentário desatualizado abaixo -----
Não é esta a maneira oficial de fazê-lo?
git submodule update --init
Eu usá-lo o tempo todo. Sem problemas até agora.
Editar:
Eu só descobri que você pode usar:
git submodule foreach --recursive git submodule update --init
O que também irá recursivamente puxar todos os submódulos, ou seja, dependências.
Como pode acontecer que o ramo padrão de seus submódulos é não master
, é assim que eu automatizar atualizações do Git completa submódulos:
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'
Primeira vez
Clone e Init Submódulo
git clone git@github.com:speedovation/kiwi-resources.git resources
git submodule init
Resto
Durante o desenvolvimento só puxar e atualização submodule
git pull --recurse-submodules && git submodule update --recursive
Atualização Git submódulo a mais recente comprometer em origem
git submodule foreach git pull origin master
forma preferida deve ser inferior
git submodule update --remote --merge
Nota: últimos dois comandos têm o mesmo comportamento
Eu não sei desde que versão do git isso está funcionando, mas é o que você está procurando:
git submodule update --recursive
Eu usá-lo com git pull
para atualizar o repositório de raiz, também:
git pull && git submodule update --recursive
http://lists.zerezo.com/git/msg674976.html que introduz um --track parâmetro
As respostas acima são boas, no entanto, estavam usando git-ganchos para tornar isso mais fácil, mas verifica-se que em git 2,14 , você pode definir git config submodule.recurse
como true para ativar submódulos para a atualizados quando você puxa para o seu repositório git.
Isto terá o efeito colateral de empurrar todos os submódulos mudar você tem, se eles estão em ramos no entanto, mas se você tiver necessidade de que o comportamento já este poderia fazer o trabalho.
Pode ser feito usando-se:
git config submodule.recurse true
Git para Windows 2.6.3 :
git submodule update --rebase --remote
Eu fiz isso através da adaptação gahooa 's resposta acima :
integrá-lo com um git [alias]
...
Se o seu projeto pai tem algo como isso em .gitmodules
:
[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
Adicionar algo como isto dentro de sua .gitconfig
[alias]
updatesubs = "!sh -c \"git submodule init && git submodule update && git submodule status\" "
Em seguida, atualizar seus submódulos, execute:
git updatesubs
Eu tenho um exemplo dele em meu ambiente configuração repo .
Aqui está a linha de comando para puxar de todos os seus repositórios git se eles são ou não submódulos:
ROOT=$(git rev-parse --show-toplevel 2> /dev/null)
find "$ROOT" -name .git -type d -execdir git pull -v ';'
Se você executá-lo em seu topo repositório git, você pode substituir "$ROOT"
em .
.
Tudo que você precisa fazer agora é um simples git checkout
Apenas certifique-se para habilitá-lo através desta configuração global: git config --global submodule.recurse true
A partir do nível superior no repo:
git submodule foreach git checkout develop
git submodule foreach git pull
Isso vai mudar todos os ramos para desenvolver e puxar mais recente
Eu acho que você vai ter que escrever um script para fazer isso. Para ser honesto, eu poderia instalar python para fazê-lo de modo que você pode usar os.walk
para cd
para cada diretório e emitir os comandos apropriados. Usando python ou alguma outra linguagem de script, além de lotes, que permitem que você adicione facilmente / subprojetos remove sem ter que modificar o script.
Observação:. Não muito fácil assim, mas viável e tem suas próprias vantagens únicas
Se alguém quiser clone única revisão HEAD
de um repositório e apenas HEAD
s de todos os seus sub-módulos (ou seja, para checkout "tronco"), então pode-se usar seguinte Lua script. Às vezes git submodule update --init --recursive --remote --no-fetch --depth=1
simples comando pode resultar em um erro git
irrecuperável. Neste caso, uma necessidade de limpar subdiretório do diretório .git/modules
e submodule clone manualmente usando comandos git clone --separate-git-dir
. A única complexidade é descobrir o URL , o caminho de diretório .git
de submodule e caminho do sub-módulo na árvore superproject.
Observação: o script só é testado contra repositório https://github.com/boostorg/boost.git
. Suas peculiaridades: todos os submódulos hospedado no mesmo host e .gitmodules
contém apenas relativa URL é
-- 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