Git 那些事儿

本贴最后更新于 2880 天前,其中的信息可能已经水流花落

Git 是目前世界上最先进的分布式版本控制系统,适合多人协作开发的大型项目。我平常也经常使用 git,来管理自己的几个小项目。简单说说 git 的原理和 git 的特点!(只有知道了一个工具的运行原理,设计思路,才能更好的使用这个工具)

#1. 自己对 SVN 和 Git 的体验

在公司一直用 SVN,自己折腾的业余项目用 Git 我的 Github。个人认为 SVN 用起来比较快捷,方便,提交代码只需要 commit 一下就行了,适合小团队的代码版本管理。但是一个大型的开源项目,可能有几百或者上千个开发者提交代码,SVN 就显得力不从心了!SO Git 大法横空出世了!

#2. Git 的诞生背景

自 2002 年开始,林纳斯·托瓦兹决定使用 BitKeeper 作为 Linux 内核主要的版本控制系统用以维护代码。因为 BitKeeper 为专有软件,这个决定在社区中长期遭受质疑。在 Linux 社区中,特别是理查德·斯托曼与自由软件基金会的成员,主张应该使用开放源代码的软件来作为 Linux 核心的版本控制系统。林纳斯·托瓦兹曾考虑过采用现成软件作为版本控制系统(例如 Monotone),但这些软件都存在一些问题,特别是性能不佳。现成的方案,如 CVS 的架构,受到林纳斯·托瓦兹的批评

2005 年,安德鲁·垂鸠写了一个简单程序,可以连接 BitKeeper 的存储库,BitKeeper 著作权拥有者拉里·麦沃伊认为安德鲁·垂鸠对 BitKeeper 内部使用的协议进行逆向工程,决定收回无偿使用 BitKeeper 的授权。Linux 内核开发团队与 BitMover 公司进行蹉商,但无法解决他们之间的歧见。林纳斯·托瓦兹决定自行开发版本控制系统替代 BitKeeper,以十天的时间,编写出第一个 git 版本
资料来自维基百科 Git-维基百科

#3. Git 于 SVN 的主要区别

SVN 是集中式版本控制系统,版本库是集中放在中央服务器的,而干活的时候,用的都是自己的电脑,所以首先要从中央服务器哪里得到最新的版本,然后干活,干完后,需要把自己做完的活推送到中央服务器。集中式版本控制系统是必须联网才能工作,如果在局域网还可以,带宽够大,速度够快,如果在互联网下,如果网速慢的话,就纳闷了。

Git 是分布式版本控制系统,那么它就没有中央服务器的,每个人的电脑就是一个完整的版本库,这样,工作的时候就不需要联网了,因为版本都是在自己的电脑上。既然每个人的电脑都有一个完整的版本库,那多个人如何协作呢?比如说自己在电脑上改了文件 A,其他人也在电脑上改了文件 A,这时,你们两之间只需把各自的修改推送给对方,就可以互相看到对方的修改了。

#4. 浅析 Git 原理
git 的底层从其本质上讲是一个内容寻址文件系统,然后基于这个内容寻址文件系统实现了一套 vcs(版本控制系统)的高层接口,方便我们使用.当然 git 也提供了底层接口,便于我们使用之做出符合自己需求的系统.

我们把文件内容交给 git 进行管理,总得有一个地方来存放这些内容是吧!
是的,在 git 中,所有的文件内容都保存在 git 仓库的 objects 目录中.

初始化 git 库

我们初始化一个 git 仓库有两种方式,git init 和 git –bare init
这两者的区别是,前者会在当前目录下生成一个.git 目录(此目录即为 git 库的目录),而当前目录为我们的工作目录,一般是 checkout 后的文件,我们编程时所读写的内容都在此目录下.
后者的 bare 的意思就是裸的意思,也就是直接把当前目录当作 git 库的目录,这个一般用在远程 git 库上,因为我们在远程 git 库上没有 checkout 的需求,只是用作单纯的 git 库
git 库还有个优点就是直接拷贝到另一个地方就可以直接用了,只要你的相应的机器上安装了 git 即可.

git 对象

