@phper
2015-11-21T21:21:18.000000Z
字数 3696
阅读 11888
git
前面有学到git中的大部门知识,基本够用,但是,代码回滚也是平时遇到的最多的。这一节就来仔细的说下git中的比较容易搞混淆的几个命令:
git pull
和 git fetch
, git reset
和 git revert
。
reset
根据这个英文单词的意思直译的就是重置
,就是还原的意思,在git中也是一样,用来将HEAD指针还原(指向
)到某个提交(commit
)。他是还原一段的,也就是说,如果这个commit 在log的中间位置,那么这个commit 之后的提交有可能都会消失掉!所以这个命令是蛮危险的。
revert
根据这个英文单词的意思直译的就是恢复,撤销
。git里面,用来撤销某一次提交(commit
) 。他只会撤销这一次提交,无论这个commit在log的哪个位置,不会影响上下的提交。而且他会将撤销的作为一个新的commit提交。
下面,举例子来说吧:
➜ shop git:(master) git log --oneline
git log
前面已经讲过,这个命令用来显示提交的log 记录,加上-- oneline
表示,在一行精简的显示log信息。
我在项目下运行下:
643a5ee 关闭老爷
3deb0e4 add 3
c755be6 new
889b027 + 聊天窗口右侧公告样式.
896ccee 仓鼠日志
be3b53a Merge remote-tracking branch 'origin/dev' into dev
5921f2d 移动端
上面是一部分log。比如,我刚错误提交了关闭老爷
(643a5ee)功能,这一步,我想撤销,怎么办呢?可以用上面的哪个命令呢?其实2个都可以用。
git reset 3deb0e4
或者 git reset HEAD~1
把指针移动643a5ee
到的上一次提交,就表示还原了。
或者git revert 643a5ee
表示撤销这次提交。也可以。
git reset
命令的使用最多的2种形式是:
git reset commitId
git reset --hard commitId
不加任何参数
表示是软重置,它会改变本地HEAD的指针, 指向3deb0e4
, 并把643a5ee
这一步的提交,还原到工作区
,我们可以再加工或者其他的操作。所以它是非常安全的。
--hard commitId
强制移动指针到这个分支,会销毁它前面的所有的信息,本地也没有了,是蛮危险的一种行为。
我们分别试一下:
➜ shop git:(master) git reset 3deb0e4
Unstaged changes after reset:
M 1.php
➜ shop git:(master) ✗ git status
On branch 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: 1.php
no changes added to commit (use "git add" and/or "git commit -a")
➜ shop git:(master) ✗
它提示我们:
Unstaged changes after reset:
M 1.php
表示,643a5ee
的提交已经被放入到工作区
了。所以,我们可以重新修改后再提交。
我们再来试一下 --hard
模式。
➜ shop git:(master) git log --oneline
a98bbd3 add 4
5ca7693 add 3
c755be6 new
➜ shop git:(master) git reset --hard 5ca7693
HEAD is now at 5ca7693 new
➜ shop git:(master) git status
On branch master
nothing to commit, working directory clean
➜ shop git:(master)
➜ shop git:(master) git log --oneline
5ca7693 add 3
c755be6 new
可以看出,我们,加上--hard
后,它把本地的修改也给还原了,所有要慎重加。
就是把暂缓区
的修改还原到工作区
,加入到暂缓区就是你已经使用git add
命令了,那么用这个命令也可以的。
➜ shop git:(master) vi 1.php
➜ shop git:(master) ✗ git add --all
➜ shop git:(master) ✗ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: 1.php
➜ shop git:(master) ✗
上面命令修改后加入到了暂缓区,那么我们就可以使用它提示的命令将这个文件或者所有的文件全部移除暂缓区到工作区:
➜ shop git:(master) ✗ git reset HEAD
Unstaged changes after reset:
M 1.php
➜ shop git:(master) ✗ git status
On branch 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: 1.php
no changes added to commit (use "git add" and/or "git commit -a")
➜ shop git:(master) ✗
上面就成功将缓存区的修改还原到了工作区了。
总结下:
如果暂缓区是干净的,可以用 git reset HEAD~ 或者 {id} 还原到上一次 或者 几次前 的修改,加 --hard 强制还原。
如果暂存区有数据没有commit,用git reset HEAD {file} 来移除暂缓区。
git revert
命令就温和的多,它仅仅是移除这个commit,而不是将指针移动到这个分支,所以这个命令常常用来会滚操作。
我们继续实验:我们继续修改这个文件,
~ shop git:(master) git log --oneline
79a2501 add 5
f56215c add 4
5ca7693 add 3
c755be6 new
我现在想将5ca7693 add 3
这个修改移除掉,注意,它在log的中间,用git reset
命令会不太好使。那么用git revert
就很好了。
➜ shop git:(master) git revert 5ca7693
Revert "add 3"
This reverts commit 5ca76938b4ec5313aa7a3260bcdb802d3a767e73.
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# On branch master
# Changes to be committed:
# modified: 1.php
#
确定推出后,就会成功了:
➜ shop git:(master) git revert 5ca7693
[master 39268a5] Revert "add 3"
1 file changed, 1 deletion(-)
我们看了下内容,确实将3给删除掉了,而且还重新提交了一次
➜ shop git:(master) git log --oneline
39268a5 Revert "add 3"
79a2501 add 5
f56215c add 4
5ca7693 add 3
c755be6 new
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到它们.
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.