git에서 커밋 사이를 앞뒤로 어떻게 이동합니까?


105

나는 a를 git bisect하고 있고 문제가있는 커밋에 도착한 후 이제 올바른 커밋에 있는지 확인하기 위해 앞으로 / 뒤로 단계를 시도하고 있습니다.

나는 HEAD^역사에서 뒤로 돌아가는 것을 알고 있지만 다음과 같이 앞으로 나아갈 수있는 또 다른 지름길이 있습니다.

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

내 목표가 F 라는 것을 알고 C 에서 D 로 이동하고 싶습니다 .


참고 : 이것은 Git : 커밋 사이에서 앞뒤로 이동하는 방법 의 복제본이 아닙니다. 내 질문은 약간 다르며 거기에 답변이 없습니다.


1
stackoverflow.com/questions/2263674/… 도 도움이 될 수 있습니다.
VonC 2011

git checkout -b new_branch HEAD~4stackoverflow.com/a/4940090/911945
Anton Tarasenko

답변:


57

나는 약간의 실험을 해왔고 이것은 앞으로 탐색하는 트릭을하는 것 같습니다 ( 편집 : 병합 커밋이없는 선형 기록이있을 때만 잘 작동합니다) :

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

towards커밋 또는 태그의 SHA1은 어디에 있습니까 ?

설명:

  • 내부 명령 $()은 다음을 의미합니다. 현재 HEAD와 커밋 사이의 모든 커밋을 가져 오고 towards(제외 HEAD) 우선 순위로 정렬 한 다음 ( git log기본적으로 이상하게 기본값 인 시간순 대신 rev-list), 마지막 커밋 을 취합니다. ( tail), 즉 우리가 가고자하는 것.
  • 이것은 서브 쉘에서 평가되고 git checkout체크 아웃을 수행하기 위해 전달됩니다 .

.profile특정 커밋으로 이동 하기 위해 파일 에서 매개 변수 예상 별칭으로 액세스 가능한 함수를 정의 할 수 있습니다 .

# 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
앞으로는 역사의 직선 부분에서는 잘 작동하지만 병합이 발생하면 루프로 이동합니다.
Kostas

예, 실제로 병합에 대해 테스트하지 않았습니다. 나는 여가 시간을 들여다 보려고 노력할 것이지만, 우리 프로젝트에서 엄격하게 선형적인 역사를 갖는 것에 동의했기 때문에 일시적으로 인센티브가 거의 없습니다;)
jakub.g

2
좋은 대답입니다! 현재 분기를 자동으로 지정하도록 수정 : stackoverflow.com/a/23172256/480608
Raine Revere

이것은 올바르지 않습니다. 플래그를 사용하는 경우를 제외하고 git log기본적으로와 동일하게 시간순으로 커밋을 표시합니다. rev-list--graph
파피로

git이 너무 복잡하다는 꽤 설득력있는 증거. 일반적으로 실행 취소 또는 다시 실행과 같은 간단한 작업의 경우 여기에 상충되는 답변 목록이 있습니다. 그리고 나는 연결된 답변 중 하나도 다루지 않았습니다. FWIW, 나는 단순한 선형 커밋 세트로 이것의 버전을 시도하고 마침내 포기했습니다.
Snowcrash

49

머리 상태가 분리되지 않고 명확 해지기 위해 필요한 것은 체크 아웃이 아니라 재설정하는 것입니다.

git reset HEAD@{1}

5
또는 git reset "HEAD@{1}"fish 및 powershell과 같은 특정 셸 git reflog에서 올바른 커밋을 찾는 데 유용 할 수도 있습니다.
스티브 쿡

1
쉘이 내용을 해석 / 확장하도록 명시 적으로 원하지 않는 한 항상 쉘 명령에 작은 따옴표를 사용하십시오. 이것은 쉘이 특수 문자를 해석하는 것을 방지하는 것이 목표 인 이와 같은 경우에 특히 중요합니다. 이렇게하면 문자열에 문제가있는 내용이 포함되어 있는지 여부를 알 필요가 없습니다.
크리스 페이지

시간 git reset HEAD을 거슬러 올라 가기 위해 그렇게 한 다음 제 위치로 돌아 가려고했습니다. 이제는 제 저장소가 어떤 상태인지 알 수없고 모든 것이 무섭습니다. 이제 어떻게해야합니까?
theonlygusti

47

나는 당신이 할 수 있다고 믿습니다.

git reset HEAD@{1}

제 시간에 한 커밋을 진행합니다. 여러 커밋을 진행하려면 HEAD @ {2}, HEAD @ {3} 등을 사용하세요.


20

이것이 제가 앞뒤로 탐색하는 데 사용하는 것입니다.

다음 커밋으로 이동

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

이전 커밋으로 이동

function p() {
    git checkout HEAD^1
}

