git reset --mixed, --soft 및 --hard의 차이점은 무엇입니까?
커밋을 분할하고 어떤 재설정 옵션을 사용할지 잘 모르겠습니다.
나는 페이지를보고 있었다 "git reset"이 평범한 영어로 무엇을하는지 설명 할 수 있습니까? , 그러나 나는 git 인덱스 또는 스테이징 영역이 무엇인지 실제로 이해하지 못하여 설명이 도움이되지 않는다는 것을 깨달았습니다.
또한 그 대답에 대한 사용 사례 --mixed
와 --soft
동일하게 보입니다 (수정하고 다시 커밋하고 싶을 때). 누군가가 그것을 더 세분화 할 수 있습니까? 나는 --mixed
아마도 함께 갈 수있는 옵션 이라는 것을 알고 있지만 그 이유 를 알고 싶습니다 . 마지막으로 --hard
어떨까요?
누군가가 세 가지 옵션을 선택하는 방법에 대한 워크 플로 예제를 제공 할 수 있습니까?
리포지토리에서 파일을 수정하면 처음에는 변경 사항이 준비 해제됩니다. 커밋하려면을 사용하여 스테이징 (즉, 인덱스에 추가)해야합니다 git add
. 커밋 할 때 커밋 된 변경 사항은 인덱스에 추가 된 변경 사항입니다.
git reset
최소한 현재 분기 ( HEAD
)가 가리키는 위치를 변경합니다. 차이 --mixed
및 --soft
색인도 수정 여부입니다. 따라서 우리 master
가이 일련의 커밋 으로 분기에 있는 경우 :
- A - B - C (master)
HEAD
를 가리키고 C
색인이 일치 C
합니다.
실행 git reset --soft B
하면 master
(따라서 HEAD
) 이제를 가리 키지 B
만 인덱스에는 여전히 변경 사항이 있습니다 C
. git status
무대로 표시됩니다. 따라서이 git commit
시점에서 실행하면 .NET과 동일한 변경 사항이 적용된 새 커밋이 생성됩니다 C
.
좋습니다. 여기서 다시 시작합니다.
- A - B - C (master)
이제합시다 git reset --mixed B
. (참고 : --mixed
기본 옵션입니다). 다시 한번, master
그리고 HEAD
B를 가리킨하지만,이 시간은 인덱스도 일치하도록 수정됩니다 B
. git commit
이 시점에서 실행 하면 인덱스가 일치하기 때문에 아무 일도 일어나지 않습니다 HEAD
. 작업 디렉토리에는 여전히 변경 사항이 있지만 색인에 없기 git status
때문에 스테이지 되지 않은 것으로 표시됩니다. 커밋하려면 git add
평소처럼 커밋해야합니다.
그리고 마지막으로, --hard
같은 것입니다 --mixed
(그것이 당신의 변화 HEAD
즉 제외하고, 인덱스) --hard
도 작업 디렉토리를 수정합니다. 에 C
있고 실행 git reset --hard B
하면에 추가 된 변경 사항 C
과 커밋되지 않은 변경 사항이 제거되고 작업 복사본의 파일이 commit과 일치 B
합니다. 이런 식으로 변경 사항을 영구적으로 잃을 수 있으므로 git status
하드 리셋을 수행 하기 전에 항상 실행 하여 작업 디렉토리가 깨끗한 지 또는 커밋되지 않은 변경 사항을 잃어도 괜찮은지 확인해야합니다.
마지막으로 시각화 :
가장 간단한 용어로 :
--soft
: 변경 사항을 커밋 해제하고 변경 사항을 준비 상태로 둡니다 ( index ).--mixed
(default): uncommit + unstage changes, changes are left in working tree.--hard
: uncommit + unstage + delete changes, nothing left.
Please be aware, this is a simplified explanation intended as a first step in seeking to understand this complex functionality.
May be helpful for visual learners who want to visualise what their project state looks like after each of these commands:
For those who use Terminal with colour turned on (git config --global color.ui auto):
git reset --soft A
and you will see B and C's stuff in green (staged and ready to commit)
git reset --mixed A
(or git reset A
) and you will see B and C's stuff in red (unstaged and ready to be staged (green) and then committed)
git reset --hard A
and you will no longer see B and C's changes anywhere (will be as if they never existed)
Or for those who use a GUI program like 'Tower' or 'SourceTree'
git reset --soft A
and you will see B and C's stuff in the 'staged files' area ready to commit
git reset --mixed A
(or git reset A
) and you will see B and C's stuff in the 'unstaged files' area ready to be moved to staged and then committed
git reset --hard A
and you will no longer see B and C's changes anywhere (will be as if they never existed)
Here is a basic explanation for TortoiseGit users:
git reset --soft
and --mixed
leave your files untouched.
git reset --hard
actually change your files to match the commit you reset to.
In TortoiseGit, The concept of the index is very hidden by the GUI. When you modify a file, you don't have to run git add
to add the change to the staging area/index. When simply dealing with modifications to existing files that are not changing file names, git reset --soft
and --mixed
are the same! You will only notice a difference if you added new files or renamed files. In this case, if you run git reset --mixed, you will have to re-add your file(s) from the Not Versioned Files list.
In these cases I like a visual that can hopefully explain this:
git reset --[hard/mixed/soft]
:
So each effect different scopes
- Hard => WorkingDir + Index + HEAD
- Mixed => Index + HEAD
- Soft => HEAD only (index and working dir unchanged).
All the other answers are great, but I find it best to understand them by breaking down files into three categories: unstaged
, staged
, commit
:
--hard
should be easy to understand, it restores everything--mixed
(default) :unstaged
files: don't changestaged
files: move tounstaged
commit
files: move tounstaged
--soft
:unstaged
files: don't changestaged
files: dont' changecommit
files: move tostaged
In summary:
--soft
option will move everything (exceptunstaged
files) intostaging area
--mixed
option will move everything intounstaged area
Before going into these three option one must understand 3 things.
1) History/HEAD
2) Stage/index
3) Working directory
reset --soft : History changed, HEAD changed, Working directory is not changed.
reset --mixed : History changed, HEAD changed, Working directory changed with unstaged data.
reset --hard : History changed, HEAD changed, Working directory is changed with lost data.
It is always safe to go with Git --soft. One should use other option in complex requirement.
You don't have to force yourself to remember differences between them. Think of how you actually made a commit.
1.Make some changes.
2.git add .
3.gc -m "I did Something"
Soft, Mixed and Hard is the way enabling you to give up the operations you did from 3 to 1.
Soft "pretended" to never see you have did "gc -m".
Mixed "pretended" to never see you have did "git add ."
Hard "pretended" to never see you have made file changes.
A short answer in what context the 3 options are used:
To keep the current changes in the code but to rewrite the commit history:
soft
: You can commit everything at once and create a new commit with a new description (if you use torotise git or any most other GUIs, this is the one to use, as you can still tick which files you want in the commit and make multiple commits that way with different files. In Sourcetree all files would be staged for commit.)mixed
: You will have to add the individual files again to the index before you make commits (in Sourcetree all the changed files would be unstaged)
To actually lose your changes in the code as well:
hard
: you don't just rewrite history but also lose all your changes up to the point you reset
Basic difference between various options of git reset command are as below.
- --soft: Only resets the HEAD to the commit you select. Works basically the same as git checkout but does not create a detached head state.
- --mixed (default option): Resets the HEAD to the commit you select in both the history and undoes the changes in the index.
- --hard: Resets the HEAD to the commit you select in both the history, undoes the changes in the index, and undoes the changes in your working directory.
--soft
: Tells Git to reset HEAD to another commit, so index and the working directory will not be altered in any way. All of the files changed between the original HEAD and the commit will be staged.
--mixed
: Just like the soft, this will reset HEAD to another commit. It will also reset the index to match it while working directory will not be touched. All the changes will stay in the working directory and appear as modified, but not staged.
--hard
: This resets everything - it resets HEAD back to another commit, resets the index to match it, and resets the working directory to match it as well.
The main difference between --mixed
and --soft
is whether or not your index is also modified. Check more about this here.
There are a number of answers here with a misconception about git reset --soft
. While there is a specific condition in which git reset --soft
will only change HEAD
(starting from a detached head state), typically (and for the intended use), it moves the branch reference you currently have checked out. Of course it can't do this if you don't have a branch checked out (hence the specific condition where git reset --soft
will only change HEAD
).
I've found this to be the best way to think about git reset
. You're not just moving HEAD
(everything does that), you're also moving the branch ref, e.g., master
. This is similar to what happens when you run git commit
(the current branch moves along with HEAD
), except instead of creating (and moving to) a new commit, you move to a prior commit.
This is the point of reset
, changing a branch to something other than a new commit, not changing HEAD
. You can see this in the documentation example:
Undo a commit, making it a topic branch
$ git branch topic/wip (1) $ git reset --hard HEAD~3 (2) $ git checkout topic/wip (3)
- You have made some commits, but realize they were premature to be in the "master" branch. You want to continue polishing them in a topic branch, so create "topic/wip" branch off of the current HEAD.
- Rewind the master branch to get rid of those three commits.
- Switch to "topic/wip" branch and keep working.
What's the point of this series of commands? You want to move a branch, here master
, so while you have master
checked out, you run git reset
.
The top voted answer here is generally good, but I thought I'd add this to correct the several answers with misconceptions.
Change your branch
git reset --soft <ref>
: resets the branch pointer for the currently checked out branch to the commit at the specified reference, . Files in your working directory and index are not changed. Committing from this stage will take you right back to where you were before the git reset
command.
Change your index too
git reset --mixed <ref>
or equivalently
git reset <ref>
:
Does what --soft
does AND also resets the index to the match the commit at the specified reference. While git reset --soft HEAD
does nothing (because it says move the checked out branch to the checked out branch), git reset --mixed HEAD
, or equivalently git reset HEAD
, is a common and useful command because it resets the index to the state of your last commit.
Change your working directory too
git reset --hard <ref>
: does what --mixed
does AND also overwrites your working directory. This command is similar to git checkout <ref>
, except that (and this is the crucial point about reset
) all forms of git reset
move the branch ref HEAD
is pointing to.
A note about "such and such command moves the HEAD":
It is not useful to say a command moves the HEAD
. Any command that changes where you are in your commit history moves the HEAD
. That's what the HEAD
is, a pointer to wherever you are. HEAD
is you, and so will move whenever you do.
mkarasek's Answer is great, in simple terms we can say...
git reset --soft
: set theHEAD
to the intended commit but keep your changes staged from last commitsgit reset --mixed
: 동일git reset --soft
하지만 유일한 차이점은 마지막 커밋에서 변경 사항을 스테이지 해제한다는 것입니다.git reset --hard
:HEAD
지정한 커밋에 대해 설정하고 커밋되지 않은 변경 사항을 포함하여 마지막 커밋의 모든 변경 사항을 재설정합니다.
'Nice programing' 카테고리의 다른 글
JSP / Servlet을 사용하여 서버에 파일을 업로드하는 방법은 무엇입니까? (0) | 2020.09.30 |
---|---|
목록 이해와지도 (0) | 2020.09.30 |
이상한 원치 않는 Xcode 로그 숨기기 (0) | 2020.09.30 |
함수 내에서 변수를 수정 한 후에도 변수가 변경되지 않는 이유는 무엇입니까? (0) | 2020.09.30 |
IFrame에서 테두리 제거 (0) | 2020.09.30 |