git 中一个非常重要的概念就是 git 对象,我们可以把 git 系统想象成一个强大的 key-value 存储,每一个对象都对应着一个 40 位的哈希值.通过这个哈希值我们便可以很容易的取得对象(当然我们可以为这些哈希值取一些有意义的别名,方便我们使用).我们可以把这个哈希值看作指针.而对应的对象就是指针所指向的实体.对象和对象之间还可以通过通过指针进行一些关联的操作.
git 对象可分为四种类型:

  • blob 对象 用来存放文件数据
  • tree 对象 对应着目录,tree 的内容为 blob 对象的指针或者其他 tree 对象的指针
  • commit 对象 每一次 commit 都会产生一个新的 commit 对象,其包含了一个指向 tree 对象的指针,指向前一次 commit 对象的指针,还包含了 commit 的时间,作者和注释等信息,就相当于为项目做了一次 snapshot,通过 commit 对象我们可以跟踪到前一次 commit 对象,这样就可以实现 log 功能了
  • tag 对象 一种特殊的 commit 对象

git 库目录
接下来分析 git 库目录中各个文件的作用

Wujunze-MacBook:test.git Junze$ ls -al
total 32
drwxr-xr-x  11 Luke  staff   374 Jun  4 20:21 .
drwxr-xr-x  24 Luke  staff   816 Jun  4 20:21 ..
-rw-r--r--   1 Luke  staff    23 Jun  4 20:21 HEAD (当前分支的指针)
drwxr-xr-x   2 Luke  staff    68 Jun  4 20:21 branches
-rw-r--r--   1 Luke  staff    85 Jun  4 20:21 config
-rw-r--r--   1 Luke  staff    73 Jun  4 20:21 description
drwxr-xr-x  12 Luke  staff   408 Jun  4 20:21 hooks (可以实现在特定操作的前或者后触发一些动作)
drwxr-xr-x   3 Luke  staff   102 Jun  4 20:21 info
drwxr-xr-x  64 Luke  staff  2176 Jun  4 20:21 objects (blob,tree,commit,tag 对象)
-rw-r--r--   1 Luke  staff    85 Jun  4 20:21 packed-refs
drwxr-xr-x   4 Luke  staff   136 Jun  4 20:21 refs (指向各个分支的指针)

objects 保存的时候,以 40 位哈希值的前两位作为子目录的名称,后 38 位作为对象的文件名
git 系统会定期对所有的 objects 进行打包操作,这样可以减少磁盘占用空间
git 中最新版本的都是直接保存的,以前版本是通过引用最新的文件以及差异进行获取的,这是因为大都数时候我们对最新的分支代码更为关注

#5.Git 的学习
先熟悉 Git 的运行原理和设计思路,然后把自己的项目迁移到 Git。自己动手用 Git,才能真正的熟练使用 Git!
推荐一个不错的 Git 教程,廖雪峰的 Git 教程!最浅显易懂的 Git 教程
也欢迎大家加 QQ 群 213470752 一起学习交流 Git 的使用!

#6.Git 常用命令
PS: 一些 Git 命令使用了别名 co=checkout ci=commit br=branch
查看、添加、提交、删除、找回,重置修改文件

git help # 显示 command 的 help

git show # 显示某次提交的内容 git show $id

git co -- # 抛弃工作区修改

git co . # 抛弃工作区修改

git add # 将工作文件修改提交到本地暂存区

git add . # 将所有修改过的工作文件提交暂存区

git rm # 从版本库中删除文件

git rm --cached # 从版本库中删除文件,但不删除文件

git reset # 从暂存区恢复到工作文件

git reset -- . # 从暂存区恢复到工作文件

git reset --hard # 恢复最近一次提交过的状态,即放弃上次提交后的所有本次修改

git ci git ci . git ci -a # 将 git add, git rm 和 git ci 等操作都合并在一起做 git ci -am "some comments"

git ci --amend # 修改最后一次提交记录

git revert <$id> # 恢复某次提交的状态,恢复动作本身也创建次提交对象

git revert HEAD # 恢复最后一次提交的状态

查看文件 diff

git diff # 比较当前文件和暂存区文件差异 git diff

git diff # 比较两次提交之间的差异

git diff .. # 在两个分支之间比较

git diff --staged # 比较暂存区和版本库差异

git diff --cached # 比较暂存区和版本库差异

