Git Pro读书笔记
本文为Git Pro读书笔记,所有内容均来自Git Pro
1 Git基础
1.1 记录每次更新到仓库
在Git里,文件有4种状态,modified, staged, commited, 还有一种状态是untracked。
Git只会暂存运行git add 时的版本,如果文件作了修改,需要运行git add 将最新的版本暂存起来, git add是一个多功能的命令。
- 用来跟踪。
- 将新的修改放入暂存区。
- 还可以用于合并时把有冲突的文件标记为已解决的文件。
1.1.1 查看已暂存和未暂存的更新
git diff 比较的是当前文件和暂存区快照的差异。
git diff --cached(--staged)比较的是暂存区和之前提交的版本(committed)的差异。
如果改动后,没有暂存,使用git status会看到暂存前后的两个版本。(哪些文件改变了), git diff也是看到暂存前后的两个版本(哪些文件具体改变了什么,比如增加什么代码,删除什么代码)。
1.1.2 提交
git commit提交,每次提交记录的是放在暂存区里的快照,任何还未暂存的仍然保持已经修改状态。
每一次提交操作,都是对项目做一个快照,以后可以回到这个状态, 或者进行比较。
我们可以跳过add步骤,使用git commit -a -m "test", Git会自动自动把已经跟踪过的文件暂存起来一并提交,从而跳过git add步骤。
1.1.3 移除
git rm README.md , 会从暂存区里删除,并且工作目录也没有了。
如果删除之前已经修改过并且已经放到暂存区的话,则必须使用git rm -f README.md强制删除, 这个删除命令是从git管理仓库里将README删除,并且工作目录里的文件也会被删除掉。
但是如果我们想要从暂存区里删除,但是想要保存工作区里的东西,该怎么办呢?使用git rm --cached README。
如果只是使用rm README.md, 那么git status会提示Changes not staged for commit。然后再运行git rm README.md会提示此次的操作记录Changes to be committed... deleted: README.md。
1.1.4 重命名
git mv README README1它相当于下面这三条命令。
$ mv README README1
$ git rm README
$ git add README1
1.2 查看提交历史
git log
git log -p, 查看提交的内容变化
git log -2, 查看最近2次的提交
git log --stat, 仅显示简要的增加行数修改
git log --pretty=oneline, 改变显示的风格
git log --author=yuzf, 只显示作者为yuzf的人的提交历史
还有一点儿其他的内容,但是不重要。
1.3 撤销操作
1.3.1 撤销最后一次提交
git commit --amend, 此命令将使用当前暂存区提交。如果刚才提交后没有任何改动,直接运行命名,相当于有机会重新编辑提交说明, 一般使用这个命令后再push到远程仓库会这样使用: git push origin localBranch:remoteBranch --force。
1.3.2 取消已暂存的文件
不需要硬记, 只需要git status, 会有提示的。git reset HAED file会从暂存区里将file取出来。
1.3.3 取消对文件的修改
git checkout -- someFile, 这条命令的意思是: 我们将之前的版本(暂存区里的版本)复制出来重写了此文件。这是一条非常危险的命令, 因为一旦用了, 我们之前所做的修改就都没有了。
记住,任何提交到git里的都可以恢复,失去的数据是没有提交的,因为对git来说,它似乎从来没有失去过。
1.4 远程仓库的使用
1.4.1 查看远程仓库
git remote, 列出远程仓库名。
git remote -v, 列出远程仓库名和地址。
1.4.2 添加远程仓库
git remote add upstream git@gitlab.xxxxxx.com:xx/xx-xx-com.git, upstream是为远程仓库制定一个名字。
1.4.3 从远程仓库抓取数据
git fetch [remote-name], 此命令会到远程仓库中拉取所有你本地仓库中还没有的数据。
我用下面几个命令来告诉自己:
git clone remoteOrigin
git branch
// dev
git branch -a
/*
dev
remotes/origin/dev
remotes/origin/master
*/
git remote add upstream xxx
git fetch upstream
git branch
// dev
git branch -a
/*
dev
remotes/origin/dev
remotes/origin/master
remotes/upstream/dev
remotes/upstream/master
*/
有一点很重要,fetch只是将远段的数据拉取到本地仓库,并不会自动合并到当前工作分支。
而git pull,自动抓取数据下来,然后将远端分支自动合并到本地仓库的当前分支。
1.4.4 推送数据到远程仓库
使用命令git push remote-name localBranch:remoteBranch
1.4.5 查看远程仓库信息
git remote show [remote-name]用于查看远程仓库详细信息。
1.4.6 远程仓库的删除和重命名
git remote rename origin test // 重命名远程仓库
git remote rm origin // 删除远程仓库
1.5 打标签
- 列出现有的标签
git tag
- 新建标签
含附注的标签
git tag -a v1.0 -m "my 1.0 version"
git show v1.0
轻量级标签
git tag v1.1
等等,还有其他的关于标签的。
2 分支
在Git中提交时,会保存一个提交对象(commit), 它会包含一个指向暂存内容快照的指针。实际上,master是一个指针,指向最后一个commit对象。而新建分支,就是新创建一个指针,指向commit对象。
2.1 何谓分支
何谓分支, 我认为这一小节尤其的重要。
2.1.1 新建分支
git branch newBranchName会创建一个新的分支指针,它将指向当前的commit对象。
那么,Git如何知道在哪一个分支上呢?很简单,Git保存了一个名为HAED的指针(HAED即当前分支的别名),HEAD指向指向哪一个分支,就在哪一个分支。
2.1.2 切换分支
git checkout branchName命令会让我们切换分支(即将HEAD指针和branchName分支指针指向的commit一致), 假如我们切换到一个新的分支, 然后commit后,新的分支就会向前移动一格,同样的,HAED指针仍然指向新的分支。而master分支是位于第二格的。
当切换分支后,工作区也会发生相应的改变, git checkout -b newBranch这个命令可以新建分支并切换分支。
2.1.3 基本的分支与合并
如果你正在开发一个新功能,突然接到通知之前的版本有一个bug,现在需要你紧急修复,因此你所需要做的事情如下:
- git status // on branch newFunction(#53)
- git checkout master // 切回master, 注意这里,留意暂存区里或者工作目录里,那些还没有提交的修改,它会和你即将检出的分支产生冲突从而阻止Git为你切换分支。因此,切换分支的时候一定要保持一个干净的工作区域, 后面会介绍几种绕过这种问题的方法(分别叫做stashing 和 commit amend)
- git checkout -b hotfix
- do something
- git commit -a -m "fix a bug"
- git checkout master
- git merge hotfix // git会提示Fast forward(快进), 由于master分支所在的commit对象是要并入的hotfix分支的直接上游,Git只需要将master分支直接右移,这种合并称为快进。
- git branch -d hotfix // 删除hotfix分支
- git checkout #53 // 之前的那个新功能的分支
值得注意的是之前hotfix分支的修改内容尚未包含到iss53中来。如果要纳入此次修改,有两种方法:
- git merge master // 将master合并到#53来
- 等#53开发完结束后,再将#53分支的更新并入到master里。
2.1.4 分支的合并
当你在#53提交了多个commit后,你的功能已经完成了,此时你想要将当前的分支合并回master分支下,此时的合并就并不能像之前的Fast forword, 因为已经产生分叉了。因此,当你执行下面的命令时:
- git checkout master
- git merge issue53
会提示Auto-merging, Merge made by the 'recursive' strategy, Git的底层操作是这样的: Git会将master和issue53的之前的共同祖先, master的末端,issue53的末端进行一次简单的三方合并,并且对三方合并后的结果重新做了一个新的快照, master会自动指向它的提交对象。这个提交对象比较特殊,它有两个祖先,即master和issue53之前对应的commit。
2.1.5 遇到冲突时的合并
有时候合并并不会十分的顺利,当不同的分支修改了同一文件的同一部分,就会产生冲突。Git就无法将干净的将两者合并到一起。
因此,当发生冲突时,Git作了合并,但是并没有提交,它会停下来等你解决冲突。要看合并的时候哪些文件差生了冲突,可以使用git status进行查看。任何包含未解决冲突的文件都会以未合并的状态(unmerged)列出来。
当发生冲突时,一旦你解决了后,并且git add后,就表示冲突已经解决。但是仍然处于合并中,然后commit后,此次合并就结束了。当然,还可以使用git mergetool,Git会提供一个可视化的工具来帮助解决冲突。
2.2 分支管理
git branch -v, 如果要查看每个分支最后一次commit信息。git branch --merged, 列出已经和当前分支合并过了的分支。git branch --no-merged, 列出还没有和当前分支合并过的分支。git branch -d branchName, 删除分支。git branch -D branchName, 一个还未被合并的分支是不可以删除的,因此如果要删除的话要使用这个命令。
2.3 远程分支
使用git fetch origin, 来同步远程服务器上的数据到本地, 它会从远程服务器上找到你没有拥有的数据,然后更新你的本地数据库, 然后把origin/master指针移动到最新的位置上。但是它不会将fetch下来的分支合并到当前的分支。
简单的说git fetch origin会更新remote索引。可以通过git branch -a查看你的仓库的所有分支, 包括fetch下来的分支。
值得注意的是,fetch操作下好新的远程分支之后,你依然无法在本地编辑该远程仓库的分支。换句话说,你不会有一个新的分支(dev),有的只是一个你无法移动的upstream/dev指针。如果要把该分支的远程内容合并到当前分支,可以运行git merge upstream/dev。如果想要一份自己的dev分支来进行开发,可以在远程分支的基础上分化出一个新的分支来。
git checkout -b localDev upstream/dev
这会切换到新建的dev本地分支,其内容同远程分支upstream/dev一致,这样你就可以继续开发了。
2.3.1 推送本地分支
git push origin localBranch:remoteBranch, 将localBranch推送到origin的remoteBranch里。
2.3.2 跟踪远程分支
从远程仓库checkout出来的本地分支,称为跟踪分支。跟踪分支是一种和某个远程分支有直接联系的本地分支。在跟踪分支里输入git push,Git会自行判断应该向哪个服务器的哪个分支推送数据。同样,在这些分支里运行git pull会获取所有远程索引,并把它们的数据都合并到本地分支来。
在克隆仓库时,git通常会自动创建一个master分支来跟踪origin/master.这就是为什么最开始可以使用pull和push 的原因。
当然,也可以随心所欲的跟踪其他分支,可以这样git checkout -b [分支名] [远程名]/[分支名], 如果使用的Git版本是高于1.6.2的,还可以使用git checkout --track origin/serverfix这个命令。
2.3.3 删除远程分支
如果你的远程分支已经合并到远程master分支里了,所以远程分支没有用了,那么该如何删除呢?git push origin :serverfix, 这样就删除了origin的serverfix分支。
2.4 分支的衍合
后来,我才发现分支的衍合v1里,讲的有错误。
2.4.1 基本的衍合操作
之前,我们用到了整合分支的命令merge, 它会进行三方合并。其实,还有另一个选择: 可以在一个分支里产生的变化补丁(A)在另一个分支(B)的基础上重新打一遍,这样,就将一个分支(A)合并到了另一个分支(B)上。
在Git里,这种操作叫做衍合rebase, 有了rebase命令,就可以把在一个分支里提交的改变移到另一个分支里重放一遍。
下面我们看一个例子:
git checkout master
git rebase dev
Git的底层实现实现如下(个人的理解):
- 找到master分支与dev分支的共同祖先, 假如为M。
- 在master分支下,跳到M那个commit对象的位置。
- 生成dev分支下M对象后面的commit对象的一系列文件补丁(A)。
- 以master下M位置处为出发点,将文件补丁(A)打在M后面。
- 然后将master自身的commit对象接在已经打好补丁的commit对象后面。
根据分支的变基,我认为也可以这么去理解。
- 找到master分支与dev分支的共同祖先,假如为M。
- 所谓变基,即是改变基底,git rebase dev的意思是将当前master分支的基底改为dev分支的最后一次提交。
- 然后对比当前分支(master)相对于该祖先的历次提交,提取相应的修改并存为临时文件(L)。
- 然后以dev最后的一次commit为基底,然后将之前存的临时文件(L)的修改按序应用。
一般我们使用rebase的目的,是想要得到一个能在远程分支上干净应用的补丁。它和merge的最终结果是一样的,只是得到的commit时间线不一样。
others
tracking, 如果git push -u origin master, 就会将本地的当前分支和origin的master分支绑定到一起,下次作操作的时候,就可以少写参数。这个就叫已经tracking了, 如果你不知道你的分支是否已经tracking了, 那么cat .git/config
Git Pro读书笔记的更多相关文章
- git使用读书笔记
Normal 0 7.8 磅 0 2 false false false EN-US ZH-CN X-NONE /* Style Definitions */ table.MsoNormalTable ...
- 【Tools】Pro Git 一二章读书笔记
记得知乎以前有个问题说:如果用一天的时间学习一门技能,选什么好?里面有个说学会Git是个很不错选择,今天就抽时间感受下Git的魅力吧. Pro Git (Scott Chacon) 读书笔记: ...
- [Git00] Pro Git 一二章读书笔记
记得知乎以前有个问题说:如果用一天的时间学习一门技能,选什么好?里面有个说学会Git是个很不错选择,今天就抽时间感受下Git的魅力吧. Pro Git (Scott Chacon) 读书笔记: ...
- 第三章 Git的入门 - 读书笔记
Android驱动月考3 第三章 Git的入门 - 读书笔记 对于Github,这是全世界最大的开源平台,你可以把你做的项目在这里开源,把你发现的一些新技术在这里开源,向全世界的开发者们分享,大家都彼 ...
- 【读书笔记《Bootstrap 实战》】6.单页营销网站
我们已经掌握了很多实用 Bootstrap 的重要技能.现在,是时候拿出更多的创意来帮助客户实现他们全方位在线营销的愿望了.此次将带领大家做一个漂亮的单页高端营销网站. 主要任务如下: □ 一个大型 ...
- 《Redis设计与实现》读书笔记
<Redis设计与实现>读书笔记 很喜欢这本书的创作过程,以开源的方式,托管到Git上进行创作: 作者通读了Redis源码,并分享了详细的带注释的源码,让学习Redis的朋友轻松不少: 阅 ...
- Linux Shell脚本攻略 读书笔记
Linux Shell脚本攻略 读书笔记 这是一本小书,总共253页,但内容却很丰富,书中的示例小巧而实用,对我这样总是在shell门前徘徊的人来说真是如获至宝:最有价值的当属文本处理,对这块我单独整 ...
- git学习利器:《Git Pro》中文版
Git书籍有<版本控制之道git>,但是很一般.强烈推荐<Git Pro>中文版! 很多开源软件的教程也是免费开源的在线阅读的. <Git Pro>中文版在线阅读h ...
- 《Github入门与实践》读书笔记 蟲咋先生的追求之旅(上)
<Github入门与实践>作者: [日] 大塚弘记 译者:支鹏浩/刘斌 简介 本书从Git的基本知识和操作方法入手,详细介绍了GitHub的各种功能,GitHub与其他工具或服务的协作 ...
随机推荐
- mysql的复杂查询,连接数据库
1.MySQL的工具:Navicat 优点:方便2.数据库的导入 mysqldump -u用户名 -p密码 数据库名称 > 导出文集路径 #结构+数据 mysqldump -u用户名 -p密码 ...
- 【17-06-16】Java入门测试题,测测你基础知识掌握程度(附答案及个人解析)
描述 前几天在知乎里看到一份这样的题,当时只是随便做了一下,对了一下答案.昨天又有了一份进阶的题,里面有些还是需要记录一下,于是就从这个入门的题开始. 题目和答案来自阿里云大学 - 知乎专栏 题目 现 ...
- tensorflow入门教程
人工智能感觉很神秘,作为google公司力推的人工智能框架tensorflow也受到很多人的关注.本文用一个最简单的例子,带领大家看看tensorflow是如何工作的.如果你对人工智能的原理不了解可以 ...
- 关于sqlmap使用手册
sqlmap 使用手册 官方wiki Github sqlmap也是渗透中常用的一个注入工具,可以用来检测sql注入漏洞. 功能与作用 完全支持MySQL,Oracle,PostgreSQL,Micr ...
- python中namedtuple介绍
namedtuple:namedtuple类位于collections模块,有了namedtuple后通过属性访问数据能够让我们的代码更加的直观更好维护.namedtuple能够用来创建类似于元祖的数 ...
- 互联网协议(Internet Protocol Suite)
互联网实现分层:有的7层有的4层:阮一峰认为分五层(个人喜欢): 最底下的一层叫做"实体层"(Physical Layer),最上面的一层叫做"应用层"(App ...
- C++、Objective-C 混合编程
在XCODE中想使用C++代码,你须要把文件的扩展名从.m改成.mm.这样才会启动g++编译器. 我们来看个測试代码: [java] view plaincopy class TestC { priv ...
- 我的Android进阶之旅------>Android知识图谱
Android知识图谱.快来看看哪方面有漏洞? 该图转自:http://blog.csdn.net/xyz_lmn/article/details/41411355
- 利用linux shell自己主动顶贴
在论坛上面发帖问个什么东西的话,一旦不顶.帖子就秒沉了,可是又实在不想每时每刻都去顶,怎么办?以下展示了怎样利用shell 的crontab实现自己主动顶贴. 闲话不多说了,以豆瓣为例-– 1: 用c ...
- OR1200中指令Cache的结构
下面内容摘自<步步惊芯--软核处理器内部设计分析>一书 12.3 ICache结构 OR1200中实现ICache的文件有or1200_ic_top.v.or1200_ic_fsm.v.o ...