讲师简介:
杨杰,PalletOne开发工程师,分布式存储DAG及内存管理模块支持毕业于北京化工大学计算机专业 ,长期从事go语言后端开发,对区块链底层原理与架构设计有深刻了解。
Git是一个开源的分布式版本控制系统,可以有效的、高速的处理从很小到非常大的项目版本管理。
Git是Linus Torvalds为了帮助管理Linux内核开发而开发的一个开放源码的版本控制软件。Git的特点版本可以不依赖网络做任何事情,对分支合并有更好的支持,即使没有网络样可以Commit,查看内部版本记录,创建项目分支等操作等网络再次连上Push到Server端。
Git基础
1.Git简史:
同生活中的许多伟大事件一样,Git 诞生于一个极富纷争大举创新的年代。Linux 内核开源项目有着为数众广的参与者。绝大多数的 Linux 内核维护工作都花在了提交补丁和保存归档的繁琐事务上(1991-2002年间)。到 2002 年,整个项目组开始启用分布式版本控制系统 BitKeeper 来管理和维护代码。
到了 2005 年,开发 BitKeeper 的商业公司同 Linux 内核开源社区的合作关系结束,他们收回了免费使用 BitKeeper 的权力。这就迫使 Linux 开源社区(特别是 Linux 的缔造者 Linus Torvalds )不得不吸取教训,只有开发一套属于自己的版本控制系统才不至于重蹈覆辙。
2.Git基础:
直接记录快照,而非差异比较
近乎所有的操作都是本地执行
时刻保持数据的完整性
多数据操作仅添加数据
文件的三种状态:
1.已提交(committed)
2.已修改(modified)
3.已暂存(staged)
Git安装:
https://gitscm.com/book/zh/v1/%E8%B5%B7%E6%AD%A5-%E5%AE%89%E8%A8it
Git初始配置:
https://gitscm.com/book/zh/v1/%E8%B5%B7%E6%AD%A5-%E5%88%9D%E6%AC%A1%E8%BF%90%E8%A1%8C-Git-%E5%89%8D%E7%9A%84%E9%85%8D%E7%BD%AE
分布式文件系统
3.常见的版本控制系统:
Subversion和 RCS 相似,Subversion 在中央服务器上保存了每个版本的 patch set。当使用户进行检出时,我们检出的实际上是检出版本对应的补丁集数据。显而易见:假如中央服务器发生异常,将导致检出与提交功可以无法用,继而造成版本控制系统的瘫痪。
Version1 保存了3个名称为 A、B、C 的文件。
Version2 文件 A、C 发生了变化,版本保存了变化后的文件。文件 B 没有发生任何变化,版本保留了一个指向 File B 的链接。
因为 Git 的快照同步机制,只要要同步一次服务器上的版本数据信息,就可在本地恢复到任何一个版本。另外,无论哪一台用户机的数据发生了丢失,都能随时同步其余用户机的数据恢复作业,这就是分布式的含义。从本质上来说,Git 不再是一种一个单纯的版本控制系统,而更像是一个微型文件系统。
Git和SVN的区别
Git是分布式的,Git把内容按元数据方式存储,而Svn是按文件存储。
Git的分支和Svn的分支不同。
Git没有一个全局的版本号,Svn有。
Git的内容完整性要优于Svn。
Git不需要联网就可以执行一些操作,而Svn需要联网。
Svn在commit前需要Update,否则会导致一些错误。
Git速度快。
Git底层命令,高层命令
4.Git目录结构
git init
在一个新目录或已有目录内执行git init时,会创建一个.git目录。几乎所有的Git存储和操作的内筒都位于该目录下。
5.底层命令(Plumbing)和高层命令(Procelain)
Git 对象:Git是一套内容寻址文件系统。意思是Git从核心上来看不过是简单地存储键值对。它允许插入任意类型的内容,并返回一个键值,通过键值可以再任何时候取出该内容。可以通过底层命令 hash-object 来示范这点,传一些数据给该命令,它会将数据保存在 .git 目录并返回表示这些数据的键值。
tree(树)对象:tree 对象可以存储文件名,同时也允许存储一组文件。Git 以一种类似 UNIX 文件系统但更简单的方式来存储内容。所有内容以 tree 或 blob 对象存储,其中 tree 对象对应于 UNIX 中的目录,blob 对象则大致对应于 inodes 或文件内容。一个单独的 tree 对象包含一条或多条 tree 记录,每一条记录含有一个指向 blob 或子 tree 对象的 SHA-1 指针,并附有该对象的权限模式 (mode)、类型和文件名信息。
commit(提交)对象:要创建一个 commit 对象,使用 commit-tree 命令,指定一个 tree 的 SHA-1,如果有任何前继提交对象,也可以指定。从你写的第一个 tree 开始:
对象存储:Git 以对象类型为起始内容构造一个文件头。然后添加一个空格,接着是数据内容的长度,最后是一个空字节 (null byte),接着用这个文件头和真正的内容拼接起来(不是文件名)计算校验和,然后用zlib对数据进行压缩,按照SHA-1 值的头两个字符作为子目录名称,剩余 38 个字符作为文件名保存压缩后的数据。这样就把一个文件存储到了git仓库中。
6.Git References
你可以执行像 git log 1a410e 这样的命令来查看完整的历史,但是这样你就要记得 1a410e 是你最后一次提交,这样才能在提交历史中找到这些对象。你需要一个文件来用一个简单的名字来记录这些 SHA-1 值,这样你就可以用这些指针而不是原来的 SHA-1 值去检索了。
在 Git 中,我们称之为“引用”(references 或者 refs,译者注)。你可在 .git/refs 目录下面找到这些包含 SHA-1 值的文件。在这个项目里,这个目录还没不包含任何文件,但是包含这样一个简单的结构:
7.传输协议
传输协议:Git 可以以两种主要的方式跨越两个仓库传输数据:基于HTTP协议之上,和 file://, ssh://, 和 git:// 等智能传输协议。这一节带你快速浏览这两种主要的协议操作过程。
智能协议:这个HTTP方法是很简单但效率不是很高。使用智能协议是传送数据的更常用的方法。这些协议在远端都有Git智能型进程在服务 - 它可以读出本地数据并计算出客户端所需要的,并生成合适的数据给它,这有两类传输数据的进程:一对用于上传数据和一对用于下载。
上传数据: 运行git push origin master, 并且 origin 被定义为一个使用SSH协议的URL。 Git 会使用 send-pack 进程,它会启动一个基于SSH的连接到服务器。
下载数据:在远端仓库有不同的方式启动 upload-pack 进程。你可以使用与 receive-pack 相同的透过SSH管道的方式,也可以通过 Git 后台来启动这个进程,它默认监听在9418号端口上。
维护及数据恢复
8.维护
你时不时的需要进行一些清理工作 ── 如减小一个仓库的大小,清理导入的库,或是恢复丢失的数据。本节将描述这类使用场景。
Git 会不定时地自动运行称为 "auto gc" 的命令。大部分情况下该命令什么都不处理。不过要是存在太多松散对象 (loose object, 不在 packfile 中的对象) 或 packfile,Git 会进行调用 git gc 命令。 gc 指垃圾收集 (garbage collect),此命令会做很多工作:收集所有松散对象并将它们存入 packfile,合并这些 packfile 进一个大的 packfile,然后将不被任何 commit 引用并且已存在一段时间 (数月) 的对象删除。
可以手工运行 auto gc 命令:$ git gc --auto
9.数据恢复
在使用 Git 的过程中,有时会不小心丢失 commit 信息。这一般出现在以下情况下:强制删除了一个分支而后又想重新使用这个分支,hard-reset 了一个分支从而丢弃了分支的部分 commit。如果这真的发生了,有什么办法把丢失的 commit 找回来呢?
9
下面的示例演示了对 test 仓库主分支进行 hard-reset 到一个老版本的 commit 的操作,然后恢复丢失的 commit 。首先查看一下当前的仓库状态:$ git log --pretty=oneline
将master分支移回值中间的一个commit:$ git reset --hard 1a410efbd13591db07496601ebc7a059dd55cfe9
10.总结
Git 作为一套 content-addressable 的文件系统,是一个非常强大的工具,而不仅仅只是一个 VCS 供人使用。希望借助于你新学到的 Git 内部原理的知识,你可以实现自己的有趣的应用,并以更高级便利的方式使用 Git。
常用工具的安装和使用
11.交互式暂存
Git提供了很多脚本来辅助某些命令行任务。这里,你将看到一些交互式命令,它们帮助你方便地构建只包含特定组合和部分文件的提交。在你修改了一大批文件然后决定将这些变更分布在几个各有侧重的提交而不是单个又大又乱的提交时,这些工具非常有用。用这种方法,你可以确保你的提交在逻辑上划分为相应的变更集,以便于供和你一起工作的开发者审阅。如果你运行git add时加上-i或者-interactive选项,Git就进入了一个交互式的shell模式。
12.储藏
经常有这样的事情发生,当你正在进行项目中某一部分的工作,里面的东西处于一个比较杂乱的状态,而你想转到其他分支上进行一些工作。问题是,你不想提交进行了一半的工作,否则以后你无法回到这个工作点。解决这个问题的办法就是git stash命令。
“‘储藏”“可以获取你工作目录的中间状态——也就是你修改过的被追踪的文件和暂存的变更——并将它保存到一个未完结变更的堆栈中,随时可以重新应用。
13.重写历史
很多时候,在 Git 上工作的时候,你也许会由于某种原因想要修订你的提交历史。Git 的一个卓越之处就是它允许你在最后可能的时刻再作决定。你可以在你即将提交暂存区时决定什么文件归入哪一次提交,你可以使用 stash 命令来决定你暂时搁置的工作,你可以重写已经发生的提交以使它们看起来是另外一种样子。这个包括改变提交的次序、改变说明或者修改提交中包含的文件,将提交归并、拆分或者完全删除——这一切在你尚未开始将你的工作和别人共享前都是可以的。
14.取消储藏
在某些情况下,你可能想应用储藏的修改,在进行了一些其他的修改后,又要取消之前所应用储藏的修改。Git没有提供类似于 stash unapply 的命令,但是可以通过取消该储藏的补丁达到同样的效果。
15.Git log
Git 很聪明,它能够通过你提供的前几个字符来识别你想要的那次提交,只要你提供的那部分 SHA-1 不短于四个字符,并且没有歧义——也就是说,当前仓库中只有一个对象以这段 SHA-1 开头。
例如,想要查看一次指定的提交,假设你运行 git log 命令并找到你增加了功能的那次提交:
$ git log
commit 734713bc047d87bf7eac9674765ae793478c50d3
Author: Scott Chacon
Date: Fri Jan 2 18:32:33 2009 -0800
fixed refs handling, added gc auto, updated tests
commit d921970aadf03b3cf0e71becdaab3147ba71cdef
Merge: 1c002dd... 35cfb2b...
Author: Scott Chacon <[email protected]
16.Git 调试
Git 同样提供了一些工具来帮助你调试项目中遇到的问题。由于 Git 被设计为可应用于几乎任何类型的项目,这些工具是通用型,但是在遇到问题时可以经常帮助你查找缺陷所在。
17.Git合并工具
配置Git:
用git config 配置Git,第一件事情就是设置名字和邮箱。
$ git config --global user.name "Jay"
$ git config --global user.email [email protected]
外部的合并与比较工具:
虽然 Git 自己实现了diff,而且到目前为止你一直在使用它,但你能够用一个外部的工具替代它,除此以外,你还能用一个图形化的工具来合并和解决冲突从而不必自己手动解决。有一个不错且免费的工具可以被用来做比较和合并工作,它就是P4Merge。
18.Git合并工具—P4Merge
下载P4Merge :
http://www.perforce.com/product/components/perforce-visual-merge-and-diff-tools
脚本设置:
配置自定义的比较和合并工具:
$ git config --global merge.tool extMerge
$ git config --global mergetool.extMerge.cmd \ 'extMerge "$BASE" "$LOCAL" "$REMOTE" "$MERGED“’
$ git config --global mergetool.trustExitCode false
$ git config --global diff.external extDiff
19.技巧和窍门
自动补全:
Mac: Linux:
Windows:
Git别名:
欢迎关注“脉冲资本”公众号更多资讯等你哦!