git reset
一、基本篇
在git的一般使用中~如果发发发发的不想将staging的文件add发入index之后~想回退取消~发可以使用命令,git reset HEAD ...~同发git add完发之后~git也做相发的提示~比会如,
引用
# Changes to be committed: # (use "git reset HEAD ..." to unstage)
#
# new file: Test.scala
git reset [--hard|soft|mixed|merge|keep] [或HEAD],前的分支重发;将当reset,到指定的或者HEAD;默发~如果不发示指定commit~默发是HEAD~最新的一即次提交,~且根据并[mode]有可能更新index和working directory。mode的取发可以是hard、soft、mixed、merged、keep。下面发发发明每发模式的意发和效果。来
A). --hard,重发;reset, index和working directory~自从以在来working directory中的任何改发都被发~把弃并HEAD指向。
具一例子~假发有三体个个commit~ git st:
commit3: add test3.c
commit2: add test2.c
commit1: add test1.c
发行git reset --hard HEAD~1后~
发示,HEAD is now at commit2~行运git log
commit2: add test2.c
commit1: add test1.c
运行git st~ 有任何发化没
B). --soft,index和working directory中的容不作任何改发~发发把内HEAD指向。发模式的效果是~发行完发后~自个从以的所有改发都发示在来会git status的"Changes to be committed"中。
具一例子~假发有三体个个commit~ git st:
commit3: add test3.c
commit2: add test2.c
commit1: add test1.c
发行git reset --soft(默发) HEAD~1后~行运git log
commit2: add test2.c
commit1: add test1.c
运行git status~ 发test3.c发于发存~发于准发提交发。此发区状即git commit就提交。会它
在使用git发行发作发发发~我发发常需要自己的修改生成将patch发发被人~但是在修改代发的发程中我发发行了多次的提交~如何生成最初的代发发到最发代发发的很从状状patch呢,下面要介发的功能是发发发中情。况
发假发我发git发件发发中的分支情如下,况
a-->b-->c
也就是发我发的代发发从状a修改到发状b~发行一次提交~然后再修改到发状c~发行一次提交。发发我发已发肯定由a到c的修改是正的~不再需要发确状b了~且要把并从a到c的发化生成一个patch发送发发人。如果直接打包的发生成会两个path~那发如何生成一个patch呢~发发就需要git-reset命令。
首先发发状a发建一个tag~假发名发称A~然后发行
git-reset --soft A
发发我发的发件发发就发发
a
状发b和发状c都已发被发除了~但是前的代发有被改发~发是发当并没状c的代发~发发我发做一次提交~发件发发发成下面的发子,
a-->d
状发d和发状c所发发的代发是完全相同的~只是名字不同。发在就可以生成一个patch打包发发发人了
C). --mixed,发reset index~但是不reset working directory。发模式是默发模式~不发个即当
示告知git reset模式发~使用会mixed模式。发模式的效果是~个working directory中文件的修改都被保留~不发发~会会弃但是也不被发发成会"Changes to be committed"~但是打会出什发发未被更新的发告。发告如下,
引用
Unstaged changes after reset:
M Test.Scala
M test.txt
D). --merge和--keep用的不多~在下面的例子中发明。
二、常用示例
下面列出一些git reset的典型的发用发景,
A) 回发add操发
引用
$ edit (1) $ git add frotz.c filfre.c
$ mailx (2) $ git reset (3) $ git pull git://info.example.com/ nitfol (4) (1) 发发文件frotz.c, filfre.c~做了些更改~把更改添加到了并index
(2) 发看发件~发发某人要你pull~有一些改发需要你merge下来
(3) 然而~已发把你index搞乱了~因发index同HEAD commit不匹配了~但是知道~你即将pull的发西不影已发修改的会响frotz.c和filfre.c~因此可以你revert发文件的改发两个。revert后~那些改发发发依在旧working directory中~因此发行git reset。
(4) 然后~发行了pull之后~自发merge~frotz.c和filfre.c发些改发依然在working directory中。
B) 回发最近一次commit
引用
$ git commit ...
$ git reset --soft HEAD^ (1) $ edit (2) $ git commit -a -c ORIG_HEAD (3) (1) 当你没你提交了之后~又发发代发有提交完整~或者想重新发发一下提交的comment~发行git reset --soft HEAD^~发working tree发跟reset之前一发~不作任何改发。 HEAD^指向HEAD之前最近的一次commit。
(2) 发working tree下的文件做修改
(3) 然后使用reset之前那次commit的注发、作者、日期等信息重新提交。注意~发行当git reset命令发~git会把老的HEAD拷发到文件.git/ORIG_HEAD中~在命令中可以使用ORIG_HEAD引用发个commit。commit 命令中 -a 参数的意思是告发git~自发把所有修改的和发除的文件都放发stage area~未被git跟响踪的新建的文件不受影。commit命令中-c 或者 -C 意思是拿已发提交的commit发象中的信息;作者~提交者~注
发~发发等,提交~那发发戳条commit命令的意思就非常了~把所有更改的文件加入清晰
stage area~使用上次的提交信息重新提交。并
C) 回发最近次几commit~把发次并几commit放到叫做topic的branch上去。 引用
$ git branch topic/wip (1)
$ git reset --hard HEAD~3 (2)
$ git checkout topic/wip (3)
(1) 你已发提交了一些commit~但是此发发发发些commit发不发成熟~不能发入master分支~但你希望在新的branch上发色发些commit改发。因此发行了git branch命令在前的当HEAD上建立了新的叫做 topic/wip的分支。
(2) 然后回发master branch上的最近三次提交。HEAD~3指向前当HEAD-3个commit的commit~git reset --hard HEAD~3即个发除最近的三commit;发除HEAD, HEAD^, HEAD~2,~将HEAD指向HEAD~3。
D) 永久发除最后几个commit
引用
$ git commit ...
$ git reset --hard HEAD~3 (1)
(1) 最后三个commit;即HEAD, HEAD^和HEAD~2,提交有发发~想永久发除发三你个
commit。
E) 回发merge和pull操作
引用
$ git pull (1) Auto-merging nitfol
CONFLICT (content): Merge conflict in nitfol Automatic merge failed; fix conflicts and then commit the result.
$ git reset --hard (2) $ git pull . topic/branch (3) Updating from 41223... to 13134... Fast-forward
$ git reset --hard ORIG_HEAD (4)
(1) 从origin拉下一些更新~但是发生了多突~发发有发发多发发去解发些发突~因此来很冲你没决冲
你决定稍候有空的发候再重新pull。
(2) 由于pull操作发生了突~因此所有冲pull下的改发未提交~仍然再来尚stage area中~发发情下况git reset --hard 与 git reset --hard HEAD意思相同~都是除即清index和working tree中被的发西。搞乱
(3) 将topic/branch合到前的并当branch~发次有发生突~且合后的更改自发提交。没冲并并 (4) 但是此发又发发你将topic/branch合发发发发早~因此发定退发并来尚决merge~发行git reset --hard ORIG_HEAD回发发才的pull/merge操作。发明,前面发发~发行git reset发~git会把reset之前的HEAD放入.git/ORIG_HEAD文件中~命令行中使用ORIG_HEAD引用发个commit。同发的~发行pull和merge操作发~git都把发行操作前的会HEAD放入ORIG_HEAD中~以防回发操作。
F) 在被发染的working tree中回发merge或者pull
引用
$ git pull (1) Auto-merging nitfol
Merge made by recursive.
nitfol | 20 +++++---- ...
$ git reset --merge ORIG_HEAD (2)(1) 即你你便已发在本地更改了一些的working tree~也可安全的你git pull~前提是知道你将要pull的容不覆盖的内会你working tree中的容。内
(2) git pull完后~发发发次你pull下的修改不发意~想要回发到来pull之前的发~前面的介发状从知道~我发可以发行git reset --hard ORIG_HEAD~但是发命令有副作用就是空的个个清你
working tree~发发发的本地未即弃你add的那些改发。发了避免发弃working tree中的容~可内以使用git reset --merge ORIG_HEAD~注意其中的--hard 发成了 --merge~发发就可以避免在回发发除清working tree。
G) 被中的工作流程断
在发发发发中发常出发发发的情形,正在发发一大的你个feature~此发了一发急的来个bug需要修发~但是目前在working tree中的容发有成型~发不足以内没commit~但是又必发切发的你另外的branch去fix bug。发看下面的例子
引用
$ git checkout feature ;# you were working in "feature" branch and
$ work work work ;# got interrupted $ git commit -a -m "snapshot WIP" (1)
$ git checkout master
$ fix fix fix
$ git commit ;# commit with real log
$ git checkout feature
$ git reset --soft HEAD^ ;# go back to WIP state (2) $ git reset (3)(1) 发次于发发提交~因此便添加一发发注发可。属随个即
(2) 发次reset发除了WIP commit~且把并working tree发置成提交WIP快照之前的发。状 (3) 此发~在index中依然发留着“snapshot WIP”提交发所做的uncommit changes~git reset将会清理index成发未提交尚"snapshot WIP"发的发便于接下发发工作。状来
(H) Reset发的一文件独个
假发已发添加了一文件发入你个index~但是而后又不打算把发文件提交~此发可以使用个git reset把发文件个从index中去除。
引用
$ git reset -- frotz.c (1) $ git commit -m "Commit files in index" (2) $ git add frotz.c (3)(1) 把文件frotz.c从index中去除~
(2) 把index中的文件提交
(3) 再次把frotz.c加入index
(I) 保留working tree并弃发发一些之前的commit
假发正在发发一些文件~且已发提交~接你并你当着发发工作~但是发在发发发前在working tree中的容发发于一内属另个branch~发之前的与commit没你启个有什发发系。此发~可以发一新的
branch~且保留并着working tree中的容。内
引用
$ git tag start
$ git checkout -b branch1
$ edit
$ git commit ... (1) $ edit
$ git checkout -b branch2 (2) $ git reset --keep start (3)
(1) 发次是把在branch1中的改发提交了。
(2) 此发发发~之前的提交不于发属个branch~此发新建了你branch2~切发到了并branch2上。
(3) 此发可以用你reset --keep把在start之后的commit清除掉~但是保持working tree不发。