2013-05-31 22 views
13

Zwykle używam git pull --rebase, jeśli pracuję bezpośrednio nad masterem (którego staram się nie robić). W przypadku, gdy zapomniałem zrobić rebase i po prostu zrobiłem git pull, czy istnieje sposób, aby to cofnąć i uczynić liniowym zamiast scalania? Czy zrobienie w tym momencie rebelii byłoby złym pomysłem (gdyby to mogło nawet przynieść cokolwiek)?git rebase po odciągnięciu

Wiem, że mogę domyślnie włączyć opcję włączania przeciągania, więc nie zapominam, ale jest to raczej kwestia zrozumienia, co należy zrobić w tym przypadku.

+3

myślę 'git zresetować --hard' z powrotem przed pociągnięciem i ponów pociągnięcie jest drogą. – Alex

+0

Dziękuję. Czy możesz napisać to jako odpowiedź zamiast komentarza? –

Odpowiedz

3

myślę git reset --hard przed powrotem do uchwytu i przerobić pull jest droga

14

Krótka odpowiedź (już podane przez @Alex w komentarzach): git reset --hard HEAD^, ale tylko wtedy, gdy istnieje scalającej (w przeciwnym razie jesteś tylko tworzenie kopii zapasowych z jednego popełnić swoją fast-forward).

Długa wersja z wyjaśnieniem:

git pull jest naprawdę tylko git fetch następnie git merge (chyba, że ​​zastępują z --rebase, jak można zauważyć). Więc po prostu trzeba zobaczyć, czy masz rzeczywiste scalającej czy nie:

$ git pull 
Updating 171ce6f..523bacb 
Fast-forward 
mp.py | 24 ++++++++++++++++++++++++ 
1 files changed, 24 insertions(+), 0 deletions(-) 
create mode 100644 mp.py 

W tym przypadku nie było scalającej, tylko do przodu, tak, nie ma problemu, nie ma żadnych zmian do rebase! Jeśli zrobisz git log zobaczysz brak scalenia-commit, szczególnie jeśli wykonasz poniższe wykresy.

Zmuszmy do scalenia.

$ git reset --hard HEAD^ 
HEAD is now at 171ce6f ignore *.log files 

[teraz jestem jeden za remotes/origin/master]

$ echo '# pointless comment' >> selfref.py 
$ git add selfref.py 
$ git commit -m 'added to force merge' 
[master 260e129] added to force merge 
1 files changed, 1 insertions(+), 0 deletions(-) 
$ git pull 
Merge made by recursive. 
mp.py | 24 ++++++++++++++++++++++++ 
1 files changed, 24 insertions(+), 0 deletions(-) 
create mode 100644 mp.py 

Widzimy, że to się stało, nawet jeśli powyższy tekst brakuje, z:

$ git log --graph --decorate --abbrev-commit --pretty=oneline 
* c261bad (HEAD, master) Merge branch 'master' of [ssh url] 
|\ 
| * 523bacb (origin/master, origin/HEAD) add multiprocessing example 
* | 260e129 added to force merge 
|/ 
* 171ce6f ignore *.log files 

Chcemy uzyskać lokalną nazwę oddziału master, aby ponownie wskazać (w tym przypadku) 260e129. Na szczęście to jest naprawdę łatwe do nazwy:

$ git rev-parse HEAD^ 
260e1297900b903404c32f3706b0e3139c043ce0 

(Drugi rodzic obecnej, z dwojgiem rodziców, scalanie popełnić jest HEAD^2.) Więc:

$ git reset --hard HEAD^ 
HEAD is now at 260e129 added to force merge 

i teraz możemy rebase na remotes/origin/master (I będziesz używać bardzo krótką nazwę, origin, że aby wymienić):

$ git rebase origin 
First, rewinding head to replay your work on top of it... 
Applying: added to force merge 

teraz pokazy dziennika jednej linii wykresu Y:

$ git log --graph --decorate --abbrev-commit --pretty=oneline 
* 4a0b2e2 (HEAD, master) added to force merge 
* 523bacb (origin/master, origin/HEAD) add multiprocessing example 
* 171ce6f ignore *.log files 

Z tego wszystkiego powinieneś być w stanie dowiedzieć się, co zrobić, jeśli uruchomisz git pull i narzeka, że ​​scalanie nie powiedzie się. :-)

0

Chcę dać ci kilka rad, które pomogą zachować linearność historii. Ustaw następującą konfigurację git, aby automatycznie odnawiać gałąź po wykonaniu polecenia pull.

$ git config branch.autosetuprebase always 

Po zastosowaniu tego ustawienia nie trzeba wpisywać pełnej polecenie ściągania z --rebase parametru tylko git pull.

Więcej informacji można uzyskać w tym artykule http://stevenharman.net/git-pull-with-automatic-rebase

+0

Jak stwierdzono w moim pytaniu, wiem, że mogę to zrobić. Próbuję tylko dowiedzieć się, co robić w tym przypadku. –