SORU
28 HAZİRAN 2010, PAZARTESİ


Neden git-rebase tüm ben'm yapmayı taahhüt ezici olduğunda bana birleştirme çakışmaları veriyor mu?

İlk birkaç düzine deneme-yanılma bir sürü vardı 400 iptalleri ile Git deposu var. Birçok tek bir taahhüt içine ezmek aşağı işleyen bu temizlemek istiyoruz. Doğal olarak, git-rebase gitmek için yol gibi görünüyor. Benim sorun çakışmaları birleştirme ile sona ereceğini ve bu çatışmaları çözmek için kolay değildir. Sadece kaydeder (silme ya da yeniden düzenleme) ezici olduğum için herhangi bir çakışma olması gerekir neden anlamıyorum. Çok büyük bir olasılıkla, bu tamamen gıt-rebase onun kabakları ne anlama olmadığımı gösterir.

İşte ben kullanıyorum komut modifiye edilmiş bir versiyonu:


repo_squash.sh (bu aslında çalıştırılan komut):


rm -rf repo_squash
git clone repo repo_squash
cd repo_squash/
GIT_EDITOR=../repo_squash_helper.sh git rebase --strategy theirs -i bd6a09a484b8230d0810e6689cf08a24f26f287a

repo_squash_helper.sh (bu komut repo_squash.sh yalnızca tarafından kullanılır):


if grep -q "pick " $1
then
#  cp $1 ../repo_squash_history.txt
#  emacs -nw $1
  sed -f ../repo_squash_list.txt < $1 > $1.tmp
  mv $1.tmp $1
else
  if grep -q "initial import" $1
  then
    cp ../repo_squash_new_message1.txt $1
  elif grep -q "fixing bad import" $1
  then
    cp ../repo_squash_new_message2.txt $1
  else
    emacs -nw $1
  fi
fi

repo_squash_list.txt: (bu dosya repo_squash_helper.sh yalnızca tarafından kullanılır)


# Initial import
s/pick \(251a190\)/squash \1/g
# Leaving "Needed subdir" for now
# Fixing bad import
s/pick \(46c41d1\)/squash \1/g
s/pick \(5d7agf2\)/squash \1/g
s/pick \(3da63ed\)/squash \1/g

Bu bırakacağım "Yeni Mesaj" senin hayal gücüne içeriği. Başlangıçta, ben bunu yaptım "olmadan strateji onların" seçeneği (örneğin, varsayılan kullanarak strateji, anladığım tek şey, eğer bu belgeler doğru ise özyinelemeli, ama emin değilim hangi özyinelemeli strateji kullanılır), ve o da işe yaramadı. Ayrıca, gereken işaret, kullanma diye kodu repo_squash_helper.sh kurtardım kapalı orijinal dosya sed komut çalışır ve koştu sed komut karşı emin olmak için yapmak istediğim için yapmak oldu. Yine de, hatta neden orada olduğunu bilmiyorumkullanılan bu yüzden bunun pek bir önemi olmaz bu yüzden bir çakışma olabilir. Tavsiye ya da herhangi bir fikir yararlı olacaktır, ama çoğunlukla sadece bu ezici çalışma almak istiyorum.

Tartışma Jefromi: ekstra bilgilerle güncellendi

""Depo, test deposu da benzer bir komut kullandım. bizim gerçek masif üzerinde çalışmaya başlamadan önce Çok basit bir depo olduğunu ve testin temiz bir şekilde çalıştı.

Başarısız olsun mesajı

Finished one cherry-pick.
# Not currently on any branch.
nothing to commit (working directory clean)
Could not apply 66c45e2... Needed subdir

Bu ilk squash sonra ilk pick taahhüt. git status çalışan temiz bir çalışma dizini verir. Sonra eğer ** 16, ben bir kaç tamamlandıktan sonra çok benzer bir mesaj gönderin. Ben daha sonra tekrar yapmak, bir düzine işleyen bir çift sonra çok benzer bir mesaj aldım. Eğer yine yaparsam, yaklaşık yüz geçer bu sefer iptalleri ve bu mesajı veriyor

Automatic cherry-pick failed.  After resolving the conflicts,
mark the corrected paths with 'git add <paths>', and
run 'git rebase --continue'
Could not apply f1de3bc... Incremental

Ben o zaman git status, çalıştırın.

