本文共 5101 字,大约阅读时间需要 17 分钟。
很多时候,git新手容易误操作,这个时候,可以用git reset 和git revert命令reset是指将当前head的内容重置,不会留任何痕迹。
Sets the current head to the specified commit and optionally resets the index and working tree to match.
git reset --hard HEAD~3会将最新的3次提交全部重置,就像没有提交过一样。
根据--soft --mixed --hard,会对working tree和index和HEAD进行重置。
revert是撤销某次提交,但是这次撤销也会作为一次提交进行保存
人总有犯错误的时候,如果发现不小心把私货提交到公共代码库,改如何挽回呢?
例如如下代码库:
$ mkdir git-partial-revert$ cd git-partial-revert$ echo "hello a" >a.txt$ echo "hello b" >b.txt$ git initInitialized empty Git repository in /home/liang/project/git/git-partial-revert/.git/$ git add *.txt$ git commit -m "initial version"[master (root-commit) b5e1a24] initial version 2 files changed, 2 insertions(+), 0 deletions(-) create mode 100644 a.txt create mode 100644 b.txt$ git logcommit b5e1a24fc65202977b903435750dd9fb5e0d04d0Author: Liang Wang Date: Fri Jul 30 13:20:38 2010 +0800 initial version
以下是一次错误的修改。
$ echo "hello a from b" >>a.txt$ echo "hello b from a" >>b.txt$ git commit -a -m "hello a from b"[master df3144e] hello a from b 2 files changed, 2 insertions(+), 0 deletions(-)$ git push origin master$ git logcommit df3144e3168f6ec189ed0b2b57908d8d4e862fe5Author: Liang Wang Date: Fri Jul 30 13:22:51 2010 +0800 hello a from bcommit b5e1a24fc65202977b903435750dd9fb5e0d04d0Author: Liang Wang Date: Fri Jul 30 13:20:38 2010 +0800 initial version
错误在于只应该提交对于a.txt
的修改,b.txt
的修改是私货,应该留在本地,以后提交。
第一种方法:纯手工修改。取决于要修改的内容多少,这可能是最简单也可能是最笨的方法。
如果错误发生在最新的commit里面,可以使用git reset
修改。如下:
$ git reset b5e1a24f -- b.txtUnstaged changes after reset:M b.txt$ cat b.txthello bhello b from a$ git logcommit df3144e3168f6ec189ed0b2b57908d8d4e862fe5Author: Liang WangDate: Fri Jul 30 13:22:51 2010 +0800 hello a from bcommit b5e1a24fc65202977b903435750dd9fb5e0d04d0Author: Liang Wang Date: Fri Jul 30 13:20:38 2010 +0800 initial version$ git diffdiff --git a/b.txt b/b.txtindex b1bdbca..ab47375 100644--- a/b.txt+++ b/b.txt@@ -1 +1,2 @@ hello b+hello b from a$ git status# On branch master# Changes to be committed:# (use "git reset HEAD ..." to unstage)## modified: b.txt## Changed but not updated:# (use "git add ..." to update what will be committed)# (use "git checkout -- ..." to discard changes in working directory)## modified: b.txt#$ git diff --cacheddiff --git a/b.txt b/b.txtindex ab47375..b1bdbca 100644--- a/b.txt+++ b/b.txt@@ -1,2 +1 @@ hello b-hello b from a$ git commit -m "revert change in b"[master d49f9f2] revert change in b 1 files changed, 0 insertions(+), 1 deletions(-)$ git push origin master$ git status# On branch master# Changed but not updated:# (use "git add ..." to update what will be committed)# (use "git checkout -- ..." to discard changes in working directory)## modified: b.txt#no changes added to commit (use "git add" and/or "git commit -a")$ git diffdiff --git a/b.txt b/b.txtindex b1bdbca..ab47375 100644--- a/b.txt+++ b/b.txt@@ -1 +1,2 @@ hello b+hello b from a$ git log --statcommit d49f9f2531ed9106ea53006bd698bbcdd54698e9Author: Liang Wang Date: Fri Jul 30 13:34:43 2010 +0800 revert change in b b.txt | 1 - 1 files changed, 0 insertions(+), 1 deletions(-)commit df3144e3168f6ec189ed0b2b57908d8d4e862fe5Author: Liang Wang Date: Fri Jul 30 13:22:51 2010 +0800 hello a from b a.txt | 1 + b.txt | 1 + 2 files changed, 2 insertions(+), 0 deletions(-)commit b5e1a24fc65202977b903435750dd9fb5e0d04d0Author: Liang Wang Date: Fri Jul 30 13:20:38 2010 +0800 initial version a.txt | 1 + b.txt | 1 + 2 files changed, 2 insertions(+), 0 deletions(-)
这时b的修改就从公共代码库上拿掉了,但是还保留在本地。
或者也可以使用git revert
。下面操作的缺点是没有保留对于b.txt
的修改。如何保留修改留给读者作为习题
$ git revert -n df3144e31Finished one revert.$ git status# On branch master# Changes to be committed:# (use "git reset HEAD..." to unstage)## modified: a.txt# modified: b.txt#$ git diff --cacheddiff --git a/a.txt b/a.txtindex 2c5e468..74614c9 100644--- a/a.txt+++ b/a.txt@@ -1,2 +1 @@ hello a-hello a from bdiff --git a/b.txt b/b.txtindex ab47375..b1bdbca 100644--- a/b.txt+++ b/b.txt@@ -1,2 +1 @@ hello b-hello b from a$ git reset HEAD a.txtUnstaged changes after reset:M a.txt$ cat a.txthello a$ git checkout -- a.txt$ cat a.txthello ahello a from b$ cat b.txthello b$ git commit -m "revert change in b"[master 5f6a2e1] revert change in b 1 files changed, 0 insertions(+), 1 deletions(-)$ git log --statcommit 5f6a2e16bfd59281d0150e3644aa1485dd6c0078Author: Liang Wang Date: Fri Jul 30 14:17:44 2010 +0800 revert change in b b.txt | 1 - 1 files changed, 0 insertions(+), 1 deletions(-)commit df3144e3168f6ec189ed0b2b57908d8d4e862fe5Author: Liang Wang Date: Fri Jul 30 13:22:51 2010 +0800 hello a from b a.txt | 1 + b.txt | 1 + 2 files changed, 2 insertions(+), 0 deletions(-)commit b5e1a24fc65202977b903435750dd9fb5e0d04d0Author: Liang Wang Date: Fri Jul 30 13:20:38 2010 +0800 initial version a.txt | 1 + b.txt | 1 + 2 files changed, 2 insertions(+), 0 deletions(-)
如果错误的修改已经不是最新的commit,则只能使用git revert
。
转载地址:http://ahutb.baihongyu.com/