Bir klasörden bir alt modül deposu oluşturun ve git commit geçmişini saklayın


111

Diğer web uygulamalarını belirli bir şekilde araştıran bir web uygulamam var. Bir demosklasörde bazı web demoları içerir ve demodan birinin artık kendi deposu olmalıdır. Bu demo uygulaması için ayrı bir depo oluşturmak ve bunu birAlt paket kayıt geçmişini kaybetmeden ana depodan alt modül .

İşlem geçmişini bir arşiv klasöründeki dosyalardan saklamak ve ondan bir havuz oluşturmak ve bunun yerine alt modül olarak kullanmak mümkün müdür ?


1 dizinini Git deposu A'dan Git deposu B'ye nasıl taşıyacağımı araştırıyordum. +1 makale bağlantısı için.
Chetabahana


Evet, bu gerçekten çok benzer, çözümler biraz farklı, bunu paylaştığınız için teşekkürler
GabLeRoux

Yanıtlar:


191

Ayrıntılı Çözüm

Npm kullanarak git alt modüllerine hızlı bir alternatif için bu cevabın sonundaki nota (son paragraf) bakın;)

Aşağıdaki cevapta, bir depodan bir klasörü nasıl çıkaracağınızı ve ondan bir git deposu oluşturacağınızı ve ardından onu bir klasör yerine bir alt modül olarak dahil edeceğinizi öğreneceksiniz .

Gerg Bayer'in Dosyaları Bir Git Deposundan Diğerine Taşıma, Geçmişi Koruma başlıklı makalesinden esinlenilmiştir.

Başlangıçta şöyle bir şeyimiz var:

<git repository A>
    someFolders
    someFiles
    someLib <-- we want this to be a new repo and a git submodule!
        some files

Adımlar feryat, ben bu sevk edecektir someLibolarak <directory 1>.

Sonunda şöyle bir şeye sahip olacağız:

<git repository A>
    someFolders
    someFiles
    @submodule --> <git repository B>

<git repository B>
    someFolders
    someFiles

Başka bir depodaki bir klasörden yeni bir git deposu oluşturun

Aşama 1

Bölmek için deponun yeni bir kopyasını alın.

git clone <git repository A url>
cd <git repository A directory>

Adım 2

Mevcut klasör yeni depo olacaktır, bu nedenle mevcut uzaktan kumandayı kaldırın.

git remote rm origin

Aşama 3

İstenen klasörün geçmişini çıkarın ve işleyin

git filter-branch --subdirectory-filter <directory 1> -- --all

Artık deponuzun directory 1kök dizininde bulunan ve ilgili tüm işleme geçmişiyle birlikte bir git deposuna sahip olmalısınız .

4. adım

Çevrimiçi deponuzu oluşturun ve yeni deponuzu itin!

git remote add origin <git repository B url>
git push

upstreamİlk itmeniz için şubeyi ayarlamanız gerekebilir

git push --set-upstream origin master

Temizle <git repository A>(isteğe bağlı, yorumlara bakın)

Bu klasörün geçmişinin izlerini (dosyaları ve işleme geçmişini) silmek istiyoruz <git repository B>, <git repository A>bu nedenle geçmiş yalnızca bir kez var.

Bu, hassas verilerin github'dan kaldırılmasına dayanmaktadır .

Yeni bir klasöre gidin ve

git clone <git repository A url>
cd <git repository A directory>
git filter-branch --force --index-filter 'git rm --cached --ignore-unmatch <directory 1> -r' --prune-empty --tag-name-filter cat -- --all

<directory 1>Kaldırmak istediğiniz klasörle değiştirin . -rbunu belirtilen dizin içinde yinelemeli olarak yapacak :). Şimdi etmek itmek origin/masterile--force

git push origin master --force

Boss Aşaması (Aşağıdaki Nota bakın)

Bir oluşturun submodule gelen <git repository B>INTO<git repository A>

git submodule add <git repository B url>
git submodule update
git commit

Her şeyin beklendiği gibi çalışıp çalışmadığını doğrulayın ve push