# Not currently on any branch.
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
# modified:   repo/file_A.cpp
# modified:   repo/file_B.cpp
#
# Unmerged paths:
#   (use "git reset HEAD <file>..." to unstage)
#   (use "git add/rm <file>..." as appropriate to mark resolution)
#
# both modified:      repo/file_X.cpp
#
# Changed but not updated:
#   (use "git add/rm <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
# deleted:    repo/file_Z.imp

"Her ikisi de değiştirilmiş bu sadece bir seçim sonucuydu bu yana" biraz kulağa garip. Bu da dikkati çekiyor, eğer ben bak "çatışma", kaynar Aşağı için bir tek satır sürümü ile başlayan bir sekme karakteri, diğeri ile dört boşluk. Bu config dosyamı hazırladım, ama öyle bir şey yok nasıl bir sorun olabilir gibi geldi. (Çekirdek not ettim.ignorecase true olarak ayarlanır, ama belli ki git-clone otomatik olarak yaptı. Tamamen özgün kaynağı bir Windows makinede olduğunu düşünürsek şaşırmadım.)

Ben elle daha sonra kısa bir süre sonra başarısız olur file_x.cpp başka bir çatışma ile tamir edersen bu sefer (CMakeLists.txt bir sürüm bulunması gerektiğini düşünüyor ve bir sürüm düşünüyor bir dosya gerekmiyor arasında. Eğer ben bunu düzeltmek çatışma demek istiyorum bu dosyayı (ki bence öyle), bir kaç tamamlar daha sonra ben başka bir çatışma (aynı dosya) nerede şimdi orada bazı oldukça önemsiz olmayan bir değişiklik. Hala tek çatışmalar boyunca % ile ilgili.

Ayrıca bu proje svn deposuna başladı bu çok önemli, olabilir beri işaret etmeliyim. Başlangıç tarihi çok büyük bir olasılıkla bu svn deposundan alındı.

Güncelleme #2:

Gırgırına (Jefromi yorumları etkisinde), üstü benim repo_squash.sh yapmak olmaya karar verdim:

rm -rf repo_squash
git clone repo repo_squash
cd repo_squash/
git rebase --strategy theirs -i bd6a09a484b8230d0810e6689cf08a24f26f287a

Ve sonra, ben sadece orijinal girişleri kabul etti. I. e., "rebase" bir şey değişmemiş olmalı. Aynı sonuç, daha önce tarif etmişti.

Güncelleme #3:

Strateji ihmal ve son komut yerine alternatif olarak,:

git rebase -i bd6a09a484b8230d0810e6689cf08a24f26f287a

Ben artık "" rebase sorunları, ama yine de diğer çatışmalar kaldı. işlemek için hiçbir şey elde

Sorun yaratır oyuncak depo güncelleme:

test_squash.sh (bu aslında çalıştırın dosya):

#========================================================
# Initialize directories
#========================================================
rm -rf test_squash/ test_squash_clone/
mkdir -p test_squash
mkdir -p test_squash_clone
#========================================================

#========================================================
# Create repository with history
#========================================================
cd test_squash/
git init
echo "README">README
git add README
git commit -m"Initial commit: can't easily access for rebasing"
echo "Line 1">test_file.txt
git add test_file.txt
git commit -m"Created single line file"
echo "Line 2">>test_file.txt 
git add test_file.txt 
git commit -m"Meant for it to be two lines"
git checkout -b dev
echo Meaningful code>new_file.txt
git add new_file.txt 
git commit -m"Meaningful commit"
git checkout master
echo Conflicting meaningful code>new_file.txt
git add new_file.txt 
git commit -m"Conflicting meaningful commit"
# This will conflict
git merge dev
# Fixes conflict
echo Merged meaningful code>new_file.txt
git add new_file.txt
git commit -m"Merged dev with master"
cd ..

#========================================================
# Save off a clone of the repository prior to squashing
#========================================================
git clone test_squash test_squash_clone
#========================================================

#========================================================
# Do the squash
#========================================================
cd test_squash
GIT_EDITOR=../test_squash_helper.sh git rebase -i HEAD@{7}
#========================================================

#========================================================
# Show the results
#========================================================
git log
git gc
git reflog
#========================================================

test_squash_helper.sh (test_sqash.sh tarafından kullanılır):

# If the file has the phrase "pick " in it, assume it's the log file
if grep -q "pick " $1
then
  sed -e "s/pick \(.*\) \(Meant for it to be two lines\)/squash \1 \2/g" < $1 > $1.tmp
  mv $1.tmp $1
# Else, assume it's the commit message file
else
# Use our pre-canned message
  echo "Created two line file" > $1
fi

P. S.: Evet, bazılarınız-geri çekilin editör olarak emacs kullanarak beni gördüğünde yalakalık biliyorum.

P. P. S.: rebase sonra mevcut deponun bizim klonlar tüm darbe gerekecek. (Çizgisinde "eceksin değil yayınlandıktan sonra bir depo rebase".)

P. P. P. S: bu herkes için bir ödül eklemek için nasıl bana söyleyebilir misiniz? Mod veya görünümü düzenleme modunda olup olmadığımı seçeneği bu ekran üzerinde herhangi bir yerde görmüyorum.

CEVAP
29 HAZİRAN 2010, Salı


Tamam, bir cevap atmak için yeterince emin değilim. Belki düzenlemek zorunda kalacak, ama sorunun ne olduğunu biliyorum sanırım.

Oyuncak repo test case içinde birleştirme - daha da kötüsü, bir çatışmalar ile birleştirme vardır. Ve birleştirme üzerinde rebasing. -p olmadan tamamen -i ile çalışmıyor), birleştirir göz ardı edilir. Bu çakışma çözünürlüğü içinde ne yaptıysan anlamına gelirorada değilrebase kiraz almaya çalıştığında, bir sonraki yama geçerli olmayabilir tamamlamak. (Bu bir git cherry-pick üç yönlü bir yaparak yamayı çünkü çatışma orijinal taahhüt mevcut taahhüt ve ortak atasından birleştirme olarak gösterilir inanıyorum.)

