Basit çözüm: Birleştirdikten sonra 'iş' dalını kaldırın
Kısa cevap: git'i istediğiniz gibi kullanabilirsiniz (birleştirme dahil olmak üzere basit bir iş akışı için aşağıya bakın). Geçici çalışma dalını silmek için ' git branch -d work ' ile her ' git merge work ' komutunu izlediğinizden emin olun .
Arka plan açıklaması:
Birleştirme / dcommit sorunu, bir dalı 'git svn dcommit' olduğunda, bu dalın birleştirme geçmişinin 'düzleştirildiğidir': git, bu dalda giden tüm birleştirme işlemlerini unutur: Yalnızca dosya içeriği korunur, ancak bu içeriğin (kısmen) başka bir branştan gelmesi kaybolur. Bakınız: git svn dcommit neden yerel şubeler için birleştirme taahhütlerinin geçmişini kaybediyor?
(Not: Git-svn'nin bu konuda yapabileceği pek bir şey yoktur: svn, çok daha güçlü git birleşmelerini anlamıyor. Bu nedenle, svn deposunun içinde bu birleştirme bilgileri hiçbir şekilde temsil edilemez.)
Ama bütün sorun bu. 'Ana dal' ile birleştirildikten sonra 'iş' dalını silerseniz, git deponuz% 100 temizdir ve svn deponuz gibi görünür.
Benim iş akışı:
Tabii ki, ilk önce uzak svn deposunu yerel bir git deposuna klonladım (bu biraz zaman alabilir):
$> git svn clone <svn-repository-url> <local-directory>
Tüm işler "yerel dizin" içinde olur. Sunucudan güncellemeler almam gerektiğinde ('svn update' gibi) şunu yaparım:
$> git checkout master
$> git svn rebase
Tüm geliştirme işlerimi şu şekilde yaratılmış olan ayrı bir dalda yapıyorum:
$> git checkout -b work
Tabii ki, işiniz için istediğiniz kadar dal oluşturabilir ve aralarında dilediğiniz gibi birleştirebilir ve yeniden oluşturabilirsiniz (sadece işiniz bittiğinde onları silebilirsiniz - aşağıda tartışıldığı gibi). Normal işimde çok sık taahhüt ediyorum:
$> git commit -am '-- finished a little piece of work'
Bir sonraki adım (git rebase -i) isteğe bağlıdır --- sadece svn'de arşivlemeden önce tarihi temizler: Başkalarıyla paylaşmak istediğim sabit bir mil taşına ulaştığımda, bu 'çalışmanın' tarihini yeniden yazarım taahhüt mesajlarını temizleyin ve temizleyin (diğer geliştiricilerin yolda yaptığım tüm küçük adımları ve hataları görmesi gerekmez - sadece sonuç). Bunun için yaparım
$> git log
ve svn deposunda bulunan son taahhüdün sha-1 karmasını kopyalayın (git-svn-id ile gösterildiği gibi). Sonra ararım
$> git rebase -i 74e4068360e34b2ccf0c5869703af458cde0cdcb
Sadece benim yerine son svn taahhüdümüzün sha-1 karmasını yapıştırın. Ayrıntılar için 'git help rebase' ile belgeleri okumak isteyebilirsiniz. Kısacası: Bu komut önce taahhütlerinizi sunan bir düzenleyici açar ---- sadece önceki seçimlerle ezmek istediğiniz tüm taahhütler için 'seçim'i' squash 'olarak değiştirin. Tabii ki, ilk satır bir 'seçim' olarak kalmalıdır. Bu şekilde, birçok küçük taahhüdünüzü bir veya daha fazla anlamlı birime yoğunlaştırabilirsiniz. Kaydedin ve düzenleyiciden çıkın. İşlem günlüğü iletilerini yeniden yazmanızı isteyen başka bir düzenleyici alacaksınız.
Kısacası: 'Kod korsanlığı'nı bitirdikten sonra,' iş 'şubeme diğer programcılara nasıl sunmak istediğimi (veya tarihe göz attığımda birkaç hafta içinde işi nasıl görmek istediğimi) görünene kadar masaj yapıyorum. .
Svn deposundaki değişiklikleri zorlamak için şunu yaparım:
$> git checkout master
$> git svn rebase
Şimdi svn deposunda bu sırada gerçekleşen tüm değişikliklerle güncellenen eski 'ana' şubeye geri döndük (yeni değişiklikleriniz 'iş' dalında gizli).
Yeni 'iş' değişikliklerinizle çatışabilecek değişiklikler varsa, yeni işinizi zorlayabilmeniz için önce bunları yerel olarak çözmeniz gerekir (aşağıdaki ayrıntılara bakın). Ardından, değişikliklerimizi svn'ye gönderebiliriz:
$> git checkout master
$> git merge work # (1) merge your 'work' into 'master'
$> git branch -d work # (2) remove the work branch immediately after merging
$> git svn dcommit # (3) push your changes to the svn repository
Not 1: 'git branch -d work' komutu oldukça güvenlidir: Yalnızca artık ihtiyacınız olmayan dalları silmenizi sağlar (çünkü zaten geçerli dalınızla birleştirilmiştir). Çalışmanızı 'ana' dal ile birleştirmeden önce bu komutu yanlışlıkla uygularsanız, bir hata mesajı alırsınız.
Not 2: Birleştirme ve dcommit arasında 'git branch -d work' ile şubenizi sildiğinizden emin olun: Dcommit'ten sonra dalı silmeye çalışırsanız bir hata mesajı alırsınız: 'git svn dcommit' yaptığınızda git şunu unutur: şubeniz 'usta' ile birleştirildi. Güvenlik kontrolünü yapmayan 'git branch -D work' ile kaldırmalısınız.
Şimdi, yanlışlıkla 'usta' dalına saldırmaktan kaçınmak için hemen yeni bir 'iş' dalı oluşturuyorum:
$> git checkout -b work
$> git branch # show my branches:
master
* work
'İşinizi' svn'deki değişikliklerle entegre etmek:
'git svn rebase', benim 'iş' dalımda çalışırken diğerlerinin svn deposunu değiştirdiğini gösterdiğinde:
$> git checkout master
$> git svn rebase # 'svn pull' changes
$> git checkout work # go to my work
$> git checkout -b integration # make a copy of the branch
$> git merge master # integrate my changes with theirs
$> ... check/fix/debug ...
$> ... rewrite history with rebase -i if needed
$> git checkout master # try again to push my changes
$> git svn rebase # hopefully no further changes to merge
$> git merge integration # (1) merge your work with theirs
$> git branch -d work # (2) remove branches that are merged
$> git branch -d integration # (2) remove branches that are merged
$> git svn dcommit # (3) push your changes to the svn repository
Daha güçlü çözümler var:
Sunulan iş akışı basit: Git'in yetkilerini sadece 'update / hack / dcommit' her turunda kullanıyor --- ancak uzun vadeli proje geçmişini svn deposu kadar doğrusal bırakıyor. Sadece eski bir svn projesinde küçük ilk adımlarda git merges kullanmaya başlamak istiyorsanız bu sorun olmaz.
Eğer git birleştirmeye de daha aşina hale geldiğinde, diğer iş akışlarını keşfetmek için çekinmeyin: Eğer ne yaptığınızı biliyorsanız, yapabilirsiniz svn birleştirme ile git birleştirmeleri mix ( sadece svn birleştirme ile yardım etmeye (veya benzeri) git-svn kullanarak? )