关键词:
一 、git reset,git revert,git checkout的区别和联系
主要参考:http://www.cnblogs.com/houpeiyong/p/5890748.html
git reset
、git checkout
和git revert
是你的Git工具箱中最有用的一些命令。它们都用来撤销代码仓库中的某些更改,而前两个命令不仅可以作用于提交,还可以作用于特定文件。
因为它们非常相似,所以我们经常会搞混,不知道什么场景下该用哪个命令。在这篇文章中,我们会比较git reset
、git checkout
和git revert
最常见的用法。希望你在看完后能游刃有余地使用这些命令来管理你的仓库。
Git仓库有三个主要组成——工作目录,缓存区和提交历史。
提交层面的操作
你传给git reset
和git checkout
的参数决定了它们的作用域。如果你没有包含文件路径,这些操作对所有提交生效。我们这一节要探讨的就是提交层面的操作。注意,git revert
没有文件层面的操作。
Reset
在提交层面上,reset将一个分支的末端指向另一个提交。这可以用来移除当前分支的一些提交。比如,下面这两条命令让hotfix分支向后回退了两个提交。
git checkout hotfix
git reset HEAD~2
hotfix分支末端的两个提交现在变成了悬挂提交。也就是说,下次Git执行垃圾回收的时候,这两个提交会被删除。换句话说,如果你想扔掉这两个提交,你可以这么做。
如果你的更改还没有共享给别人,git reset
是撤销这些更改的简单方法。当你开发一个功能的时候发现『糟糕,我做了什么?我应该重新来过!』时,reset就像是go-to命令一样。
除了在当前分支上操作,你还可以通过传入这些标记来修改你的缓存区或工作目录:
- --soft – 缓存区和工作目录都不会被改变
- --mixed – 默认选项。缓存区和你指定的提交同步,但工作目录不受影响
- --hard – 缓存区和工作目录都同步到你指定的提交
把这些标记想成定义git reset
操作的作用域就容易理解多了。
这些标记往往和HEAD作为参数一起使用。比如,git reset --mixed HEAD
将你当前的改动从缓存区中移除,但是这些改动还留在工作目录中。另一方面,如果你想完全舍弃你没有提交的改动,你可以使用git reset --hard HEAD
。这是git reset
最常用的两种用法。
当你传入HEAD以外的其他提交的时候要格外小心,因为reset操作会重写当前分支的历史。正如Rebase黄金法则所说的,在公共分支上这样做可能会引起严重的后果。
Checkout
你应该已经非常熟悉提交层面的git checkout
。当传入分支名时,可以切换到那个分支。
git checkout hotfix
上面这个命令做的不过是将HEAD移到一个新的分支,然后更新工作目录。因为这可能会覆盖本地的修改,Git强制你提交或者缓存工作目录中的所有更改,不然在checkout的时候这些更改都会丢失。和git reset
不一样的是,git checkout
没有移动这些分支。
除了分支之外,你还可以传入提交的引用来checkout到任意的提交。这和checkout到另一个分支是完全一样的:把HEAD移动到特定的提交。比如,下面这个命令会checkout到当前提交的祖父提交。
git checkout HEAD~2
这对于快速查看项目旧版本来说非常有用。但如果你当前的HEAD没有任何分支引用,那么这会造成HEAD分离。这是非常危险的,如果你接着添加新的提交,然后切换到别的分支之后就没办法回到之前添加的这些提交。因此,在为分离的HEAD添加新的提交的时候你应该创建一个新的分支。
Revert
Revert撤销一个提交的同时会创建一个新的提交。这是一个安全的方法,因为它不会重写提交历史。比如,下面的命令会找出倒数第二个提交,然后创建一个新的提交来撤销这些更改,然后把这个提交加入项目中。
git checkout hotfix
git revert HEAD~2
相比git reset
,它不会改变现在的提交历史。因此,git revert
可以用在公共分支上,git reset
应该用在私有分支上。
你也可以把git revert
当作撤销已经提交的更改,而git reset HEAD
用来撤销没有提交的更改。
就像git checkout
一样,git revert
也有可能会重写文件。所以,Git会在你执行revert之前要求你提交或者缓存你工作目录中的更改。
文件层面的操作
git reset
和git checkout
命令也接受文件路径作为参数。这时它的行为就大为不同了。它不会作用于整份提交,参数将它限制于特定文件。
Reset
当检测到文件路径时,git reset
将缓存区同步到你指定的那个提交。比如,下面这个命令会将倒数第二个提交中的foo.py加入到缓存区中,供下一个提交使用。
git reset HEAD~2 foo.py
和提交层面的git reset
一样,通常我们使用HEAD而不是某个特定的提交。运行git reset HEAD foo.py
会将当前的foo.py从缓存区中移除出去,而不会影响工作目录中对foo.py的更改。
--soft、--mixed和--hard对文件层面的git reset
毫无作用,因为缓存区中的文件一定会变化,而工作目录中的文件一定不变。
Checkout
Checkout一个文件和带文件路径git reset
非常像,除了它更改的是工作目录而不是缓存区。不像提交层面的checkout命令,它不会移动HEAD引用,也就是你不会切换到别的分支上去。
比如,下面这个命令将工作目录中的foo.py同步到了倒数第二个提交中的foo.py。
git checkout HEAD~2 foo.py
和提交层面相同的是,它可以用来检查项目的旧版本,但作用域被限制到了特定文件。
如果你缓存并且提交了checkout的文件,它具备将某个文件回撤到之前版本的效果。注意它撤销了这个文件后面所有的更改,而git revert
命令只撤销某个特定提交的更改。
和git reset
一样,这个命令通常和HEAD一起使用。比如git checkout HEAD foo.py
等同于舍弃foo.py没有缓存的更改。这个行为和git reset HEAD --hard
很像,但只影响特定文件。
总结
你现在已经掌握了Git仓库中撤销更改的所有工具。git reset
、git checkout
、和 git revert
命令比较容易混淆,但当你想起它们对工作目录、缓存区和提交历史的不同影响,就会容易判断现在应该用哪个命令。
下面这个表格总结了这些命令最常用的使用场景。记得经常对照这个表格,因为你使用Git时一定会经常用到。
命令 | 作用域 | 常用情景 |
---|---|---|
git reset | 提交层面 | 在私有分支上舍弃一些没有提交的更改 |
git reset | 文件层面 | 将文件从缓存区中移除 |
git checkout | 提交层面 | 切换分支或查看旧版本 |
git checkout | 文件层面 | 舍弃工作目录中的更改 |
git revert | 提交层面 | 在公共分支上回滚更改 |
git revert | 文件层面 | (然而并没有) |
二、git reset --hard.--soft,--mixed三种模式的区别
其中,git reset --hard表示head和当前分支指针都指向之前某个提交,工作区,暂存区,仓库全部更新, git status干净,常用于私有分支上的回滚(公有分支使用git revert,因为保留历史版本)
git reset --soft 表示head和当前分支指针都指向之前某个提交,只有提交的仓库发生改变,工作区和暂存区保留不变,git status显示暂存区会存在一个文件,在文件为reset之前的数据到当前commit的变化,以供下次提交,
可以利用此特点,删除两个提交之前的其他提交节点,有利于做patch。
git reset --mixed, 表示head和当前分支指针都指向之前某个提交,只有当前工作区不变,git status显示有未提交的文件。
主要参考:http://www.iteye.com/topic/1134995
三、git打补丁patch
1使用git format-patch生成所需要的patch:
当前分支所有超前master的提交:
git format-patch -M master
某次提交以后的所有patch:
git format-patch 4e16 --4e16指的是commit名
从根到指定提交的所有patch:
git format-patch --root 4e16
某两次提交之间的所有patch:
git format-patch 365a..4e16 --365a和4e16分别对应两次提交的名称
某次提交(含)之前的几次提交:
git format-patch –n 07fe --n指patch数,07fe对应提交的名称
故,单次提交即为:
git format-patch -1 07fe
git format-patch生成的补丁文件默认从1开始顺序编号,并使用对应提交信息中的第一行作为文件名。如果使用了-- numbered-files选项,则文件名只有编号,不包含提交信息;如果指定了--stdout选项,可指定输出位置,如当所有patch输出到一个文件;可指定-o <dir>指定patch的存放目录;
2应用patch:
先检查patch文件:git apply --stat newpatch.patch
检查能否应用成功:git apply --check newpatch.patch
打补丁:git am --signoff < newpatch.patch
(使用-s或--signoff选项,可以commit信息中加入Signed-off-by信息)
如果应用patch出现问题:参考git am PATCH 失败的处理方法http://blog.csdn.net/sunnylgz/article/details/7660638
参考:http://blog.csdn.net/sunnylgz/article/details/7661920
四、修改上次提交
1 git commit --amend
合并缓存区中的修改和最近的一次commitj,然后用生成的新的commit替换掉原来老的,如果缓存区没有内容,那么利用amend可以修改上一次commit的描述。
开发过程中很容易忘记stage某个文件或填写了不够准确的commit描述. --amend就是用来fix这些错误的.
不要对一个公共的commit使用amend
amend后生成的commit是一个全新的commit, 之前的老的commit会从项目历史中被删除. 如果你amend了一个被其他开发者使用的commit, 会严重影响其他开发者.
2 git commit --amend -m "xxx" 暂存区中没有要合并的文件时候,就是修改commmit描述
参考:http://www.cnblogs.com/irocker/p/git-commit--amend.html
五、cherry-pick , merge,rebase
cherry-pick:用于把其他本地分支的一个或者几个commit修改应用到当前分支。
主要用法看这个例子:http://blog.csdn.net/carolzhang8406/article/details/49761665
http://sg552.iteye.com/blog/1300713
git疑难解决
1、push.defaultisunset‘matching‘参数是Git1.x的默认行为,其意是如果你执行gitpush但没有指定分支,它将push所有你本地的分支到远程仓库中对应匹配的分支。而Git2.x默认的是simple,意味着执行gitpush没有指定分支时,只有当前分支会... 查看详情
第四周疑难点
18-20题的编程和解读不清楚?https://blog.csdn.net/a1015553840/article/details/50979640c++编译器有点问题,搞好IDE再回来。 查看详情
git使用疑难问题分析
Git在实际的使用过程中会遇到很多实际问题,下面对这些问题做一一分析和解决。目录:1.nonewchange问题;2.unpackererror问题;3.中文乱码; 1.推送代码是出现以下问题:![remoterejected]master->refs/for/master(nonewchanges)问题分析:Gitb... 查看详情
git学习中遇到的疑难杂症(代码片段)
GIT仓库如何恢复到前一次提交一、通过使用Git版本恢复命令reset,可以回退版本 reset命令有3种方式: 1、git reset –mixed:此为默认方式,不带任何参数的gitreset,即时这种方式,它回退到某个版本,只... 查看详情
javase疑难点记录
Object类与其集成的方法枚举/枚举与Switch内部类BigInteger线程中的单例设计模式懒汉式,饿汉式????synchronized与lock用法区别组合设计模式ArrayList(Debug)???Iterator迭代器(nextremove方法)集合与迭代器迭代过程中的操作Iterablemap.entry()... 查看详情
第一章小结及疑难点
第一章小结及疑难点计算机网路与分布式计算机系统的主要区别是什么???分布式系统最主要的特点是,整个系统中的各个计算机对用户都是透明的。用户通过输入命令就可以运行程序,但用户并不知道是哪台计算机在为它运行... 查看详情
finereport---finereport入门常见疑难点
一、入门介绍 二、入门需知注意:开发人员可以设置DEBUG级别,有助于测试 查看详情
直播疑难杂症排查—序
...、花屏、黑屏、杂音、音画不同步等等等等,这其中,有一些是网络原因,有一些是客户的使用姿势问题,有一些是参数配置错误,当然,也有一些是SDK本身的问题。总结下来,如果开发者能够对直播领域的一些基础知识有更深... 查看详情
系列序—直播疑难杂症排查
...、花屏、黑屏、杂音、音画不同步等等等等,这其中,有一些是网络原因,有一些是客户的使用姿势问题,有一些是参数配置错误,当然,也有一些是SDK本身的问题。总结下来,如果开发者能够对直播领域的一些基础知识有更深... 查看详情
gitlab-ci配置疑难备忘
...b服务器上加上了ci,大部份操作都比较顺利,但是也碰到一些问题抓狂,记录如下。 1、关于一个project配多个runner:在gitlab-ci里是支持的,但是含义确有点反常,我之前认为是每个runner都会独立运行所有job,这样一来可以在... 查看详情
ubuntu的一些常用命令及疑难杂症
记录ubuntu下各种注意事项及常用命令 1,发热:因为硬件厂商对linux类系统的支持不足,驱动不会自动安装,所以要自己装。。。http://www.linuxidc.com/Linux/2015-04/116450.htm 2,装上chrome后删掉firefoxhttp://jingyan.baidu.com/article/335530da980... 查看详情
c疑难点
很容易得出p[-2]=10,p[-1]=20,p[0]=30,p[1]=40,p[2]=50,p[3]=60;p++,指针p往后移一个单位,则p=a+3,此时p[0]=*(p+0)=40;*p++,是先取出*p的值,再执行p+ 查看详情
相机镜头光学中的一些疑难问题的解释
1、变焦和对焦有什么区别?变焦就是改变镜头的焦距(准确说是像距),以改变拍摄的视角,也就是通常所说的把被摄体拉近或推远。例如18-55mm和70-200mm镜头就是典型的变焦镜头。焦距越长,视角越窄。对焦通常指调整镜片组... 查看详情
“疑难杂症”又二记
“疑难杂症”又二记0. 引子 近来工作又遇到一些“疑难杂症”,在此简单记下,自省省人 ~ 1.都是WaitForSeconds惹的祸~ 眼下开发的游戏非常多地方都用到了Hotween,个人感觉还是挺不错的(题外话,... 查看详情
加密,认证疑难名词总结----rsa,公钥,私钥,ca,数字签名,数字证书(代码片段)
...样的方式,自己总结,以便后来查看,同时也希望能帮助一些人少走弯路,省去baidu,google,看RFC的时间。对称和非对称,公钥和私钥:加密的两种方式:对称加密和非对称加密。对称加密:加密的密钥也叫公钥和 查看详情
c疑难点
很容易得出p[-2]=10,p[-1]=20,p[0]=30,p[1]=40,p[2]=50,p[3]=60;p++,指针p往后移一个单位,则p=a+3,此时p[0]=*(p+0)=40;*p++,是先取出*p的值,再执行p++操作,则*p++=40,p=a+4;*... 查看详情
侵财类案件常见疑难问题辨析
...、此罪与彼罪辨难度大,因此在办理过程中,经常用遇到一些疑难问题。对于这些疑难问题,科长经常做“老中医”,当面解答年轻人们办案中的疑问,点拨办案窍门。 1、盗窃罪认定的基本原则 今天科长给大家... 查看详情
vue+elementui遇到的一些疑难问题总结(代码片段)
elementui疑难总结1.el-date-picker时间区间控制2.el-cascader获取name3.el-tree搜索判断是否匹配到值1.el-date-picker时间区间控制控制只能选区间(7天,一个月,两个月等等)重点为:picker-options="pickerOptions"以只能选两... 查看详情