在實際開發(fā)過程中耻讽,作為一名程序猿,可能會遇到這樣一個問題速勇,有時候提交的代碼太多了壕探,希望將代碼回滾阅签,有時候要將本地的修改廢棄掉十办。這些操作都會在日常開發(fā)中遇到馅扣,今天希望把提交中一個文件回滾盈蛮,但是不小心把所有文件全部會滾了兄纺,一臉懵逼大溜。所以,這篇文章就來好好總結以下git的撤銷修改操作估脆。
撤銷修改:
情形1:文件修改后還沒有被放到暫存區(qū)
當對git工作區(qū)中的文件進行修改之后钦奋,通過git status
命名會出現(xiàn)以下信息:
On branch master
Your branch is up to date with 'origin/master'.
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: README.md
no changes added to commit (use "git add" and/or "git commit -a")
情形2:文件被添加到了暫存區(qū)
如果將文件README.md通過git add
放入stage(暫存區(qū)),通過git status
會出現(xiàn)以下信息:
On branch master
Your branch is up to date with 'origin/master'.
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: README.md
根據(jù)提示疙赠,只需要通過git reset
就可以將修改從暫存區(qū)中清除付材,此時實際上是回到了情形1中:
git reset HEAD README.md
Unstaged changes after reset:
M README.md
git status
On branch master
Your branch is up to date with 'origin/master'.
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: README.md
no changes added to commit (use "git add" and/or "git commit -a")
情形3:文件被提交到了本地分支
如果通過git commit
將修改提交到了本地分支,這次修改又該怎么撤銷圃阳?
1.通過git log
查看本地分支的歷史提交記錄:
commit d24b19e5cee389f1e1f2bb906fc5765d321da8cd (HEAD -> master)
Author: xxxxxxxxxx
Date: Wed Jul 25 22:44:48 2018 +0800
修改README.md
commit 2f4c6e119c38a8f0b71dd20244903f57079fbc3c (origin/master)
Author: xxxxxxxxxx
Date: Wed Jul 25 20:53:13 2018 +0800
udpate
2.通過git reset --hard {commitId}
或者git reset --hard HEAD~1
HEAD is now at 2f4c6e1 udpate
可以看到HEAD現(xiàn)在指向的是2f4c6e1
這次提交厌衔,最新的提交也已經(jīng)沒了。
3.但是如果在一次提交中包含了多個文件捍岳,撤銷修改只希望撤銷其中的一個文件富寿,上述這個命令顯然是不能夠滿足需求的。如果是這樣的話锣夹,可以通過git reset --soft HEAD~1
來實現(xiàn):
On branch master
Your branch is up to date with 'origin/master'.
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: README.md
命令 git reset --soft {commitId}
的作用就是將修改從本地分支回滾作喘,但是會保留在暫存區(qū)中。
所以這里就有必要講講git reset這個命令:
git reset [<mode>] [<commit>]
This form resets the current branch head to <commit> and possibly
updates the index (resetting it to the tree of <commit>) and the
working tree depending on <mode>. If <mode> is omitted, defaults to
"--mixed". The <mode> must be one of the following:
--soft
Does not touch the index file or the working tree at all (but
resets the head to <commit>, just like all modes do). This
leaves all your changed files "Changes to be committed", as git
status would put it.
--mixed
Resets the index but not the working tree (i.e., the changed
files are preserved but not marked for commit) and reports what
has not been updated. This is the default action.
If -N is specified, removed paths are marked as intent-to-add
(see git-add(1)).
--hard
Resets the index and working tree. Any changes to tracked files
in the working tree since <commit> are discarded.
--merge
Resets the index and updates the files in the working tree that
are different between <commit> and HEAD, but keeps those which
are different between the index and working tree (i.e. which
have changes which have not been added). If a file that is
different between <commit> and the index has unstaged changes,
reset is aborted.
In other words, --merge does something like a git read-tree -u
-m <commit>, but carries forward unmerged index entries.
--keep
Resets index entries and updates files in the working tree that
are different between <commit> and HEAD. If a file that is
different between <commit> and HEAD has local changes, reset is
aborted.
這里面值得注意的就是:
1.如果使用--hard
模式的話晕城,commit之后的所有修改都會被廢棄,無法找回窖贤。之前不慎用了--hard
,欲哭無淚砖顷。
2.默認使用的是--mixed
,重置了暫存區(qū)(index)赃梧,但不會重置工作區(qū)(working tree)滤蝠。所有的修改都還在。
其實上述三種模式總結以下就是:
reset模式 | 工作區(qū) | 暫存區(qū) | 本地分支 |
---|---|---|---|
--hard | 無 | 無 | 無 |
--mixed | 保留 | 無 | 無 |
--soft | 保留 | 保留 | 無 |