에 대한 미묘함을 설명하는 흥미로운 게시물 을 보았습니다 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)
그리고 마스터가 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
.
답변
git
당신이 가지고 있음을 기억하십시오 :
- 작업중인 커밋을 알려주 는
HEAD
포인터 - 작업 트리 시스템에있는 파일의 상태를 나타냅니다,
- 준비 영역 (또한 불리는 인덱스 가 나중에 함께 헌신 할 수 있도록 변경 “단계”),
다음에 대한 자세한 설명을 포함하십시오 :
--hard
,--soft
및--merge
;
위험성이 증가하는 순서로 :
--soft
움직HEAD
이지만 준비 영역이나 작업 트리를 건드리지 않습니다.--mixed
HEAD
준비 영역을 이동 하고 업데이트하지만 작업 트리는 업데이트하지 않습니다.--merge
이동HEAD
, 준비 영역을 재설정하고 작업 트리의 모든 변경 사항을 새 작업 트리로 이동합니다.--hard
스테이징 영역과 작업 트리를 새로운 것으로 이동HEAD
하고 조정하여HEAD
모든 것을 버립니다.
구체적인 사용 사례 및 워크 플로우;
--soft
다른 장소로 옮기고 “장소를 잃지 않고”패치하고 싶을 때 사용하십시오 . 이것이 필요한 경우는 매우 드 rare니다.
–
# git reset --soft example
touch foo // Add a file, make some changes.
git add foo //
git commit -m "bad commit message" // Commit... D'oh, that was a mistake!
git reset --soft HEAD^ // Go back one commit and fix things.
git commit -m "good commit" // There, now it's right.
–
-
사용
--mixed
커밋 무슨 일이 다른에서 같이보고 싶은,하지만 당신은 당신이 이미 가지고있는 모든 변경 사항을 잃고 싶지 않을 때 (기본값). -
--merge
새 지점으로 이동하고 있지만 이미 변경 사항을 작업 트리에 통합하려는 경우에 사용하십시오 . -
--hard
새로운 커밋에서 모든 것을 지우고 새로운 슬레이트를 시작하는 데 사용하십시오 .
답변
포스트 신비성을 재설정 블로그에 프로 힘내 아주 제공 낙승 에 대한 설명을 git reset
하고 git checkout
.
해당 게시물 상단에서 도움이되는 모든 토론이 끝나면 저자는 규칙을 다음과 같은 간단한 3 단계로 줄입니다.
그것은 기본적으로입니다. 이
reset
명령은이 세 트리를 특정 순서대로 덮어 쓰고 지시하면 중지합니다.
- HEAD가 가리키는 분기를 이동하십시오 (있는 경우 중지
--soft
).- 그런 다음 색인을 다음과 같이 보이게하십시오 (여기서는 중지
--hard
).- 그런 다음 작업 디렉토리를 이렇게 보이게하십시오.
옵션
--merge
과--keep
옵션 도 있지만 지금은 더 간단하게 유지하고 싶습니다. 다른 기사 에서도 마찬가지 입니다.
답변
git에 무언가를 커밋하면 먼저 변경 사항을 준비해야합니다 (색인에 추가). 이것은 git이 커밋의 일부로 간주하기 전에이 커밋에 포함하려는 모든 파일을 git add해야한다는 것을 의미합니다. 먼저 git repo의 이미지를 살펴 보겠습니다.
이제 간단합니다. 우리는 작업 디렉토리에서 작업하여 파일, 디렉토리 및 모두를 만들어야합니다. 이러한 변경 사항은 추적되지 않은 변경 사항입니다. 추적하려면 git add 명령 을 사용하여 git index에 추가해야합니다 . git index에 추가되면 git 저장소로 변경하려면이 변경 사항을 커밋 할 수 있습니다.
그러나 갑자기 인덱스에 추가 한 파일이 하나 더 필요하다는 것을 커밋하면서 알았습니다 .git 저장소를 푸시 할 필요는 없습니다. 그것은 우리가 그 파일을 색인에 원하지 않는 것을 의미합니다. 이제 질문은 git index에서 해당 파일을 제거하는 방법입니다 .git add 를 사용하여 파일을 색인 에 넣었 으므로 git rm 을 사용하는 것이 논리적입니다 . 잘못된! git rm 은 단순히 파일을 삭제하고 인덱스에 삭제를 추가합니다. 이제해야 할 일 :
사용하다:-
자식 재설정
색인을 지우고 작업 디렉토리를 그대로 둡니다. (간단히 모든 것을 언 스테이징).
여러 옵션과 함께 사용할 수 있습니다. git reset 과 함께 사용하는 세 가지 주요 옵션 인 –hard, –soft 및 –mixed가 있습니다. 이는 재설정 할 때 HEAD 포인터 외에 재설정 대상에 영향을줍니다.
첫째, –hard 재설정 모든 것을. 현재 디렉토리는 그 지점을 따라 온 경우와 똑같습니다. 작업 디렉토리와 색인이 해당 커밋으로 변경됩니다. 이것은 내가 가장 자주 사용하는 버전입니다. git reset –hard 는 svn revert 와 같습니다 .
다음으로 완전한 반대쪽 인 –soft 는 작업 트리 나 인덱스를 재설정하지 않습니다. HEAD 포인터 만 이동합니다. 이렇게하면 현재 상태는 디렉토리에서 전환하려는 커밋과 다른 변경 사항이 적용되고 커밋을위한 “스테이징”됩니다. 커밋을 로컬로 만들지 만 커밋을 git 서버로 푸시하지 않은 경우 이전 커밋으로 재설정하고 좋은 커밋 메시지로 다시 커밋 할 수 있습니다.
마지막으로 –mixed 는 인덱스를 재설정하지만 작업 트리는 재설정하지 않습니다. 따라서 변경 사항은 모두 여전히 존재하지만 “스테이지되지 않은”상태이므로 git add’ed 또는 git commit -a 이어야 합니다. 우리는 때때로 git commit -a보다 의도 한 것보다 많은 것을 커밋하면 이것을 사용합니다 .git reset –mixed로 커밋을 취소하고 커밋하려는 것을 추가하고 커밋 할 수 있습니다.
git revert와 git reset의 차이점 :-
간단히 말해서, git reset 은 “수정되지 않은 실수 수정” 명령 이고 git revert 는 “수정 된 실수 수정” 명령 입니다.
그것은 우리가 어떤 변화에서 약간의 실수를 저지르고 그것을 커밋하고 git repo에 푸시했다면, git revert 가 해결책입니다. 푸시 / 커밋하기 전에 동일한 오류를 식별 한 경우 git reset 을 사용하여 문제를 해결할 수 있습니다 .
혼란을 없애는 데 도움이되기를 바랍니다.
답변
TL; DR
git reset
스테이징을 마지막 커밋으로 재설정합니다.--hard
작업 디렉토리의 파일을 마지막 커밋으로 재설정하는 데에도 사용하십시오 .
더 긴 버전
그러나 그것은 명백히 단순하기 때문에 많은 장황한 답변입니다. git reset
변경 사항을 취소하는 맥락에서 읽는 것이 더 합리적이었습니다 . 예를 들면 다음과 같습니다.
git revert가 변경을 취소하는 “안전한”방법 인 경우 git reset을 위험한 방법으로 생각할 수 있습니다. git reset으로 실행을 취소하고 커밋이 더 이상 참조 또는 참조 로그에 의해 참조되지 않는 경우 원래 사본을 검색 할 방법이 없습니다. 이는 영구 실행 취소입니다. 이 도구는 작업을 잃을 수있는 유일한 Git 명령 중 하나이므로이 도구를 사용할 때는주의해야합니다.
에서 https://www.atlassian.com/git/tutorials/undoing-changes/git-reset
이
커밋 수준에서 재설정은 분기의 끝을 다른 커밋으로 이동하는 방법입니다. 현재 브랜치에서 커밋을 제거하는 데 사용할 수 있습니다.
에서 https://www.atlassian.com/git/tutorials/resetting-checking-out-and-reverting/commit-level-operations
답변
이 복잡한 기능을 이해하기위한 첫 번째 단계로 단순화 된 설명입니다.
다음 각 명령 후에 프로젝트 상태를 시각화하려는 시각 학습자에게 도움이 될 수 있습니다.
색상을 켠 상태에서 터미널을 사용하는 사용자 (git config –global color.ui auto) :
git reset --soft A
그리고 당신은 B와 C의 물건을 녹색으로 볼 것입니다 (단계적이며 커밋 준비가되었습니다)
git reset --mixed A
(또는 git reset A
) B와 C의 내용이 빨간색으로 표시됩니다 (미 준비 및 준비 (녹색) 및 커밋 준비 완료).
git reset --hard A
더 이상 어디에도 B와 C의 변화가 보이지 않을 것입니다.
또는 ‘Tower’또는 ‘SourceTree’와 같은 GUI 프로그램을 사용하는 사람들
git reset --soft A
‘준비된 파일’영역에서 B와 C의 내용을 커밋 할 준비가 된 것을 볼 수 있습니다.
git reset --mixed A
(또는 git reset A
) ‘스테이지되지 않은 파일’영역에서 B 및 C의 항목을 스테이지로 이동 한 다음 커밋 할 수 있습니다.
git reset --hard A
더 이상 어디에도 B와 C의 변화가 보이지 않을 것입니다.
답변
Checkout은 특정 커밋에서 헤드를 가리 킵니다.
재설정은 특정 커밋에서 분기를 가리 킵니다. 분기는 커밋에 대한 포인터입니다.
또한, 헤드가 브랜치가 가리키는 커밋을 가리 키지 않으면 헤드가 분리 된 것입니다. (잘못된 것으로 판명되었습니다. 의견을 참조하십시오 …)