Birden fazla git deposunu nasıl düzenlersiniz, böylece hepsi birlikte yedeklenir?


98

SVN ile, bir sunucuda tuttuğum ve birkaç makinede kontrol ettiğim tek bir büyük depom vardı. Bu oldukça iyi bir yedekleme sistemiydi ve herhangi bir makinede kolayca çalışmamı sağladı. Belirli bir projeyi kontrol edebilir, taahhüt edebilir ve 'ana' projeyi güncelleyebilir veya her şeyi kontrol edebilirim.

Şimdi, çeşitli projeler için, birçoğu github'da bulunan bir sürü git depom var. Git-svn komutuyla içe aktarılan bahsettiğim SVN deposuna da sahibim ..

Temel olarak, tüm kodumun (sadece projeler değil, rastgele parçacıklar ve komut dosyaları, özgeçmişim gibi bazı şeyler, yazdığım makaleler, yaptığım web siteleri vb.) Büyük bir depoda olmasını seviyorum. yedek olarak makineler veya bellek çubukları / sabit sürücüler.

Sorun, özel bir depo olduğundan ve git belirli bir klasörün teslim alınmasına izin vermediğinden (github'a ayrı bir proje olarak gönderebilirdim, ancak değişikliklerin hem ana depoda hem de alt depoları)

Ben olabilir git submodule sistemi kullanmak, ancak (o yedekleme için yararsız yani, submodules diğer depoları işaretçiler, ve gerçekten gerçek kod içermeyen) Ben de istiyorum nasıl harekete geçmediği

Şu anda git-repos klasörüm var (örneğin, ~ / code_projects / proj1 / .git / ~ / code_projects / proj2 / .git /) ve proj1'de değişiklikler yaptıktan git push githubsonra dosyaları ~ / içine kopyalıyorum. Documents / code / python / projects / proj1 / ve tek bir commit yapın (tek tek depolardaki sayısız yerine) O zaman yap git push backupdrive1, git push mymemorystickvb.

Öyleyse, soru şu: Kişisel kodunuz ve projeleriniz git depolarıyla nasıl senkronize edilir ve yedeklenir?

Yanıtlar:


74

İlgili olmayan verileri belirli bir Git deposuna koymamanızı şiddetle tavsiye ederim . Yeni depolar oluşturmanın ek yükü oldukça düşüktür ve bu, farklı soyları tamamen ayrı tutmayı mümkün kılan bir özelliktir .

Bu fikirle mücadele etmek, gereksiz yere karmaşık bir tarihle sonuçlanmak anlamına gelir, bu da yönetimi daha zor hale getirir ve - daha da önemlisi - sonuçta ortaya çıkan seyreltme nedeniyle "arkeoloji" araçlarını daha az kullanışlı hale getirir. Ayrıca, bahsettiğiniz gibi Git, "klonlama birimi" nin depo olduğunu varsayar ve pratikte dağıtılmış yapısı nedeniyle bunu yapmak zorundadır.

Çözümlerden biri, her projeyi / paketi / vb. Saklamaktır. kutsanmış bir hiyerarşi altında kendi çıplak deposu olarak (yani, çalışma ağacı olmadan), örneğin:

/repos/a.git
/repos/b.git
/repos/c.git

Birkaç kural oluşturulduktan sonra, "monolitik" SVN depolarından tamamen farklı olmayan bir rol sunan tam hiyerarşiye idari işlemleri (yedekleme, paketleme, web yayınlama) uygulamak önemsiz hale gelir. Biri o eklenmesiyle de SVN iş akışları için biraz benzer hale bu depoları ile çalışma yapabilirsiniz yerel kaydedilmesini ve dalları kullanın:

svn checkout   --> git clone
svn update     --> git pull
svn commit     --> git push

Birden çok taraf arasında senkronizasyon kolaylığı sağlamak için her çalışan klonda birden fazla uzaktan kumandanız olabilir:

$ cd ~/dev
$ git clone /repos/foo.git       # or the one from github, ...
$ cd foo
$ git remote add github ...
$ git remote add memorystick ...

Daha sonra, "kaynakların" her birinden getirebilir / çekebilir, yerel olarak çalışabilir ve taahhüt edebilir ve sonra hazır olduğunuzda bu uzaktan kumandaların her birine itebilir ("yedek") (bunun aynı işlemleri ve geçmişi nasıl uzaktan kumandaların her biri!):

$ for remote in origin github memorystick; do git push $remote; done

Mevcut bir çalışma havuzunu ~/dev/foo bu kadar çıplak bir depoya dönüştürmenin en kolay yolu muhtemelen:

$ cd ~/dev
$ git clone --bare foo /repos/foo.git
$ mv foo foo.old
$ git clone /repos/foo.git

bu çoğunlukla svn importa'ya eşdeğerdir , ancak var olan "yerel" tarihi atmaz.

Not: alt modüller , paylaşılan ilişkili kökenleri içeren bir mekanizmadır , bu nedenle onları gerçekten çözmeye çalıştığınız sorun için uygun bir araç olarak görmem.


18
Sonunda birçok ayrı depoya sahip olmam ve hepsini yönetmeye yardımcı olacak basit komut dosyaları yazmam, git'te eksik bir şeyler olduğunu hissettiriyor. Ne olduğuna veya ne yapacağıma tam olarak karar veremiyorum.
DonGar

Pek çok ayrı projeyi de yönetiyor musunuz? Projeler ve depolar arasındaki bire bir ilişki, dağıtılmış bir dünyada mantıklı geliyor, ancak yine de yedekleme ve yönetim kolaylığı için ortak bir dizin ağacında çıplak depoları düzenlerdim. (Başka bir deyişle, Git / Hg / Bzr sizi yönetimi proje görevlerinden ayırmaya zorlarken, çoğu SVN iş akışı ikisini birleştirir; artık insanların yönetim bölümünü
GitHub'a

2
bu fikir yalnızca kendi projelerinize ev sahipliği yapıyorsanız ve / veya hepsi açık kaynak kodluysa mantıklıdır. Aksi takdirde,
github'a

2
"Uzakta bulunan github memorystick için; git push $ remote; done" yerine, tek bir komutla birçok uzaktan kumandaya itmek için özel bir uzaktan kumanda yapılandırılabilir: stackoverflow.com/questions/36862/… . (Bazı durumlarda daha uygun olabilir.)
imzala - Ivan Zakharyaschev

2
Bence eksik olan şey, git'in nesnelerini alt ağaca göre ayrı tutmasının bir yolu, böylece tek bir "havuz", ayrı senkronize birimlerden (geri kalanı olmadan ayrı ayrı indirilen), insanların belirli bir şey üzerinde çalışabileceği şekilde oluşturulabilir. geri kalanını bilmeden alt kümeler.
peterk

28

Damien'ın cevabına önerdiği yerde eklemek istiyorum :

$ for remote in origin github memorystick; do git push $remote; done

Tüm bireysel gerçek uzaktan kumandaları 1 komutla göndermek için özel bir uzaktan kumanda kurabilirsiniz; Bunu http://marc.info/?l=git&m=116231242118202&w=2 adresinde buldum :

Yani "git push" için (aynı dalları birden çok kez itmenin mantıklı olduğu durumlarda), benim yaptığımı gerçekten yapabilirsiniz:

  • .git / config şunları içerir:

    [remote "all"]
    url = master.kernel.org:/pub/scm/linux/kernel/git/torvalds/linux-2.6
    url = login.osdl.org:linux-2.6.git
    
  • ve şimdi git push all master"ana" dalı bu uzak depoların her ikisine de gönderecektir
    .

Ayrıca, yapılandırmayı kullanarak URL'leri iki kez yazarak kendinizi kurtarabilirsiniz:

[url "<actual url base>"]
    insteadOf = <other url base>

3

Ayrıca bunun üstesinden gelmek için önerilen yolları merak ediyorum ve kullandığım mevcut kurulumu (SVN ile) açıklayacağım. Temel olarak, kendi bin ve lib dizinlerini içeren bir mini dosya sistemi hiyerarşisi içeren bir depo oluşturdum. Bu ağacın kökünde, ortamınızı bu bin, lib vb. Diğer dizinleri uygun ortam değişkenlerine ekleyecek şekilde ayarlayacak komut dosyası vardır. Yani kök dizini esasen şöyle görünür:

./bin/            # prepended to $PATH
./lib/            # prepended to $LD_LIBRARY_PATH
./lib/python/     # prepended to $PYTHONPATH
./setup_env.bash  # sets up the environment

Şimdi / bin ve / lib içinde birden çok proje ve bunlara karşılık gelen kitaplıklar var. Bunun standart bir proje olmadığını biliyorum, ancak grubumdaki başka birinin depoyu kontrol etmesi, 'setup_env.bash' komut dosyasını çalıştırması ve tüm projelerin yerel olarak en güncel sürümlerine kendi Çıkış yapmak. / Usr / bin veya / usr / lib'yi yükleme / güncelleme konusunda endişelenmelerine gerek yoktur ve her kontrol için birden fazla ödeme ve çok yerelleştirilmiş bir ortama sahip olmayı kolaylaştırır. Birisi ayrıca tüm depoyu yeniden çalıştırabilir ve herhangi bir programı kaldırma konusunda endişelenmeyebilir.

Bu bizim için iyi çalışıyor ve bunu değiştirip değiştirmeyeceğimizden emin değilim. Bununla ilgili sorun, bu tek büyük depoda çok sayıda proje bulunmasıdır. Böyle bir ortam yaratmanın ve projeleri kendi havuzlarına ayırmanın git / Hg / bzr standart bir yolu var mı?


3

, Git depolarını iç içe geçirmeyi henüz denemedim çünkü ihtiyacım olan bir durumla karşılaşmadım. #Git kanalında okuduğum gibi, depoları iç içe yerleştirerek git'in kafası karışmış görünüyor, yani git-init'i bir git deposunun içine koymaya çalışıyorsunuz. İç içe geçmiş bir git yapısını yönetmenin tek yolu, ya git-submoduleda Android'in repoyardımcı programını kullanmaktır.

Tanımladığınız yedekleme sorumluluğuna gelince, yetkilendirin diyorum ... Benim için genellikle her proje için "başlangıç" havuzunu iş yerindeki bir ağ sürücüsüne koyarım, bu da BT teknisyenleri tarafından düzenli olarak yedekleme stratejileri tarafından yedeklenir. seçim. Çok basit ve bunun için endişelenmeme gerek yok. ;)


2

Birden çok Git deponuzu aynı anda yönetmek için mr kullanmaya ne dersiniz :

Mr (1) komutu, sanki tek bir birleşik havuzmuş gibi bir dizi havuzda kullanıma alma, güncelleme veya diğer eylemleri gerçekleştirebilir. Subversion, git, cvs, mercurial, bzr, darcs, cvs, vcsh, fossil ve veracity depolarının her türlü kombinasyonunu destekler ve diğer revizyon kontrol sistemleri için destek kolayca eklenebilir. [...]

Basit kabuk komut dosyasıyla son derece yapılandırılabilir. Yapabileceği şeylerin bazı örnekleri şunları içerir:

[...]

  • Bir git deposunu güncellerken, iki farklı üst akıştan çekin ve ikisini birleştirin.
  • Birkaç depo güncellemesini paralel olarak çalıştırarak güncelleme sürecini büyük ölçüde hızlandırın.
  • Bir dizüstü bilgisayarın çevrimdışı olması nedeniyle başarısız olan eylemleri hatırlayın, böylece tekrar çevrimiçi olduğunda yeniden denenebilirler.

1

İç içe geçmiş git depolarına sahip olmanın başka bir yöntemi vardır, ancak peşinde olduğunuz sorunu çözmez. Yine de çözümü arayan diğerleri için:

En üst düzey git deposunda, iç içe geçmiş git deposunu içeren klasörü .gitignore içinde gizleyin. Bu, iki ayrı (ancak iç içe geçmiş!) Git deposuna sahip olmayı kolaylaştırır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.