2017-12-02 142 views
7

Chyba rozumiem git pull i to jak to wytłumaczyć w to, co ja nazywam „prościej”:Jak wyjaśnić "git pull --rebase" w prostych słowach?

  1. Generalnie git pull jest o scalanie jest „remote” oddział w „local” gałąź.
  2. Bardziej szczegółowo, git używa zawartości "zdalnego" oddziału do "aktualizacji"/"modyfikacji" zawartości "lokalnej" gałęzi.
  3. Bardziej szczegółowo, jeśli plik został zmodyfikowany w gałęzi "lokalnej", ale nie w gałęzi "zdalnej", to po scaleniu zawartość pliku będzie taka sama jak zawartość w "lokalnym". " gałąź. Odwrotna też jest prawda. Jeśli plik został zmodyfikowany w gałęzi "zdalnej", ale nie w gałęzi "lokalnej", zawartość zostanie pobrana z gałęzi "zdalnej".
  4. Jeśli plik został zmodyfikowany w obu gałęziach ("lokalny" i "zdalny") niż git, to spróbuj, aby wprowadzić modyfikacje z obu oddziałów. Jeśli zmiany nastąpią w różnych miejscach pliku, obie zmiany zostaną zastosowane i będą obecne w treści pliku po scaleniu.
  5. Jeśli zmiany zachodzą w tym samym miejscu, mamy tzw. Konflikt scalający i nie zamierzam dotykać tej sprawy dla uproszczenia.
  6. W wyniku scalenia modyfikujemy "lokalne" repozytorium i dlatego musimy "zatwierdzić".

Teraz chcę uzyskać ten sam rodzaj wyjaśnienia dla git pull --rebase. Nie chcę używać takich pojęć jak "głowa", "indeks", "pobieranie", "upstream", ponieważ te pojęcia/pojęcie tylko mylić początkujących, takich jak ja. Wiem, że muszę nauczyć się tych "zaawansowanych" koncepcji i robię to czytając samouczki, ale na razie, jako część mojego procesu uczenia się, chcę zrozumieć git pull --rebase.

DODANO

Myślę, że w pewnym momencie usłyszałem następujące wyjaśnienie. Pod numerem git pull --rebase. Kiedy się łączymy, robimy to nie w sposób "symetryczny", jak opisano powyżej. Zamiast tego najpierw "zapomnieliśmy" zmian w "lokalnym" repozytorium i zastosowaliśmy tylko zmiany z "zdalnego" repozytorium. Robiąc to, zasadniczo "kopiujemy" zdalne repozytorium takim jakim jest. Następnie stosujemy zmiany z "lokalnego" repozytorium na górze. Jednak nadal nie jest dla mnie jasne, co to dokładnie oznacza. W szczególności, co oznacza "na wierzchu".

+0

Należy pamiętać, że git pull to pobieranie git, a następnie git merge. To może pomóc zrozumieć, czym jest HEAD, wraz z indeksem. Jeśli tego nie zrobisz, trafisz na piaszczystą ławicę, jeśli coś nie pójdzie tak szybko, jak planowano. – rubenvb

+0

Jak napisałem w pytaniu, nie wiem, co znaczy "przynieść". – Roman

+1

@Roman, robisz teraz ... – alexis

Odpowiedz

6

Widzę dwie rzeczy, które można wyjaśnić: Skupiasz się na stanie pliku w dwóch oddziałach, ale lepszym sposobem na rozważenie tego, co się dzieje jest pod względem zestawów zmian, które miały miejsce. Drugą kwestią jest to, że git pull jest skrótem dla dwóch operacji: git fetch i git merge. Tak, piszesz, że "nie chcesz używać słów takich jak fetch", ale to nie jest "zaawansowana koncepcja". Jeśli chcesz zrozumieć, co się dzieje, musisz zacząć od tego.

  • git fetch zasadniczo informuje lokalnego repo zmian, że nie wie.

  • git merge ujednolica nowo przybyłe zmiany z lokalnymi zmianami.

Połów jest, że jeśli rzeczy zostały dzieje się na obu repo bez synchronizacji, mogą być rozbieżne:

... b--o--o--o--o (remote) 
    \ 
     x--x--x  (local) 

Powyższe pokazuje czas od lewej do prawej; najbardziej prawy punkt jest najnowszy. Tak więc nowo wprowadzone zmiany są modyfikacjami do starszego stanu plików, z oznaczeniem "b".

  • git pull, czyli zwykły git merge, połączą najnowsze stan dwóch gałęzi najlepiej jak to możliwe.

  • git pull --rebase będzie udawać, że zmiany zostały wprowadzone nie w stan oznaczony "b", ale w najbardziej aktualnym stanie zdalnym. Innymi słowy będzie próbował przepisać historię tak, że wygląda tak:

    ... b--o--o--o--o    (remote) 
           \ 
            x--x--x  (local) 
    

To jest różnica. Jedną z konsekwencji jest to, że jeśli nie rebase, historia repo zawiera pewne stany (które możesz przewinąć w przyszłości, jeśli chcesz), gdzie zastosowano zmiany "x", ale zmiany "o" są nieobecne. Po ponownym ustawieniu takiego miejsca nie ma w repozytorium.

+0

dziękuję za bardzo jasną odpowiedź. Zrozumiałem wszystko, co napisałeś i nauczyłem się, co oznaczają 'fetch' i' rebase'. Jedyne, czego mi brakuje, to wiedza, czy zawartość mojego lokalnego oddziału różni się w zależności od tego, co robię "git pull" lub "git pull --rebase".Innymi słowy, równoczesne robienie 'o-o-o' i' x-x-x', a następnie łączenie, daje wynik (treść), który różni się od treści, którą otrzymujemy, gdy najpierw wykonujemy 'o-o'', a następnie' x-x-x'. Innymi słowy, czy są to operacje przemienne "o-o-o" i "x-x-x"? – Roman

+0

@Roman: Rzeczywiście, są przypadki, gdy te * nie są * dobrze zachowane, i dostajesz różne wyniki. Nie są one zbyt powszechne, ale istnieją. Doradzam nowicjuszom w Git, aby całkowicie uniknąć 'git pull': najpierw uruchom' git fetch', a następnie uruchom 'git merge', jeśli chcesz scalić, lub' git rebase', jeśli chcesz uzyskać rebase. Dzielenie tych dwóch daje ci szansę na uruchomienie 'git log' pomiędzy, aby podjąć decyzję, a także dać ci bardziej przejrzysty obraz tego, co się dzieje. – torek

1

Prosta: dopóki twoja praca jest lokalna (co oznacza, że ​​nie została pchnięta), git pull --rebase posłuży do odtworzenia twoich lokalnych prac na podstawie zaktualizowanej historii.

git fetch zaktualizuje tę historię za pomocą ostatnich zatwierdzeń zdalnego repo (np. origin/master).
Wówczas twoja praca (twoje lokalne zatwierdzenia oddziału master) będzie odtwarzane jeden po drugim (czyli co robi rebase) na tej zaktualizowanej historii.

Chodzi o to, że jeśli chcesz się popchnąć, to pchnięcie będzie bardzo proste i nie będzie wymagało scalenia, ponieważ twoje zatwierdzenia są po prostu nowymi zobowiązaniami wykonanymi nad origin/master.

pamiętać, że można ukryć, że część rebase całkowicie since Git 2.6:

git config pull.rebase true 
git config rebase.autoStash true 

I nawet jeśli rebase nie idzie dobrze i trzeba przerwać, Git przywróci ukryty bieżącej pracy dla Ciebie since Git 2.10.