Açıklamalarda da ifade ettiğimiz gibi ne yazık ki, -i -p (korumak birleştirir) çok iyi geçinmezler. Düzenleme/uygun sözcükler kullanmak çalıştığını biliyorum, Ve bu yeniden düzenleme yok. Ancak, Beninanıyorumbu kabakları ile gayet iyi çalışıyor. Bu belgelenmiştir, ama aşağıda vereceğim tarif test durumları için çalıştı. Eğer durum çok, çok daha karmaşık ise, hala mümkün olacak olsa bir sürü sorun istediğin işi yapıyor olabilir. (Kıssadan hisse: rebase -i ile temizleyinöncebirleştirme.)

Birlikte squash istediğimiz yere gelelim çok basit bir durum var diyelim, A, B ve C:

- o - A - B - C - X - D - E - F (master)
   \             /
    Z -----------

Eğer olsaydı şimdi, dediğim gibi, X çakışma, git rebase -i -p beklediğiniz gibi çalışır.

Eğer çakışma varsa, işler biraz yanıltıcıdır olsun. İyi eziyor, sonra birleştirme yeniden çalıştığında, çatışmalar tekrar yaşanır. Onları tekrar çözmek, dizin Ekle, git rebase --continue üzerinde hareket etmek için kullanın. (Tabii ki, bunları tekrar orijinal sürüm taahhüt birleştirme kontrol ederek çözebilirsiniz.)

Eğer olması rerere etkin repo (rerere.enabled true), bu şekilde daha kolay - git yapabilir *re**re*kablolu *re*çözüm ne zaman başlangıçta vardı çatışmalar, ve tüm yapmanız gereken incelemek için emin olun işe yaradı değil mi, ekleme dosyaları için dizin ve devam edin. (Hatta bir adım daha ileriye rerere.autoupdate, açma gidebilirsin ve hatta başarısız olmaz birleştirmek için onları ekleyin.). Anlaşmazlık çözümü Kendin yapmak zorunda kalacaksın o yüzden hiç rerere etkinleştirmeniz olmadığını, ancak, tahmin ediyorum,*.

* Ya da, sen-ebil denemek rerere-train.sh script gıt-contrib, girişimleri için "Başbakan [] rerere veritabanından varolan bir birleştirme tamamlar" - temelde hepsi doğru birleştirmeyi taahhüt eder, çalışır Birleştir onları, ve eğer birleştirme başarısız yakalar sonuçları ve gösterir onlara git-rerere. Bu zaman alıcı olabilir, ve hiç kullanmadım, ama çok yararlı olabilir.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Doug Bernards

    Doug Bernard

    7 Kasım 2007
  • Tina Chen

    Tina Chen

    26 Mayıs 2012
  • Visual Life

    Visual Life

    3 Temmuz 2006