git push origin master

Not

Tüm bunları yaptıktan sonra, benim durumumda kendi bağımlılıklarımı yönetmek için npm kullanmanın daha uygun olduğunu fark ettim . Git url'leri ve sürümlerini belirleyebiliriz, bağımlılıklar olarak package.json git url'lerini görebiliriz .

Eğer bu şekilde yaparsanız, bir gereksinim olarak kullanmak istediğiniz deposu bir olmalıdır npm modülü bir içermelidir böylece package.jsondosya veya bu hatayı alırsınız: Error: ENOENT, open 'tmp.tgz-unpack/package.json'.

tldr (alternatif çözüm)

Git url'leri ile npm kullanmayı ve bağımlılıkları yönetmeyi daha kolay bulabilirsiniz :

  • Klasörü yeni bir depoya taşı
  • npm inither iki depoda da çalıştır
  • npm install --save git://github.com/user/project.git#commit-ishbağımlılıklarınızın kurulmasını istediğiniz yerde çalıştırın

39
"<Git deposunu A> temizle" adımından kaçınılmalıdır. Bunu yaparak eski sürümleri / taahhütleri geçmişinizden tam olarak geri yükleyemez / kullanıma alamazsınız. Sadece klasöre gitmeli ve alt modülü eklemelisiniz. Böylece, eski taahhütleri kontrol ederken tamamen çalışan bir kopyaya sahip olduğunuzdan emin olursunuz.
Cybot

2. Adımdan cd someLibönce yapman gerekmez mi? "Mevcut klasör yeni depo olacak" diyorsunuz ama aslında öyle olmayacak; yeni depo (alt modül) bu klasörün içindedir .
Jago

1
onaylama: evet, birden fazla alt modül için çalışıyor. Ayrıntılı cevap için çok teşekkürler. Ayrıca npm kullanmak zorunda kalmadı.
Breno Inojosa

2
3. adımda oluşturulan hakkında bilgi eklerim refs/original/....
Emile Bergeron

6
GitHub, bir klasörün yeni bir depoya nasıl çıkarılacağına dair bir makale hazırladı: help.github.com/articles/…
jrobichaud

9

@GabLeRoux'nun çözümü dalları eziyor ve ilgili taahhütler.

Tüm bu ekstra dalları ve taahhütleri klonlamanın ve saklamanın basit bir yolu:

1 - Bu git takma adına sahip olduğunuzdan emin olun

git config --global alias.clone-branches '! git branch -a | sed -n "/\/HEAD /d; /\/master$/d; /remotes/p;" | xargs -L1 git checkout -t'

2 - Uzaktan kumandayı klonlayın, tüm dalları çekin, uzaktan kumandayı değiştirin, dizininizi filtreleyin,

git clone git@github.com:user/existing-repo.git new-repo
cd new-repo
git clone-branches
git remote rm origin
git remote add origin git@github.com:user/new-repo.git
git remote -v
git filter-branch --subdirectory-filter my_directory/ -- --all
git push --all
git push --tags

3

GabLeRoux'nun çözümü git lfs, ayırmak istediğiniz dizinin altında büyük dosyalar kullanmanız dışında iyi çalışır . Bu durumda, 3. adımdan sonra tüm büyük dosyalar gerçek dosyalar yerine işaretçi dosyalar olarak kalacaktır. Sanırım bunun nedeni muhtemelen .gitattributesfiltre dalı işleminde kaldırılan dosyadır.

Bunu fark ederek, aşağıdaki çözümün benim için çalıştığını görüyorum:

cp .gitattributes .git/info/attributes

.gitattributesSilinmeyi önlemek için hangi git lfs'nin büyük dosyaları .git/dizine izlemek için kullandığı kopyalanıyor .

Filtre dalı tamamlandığında .gitattributes, yeni depo için hala git lfs kullanmak istiyorsanız, geri koymayı unutmayın :

mv .git/info/attributes .gitattributes
git add .gitattributes
git commit -m 'added back .gitattributes'
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.