git diff --stat # 仅仅比较统计信息

查看提交记录

git log git log # 查看该文件每次提交记录

git log -p # 查看每次详细修改内容的 diff

git log -p -2 # 查看最近两次详细修改内容的 diff

git log --stat #查看提交统计信息

tig

Mac 上可以使用 tig 代替 diff 和 log,brew install tig

Git 本地分支管理

查看、切换、创建和删除分支

git br -r # 查看远程分支

git br <new_branch> # 创建新的分支

git br -v # 查看各个分支最后提交信息

git br --merged # 查看已经被合并到当前分支的分支

git br --no-merged # 查看尚未被合并到当前分支的分支

git co # 切换到某个分支

git co -b <new_branch> # 创建新的分支,并且切换过去

git co -b <new_branch> # 基于 branch 创建新的 new_branch

git co $id # 把某次历史提交记录 checkout 出来,但无分支信息,切换到其他分支会自动删除

git co $id -b <new_branch> # 把某次历史提交记录 checkout 出来,创建成一个分支

git br -d # 删除某个分支

git br -D # 强制删除某个分支 (未被合并的分支被删除的时候需要强制)

分支合并和 rebase

git merge # 将 branch 分支合并到当前分支

git merge origin/master --no-ff # 不要 Fast-Foward 合并,这样可以生成 merge 提交

git rebase master # 将 master rebase 到 branch,相当于: git co && git rebase master && git co master && git merge

Git 补丁管理(方便在多台机器上开发同步时用)

git diff > ../sync.patch # 生成补丁

git apply ../sync.patch # 打补丁

git apply --check ../sync.patch #测试补丁能否成功

Git 暂存管理

git stash # 暂存

git stash list # 列所有 stash

git stash apply # 恢复暂存的内容

git stash drop # 删除暂存区

Git 远程分支管理

git pull # 抓取远程仓库所有分支更新并合并到本地

git pull --no-ff # 抓取远程仓库所有分支更新并合并到本地,不要快进合并

git fetch origin # 抓取远程仓库更新

git merge origin/master # 将远程主分支合并到本地当前分支

git co --track origin/branch # 跟踪某个远程分支创建相应的本地分支

git co -b <local_branch> origin/<remote_branch> # 基于远程分支创建本地分支,功能同上

git push # push 所有分支

git push origin master # 将本地主分支推到远程主分支

git push -u origin master # 将本地主分支推到远程(如无远程主分支则创建,用于初始化远程仓库)

git push origin <local_branch> # 创建远程分支, origin 是远程仓库名

git push origin <local_branch>:<remote_branch> # 创建远程分支

git push origin :<remote_branch> #先删除本地分支(git br -d ),然后再 push 删除远程分支

Git 远程仓库管理

GitHub

git remote -v # 查看远程服务器地址和仓库名称

git remote show origin # 查看远程服务器仓库状态

git remote add origin git@ github:robbin/robbin_site.git # 添加远程仓库地址

git remote set-url origin git@ github.com:robbin/robbin_site.git # 设置远程仓库地址(用于修改远程仓库地址) git remote rm # 删除远程仓库

创建远程仓库

git clone --bare robbin_site robbin_site.git # 用带版本的项目创建纯版本仓库

scp -r my_project.git git@ git.csdn.net:~ # 将纯仓库上传到服务器上

mkdir robbin_site.git && cd robbin_site.git && git --bare init # 在服务器创建纯仓库

git remote add origin git@ github.com:robbin/robbin_site.git # 设置远程仓库地址

git push -u origin master # 客户端首次提交

git push -u origin develop # 首次将本地 develop 分支提交到远程 develop 分支,并且 track

git remote set-head origin master # 设置远程仓库的 HEAD 指向 master 分支

也可以命令设置跟踪远程库和本地库

git branch --set-upstream master origin/master

git branch --set-upstream develop origin/develop

##总结
Git 是工具,是开发者用工具,开发者利用工具让项目的管理更加方便!开发者不要被 Git 所限制,不能被工具牵着走!
使用 Git,可以自己搭建 Git 服务,可以可以使用第三方提供的免费服务!例如:GitHub OSC Coding
大家有什么好的学习 Git 学习心得或者方法的可以邮件 1017109588@qq.com 一起交流学习哦!
原文链接 https://wujunze.com/git_something.jsp 转载文章请保留原文链接

