Como você organiza vários repositórios git, para que seja feito backup de todos eles juntos?
Pergunta
Com o SVN, eu tinha um único grande repositório que mantinha em um servidor e fazia check-out em algumas máquinas.Este era um sistema de backup muito bom e me permitiu trabalhar facilmente em qualquer uma das máquinas.Eu poderia fazer check-out de um projeto específico, confirmar e atualizar o projeto 'mestre', ou poderia fazer check-out de tudo.
Agora, tenho vários repositórios git, para vários projetos, vários dos quais estão no github.Também tenho o repositório SVN que mencionei, importado através do comando git-svn.
Basicamente, gosto de ter todo o meu código (não apenas projetos, mas trechos e scripts aleatórios, algumas coisas como meu currículo, artigos que escrevi, sites que criei e assim por diante) em um grande repositório que posso facilmente clonar remotamente. máquinas ou cartões de memória/discos rígidos como backup.
O problema é que, como é um repositório privado, e o git não permite o check-out de uma pasta específica (que eu poderia enviar para o github como um projeto separado, mas fazer com que as alterações apareçam no repositório principal e no sub- repositórios)
EU poderia uso o sistema de submódulos git, mas ele também não funciona como eu quero (os submódulos são ponteiros para outros repositórios e não contêm realmente o código real, por isso é inútil para backup)
Atualmente tenho uma pasta de repositórios git (por exemplo, ~/code_projects/proj1/.git/ ~/code_projects/proj2/.git/) e depois de fazer alterações no proj1 eu faço git push github
, então copio os arquivos em ~/Documents/code/python/projects/proj1/ e faço um único commit (em vez dos numerosos nos repositórios individuais).Então faça git push backupdrive1
, git push mymemorystick
etc.
Então, a pergunta:Como fazer seu código pessoal e projetos com repositórios git e mantê-los sincronizados e com backup?
Solução
Eu poderia fortemente Aconselhar contra colocar dados não relacionados em um determinado repositório Git.A sobrecarga de criar novos repositórios é bastante baixa, e isso é um recurso Isso torna possível manter diferentes linhagens completamente separadas.
Lutar contra essa idéia significa acabar com a história desnecessariamente emaranhada, o que torna a administração mais difícil e-mais importante-ferramentas de "arqueologia" menos úteis devido à diluição resultante.Além disso, como você mencionou, o GIT assume que a "unidade de clonagem" é o repositório e praticamente precisa fazê -lo por causa de sua natureza distribuída.
Uma solução é manter cada projeto/pacote/etc.como seu próprio nuRepositório (ou seja, sem árvore de trabalho) sob uma hierarquia abençoada, como:
/repos/a.git
/repos/b.git
/repos/c.git
Depois que algumas convenções foram estabelecidas, torna -se trivial aplicar operações administrativas (backup, embalagem, publicação na web) à hierarquia completa, que tem um papel que não é totalmente diferente dos repositórios "monolíticos" do SVN.Trabalhar com esses repositórios também se torna um pouco semelhante aos fluxos de trabalho da SVN, com a adição que umpode use commits e ramificações locais:
svn checkout --> git clone
svn update --> git pull
svn commit --> git push
Você pode ter vários controles remotos em cada clone de trabalho, para a facilidade de sincronizar entre as várias partes:
$ cd ~/dev
$ git clone /repos/foo.git # or the one from github, ...
$ cd foo
$ git remote add github ...
$ git remote add memorystick ...
Você pode buscar/puxar de cada uma das "fontes", trabalhar e se comprometer localmente e depois empurrar ("backup") para cada um desses controles remotos quando estiver pronto com algo como (observe como isso empurra o mesmo Comprometes e história para cada um dos controles remotos!):
$ for remote in origin github memorystick; do git push $remote; done
A maneira mais fácil de transformar um repositório de trabalho existente ~/dev/foo
em um repositório tão vazio é provavelmente:
$ cd ~/dev
$ git clone --bare foo /repos/foo.git
$ mv foo foo.old
$ git clone /repos/foo.git
que é principalmente equivalente a um svn import
-mas não joga a história "local" existente.
Observação: submódulos são um mecanismo para incluir recursos compartilhados relacionadoLinhagens, então eu realmente não as consideraria uma ferramenta apropriada para o problema que você está tentando resolver.
Outras dicas
Eu quero adicionar A resposta de Damien onde ele recomenda:
$ for remote in origin github memorystick; do git push $remote; done
Você pode configurar um controle remoto especial para enviar para todos os controles remotos reais individuais com 1 comando;Eu encontrei em http://marc.info/?l=git&m=116231242118202&w=2:
Portanto, para "Git Push" (onde faz sentido empurrar os mesmos ramos várias vezes), você pode realmente fazer o que eu faço:
.git/config contém:
[remote "all"] url = master.kernel.org:/pub/scm/linux/kernel/git/torvalds/linux-2.6 url = login.osdl.org:linux-2.6.git
e agora
git push all master
irá enviar o branch "master" para ambos
desses repositórios remotos.
Você também pode evitar digitar os URLs duas vezes usando a construção:
[url "<actual url base>"] insteadOf = <other url base>
Também estou curioso sobre as maneiras sugeridas de lidar com isso e descreverei a configuração atual que uso (com SVN).Basicamente, criei um repositório que contém uma hierarquia de mini-sistema de arquivos, incluindo seus próprios diretórios bin e lib.Existe um script na raiz desta árvore que irá configurar seu ambiente para adicionar estes bin, lib, etc...outros diretórios para as variáveis de ambiente adequadas.Portanto, o diretório raiz se parece essencialmente com:
./bin/ # prepended to $PATH
./lib/ # prepended to $LD_LIBRARY_PATH
./lib/python/ # prepended to $PYTHONPATH
./setup_env.bash # sets up the environment
Agora dentro de /bin e /lib existem vários projetos e suas bibliotecas correspondentes.Eu sei que este não é um projeto padrão, mas é muito fácil para alguém do meu grupo verificar o repositório, executar o script 'setup_env.bash' e ter as versões mais atualizadas de todos os projetos localmente em seu Confira.Eles não precisam se preocupar em instalar/atualizar /usr/bin ou /usr/lib e é simples ter vários checkouts e um ambiente muito localizado por checkout.Alguém também pode simplesmente fazer rm em todo o repositório e não se preocupar em desinstalar nenhum programa.
Isso está funcionando bem para nós e não tenho certeza se vamos mudar isso.O problema com isso é que existem muitos projetos neste grande repositório.Existe uma maneira padrão git/Hg/bzr de criar um ambiente como este e dividir os projetos em seus próprios repositórios?
, Ainda não tentei aninhar repositórios git porque não me deparei com uma situação em que fosse necessário.Como li no #git canal O git parece ficar confuso ao aninhar os repositórios, ou seja,você está tentando git-init dentro de um repositório git.A única maneira de gerenciar uma estrutura git aninhada é usar git-submodule
ou Android repo
Utilitário.
Quanto à responsabilidade de backup que você está descrevendo, eu digo delegar isto...Para mim, normalmente coloco o repositório de "origem" de cada projeto em uma unidade de rede no trabalho, cujo backup é feito regularmente pelos técnicos de TI de acordo com a estratégia de backup de sua escolha.É simples e não preciso me preocupar com isso.;)
Que tal usar senhor para gerenciar seus vários repositórios Git de uma só vez:
O comando MR (1) pode fazer o check -out, atualizar ou executar outras ações em um conjunto de repositórios como se fossem um repositório combinado.Ele suporta qualquer combinação de subversão, GIT, CVS, Mercurial, BZR, DARCs, CVS, VCSH, repositórios fósseis e veracidade, e o suporte a outros sistemas de controle de revisão pode ser facilmente adicionado.[...]
É extremamente configurável por meio de scripts de shell simples.Alguns exemplos de coisas que isso pode fazer incluem:
[...]
- Ao atualizar um repositório git, extraia de dois upstreams diferentes e mescle os dois.
- Execute várias atualizações de repositório em paralelo, acelerando bastante o processo de atualização.
- Lembre-se de ações que falharam devido ao fato de um laptop estar off-line, para que possam ser repetidas quando ele ficar on-line novamente.
Existe outro método para ter repositórios git aninhados, mas isso não resolve o problema que você procura.Ainda assim, para outros que procuram a solução eu estava:
No repositório git de nível superior, apenas oculte a pasta em .gitignore que contém o repositório git aninhado.Isso facilita ter dois repositórios git separados (mas aninhados!).