Neden "bizim" ve "onların" anlamı git-svn ile tersine çevrildi


91

Git-svn kullanıyorum ve a yaptıktan sonra bir birleştirme çakışmasını düzeltmem gerektiğinde git svn rebase, --oursve --theirsseçeneklerinin anlamının git checkouttersine döndüğünü fark ettim . Yani bir çatışma varsa ve SVN sunucusundan gelen sürümü saklamak ve yerel olarak yaptığım değişiklikleri atmak oursistiyorsam, olmasını beklediğim zaman kullanmalıyım theirs.

Neden?

Misal:

mkdir test
cd test
svnadmin create svnrepo
svn co file://$PWD/svnrepo svnwc
cd svnwc
echo foo > test.txt
svn add test.txt
svn ci -m 'svn commit 1'
cd ..
git svn clone file://$PWD/svnrepo gitwc
cd svnwc
echo bar > test.txt 
svn ci -m 'svn commit 2'
cd ..
cd gitwc
echo baz > test.txt 
git commit -a -m 'git commit 1'
git svn rebase

git checkout --ours test.txt
cat test.txt 
# shows "bar" but I expect "baz"

git checkout --theirs test.txt
cat test.txt 
# shows "baz" but I expect "bar"

Jut, "bizim" ve "onların" taraflarını daha iyi göstermek için yanıtımı birçok diyagramla güncelledi.
VonC

Yanıtlar:


232

Bu, bir geri ödemenin yaptığı şeyle tutarlı görünüyor.

  • git svn rebase geçerli HEAD’in SVN üst öğesinden revizyonları alır ve buna karşı mevcut (SVN’ye bağlı olmayan) çalışmayı yeniden oluşturur.

  • git rebase
    Şunlardan bahsediyor: Bir yeniden temelde birleştirmenin, <upstream>dalın üstündeki çalışma dalından her kaydetmeyi tekrarlayarak çalıştığını unutmayın .
    Bu nedenle, bir birleştirme çakışması olduğunda:

    • Bizimki kadar bildirilen yan başlayarak diye uzak rebased serisidir<upstream> ,
    • ve onlarınki çalışma koludur .
      Başka bir deyişle, taraflar değiştirilir .

git rebase, <upstream>dalın tepesindeki çalışma dalından her bir işlemi yeniden oynatır .

Her iki tanımı da uzlaştırırsanız:

  • SVN'den gelen işlemeler, en üstünde yerel Git işlemlerinin yeniden oynatıldığı işlemlerdir. Bunlar, "şimdiye kadar yeniden yapılan serilerin" bir parçasıdır ve "bizim" olarak adlandırılırlar (sizin durumunuzda, içerikli test.txtdosya bar)
  • çalışma dalı (sizin durumunuzda, SVN tarafından bilinmeyen Git işlemlerini içeren test.txtdosya baz) "onların" dır ve bu yerel Git işlemlerinin her biri yeniden oynatılır.