감사! 나는 지금 이것을 사용하고있다! 저와 같은 다른 초보자를위한 참고 사항 : HEAD를 다시 git checkout <current branch>연결하려면 최신 커밋에 연결합니다. git checkout -b <new-branch-name>현재 커밋에서 새 분기를 변경할 수 있습니다. git rebase -i또한 작동합니다. 또한 노드 버전 관리자 "n"과의 충돌을 피하기 위해 n()함수 이름을 지정했습니다 nx(). 별칭을 확인하십시오!
Steven Choi

내가 먼저 이해하는 기능 () {...} 유닉스 / 리눅스 bash는 스크립트 파일을 제작을 위해, 나는 약간 하드 윈도우에서 온
IcyBrk

9

F가 trunk(여기에 자신의 브랜치 이름을 입력하십시오) 에 대한 최신 커밋이라고 말 하십시오 ... trunk~0(또는 그냥 trunk), E를 trunk~1, D trunk~2등 으로 참조 할 수 있습니다 .

커밋 이름을 지정하는 더 많은 방법에 대해서는 리플 로그 를 살펴보십시오 .


1
~ 트렁크 ~ 2가있다, 없다 앞을 향해 열린 길을 건너 돌아 간다
EmmanuelMess

예. 이 답변은를 가리키는 trunk라는 분기가 있고 F해당 분기의 기록에서 이동하려는 위치를 알고 있다고 가정합니다 . HEAD에 비해 앞으로 이동하려는 것이 아니라 트렁크에 비해 덜 뒤로 이동합니다.
쓸모없는

@EmmanuelMess trunk~2A는 어때?
theonlygusti

@theonlygusti HEAD에서 두 번 뒤로 이동합니다.
EmmanuelMess

당신은 여전히 질문에 나와 있지 않은 지점 trunk과 현재가 HEAD동일 하다고 가정 하고 있습니다. 제가 말한 것은 제가 가정하는 것이 아니며 , 중간 쯤에있을 것 같지 않습니다bisect
쓸모없는

3

뒤로 이동하는 것은 나무 아래로 이동하기 때문에 사소하며 항상 한 가지 방법이 있습니다.

  function git_down
        git checkout HEAD^
  end

앞으로 순회 할 때 트리 위로 이동하므로 대상 분기를 명시해야합니다.

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

사용법 : git down,git up <branch-name>


병합이 관련 될 때 뒤로 이동하는 것도 완전히 고유하지 않습니다. 비록 HEAD^일반적으로 합리적인 기본값입니다.
kdb

2

앞을보고 싶다면 Git에 엄격한 명령이 없기 때문에이 트릭을 수행 할 수 있습니다.

git log --reverse COMMIT_HASH..

로그 기록 해시 목록 :

A
B
C -> put this
D

명령을 사용 git log --reverse C..하면 출력에 BA 가 표시됩니다 .


1

아마도 가장 좋은 방법은 아니지만 git log커밋 목록을보고 git checkout [sha1 of D]D로 이동하는 데 사용할 수 있습니다.


6
이해가 안 돼요, 그가 C에 있다면 git log는 그에게 C, B와 A 만 보여줄 것입니다.
Bilthon

좋아, 그것을 가지고,하지만 당신은 VonC에 의해 주어진 링크에 표시된 것처럼 까다로운 자식 로그를해야 할 것이다
Bilthon

1

방금 이것에 대한 테스트를했습니다. 예를 들어 당신이 마스터 브랜치에 있다고 말하십시오.

git checkout HEAD@{3}

따라서 머리가 분리되고 다른 커밋으로 이동하기 위해 다시 시도 할 수 있습니다.

git checkout HEAD@{4}

주변을 둘러보고 나면 해당 지점을 확인하여 원래 상태로 돌아갈 수 있습니다. 내 예 : 마스터 브랜치

git checkout master

원래 상태로 가고 싶지 않고 커밋 중 하나를 머리로 유지하고 거기에서 계속하려면 거기에서 분기해야합니다. 예를 들어 "git checkout HEAD @ {4}"뒤에 다음을 실행할 수 있습니다.

git checkout -b MyNewBranch

0

해결 방법으로 다음을 사용하여 HEAD로 돌아갈 수 있습니다.

git checkout <branch>

그런 다음 원하는 커밋으로 이동하십시오.

git checkout HEAD~<offset>

0

vs 코드를 사용하는 경우 Git 히스토리는 편집기 자체에서 커밋을 효율적으로보고 내용을 확인할 수있는 멋진 플러그인입니다. 링크를 확인 하십시오


0
branchName=master; commitInOrder=1; git checkout $(git log --pretty=%H "${branchName}" | tac | head -n "${commitInOrder}" | tail -n 1)

어디:

branchName 지점 이름과 같음

commitInOrder 선택한 브랜치의 첫 번째 커밋부터 순서대로 커밋과 같습니다 (따라서 1은 첫 번째 커밋, 2는 브랜치의 두 번째 커밋 등).

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.