질문 : 평범한 영어로 "git reset"은 무엇을합니까?
git reset
에 대한 미묘함을 설명하는 흥미로운 게시물 을 보았습니다.
안타깝게도 읽을수록 완전히 이해하지 못하는 것 같습니다. 저는 SVN 배경에서 왔으며 Git은 완전히 새로운 패러다임입니다. 나는 쉽게 수은을 얻었지만 Git은 훨씬 더 기술적입니다.
나는 git reset
이 hg revert
가깝다고 생각하지만 차이점이있는 것 같습니다.
git reset
은 정확히 무엇을합니까? 다음에 대한 자세한 설명을 포함하십시오.
- 옵션은
--hard
,--soft
및--merge
; - 당신이 사용하는 이상한 표기
HEAD
등HEAD^
와HEAD~1
; - 구체적인 사용 사례 및 작업 흐름
- 작업 사본,
HEAD
및 글로벌 스트레스 수준에 대한 결과.
답변
일반적으로 git reset
의 기능은 현재 분기를 가져 와서 다른 곳을 가리 키도록 재설정하고 가능하면 인덱스와 작업 트리를 가져 오는 것입니다. 보다 구체적으로 마스터 브랜치 (현재 체크 아웃)가 다음과 같은 경우 :
- A - B - C (HEAD, master)
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
인해 (일종의) 커밋이 손실 될 수 있습니다. 위의 장난감 예제에서 커밋C
잃었습니다. 여전히 repo에 있으며git reflog show HEAD
또는git reflog show master
를 보면 찾을 수 있지만 실제로는 더 이상 어떤 분기에서도 액세스 할 수 없습니다.- Git은 30 일 후에 이러한 커밋을 영구적으로 삭제하지만 그때까지는 브랜치를 다시 가리키면 C를 복구 할 수 있습니다 (
git checkout C; git branch <new branch name>
).
man 페이지를 의역하면 가장 일반적인 사용법은 git reset [<commit>] [paths...]
, 주어진 커밋에서 주어진 경로를 상태로 재설정합니다. 경로가 제공되지 않으면 전체 트리가 재설정되고 커밋이 제공되지 않으면 HEAD (현재 커밋)가됩니다. 이것은 git 명령 (예 : 정확한 의미는 다르지만 checkout, diff, log)에서 공통된 패턴이므로 그리 놀라운 것은 아닙니다.
예를 들어 git reset other-branch path/to/foo
는 path / to / foo의 모든 항목을 other-branch의 상태로 git reset -- .
현재 디렉토리를 HEAD의 상태로 git reset
하고 간단한 git 재설정은 모든 것을 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
변경 사항으로 표시됩니다 (예 : 커밋 준비를 위해 체크인 됨). 당신이 나쁜 커밋을 만들었다는 것을 깨달았을 때 이것을 사용하십시오. 그러나 작업은 모두 훌륭합니다. 당신이해야 할 일은 다르게 재 커밋하는 것입니다. 인덱스는 변경되지 않으므로 원하는 경우 즉시 커밋 할 수 있습니다. 결과 커밋에는 재설정하기 전과 동일한 내용이 모두 포함됩니다.--merge
는 최근에 추가되었으며 실패한 병합을 중단하는 데 도움을주기위한 것입니다.git merge
는 병합의 영향을받지 않는 파일에있는 한 더티 작업 트리 (로컬 수정이있는 트리)와 병합을 시도 할 수 있기 때문에 필요합니다.git reset --merge
--mixed
는 인덱스를 재설정하고 (예 : --mixed-모든 변경 사항이 로컬 수정으로 표시됨) 병합의 영향을받는 파일을 재설정하지만 나머지는 그대로 둡니다. 이것은 모든 것을 잘못된 병합 이전의 상태로 복원 할 것입니다. 실제로 분기를 이동하는 것이 아니라 병합을 재설정하기 만 원하기 때문에 일반적으로git reset --merge
(git reset --merge HEAD
(HEAD
는 아직 업데이트되지 않았습니다.) 좀 더 구체적으로, 파일 A와 B를 수정하고 파일 C와 D를 수정 한 브랜치에서 병합을 시도한다고 가정합니다. 어떤 이유로 병합이 실패합니다. , 중단하기로 결정했습니다.git reset --merge
합니다. C와 D를HEAD
있던 방식으로 되돌 리지만 시도 된 병합의 일부가 아니기 때문에 A와 B에 대한 수정 사항 만 남겨 둡니다.
좀 더 구체적으로 말하면 파일 A와 B를 수정하고 파일 C와 D를 수정 한 분기에서 병합을 시도한다고 가정합니다. 어떤 이유로 병합이 실패하고 중단하기로 결정합니다. git reset --merge
합니다. C와 D를 HEAD
있던 방식으로 되돌 리지만 시도 된 병합의 일부가 아니기 때문에 A와 B에 대한 수정 사항 만 남겨 둡니다.
man git reset
이 이것에 정말 좋다고 생각합니다-아마도 git이 실제로 작동하는 방식에 대한 약간의 감각이 필요합니다. 특히 시간을내어주의 깊게 읽어 보면 다양한 옵션과 사례에 대한 인덱스 및 작업 트리의 파일 상태를 자세히 설명하는 테이블이 매우 유용합니다. (하지만 예, 매우 조밀합니다. 위의 정보를 매우 간결한 형태로 전달하고 있습니다.)
언급 한 "이상한 표기법"( HEAD^
및 HEAD~1
)은 3ebe3f6과 같은 해시 이름을 사용하지 않고도 커밋을 지정하는 3ebe3f6
입니다. git-rev-parse 매뉴얼 페이지의 "수정본 지정"섹션 에 많은 예제와 관련 구문이 포함되어 있습니다. 캐럿과 물결표는 실제로 다른 것을 의미합니다.
HEAD~
HEAD~1
약자이며 커밋의 첫 번째 부모를 의미합니다.HEAD~2
는 커밋의 첫 번째 부모의 첫 번째 부모를 의미합니다.HEAD~n
을 "n 개의 HEAD 전에 커밋"또는 "HEAD의 n 세대 조상"으로 생각하십시오.HEAD^
(또는HEAD^1
)는 또한 커밋의 첫 번째 부모를 의미합니다.HEAD^2
는 커밋의 두 번째 부모를 의미합니다. 일반 병합 커밋에는 두 개의 부모가 있습니다. 첫 번째 부모는 병합 된 커밋이고 두 번째 부모는 병합 된 커밋입니다. 일반적으로 병합은 실제로 임의의 많은 부모 (문어 병합)를 가질 수 있습니다.^
와~
연산자에서와 같이 서로 연결된 수HEAD~3^2
의 3 세대 조상 번째 상위HEAD
,HEAD^^2
의 제 부모 번째 상위HEAD
, 또는HEAD^^^
HEAD~3
해당합니다.
출처 : https://stackoverflow.com/questions/2530060/in-plain-english-what-does-git-reset-do
'개발관련 > Git' 카테고리의 다른 글
로컬 Git 리포지토리가 원래 복제된 URL을 확인하는 방법 (0) | 2021.08.20 |
---|---|
package.json에서 git URL을 사용하는 분기 또는 태그에 의존할까? (0) | 2021.08.13 |
자동 커밋없이 Git 병합 (0) | 2021.08.13 |
Git으로 특정 태그 다운로드 (0) | 2021.08.10 |
Visual Studio에서 Git 사용 (0) | 2021.08.09 |