일반적으로 git reset
의 기능은 현재 분기를 가져 와서 다른 곳을 가리 키도록 재설정하고 색인 및 작업 트리를 가져올 수 있습니다. 보다 구체적으로, 마스터 분기 (현재 체크 아웃 된)가 다음과 같은 경우 :
- A - B - C (HEAD, master)
그리고 마스터가 C가 아닌 B를 가리 키기를 원한다는 것을 깨달았 git reset B
습니다.
- A - B (HEAD, master) # - C is still here, but there's no branch pointing to it anymore
Digression : 체크 아웃과 다릅니다. 당신이 실행한다면 git checkout B
, 당신은 이것을 얻을 것입니다 :
- A - B (HEAD) - C (master)
HEAD 상태가 분리되었습니다. HEAD
, 작업 트리, 색인이 모두 일치 B
하지만 마스터 지점은에 남아 있습니다 C
. D
이 시점에서 새로운 커밋 을 수행하면 원하는 것을 얻지 못할 것입니다.
- A - B - C (master)
\
D (HEAD)
reset은 커밋을하지 않으며 단지 다른 커밋을 가리 키도록 분기 (커밋에 대한 포인터)를 업데이트합니다. 나머지는 색인 및 작업 트리에 어떤 일이 발생하는지에 대한 세부 정보입니다.
사용 사례
git reset
다음 섹션의 다양한 옵션에 대한 설명 내에서 많은 주요 사용 사례를 다룹니다. 그것은 실제로 다양한 것들에 사용될 수 있습니다. 일반적인 스레드는 그들 모두가 주어진 커밋을 가리 키거나 일치하도록 분기, 인덱스 및 / 또는 작업 트리를 재설정하는 것입니다.
조심해야 할 것들
--hard
정말 직장을 잃을 수 있습니다. 작업 트리를 수정합니다.
git reset [options] commit
커밋을 잃을 수 있습니다. 위의 장난감 예제에서 commit을 잃었습니다 C
. 그것은 REPO에 아직, 당신은보고 찾을 수 있습니다 git reflog show HEAD
또는 git reflog show master
, 그러나 더 이상 실제로 어떤 지점에서 액세스 할 수 없습니다.
Git은 30 일 후에 그러한 커밋을 영구적으로 삭제하지만, 그때까지 C에 지점을 다시 지정하여 C를 복구 할 수 있습니다 ( git checkout C; git branch <new branch name>
).
인수
매뉴얼 페이지를 설명하면, 가장 일반적인 사용법은 git reset [<commit>] [paths...]
지정된 커밋에서 주어진 경로를 상태로 재설정하는 형식 입니다. 경로가 제공되지 않으면 전체 트리가 재설정되고 커밋이 제공되지 않으면 HEAD (현재 커밋)로 간주됩니다. 이것은 git 명령에서 공통적 인 패턴입니다 (예 : 정확한 의미론은 다르지만 체크 아웃, diff, log). 그리 놀라운 일이 아닙니다.
예를 들어 git reset other-branch path/to/foo
path / to / foo의 모든 항목을 other-branch의 상태로 git reset -- .
재설정하고, 현재 디렉토리를 HEAD의 상태로 git reset
재설정 하고, 단순하게 모든 항목을 HEAD의 상태로 재설정합니다.
기본 작업 트리 및 색인 옵션
재설정하는 동안 작업 트리 및 색인에 발생하는 상황을 제어하는 네 가지 주요 옵션이 있습니다.
인덱스는 git의 "스테이징 영역"이라는 점을 기억하십시오 git add
. 커밋 준비를 할 때 상황이 발생합니다 .
--hard
재설정 한 커밋과 모두 일치합니다. 아마도 가장 이해하기 쉬울 것입니다. 모든 로컬 변경 사항이 지워집니다. 하나 개의 기본 사용은 당신의 일을 멀리 불고 있지만 커밋 전환되지 않습니다 git reset --hard
수단 git reset --hard HEAD
, 즉 분기를 변경하지 않지만 모든 로컬 변경 사항을 제거. 다른 하나는 단순히 한 지점에서 다른 지점으로 지점을 이동하고 색인 / 작업 트리를 동기화 된 상태로 유지하는 것입니다. 이것은 작업 트리를 수정하기 때문에 실제로 작업을 잃을 수있는 것입니다. 당신이 실행하기 전에 로컬 작업을 버리고 싶어 매우 확신합니다 reset --hard
.
--mixed
기본, 즉이다 git reset
수단 git reset --mixed
. 작업 트리가 아닌 색인을 재설정합니다. 이것은 모든 파일이 손상되지 않았 음을 의미하지만 원래 커밋과 재설정 한 커밋 간의 차이점은 git 상태의 로컬 수정 (또는 추적되지 않은 파일)으로 표시됩니다. 잘못된 커밋을했다는 것을 알았지 만 수행 한 모든 작업을 유지하여 문제를 해결하고 다시 커밋 할 수 있도록하려는 경우에 사용하십시오. 커밋하려면 인덱스에 파일을 다시 추가해야합니다 ( git add ...
).
--soft
색인 또는 작업 트리를 건드리지 않습니다 . 모든 파일은에서와 동일 --mixed
하지만 모든 변경 사항은 changes to be committed
git 상태와 같이 표시됩니다 (예 : 커밋 준비로 체크인 됨). 커밋이 잘못되었다는 것을 알았을 때 이것을 사용하십시오.하지만 작업이 모두 훌륭합니다.해야 할 일은 다르게 다시 커밋하는 것입니다. 인덱스는 변경되지 않으므로 원하는 경우 즉시 커밋 할 수 있습니다. 결과 커밋은 재설정하기 전의 위치와 동일한 내용을 갖습니다.
--merge
최근에 추가되었으며 실패한 병합을 중단하는 데 도움이됩니다. 이는 git merge
수정이 병합의 영향을받지 않는 파일에있는 한 더티 작업 트리 (로컬 수정이있는 하나)와의 병합을 실제로 시도 할 수 있기 때문에 필요 합니다. git reset --merge
색인을 재설정 (예 --mixed
: 모든 변경 사항이 로컬 수정으로 표시됨)하고 병합의 영향을받는 파일을 재설정하지만 나머지는 그대로 둡니다. 이렇게하면 병합이 잘못되기 전의 상태로 모든 것을 복원 할 수 있습니다. 일반적으로 분기를 이동하지 않고 병합을 재설정하기 만하 기 때문에 일반적으로 git reset --merge
(의미 git reset --merge HEAD
) 로 사용합니다 . ( HEAD
병합이 실패하여 아직 업데이트되지 않았습니다)
보다 구체적으로, 파일 A와 B를 수정하고 파일 C와 D를 수정 한 분기에서 병합하려고한다고 가정합니다. 어떤 이유로 병합이 실패하고 중단하기로 결정합니다. 사용 git reset --merge
합니다. C와 D를 원래 상태로 되돌려 HEAD
주지만 병합 시도의 일부가 아니기 때문에 수정 사항을 A와 B에만 남겨 둡니다.
더 알고 싶습니까?
나는 이것이 이것 man git reset
에 정말로 좋다고 생각합니다. 아마도 git이 실제로 싱크하는 데 약간의 감각이 필요할 것입니다. 특히, 파일을주의 깊게 읽는 데 시간이 걸리면 모든 다양한 옵션 및 사례에 대한 색인 및 작업 트리의 파일 상태를 자세히 설명하는 테이블이 매우 유용합니다. (그러나 그들은 매우 조밀합니다. 위의 많은 정보를 매우 간결한 형태로 전달하고 있습니다.)
이상한 표기법
언급 한 "이상한 표기법"( HEAD^
및 HEAD~1
)은과 같은 해시 이름을 사용할 필요없이 커밋을 지정하기위한 축약 형입니다 3ebe3f6
. 그것은 완전히에 문서화 "지정 수정"섹션 예제 및 관련 구문의 많은, 자식-REV-구문 분석에 대한 매뉴얼 페이지. 캐럿과 물결표는 실제로 다른 것을 의미합니다 .
HEAD~
HEAD~1
커밋의 첫 번째 부모의 약자 이며 의미합니다. HEAD~2
커밋의 첫 번째 부모의 첫 번째 부모를 의미합니다. HEAD~n
"HEAD보다 먼저 커밋"또는 "HEAD의 n 세대 조상"으로 생각하십시오 .
HEAD^
(또는 HEAD^1
)는 커밋의 첫 번째 부모를 의미합니다. HEAD^2
커밋의 두 번째 부모를 의미합니다 . 일반적인 병합 커밋에는 두 개의 부모가 있습니다. 첫 번째 부모는 병합 된 커밋이고 두 번째 부모는 병합 된 커밋입니다. 일반적으로 병합은 실제로 많은 부모를 가질 수 있습니다 (문어 병합).
^
및 ~
연산자에서와 같이 서로 연결된 수 HEAD~3^2
의 3 세대 조상의 제 부모 HEAD
, HEAD^^2
상기 제 부모의 부모 제 HEAD
짝수 또는 HEAD^^^
동등하다 HEAD~3
.