2011-07-20 18 views
59

Robię git bisect i po przybyciu do problematycznego zatwierdzenia, próbuję teraz zrobić krok do przodu/do tyłu, aby upewnić się, że jestem we właściwym.Jak przejść do przodu i do tyłu między zatwierdzeniami w git?

Znam HEAD^, aby przejść wstecz w historii, ale jest tam inny skrót, żeby mnie do przodu (w kierunku konkretnego popełnić w przyszłości) tak:

A - B - C(HEAD) - D - E - F 

wiem, że moim celem jest F i chcę przejść od C do D.


UWAGA: to nie jest duplikatem Git: How to move back and forth between commits, moje pytanie jest nieco inna i nie odpowiedział tam

+1

http://stackoverflow.com/questions/2263674/ how-do-i-find-the-next-commit-in-git może również pomóc. – VonC

+0

'git checkout -b new_branch HEAD ~ 4', aby wrócić 4 commitów z HEAD, jak w https://stackoverflow.com/a/4940090/911945 –

Odpowiedz

39

Ja eksperymentowałem trochę i to wydaje się rade poruszać się do przodu:

git checkout $(git rev-list --topo-order HEAD..towards | tail -1) 

gdzie towards jest SHA1 z popełnienia lub znacznika.

Objaśnienie:

  • polecenie wewnątrz $() oznacza: uzyskać wszystkie zobowiązuje między obecnym HEAD i towards commit (z wyłączeniem HEAD) i sortować je w kolejności pierwszeństwa (jak w git log domyślnie - zamiast porządek chronologiczny, który jest dziwnie domyślny dla rev-list), a następnie ostatni (tail), tj. ten, do którego chcemy się udać.
  • jest to oceniane w podpowłoce i przekazywane do git checkout w celu realizacji zamówienia.

Można zdefiniować funkcję dostępną jako parametr oczekując alias w pliku .profile poruszać się do przodu w kierunku szczególności zobowiązać:

# Go forward in Git commit hierarchy, towards particular commit 
# Usage: 
# gofwd v1.2.7 
# Does nothing when the parameter is not specified. 
gofwd() { 
    git checkout $(git rev-list --topo-order HEAD.."$*" | tail -1) 
} 

# Go back in Git commit hierarchy 
# Usage: 
# goback 
alias goback='git checkout HEAD~' 
+2

Going forward działa dobrze na prostych częściach historii, ale przechodzi w pętle, gdy napotyka połączenie. – Kostas

+0

Tak, właściwie nie testowałem tego na połączeniach. Spróbuję spojrzeć w wolnym czasie, ale mam chwilową zachętę, ponieważ zgodziliśmy się mieć ściśle liniową historię w naszym projekcie;) –

+2

Świetna odpowiedź! Zmodyfikowano, aby automatycznie określał bieżący oddział: http://stackoverflow.com/a/23172256/480608 –

3
nie

Prawdopodobnie najpiękniejszy sposób, ale można użyć git log aby wyświetlić listę zatwierdzeń, a następnie użyć git checkout [sha1 of D] przenieść do D.

+5

Nie rozumiem, jeśli jest w C, to log git będzie pokaż mu tylko C, B i A. – Bilthon

+0

Ok, rozumiem, ale będziesz musiał zrobić skomplikowany dziennik git-jak wskazany w linku podanym przez VonC – Bilthon

10

Say F to najnowsza popełnić na trunk (wstawić własną nazwę oddziału tutaj) ... można o nim jako trunk~0 (lub po prostu trunk), e jak trunk~1, D jak trunk~2 e tc.

Spójrz w swoim numerze reflog, aby uzyskać jeszcze więcej sposobów na nazywanie zobowiązań.

+0

~ wraca, nie na przód, trunk ~ 2 jest A – EmmanuelMess

28

Wierzę, że można zrobić:

git checkout [email protected]{1} 

Aby przejść o jedno zatwierdzenie do przodu w czasie. Aby przejść do kolejnych zatwierdzeń, użyj HEAD @ {2}, HEAD @ {3}, itd.

+14

po prostu dodanie punktu dla jasności dla potomności: to zdecydowanie nie działa. tworzy oddzielone HEAD, a nie na poprawne zatwierdzenie tak czy inaczej. –

+3

* git reset HEAD @ {1} – xavier

+1

Po przesunięciu głowy przy jakimkolwiek konkretnym zatwierdzeniu (odłączony HEAD) przez 'git checkout HEAD @ {num} możemy zrobić' git checkout -b , aby utworzyć nowy od tego momentu, a następnie możemy kontynuować, jak zwykle. –

23

Wszystko, czego potrzebujesz, aby uzyskać jasny, nie odłączony stan głowicy, to zresetować, a nie kasę.

git reset [email protected]{1} 
1

Jako obejście, można po prostu wrócić do HEAD z

git checkout <branch> 

a następnie przenieść się do popełnienia chcesz, z

git checkout HEAD~<offset> 
2

Właśnie zrobił test na to. powiedzieć na przykład jesteś w głównej gałęzi Następnie wykonaj:

git checkout [email protected]{3} 

Więc głowa dostaje indywidualny, a następnie można spróbować go ponownie, aby przejść do jakiegokolwiek innego popełnić:

git checkout [email protected]{4} 

Gdy skończysz rozglądając się, możesz wrócić do swojego pierwotnego stanu, po prostu odwiedzając tę ​​gałąź. W moim przykładzie: Master oddziału

git checkout master 

Jeśli nie chcesz, aby przejść do stanu pierwotnego, a więc chcą zachować jedną z zatwierdzeń jak głowy i kontynuować stamtąd, to trzeba się rozwijać stamtąd. na przykład po „git checkout HEAD @ {4}” można wydać

git checkout -b MyNewBranch 
8

To co używam do poruszania się w przód iw tył.

przejściem do następnego popełnić

function n() { 
    git log --reverse --pretty=%H master | grep -A 1 $(git rev-parse HEAD) | tail -n1 | xargs git checkout 
} 

przeniesienie do poprzedniej popełnić

function p() { 
    git checkout HEAD^1 
} 
0

Przechodzenie do tyłu jest trywialny, ponieważ jesteś w ruchu w dół drzewa, a tam zawsze jedna droga

function git_down 
     git checkout HEAD^ 
    end 

przy jeździe do przodu jesteś w ruchu w górę drzewa, więc trzeba być jawne, która gałąź są kierowane:

function git_up 
     git log --reverse --pretty=%H $argv | grep -A 1 (git rev-parse HEAD) | tail -n1 | xargs git checkout 
    end 

Zastosowanie: , git up <branch-name>

Powiązane problemy