git rebase, 'yerel' ve 'uzak' takibi


174

Bir git rebase yaparken, çatışmaları çözerken genellikle 'yerel' ve 'uzaktan' ile neler olduğunu anlamakta zorlanıyorum. Bazen tarafları bir taahhütten diğerine değiştirdikleri izlenimine kapılıyorum.

Bu muhtemelen (kesinlikle) çünkü hala tam olarak anlamadım.

Yeniden basarken, 'yerel' ve 'uzak' kimdir?

(Çatışmaları çözmek için P4Merge kullanıyorum)


O okuma olması mümkün mü bu size yardımcı olur? Öğreticinin geri kalanı da çok yararlı ....
ivans

Başka bir mükemmel git kaynağı .
Bilinmiyor

Misiniz stackoverflow.com/questions/2959443/... yardım? (' git svn' kısım için değil , sadece ' git rebase' kısım için)
VonC

@VonC, evet, hepsi bu. Cevabınızın ilgili kısmını buraya kopyalamak istiyorsanız, onu işaretleyeceğim (gerçekten bu sefer veriyorum!)
Benjol

tamam ... ısırırım;) İlgili özler gönderildi.
VonC

Yanıtlar:


244

TL; DR;

Özetlemek gerekirse ( Benubird yorum olarak ), ne zaman:

git checkout A
git rebase   B    # rebase A on top of B
  • localolduğu B(rebase üzerine ),
  • remote dır-dir A

Ve:

git checkout A
git merge    B    # merge B into A
  • localolduğu A(birleştirme içine )
  • remote dır-dir B

Bir rebase anahtarları ours(rebase başlamadan önceki geçerli dal) ve theirs(üstünde yeniden birleştirmek istediğiniz dal).


kutschkem , bir GUI birleştirme aracı bağlamında şunları belirtir :

  • yerel referanslar kısmen yeniden temel alınan taahhütler : " ours" (yukarı akış şubesi)
  • remote, gelen değişiklikleri ifade eder : " theirs" - yeniden tabandan önceki geçerli şube.

Bu cevabın son bölümündeki çizimlere bakınız.


Rebase olduğunda inversiyon

Karışıklık, bir yeniden tabanın ters çevrilmesi oursve theirssırasında ters düşme ile ilgili olabilir .
(ilgili alıntılar)

git rebaseman sayfası :

Bir rebase birleşmesinin, <upstream>dalın üstündeki çalışma dalından her bir taahhüdü tekrarlayarak çalıştığını unutmayın .

Bu nedenle, bir birleşme çakışması olduğunda:

  • ' ours' olarak bildirilen taraf , şu ana kadarki yeniden temel alan seridir <upstream>,
  • ve ' theirs' çalışma koludur. Başka bir deyişle, kenarlar değiştirilir.

Gösterilen ters çevirme

Birleşmede

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

, şu andaki 'B' dalını değiştirmiyoruz, bu yüzden elimizde hala üzerinde çalıştığımız şey var (ve başka bir daldan birleşiyoruz)

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

Bir rebase üzerinde:

Ancak bir rebase'de taraf değiştiriyoruz çünkü bir rebase'in yaptığı ilk şey yukarı akış şubesini kontrol etmektir! (geçerli taahhütleri tekrar oynatmak için)

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

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

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 daha sonra rebase yeni 'bizim' şubemizdeki 'taahhütlerini' tekrar edecek:

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

Not: "yukarı akış" kavramı , verilerin okunduğu veya yeni verilerin eklendiği / oluşturulduğu referans veri kümesidir (tüm bir repo veya burada olduğu gibi yerel bir şube olabilen bir dal).


' local' ve ' remote' vs. ' mine' ve ' theirs'

Pandawood ekler yorumlarla :

