《Pro Git》学习笔记
1.Git远程模型示意图
Remote:远程仓库
Repository:本地仓库
Index:暂存区
workspace:当前工作区
2.取得Git仓库
2.1 初始化新仓库
git init
2.2 从现有仓库克隆
git clone git://github.com/xxx/xxx.git [dirName]
3.记录每次更新到仓库
3.1 文件状态变化周期
3.2 检查当前文件的状态
git status
3.3 跟踪新文件
git add <fileName>
3.4 更新已放到暂存区但是之后被修改的文件
git add <fileName>
3.5 查看已暂存和未暂存的更新
git diff 查看工作区与暂存区的差异
git diff 已暂存的文件与上次提交之间的差别
3.6 提交更新
git commit 或者 git commit -m "具体说明"
3.7 跳过暂存区直接更新
git commit -a -m "更新说明"
3.8 删除文件
git rm <文件名>
如果删除之前已经修改过并且放到了暂存区,那么使用-f选项来强制删除暂存区中的文件。该参数用来防止误删文件后丢失修改的内容。
3.9 移除对文件的跟踪但是不删除文件
git rm --cached <文件名>
删除的时候如果在“*”号前面加“\”那么就会递归删除当前目录下所有匹配的文件,例如:git rm \*.tmp。
3.10 移动文件
git mv <文件1> <文件2> 相当于先删除文件1,然后增加文件2
4.查看提交的历史
git log
常见用法:
4.1 展开内容差异
git log -p -2 (-p 展开每次提交的内容差异,用-2表示仅显示最近的两次更新)
4.2 仅显示简要的增改行数统计
git log --stat
4.3 指定格式展示提交历史
git log --pretty=oneline (将每个提交放在一行显示,还有short、full、fuller可以用)
4.4 定制记录格式
git log --pretty=format:"%h - %an, %ar : %s" ,常用格式占位符的写法及意义为:
选项 | 说明 |
%H | 提交对象(commit)的完整哈希字串 |
%h | 提交对象的简短哈希字串 |
%T | 树对象(tree)的完整哈希字串 |
%t | 树对象的简短哈希字串 |
%P | 父对象(parent)的完整哈希字串 |
%p | 父对象的简短哈希字串 |
%an | 作者(author)的名字 |
%ae | 作者的电子邮件地址 |
%ad | 作者修订日期(可以用 -date= 选项定制格式) |
%ar | 作者修订日期,按多久以前的方式显示 |
%cn | 提交者(committer)的名字 |
%ce | 提交者的电子邮件地址 |
%cd | 提交日期 |
%cr | 提交日期,按多久以前的方式显示 |
%s | 提交说明 |
4.5 限制筛选条件
git log --[n|since|after|until|author|committer] ,选项说明:
选项 | 说明 |
-(n) | 仅显示最近的 n 条提交 |
--since, --after | 仅显示指定时间之后的提交 |
--until, --before | 仅显示指定时间之前的提交 |
--author | 仅显示指定作者相关的提交 |
--committer | 仅显示指定提交者相关的提交 |
5、撤销操作
5.1 修改最后一次提交
git commit -m "initial commit"
git add forgotten_file
git commit --amend
5.2 取消已暂存的文件
git reset HEAD <文件名>
5.3 取消对文件的修改
git checktout -- <文件名>
6.远程仓库
6.1 查看当前远程仓库
git remote [-v]
6.2 添加远程仓库
git remote add <远程仓库名> <远程仓库地址>
6.3 从远程仓库抓取数据
git fetch <远程仓库名>
如果是克隆了一个仓库,此命令会自动将远程仓库归于 origin 名下。所以,git fetch origin 会抓取从你上次克隆以来别人上传到此远程仓库中的所有更新(或是上次 fetch 以来别人提交的更新)。有一点很重要,需要记住,fetch 命令只是将远端的数据拉到本地仓库,并不自动合并到当前工作分支,只有当你确实准备好了,才能手工合并。
如果设置了某个分支用于跟踪某个远端仓库的分支(参见下节及第三章的内容),可以使用 git pull 命令自动抓取数据下来,然后将远端分支自动合并到本地仓库中当前分支。在日常工作中我们经常这么用,既快且好。实际上,默认情况下git clone 命令本质上就是自动创建了本地的 master 分支用于跟踪远程仓库中的 master 分支(假设远程仓库确实有 master 分支)。所以一般我们运行git pull,目的都是要从原始克隆的远端仓库中抓取数据后,合并到工作目录中的当前分支。
6.4 推送数据到远程仓库
git push [远程仓库名] [分支名]
6.5 查看远程仓库信息
git remote show [远程仓库名]
6.6 远程仓库的删除和重命名
git remote rename <旧仓库名> <新仓库名>
7.打标签
在发布某个软件版本的时候使用Git对某一时间点上的版本打上标签。
7.1 查看已有标签
git tag [-l <标签模式>]
例如:git tag -l 'v1.4.2.*'
7.2 新建标签
Git 使用的标签有两种类型:轻量级的(lightweight)和含附注的(annotated)。轻量级标签就像是个不会变化的分支,实际上它就是个指向特 定提交对象的引用。而含附注标签,实际上是存储在仓库中的一个独立对象,它有自身的校验和信息,包含着标签的名字,电子邮件地址和日期,以及标签说明,标签本身也允许使用 GNU Privacy Guard (GPG) 来签署或验证。一般我们都建议使用含附注型的标签,以便保留相关信息;当然,如果只是临时性加注标签,或者不需要旁注额外信息,用轻量级标签也没问题。
含附注的标签:
git tag -a <标签名> [-m <标签说明>]
-a选项指定含附注类型,-m选项指定标签说明。
轻量级标签:
git tag <标签名>
7.3 签署标签
利用私钥和GPG来签署标签。
git tag -s <标签名> [-m <标签说明>]
7.4 验证标签
git tag -v <标签名>
需要有签署者的公钥存放在keyring中。
7.5 后期加注标签
git tag -v <标签名> <校验和前几位>
7.6 分享标签
git push <远程仓库名> <标签名>
8.分支理论
commit对象指向包含各个文件blob对象索引的tree对象。Git分支的本质是个指向commit对象的可变指针,Git使用master作为分支的默认名字。Git通过创建一个新的分支指针来创建新的分支:git branch <分支名>。
HEAD是一个指向正在工作中的本地分支的指针,可以将其当做当前分支的别名。
8.1 将HEAD切换到其他分支
git checktout <分支名>
切换分支的时候最好保持一个清洁的工作区域。
8.2 分支的新建与切换
git checkout -b <新分支名>
相当于:
git branch <新分支名>
git checkout <新分支名>
8.3 分支的合并
假设要将分支hotfix合并到分支master,首先检出master分支,然后合并分支。
git checkout master
git merge hotfix
8.4 删除分支
git branch -d <分支名>
8.5 查看所有分支
git branch [-v|--merged|--on-merged]
-v选项用来查看各分支最后一个commit的信息,--merged用来查看哪些分支已经并入当前分支。
8.6 利用分支来进行开发工作
长期分支(master):例如master分支,保留完全稳定的代码,稳定的分支总是比较老旧。
开发分支(develop):与master平行的专门用于后续开发或者稳定性测试的分支。
特性分支(topic):短期的用来实现单一特性的分支。
8.7 远程分支
远程分支(remote branch)是对远程仓库中分支的索引。它们是无法移动的本地分支,只有在Git进行网络交互时才会更新。远程分支一般用<远程仓库名>/<分支名>这样的形式来表示。
一次Git克隆会建立本地分支master和远程分支origin/master,它们都指向origin/master分支的最后一次提交。
(1)同步远程服务器上的数据:git fetch origin。该命令首先找到origin服务器,从上面获取数据然后把origin/master的指针移动到最新的位置。
(2)推送本地分支:git push <远程仓库名> <本地分支名>[:<远程分支名>]。如果不指定<远程分支名>,那么会使用与本地分支相同的名字。
(3)值得注意的是,即使用fetch操作获取了新的远程分支,任然无法在本地编辑远程仓库的分支,如果要把远程分支的内容合并到当前分支,可以使用:git merge <远程仓库名>/<远程分支名>。
(4)如果想要自己的可编辑分支,可以在远程分支的基础上分化出一个新的分支来:git checkout -b <新分支名> <远程仓库名>/<远程分支名>。从远程分支中checkout出来的本地分支称为跟踪分支,跟踪分支是一种和某个远程分支有直接联系的本地分支。在跟踪分支里输入 git push,Git会自行推断该向哪个服务器的哪个分支推送数据。同样在跟踪分支里运行 git pull 会获取远程索引并把它们的数据都合并到本地分支中来。
(5)删除远程分支:git push <远程仓库名> :<远程分支名>
8.8 分支的衍合
把一个分支整合到另一个分支的办法有两种:merge 和 rebase(暂译为衍合)。merge的原理是将两个分支最新的快照以及二者最新的共同祖先进行三方合并,然后生成一个新的提交对象。rebase的原理是:假设有两个分支 experiment 和 master,experiment是我们要衍合的分支。先回到两者的共同祖先,依据 experiment 后续的历次提交产生一系列补丁,然后以基底分支 master 的最后一个提交对象为新的出发点,逐个应用之前准备好的补丁文件,最后会产生一个新的合并提交对象,改写experiment的提交历史。其命令表示为:
git checkout experiment
git rebase master
rebase 和 merge 最后得到的快照内容是相同的,但 rebase 能够提供更为简洁的提交历史。一般我们使用衍合的目的,是想要得到一个能在远程分支上干净应用的补丁 — 比如某些项目你不是维护者,但想帮点忙的话,最好用衍合:先在自己的一个分支里进行开发,当准备向主项目提交补丁的时候,根据最新的 origin/master 进行一次衍合操作然后再提交,这样维护者就不需要做任何整合工作(译注:实际上是把解决分支补丁同最新主干代码之间冲突的责任,化转为由提交补丁的人来解决),只需根据你提供的仓库地址作一次快进合并,或者直接采纳你提交的补丁。
衍合也可以放到其他分支进行,并不一定非得根据分化之前的分支。以图 3-31 的历史为例,我们为了给服务器端代码添加一些功能而创建了特性分支
server,
然
后提交 C3 和 C4。然后又从 C3 的地方再增加一个 client
分支来对客户端代码进行一些相应修改,所以提交了 C8 和 C9。最后,又回到 server
分支提交了 C10。
图 3-31. 从一个特性分支里再分出一个特性分支的历史。
假设在接下来的一次软件发布中,我们决定先把客户端的修改并到主线中,而暂缓并入服务端软件的修改(因为还需要进一步测试)。这个时候,我们就可以把基于 server
分支而非 master
分支的改变(即 C8 和 C9),跳过 server
直接放到 master
分支中重演一遍,但这需要用 git rebase
的 --onto
选项指定新的基底分支 master
:
$ git rebase --onto master server client
这好比在说:“取出 client
分支,找出 client
分支和 server
分支的共同祖先之后的变化,然后把它们在 master
上重演一遍”。是不是有点复杂?不过它的结果如图 3-32 所示,非常酷(译注:虽然 client
里的 C8, C9 在 C3 之后,但这仅表明时间上的先后,而非在 C3 修改的基础上进一步改动,因为 server
和 client
这两个分支对应的代码应该是两套文件,虽然这么说不是很严格,但应理解为在 C3 时间点之后,对另外的文件所做的 C8,C9 修改,放到主干重演。):
图 3-32. 将特性分支上的另一个特性分支衍合到其他分支。
现在可以快进 master
分支了(见图 3-33):
$ git checkout master
$ git merge client
图 3-33. 快进 master 分支,使之包含 client 分支的变化。
现在我们决定把 server
分支的变化也包含进来。我们可以直接把 server
分支衍合到 master
,而不用手工切换到 server
分支后再执行衍合操作 — git rebase [主分支] [特性分支]
命令会先取出特性分支 server
,然后在主分支 master
上重演:
$ git rebase master server
于是,server
的进度应用到 master
的基础上,如图 3-34 所示:
图 3-34. 在 master 分支上衍合 server 分支。
然后就可以快进主干分支 master
了:
$ git checkout master
$ git merge server
现在 client
和 server
分支的变化都已经集成到主干分支来了,可以删掉它们了。最终我们的提交历史会变成图 3-35 的样子:
$ git branch -d client
$ git branch -d server
图 3-35. 最终的提交历史
rebase的风险:一旦分支中的提交对象发布到公共仓库,就千万不要对该分支进行rebase操作。
《Pro Git》学习笔记的更多相关文章
- js学习笔记:webpack基础入门(一)
之前听说过webpack,今天想正式的接触一下,先跟着webpack的官方用户指南走: 在这里有: 如何安装webpack 如何使用webpack 如何使用loader 如何使用webpack的开发者 ...
- PHP-自定义模板-学习笔记
1. 开始 这几天,看了李炎恢老师的<PHP第二季度视频>中的“章节7:创建TPL自定义模板”,做一个学习笔记,通过绘制架构图.UML类图和思维导图,来对加深理解. 2. 整体架构图 ...
- PHP-会员登录与注册例子解析-学习笔记
1.开始 最近开始学习李炎恢老师的<PHP第二季度视频>中的“章节5:使用OOP注册会员”,做一个学习笔记,通过绘制基本页面流程和UML类图,来对加深理解. 2.基本页面流程 3.通过UM ...
- 2014年暑假c#学习笔记目录
2014年暑假c#学习笔记 一.C#编程基础 1. c#编程基础之枚举 2. c#编程基础之函数可变参数 3. c#编程基础之字符串基础 4. c#编程基础之字符串函数 5.c#编程基础之ref.ou ...
- JAVA GUI编程学习笔记目录
2014年暑假JAVA GUI编程学习笔记目录 1.JAVA之GUI编程概述 2.JAVA之GUI编程布局 3.JAVA之GUI编程Frame窗口 4.JAVA之GUI编程事件监听机制 5.JAVA之 ...
- seaJs学习笔记2 – seaJs组建库的使用
原文地址:seaJs学习笔记2 – seaJs组建库的使用 我觉得学习新东西并不是会使用它就够了的,会使用仅仅代表你看懂了,理解了,二不代表你深入了,彻悟了它的精髓. 所以不断的学习将是源源不断. 最 ...
- CSS学习笔记
CSS学习笔记 2016年12月15日整理 CSS基础 Chapter1 在console输入escape("宋体") ENTER 就会出现unicode编码 显示"%u ...
- HTML学习笔记
HTML学习笔记 2016年12月15日整理 Chapter1 URL(scheme://host.domain:port/path/filename) scheme: 定义因特网服务的类型,常见的为 ...
- DirectX Graphics Infrastructure(DXGI):最佳范例 学习笔记
今天要学习的这篇文章写的算是比较早的了,大概在DX11时代就写好了,当时龙书11版看得很潦草,并没有注意这篇文章,现在看12,觉得是跳不过去的一篇文章,地址如下: https://msdn.micro ...
- ucos实时操作系统学习笔记——任务间通信(消息)
ucos另一种任务间通信的机制是消息(mbox),个人感觉是它是queue中只有一个信息的特殊情况,从代码中可以很清楚的看到,因为之前有关于queue的学习笔记,所以一并讲一下mbox.为什么有了qu ...
随机推荐
- HW5.30
public class Solution { public static void main(String[] args) { for(int i = 3; i <= 1000; i++) i ...
- SRM 596 DIV 2
前段时间终于配置好了TopCoder的环境,所以就拿这场的DIV2练习了一下 1. 250pt FoxAndSightseeing 题意 给你n个城市的位置,他们在同一直线上,要求你跳过其中某一个城市 ...
- Linux shell 常用
使用Linux shell是我每天的基本工作,但我经常会忘记一些有用的shell命令和l技巧.当然,命令我能记住,但我不敢说能记得如何用它执行某个特定任务.于是,我开始在一个文本文件里记录这些用法,并 ...
- SaltStack管理从这里开始
Modules 1:查看所有module列表: salt 'jcfx-4' sys.list_modules jcfx-4: - acl - aliases - alternatives - apac ...
- Python Django manage.py提供的命令及用法
λpython manage.pyType'manage.py help <subcommand>'for help on a specific subcommand. Available ...
- 自定义文件上传的按钮的样式css+js
核心就是一段css遮住了原生的input框,然后用js将文件的值传入到另一个指定的input框中 原文链接 http://geniuscarrier.com/how-to-style-a-html-f ...
- iOS 应用数据存储的常用方式
iOS 开发中,经常会有将数据存储到本地的需求.比如一些数据的缓存,或者记录下用户的账号密码,记录下下次是否自动登录等,这些都需要将数据记录到本地.iOS中,数据存储到本地的常见方式有三种: 一: 使 ...
- ECSHOP在线手册布局参考图--积分商城 exchange_list.dwt
A.购物车 1,设置方法 程序自动读取购物车的商品数量 2,代码相关 cart.lbi 中 {insert_scripts files='transport.js'} <div clas ...
- ECSHOP在线手册之布局参考图-首页 index.dwt
A.logo替换 1,设置方法 后台商店设置里,上传logo就行,注意logo的名称必须是logo.gif 2,代码相关 page_header.lbi 中 <a href=" ...
- 拼接json示例 json分页并显示所有页码
<%@ page language="java" import="java.util.*" pageEncoding="gbk"%&g ...