Nice programing

git reset --mixed, --soft 및 --hard의 차이점은 무엇입니까?

nicepro 2020. 9. 30. 11:28
반응형

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그리고 HEADB를 가리킨하지만,이 시간은 인덱스도 일치하도록 수정됩니다 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

  1. Hard => WorkingDir + Index + HEAD
  2. Mixed => Index + HEAD
  3. 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) :
    1. unstaged files: don't change
    2. staged files: move to unstaged
    3. commit files: move to unstaged
  • --soft:
    1. unstaged files: don't change
    2. staged files: dont' change
    3. commit files: move to staged

In summary:

  • --soft option will move everything (except unstaged files) into staging area
  • --mixed option will move everything into unstaged 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)
  1. 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.
  2. Rewind the master branch to get rid of those three commits.
  3. 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. HEADis you, and so will move whenever you do.


mkarasek's Answer is great, in simple terms we can say...

  • git reset --soft : set the HEAD to the intended commit but keep your changes staged from last commits
  • git reset --mixed: 동일 git reset --soft하지만 유일한 차이점은 마지막 커밋에서 변경 사항을 스테이지 해제한다는 것입니다.
  • git reset --hard: HEAD지정한 커밋에 대해 설정하고 커밋되지 않은 변경 사항을 포함하여 마지막 커밋의 모든 변경 사항을 재설정합니다.

참고 URL : https://stackoverflow.com/questions/3528245/whats-the-difference-between-git-reset-mixed-soft-and-hard

반응형