Benim için hala "yerel" olan ve "uzak" olan soru hala devam ediyor ("bizim" ve "onların" terimleri git'e basarken kullanılmadığından, bunlara atıfta bulunarak bir cevap daha kafa karıştırıcı görünüyor) .

GUI git mergetool

kutschkem ekler ve haklı olarak:

Çatışmaları çözerken git şöyle bir şey söyleyecektir:

local: modified file and remote: modified file. 

Sorunun bu noktada yerel ve uzak tanımlamayı amaçladığından eminim. Bu noktada, bana göre deneyimlerimden:

  • yerel referanslar kısmen yeniden temel alınan taahhütler : " ours" (yukarı akış şubesi)
  • remote, gelen değişiklikleri ifade eder : " theirs" - yeniden tabandan önceki geçerli şube.

git mergetoolgerçekten de 'yerel' ve 'uzak' ifadelerinden bahsediyor :

Merging:
f.txt

Normal merge conflict for 'f.txt':
  {local}: modified file
  {remote}: modified file
Hit return to start merge resolution tool (kdiff3):

Örneğin, KDiff3 olur şöyle birleştirme çözünürlüğünü görüntülemek :

KDiff3

Ve meld bunu da gösterecekti :

Meld fark

İçin aynı VimDiff , görüntüler :

Vimdiff'i git mergetool -t gvimdiff ile bir birleştirme aracı olarak çağır. Git'in son sürümleri Vimdiff'i aşağıdaki pencere düzeniyle çağırır:

+--------------------------------+
| LOCAL  |     BASE     | REMOTE |
+--------------------------------+
|             MERGED             |
+--------------------------------+
  • LOCAL:
    Geçerli daldaki dosyanın içeriğini içeren geçici bir dosya.
  • BASE:
    Birleştirme için ortak tabanı içeren geçici bir dosya.
  • REMOTE:
    Birleştirilecek dosyanın içeriğini içeren geçici bir dosya.
  • MERGED:
    Çakışma işaretlerini içeren dosya.

Git mümkün olduğunca otomatik çatışma çözümü olarak yürüttü ve bu dosyanın devlet her ikisinin bir kombinasyonudur LOCALve REMOTEGit kendini çözmek olamayacağını şey çevreleyen çatışma işaretleri ile. Bu dosyaya kararın sonucunu yazmalısınız.
mergetool


13
Benim için hala "yerel" olan ve "uzak" olan soru hala devam ediyor ("bizim" ve "onların" terimleri git'e basarken kullanılmadığından, bunlara atıfta bulunarak bir cevap daha kafa karıştırıcı görünüyor) . Soru "kim yerel ve kim uzak" - bu yüzden bir cevap mutlaka "yerel" ve "uzak" sözcüklerinden bahsetmeyi gerektirir
PandaWood

@PandaWood: "local", "geçerli dal" ("onların" olur), "uzak", "yukarı akış daldır" ("bizim" olur).
VonC

3
Özetlemek gerekirse: git checkout A; git rebase BYerel olarak B olduğunda, uzaktan kumanda A'dır. Bilmem gereken tek şey ...
Benubird

1
git böyle bir kullanılabilirlik karmaşasıdır. Bu hiç mantıklı: Eğer zaman git checkout A; git rebase Byerel B, A uzak . Ben ise checkout Ao zaman am onlar üzerinde var olduğu anda dosyalara bakarak A, herhangi bir şekilde bu nasıl oluyor uzaktan ? (Benubird'in yanlış olduğunu söylemiyorum; Git'in aptal bir UX'si olduğunu söylüyorum)
Rafa

1
@VonC emin; benim (sıralamam) nokta, okuma belgeleri almamalı, diyagramlara bakmamalı ve StackOverflow'a göz atmak zorunda olmamalıdır. Sadece komut açık, net bir geri bildirim verdiyse. Örneğin, yerel / uzak / onların / bizimki / benimki / seninki yerine, sadece göster {branch A}ve {branch B}benzeri.
Rafa

45

Alt çizgi

git rebase

  • YEREL = üzerine bastığınız baz
  • UZAKTAN = üstte ilerlediğiniz taahhütler

git birleştirme

  • LOCAL = birleştirdiğiniz orijinal şube
  • REMOTE = taahhütlerini birleştirdiğiniz diğer şube

Başka bir deyişle, YEREL her zaman orijinaldir ve UZAKTAN her zaman taahhütleri daha önce orada olmayan adamdır, çünkü bir araya getirildikleri veya üstüne yeniden baslandıkları

Kanıtla!

Kesinlikle. Benim sözüme güvenme! İşte kendiniz görmek için yapabileceğiniz kolay bir deney.

İlk olarak, git mergetool'u doğru yapılandırdığınızdan emin olun. (Eğer yapmadıysanız, muhtemelen bu soruyu zaten okumazsınız.) O zaman çalışacak bir dizin bulun.

Deponuzu ayarlayın:

md LocalRemoteTest
cd LocalRemoteTest

Bir başlangıç ​​taahhüdü oluşturun (boş bir dosyayla):

git init
notepad file.txt  (use the text editor of your choice)
  (save the file as an empty file)
git add -A
git commit -m "Initial commit."

Ana olmayan bir dalda bir taahhüt oluşturun:

git checkout -b notmaster
notepad file.txt
  (add the text: notmaster)
  (save and exit)
git commit -a -m "Add notmaster text."

Ana dalda bir taahhüt oluşturun:

git checkout master
notepad file.txt
  (add the text: master)
  (save and exit)
git commit -a -m "Add master text."

gitk --all

Bu noktada deponuz şöyle görünmelidir:

Temel taahhüt ve iki tek taahhütlü şubesi olan depo

Şimdi rebase testi için:

git checkout notmaster
git rebase master
  (you'll get a conflict message)
git mergetool
  LOCAL: master
  REMOTE: notmaster

Şimdi birleştirme testi. Herhangi bir değişikliği kaydetmeden birleştirme aracınızı kapatın ve sonra yeniden temeli iptal edin:

git rebase --abort

Sonra:

git checkout master
git merge notmaster
git mergetool
  LOCAL: master
  REMOTE: notmaster
git reset --hard  (cancels the merge)

Sonuçlarınız yukarıda gösterilenlerle aynı olmalıdır.


1
+1. Yani açıklık getirmektedir local/ remote(diğer inversiyonu hakkındadır Yukarıda kendi cevap ile mücadele yönleri oursvs theirsneyse)
VonC

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.