[关闭]
@phper 2015-11-21T13:21:18.000000Z 字数 3696 阅读 11419

git 使用(9)git pull和git fetch、git reset 和 git revert 的区别用法

git


前面有学到git中的大部门知识,基本够用,但是,代码回滚也是平时遇到的最多的。这一节就来仔细的说下git中的比较容易搞混淆的几个命令:

git pullgit fetch, git resetgit revert

git reset 和 git revert

reset根据这个英文单词的意思直译的就是重置,就是还原的意思,在git中也是一样,用来将HEAD指针还原(指向)到某个提交(commit)。他是还原一段的,也就是说,如果这个commit 在log的中间位置,那么这个commit 之后的提交有可能都会消失掉!所以这个命令是蛮危险的。

revert根据这个英文单词的意思直译的就是恢复,撤销。git里面,用来撤销某一次提交(commit) 。他只会撤销这一次提交,无论这个commit在log的哪个位置,不会影响上下的提交。而且他会将撤销的作为一个新的commit提交。

下面,举例子来说吧:

  1. shop git:(master) git log --oneline

git log 前面已经讲过,这个命令用来显示提交的log 记录,加上-- oneline 表示,在一行精简的显示log信息。

我在项目下运行下:

  1. 643a5ee 关闭老爷
  2. 3deb0e4 add 3
  3. c755be6 new
  4. 889b027 + 聊天窗口右侧公告样式.
  5. 896ccee 仓鼠日志
  6. be3b53a Merge remote-tracking branch 'origin/dev' into dev
  7. 5921f2d 移动端

上面是一部分log。比如,我刚错误提交了关闭老爷(643a5ee)功能,这一步,我想撤销,怎么办呢?可以用上面的哪个命令呢?其实2个都可以用。

git reset 3deb0e4 或者 git reset HEAD~1把指针移动643a5ee到的上一次提交,就表示还原了。

或者git revert 643a5ee 表示撤销这次提交。也可以。

git reset 还原已经commit的用法

git reset 命令的使用最多的2种形式是:

git reset commitId
git reset --hard commitId

不加任何参数 表示是软重置,它会改变本地HEAD的指针, 指向3deb0e4, 并把643a5ee这一步的提交,还原到工作区,我们可以再加工或者其他的操作。所以它是非常安全的。

--hard commitId 强制移动指针到这个分支,会销毁它前面的所有的信息,本地也没有了,是蛮危险的一种行为。

我们分别试一下:

  1. shop git:(master) git reset 3deb0e4
  2. Unstaged changes after reset:
  3. M 1.php
  4. shop git:(master) git status
  5. On branch master
  6. Changes not staged for commit:
  7. (use "git add <file>..." to update what will be committed)
  8. (use "git checkout -- <file>..." to discard changes in working directory)
  9. modified: 1.php
  10. no changes added to commit (use "git add" and/or "git commit -a")
  11. shop git:(master)

它提示我们:
Unstaged changes after reset:
M 1.php

表示,643a5ee的提交已经被放入到工作区了。所以,我们可以重新修改后再提交。

我们再来试一下 --hard模式。

  1. shop git:(master) git log --oneline
  2. a98bbd3 add 4
  3. 5ca7693 add 3
  4. c755be6 new
  5. shop git:(master) git reset --hard 5ca7693
  6. HEAD is now at 5ca7693 new
  7. shop git:(master) git status
  8. On branch master
  9. nothing to commit, working directory clean
  10. shop git:(master)
  11. shop git:(master) git log --oneline
  12. 5ca7693 add 3
  13. c755be6 new

可以看出,我们,加上--hard后,它把本地的修改也给还原了,所有要慎重加。

git reset命令还原暂缓区的用法

就是把暂缓区的修改还原到工作区,加入到暂缓区就是你已经使用git add命令了,那么用这个命令也可以的。

  1. shop git:(master) vi 1.php
  2. shop git:(master) git add --all
  3. shop git:(master) git status
  4. On branch master
  5. Changes to be committed:
  6. (use "git reset HEAD <file>..." to unstage)
  7. modified: 1.php
  8. shop git:(master)

上面命令修改后加入到了暂缓区,那么我们就可以使用它提示的命令将这个文件或者所有的文件全部移除暂缓区到工作区:

  1. shop git:(master) git reset HEAD
  2. Unstaged changes after reset:
  3. M 1.php
  4. shop git:(master) git status
  5. On branch master
  6. Changes not staged for commit:
  7. (use "git add <file>..." to update what will be committed)
  8. (use "git checkout -- <file>..." to discard changes in working directory)
  9. modified: 1.php
  10. no changes added to commit (use "git add" and/or "git commit -a")
  11. shop git:(master)

上面就成功将缓存区的修改还原到了工作区了。

总结下:

如果暂缓区是干净的,可以用 git reset HEAD~ 或者 {id} 还原到上一次 或者 几次前 的修改,加 --hard 强制还原。

如果暂存区有数据没有commit,用git reset HEAD {file} 来移除暂缓区。

git revert 命令移除某一次提交

git revert命令就温和的多,它仅仅是移除这个commit,而不是将指针移动到这个分支,所以这个命令常常用来会滚操作。

我们继续实验:我们继续修改这个文件,

  1. ~ shop git:(master) git log --oneline
  2. 79a2501 add 5
  3. f56215c add 4
  4. 5ca7693 add 3
  5. c755be6 new

我现在想将5ca7693 add 3这个修改移除掉,注意,它在log的中间,用git reset命令会不太好使。那么用git revert就很好了。

  1. shop git:(master) git revert 5ca7693
  2. Revert "add 3"
  3. This reverts commit 5ca76938b4ec5313aa7a3260bcdb802d3a767e73.
  4. # Please enter the commit message for your changes. Lines starting
  5. # with '#' will be ignored, and an empty message aborts the commit.
  6. # On branch master
  7. # Changes to be committed:
  8. # modified: 1.php
  9. #

确定推出后,就会成功了:

  1. shop git:(master) git revert 5ca7693
  2. [master 39268a5] Revert "add 3"
  3. 1 file changed, 1 deletion(-)

我们看了下内容,确实将3给删除掉了,而且还重新提交了一次

  1. shop git:(master) git log --oneline
  2. 39268a5 Revert "add 3"
  3. 79a2501 add 5
  4. f56215c add 4
  5. 5ca7693 add 3
  6. c755be6 new

git fetch

 download new branches and data from a remote repository.
 可以git fetch [alias]取某一个远程repo,也可以git fetch --all取到全部repo
 fetch将会取到所有你本地没有的数据,所有取下来的分支可以被叫做remote branches,它们和本地分支一样(可以看diff,log等,也可以merge到其他分支),但是Git不允许你checkout到它们. 

git pull

 fetch from a remote repo and try to merge into the current branch.
 pull == fetch + merge FETCH_HEAD
 git pull会首先执行git fetch,然后执行git merge,把取来的分支的head merge到当前分支.这个merge操作会产生一个新的commit.    
 如果使用--rebase参数,它会执行git rebase来取代原来的git merge.
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注