参考
Git 官方文档
Git 原理浅析
廖雪峰 Git 教程
等技术文档

  • Git

    Git 是 Linux Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软件。

    205 引用 • 357 回帖
  • 分享

    有什么新发现就分享给大家吧!

    242 引用 • 1750 回帖
  • 程序员

    程序员是从事程序开发、程序维护的专业人员。

    534 引用 • 3528 回帖 • 1 关注
  • Linux

    Linux 是一套免费使用和自由传播的类 Unix 操作系统,是一个基于 POSIX 和 Unix 的多用户、多任务、支持多线程和多 CPU 的操作系统。它能运行主要的 Unix 工具软件、应用程序和网络协议,并支持 32 位和 64 位硬件。Linux 继承了 Unix 以网络为核心的设计思想,是一个性能稳定的多用户网络操作系统。

    915 引用 • 931 回帖

相关帖子

7 回帖

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...
请输入回帖内容 ...

推荐标签 标签

  • 笔记

    好记性不如烂笔头。

    304 引用 • 777 回帖
  • 倾城之链
    23 引用 • 66 回帖 • 102 关注
  • 程序员

    程序员是从事程序开发、程序维护的专业人员。

    534 引用 • 3528 回帖 • 1 关注
  • Git

    Git 是 Linux Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软件。

    205 引用 • 357 回帖
  • Spring

    Spring 是一个开源框架,是于 2003 年兴起的一个轻量级的 Java 开发框架,由 Rod Johnson 在其著作《Expert One-On-One J2EE Development and Design》中阐述的部分理念和原型衍生而来。它是为了解决企业应用开发的复杂性而创建的。框架的主要优势之一就是其分层架构,分层架构允许使用者选择使用哪一个组件,同时为 JavaEE 应用程序开发提供集成的框架。

    941 引用 • 1458 回帖 • 153 关注
  • InfluxDB

    InfluxDB 是一个开源的没有外部依赖的时间序列数据库。适用于记录度量,事件及实时分析。

    2 引用 • 55 关注
  • WebClipper

    Web Clipper 是一款浏览器剪藏扩展,它可以帮助你把网页内容剪藏到本地。

    3 引用 • 9 回帖 • 5 关注
  • Sublime

    Sublime Text 是一款可以用来写代码、写文章的文本编辑器。支持代码高亮、自动完成,还支持通过插件进行扩展。

    10 引用 • 5 回帖
  • 互联网

    互联网(Internet),又称网际网络,或音译因特网、英特网。互联网始于 1969 年美国的阿帕网,是网络与网络之间所串连成的庞大网络,这些网络以一组通用的协议相连,形成逻辑上的单一巨大国际网络。

    96 引用 • 330 回帖
  • OAuth

    OAuth 协议为用户资源的授权提供了一个安全的、开放而又简易的标准。与以往的授权方式不同之处是 oAuth 的授权不会使第三方触及到用户的帐号信息(如用户名与密码),即第三方无需使用用户的用户名与密码就可以申请获得该用户资源的授权,因此 oAuth 是安全的。oAuth 是 Open Authorization 的简写。

    36 引用 • 103 回帖 • 8 关注
  • 开源中国

    开源中国是目前中国最大的开源技术社区。传播开源的理念,推广开源项目,为 IT 开发者提供了一个发现、使用、并交流开源技术的平台。目前开源中国社区已收录超过两万款开源软件。

    7 引用 • 86 回帖 • 1 关注
  • LaTeX

    LaTeX(音译“拉泰赫”)是一种基于 ΤΕΧ 的排版系统,由美国计算机学家莱斯利·兰伯特(Leslie Lamport)在 20 世纪 80 年代初期开发,利用这种格式,即使使用者没有排版和程序设计的知识也可以充分发挥由 TeX 所提供的强大功能,能在几天,甚至几小时内生成很多具有书籍质量的印刷品。对于生成复杂表格和数学公式,这一点表现得尤为突出。因此它非常适用于生成高印刷质量的科技和数学类文档。

    9 引用 • 32 回帖 • 165 关注
  • 爬虫

    网络爬虫(Spider、Crawler),是一种按照一定的规则,自动地抓取万维网信息的程序。

    106 引用 • 275 回帖
  • gRpc
    10 引用 • 8 回帖 • 56 关注
  • 宕机

    宕机,多指一些网站、游戏、网络应用等服务器一种区别于正常运行的状态,也叫“Down 机”、“当机”或“死机”。宕机状态不仅仅是指服务器“挂掉了”、“死机了”状态,也包括服务器假死、停用、关闭等一些原因而导致出现的不能够正常运行的状态。

    13 引用 • 82 回帖 • 38 关注
  • 链书

    链书(Chainbook)是 B3log 开源社区提供的区块链纸质书交易平台,通过 B3T 实现共享激励与价值链。可将你的闲置书籍上架到链书,我们共同构建这个全新的交易平台,让闲置书籍继续发挥它的价值。

    链书社

    链书目前已经下线,也许以后还有计划重制上线。

    14 引用 • 257 回帖 • 5 关注
  • 持续集成

    持续集成(Continuous Integration)是一种软件开发实践,即团队开发成员经常集成他们的工作,通过每个成员每天至少集成一次,也就意味着每天可能会发生多次集成。每次集成都通过自动化的构建(包括编译,发布,自动化测试)来验证,从而尽早地发现集成错误。

    14 引用 • 7 回帖 • 2 关注
  • SVN

    SVN 是 Subversion 的简称,是一个开放源代码的版本控制系统,相较于 RCS、CVS,它采用了分支管理系统,它的设计目标就是取代 CVS。

    29 引用 • 98 回帖 • 692 关注
  • Postman

    Postman 是一款简单好用的 HTTP API 调试工具。

    4 引用 • 3 回帖 • 1 关注
  • IDEA

    IDEA 全称 IntelliJ IDEA,是一款 Java 语言开发的集成环境,在业界被公认为最好的 Java 开发工具之一。IDEA 是 JetBrains 公司的产品,这家公司总部位于捷克共和国的首都布拉格,开发人员以严谨著称的东欧程序员为主。

    180 引用 • 400 回帖
  • 百度

    百度(Nasdaq:BIDU)是全球最大的中文搜索引擎、最大的中文网站。2000 年 1 月由李彦宏创立于北京中关村,致力于向人们提供“简单,可依赖”的信息获取方式。“百度”二字源于中国宋朝词人辛弃疾的《青玉案·元夕》词句“众里寻他千百度”,象征着百度对中文信息检索技术的执著追求。

    63 引用 • 785 回帖 • 251 关注
  • sts
    2 引用 • 2 回帖 • 149 关注
  • Logseq

    Logseq 是一个隐私优先、开源的知识库工具。

    Logseq is a joyful, open-source outliner that works on top of local plain-text Markdown and Org-mode files. Use it to write, organize and share your thoughts, keep your to-do list, and build your own digital garden.

    4 引用 • 55 回帖 • 8 关注
  • NetBeans

    NetBeans 是一个始于 1997 年的 Xelfi 计划,本身是捷克布拉格查理大学的数学及物理学院的学生计划。此计划延伸而成立了一家公司进而发展这个商用版本的 NetBeans IDE,直到 1999 年 Sun 买下此公司。Sun 于次年(2000 年)六月将 NetBeans IDE 开源,直到现在 NetBeans 的社群依然持续增长。

    78 引用 • 102 回帖 • 643 关注
  • JSON

    JSON (JavaScript Object Notation)是一种轻量级的数据交换格式。易于人类阅读和编写。同时也易于机器解析和生成。

    51 引用 • 190 回帖
  • HTML

    HTML5 是 HTML 下一个的主要修订版本,现在仍处于发展阶段。广义论及 HTML5 时,实际指的是包括 HTML、CSS 和 JavaScript 在内的一套技术组合。

    103 引用 • 294 回帖
  • Solo

    Solo 是一款小而美的开源博客系统,专为程序员设计。Solo 有着非常活跃的社区,可将文章作为帖子推送到社区,来自社区的回帖将作为博客评论进行联动(具体细节请浏览 B3log 构思 - 分布式社区网络)。

    这是一种全新的网络社区体验,让热爱记录和分享的你不再感到孤单!

    1425 引用 • 10043 回帖 • 470 关注