Başka bir deyişle, SVN veya değil:

  • " <upstream>" dal (üstünde her şey yeniden oynatılan ve şimdiye kadar yeniden yapılan taahhütlerin bir parçası olan ")" bizim "dir.
  • yeniden oynatılan (çalışma dalı) " onların " dır .

İyi anımsatıcı ucu ile CommaToast :

HEAD'in işaret ettiği şey "bizim"

(ve git rebase upstreama'nın yaptığı ilk şey upstream, üstüne yeniden ödeme yapmak istediğiniz şubeyi kontrol etmek: HEAD upstream- oursşimdi.)


Kafa karışıklığı muhtemelen bir klasikte çalışma kolunun rolünden kaynaklanıyor git merge.
Birleşirken:

  • "çalışma kolu", "şimdiye kadar birleştirilmiş" olanı içeren daldır ve "bizim" olarak kabul edilir,
  • diğer commit, tekrarlanmayan ama çalışma dalının tepesinde birleşen ve "onların" olarak kabul edileni temsil eder.

Gibi git rebaseadam sayfası bahseder, bir rebase sırasında birleştirme tarafı takas anlamına gelir.


Aynı şeyi söylemenin başka bir yolu da şunu dikkate almaktır:

  • teslim aldığımız şubede sahip olduğumuz şey ' bizim ',
  • sahip olduğumuz (ve birleştirilen ya da yeniden oynatılan) ' onların '.

Birleştirmede :

x--x--x--x--x(*) <- current branch B ('*'=HEAD)
    \
     \
      \--y--y--y <- other branch to merge

, mevcut 'B' dalını değiştirmiyoruz, yani elimizdeki şey hala üzerinde çalıştığımız şeydir (ve başka bir daldan birleşiyoruz)

x--x--x--x--x---------o(*)  MERGE, still on branch B
    \       ^        /
     \     ours     /
      \            /
       --y--y--y--/  
               ^
              their

Ancak bir geri ödemede taraf değiştiririz çünkü bir yeniden ödemenin yaptığı ilk şey yukarı akış şubesini kontrol etmektir! (mevcut taahhütleri üstüne tekrar oynatmak için)

x--x--x--x--x(*) <- current branch B
    \
     \
      \--y--y--y <- upstream branch

A , B'yi git rebase upstreamilk HEADolarak yukarı akış şubesine değiştirecektir HEAD(bu nedenle, önceki "mevcut" çalışma koluna kıyasla 'bizim' ve 'onların' anahtarları).

x--x--x--x--x <- former "current" branch, new "theirs"
    \
     \
      \--y--y--y(*) <- upstream branch with B reset on it,  
                       new "ours", to replay x's on it

, ve sonra yeniden ödeme, yeni 'bizim' B şubemizdeki 'kendi' taahhütlerini tekrarlayacak:

x--x..x..x..x <- old "theirs" commits, now "ghosts", available through reflogs
    \
     \
      \--y--y--y--x'--x'--x'(*) <-  branch B with HEAD updated ("ours")
               ^
               |
        upstream branch

Tek ek adım, git svn rebaseSVN işlemlerini temsil eden Git uzak dalında ilk olarak bir svn "getirme" işleminin gerçekleştirilmesidir.
Başlangıçta var:

x--x--x--x--x(*) <- current branch B, "ours" for now.
    \                                   
     \
      \--y--y--y <- SVN tracking branch, "theirs for now"

, önce SVN izleme şubesini SVN'den gelen yeni işlemlerle güncelleyin

x--x--x--x--x(*) <- current branch B, still "ours", not for long
    \                                   
     \
      \--y--y--y--y'--y' <- SVN tracking branch updated

, ardından mevcut şubeyi SVN tarafına geçirirsiniz ("bizim" olur)

x--x--x--x--x <- for "B", now "their" during the rebase
    \                                   
     \
      \--y--y--y--y'--y'(*) <- SVN tracking branch updated, and branch B: 
                               now "ours" (this is "what we now have")

, üzerinde çalıştığınız taahhütleri tekrarlamadan önce (ancak bu yeniden ödeme sırasında artık "onların" olan)

x--x..x..x..x <- old "theirs" commits, now "ghosts", available through reflogs
    \
     \
      \--y--y--y--y'--y'--x'--x'--x'(*) <-  branch B with HEAD updated ("ours")
                      ^
                      |
        upstream SVN tracking branch

9
Vay canına, ne harika bir cevap, teşekkürler! Ana git rebasesayfadaki bu yorumu tamamen kaçırmış olmalıyım ...
Marc Liyanage

@epologee: rica ederim. Ayrıca, yalnızca git kullandığınızda, bir yeniden ödeme veya birleştirme sırasında neler olup bittiğini anlamak için de yararlıdır. Ve yukarı akış tanımına ekler: stackoverflow.com/questions/2739376/…
VonC

5
Tanrım!!! Torvalds ne tür ilaçlar alıyordu? Bu çok karmaşık! Git çok tehlikeli bir araçtır. Dışarıdaki bilgiyi veya sezginizi kullanmaya çalışırsanız, tüm çalışmanızı kolayca yok edebilirsiniz. Yazılım geliştirme solucan deliğinden aşağı gitti!
ATL_DEV

@ user148298 Bu işlevde yanlış bir şey yok. Git uzmanı değilseniz tüm bu tür şeyleri bilmenize gerek yok. Ve eğer gelişmiş fonksiyonlara ihtiyacınız varsa, önce onu öğrenmeniz gerekecektir.
Earth Engine
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.