版本控制系统(Version Control System,VCS)可以帮助我们记录和跟踪项目中各文件内容的修改变化。

1.1 版本库

版本库(Repository)是版本控制系统用来存储所有历史数据的地方。

集中式版本库(Centralized Repository)——所有的程序员都会把他们的改动提交到服务器上的一个公共版本库中。具体来说,每一个程序员在本地有一个工作目录树,其内容是该版本库中最新的代码。

集中式版本库的局限性:

  • 首先,在本地工作目录树中,只能看到代码的最新版本。如果想查询历史修改记录,就必须与服务器上的版本库打交道。
  • 其次,同远程的版本库连接,通常须要使用网络。

使用分布式版本控制系统(Distributed version control system,DVCS),每个人都会在本地有自己的版本库,而不是连接到服务器上的一个公共的版本库。所有的历史记录都存储在本地的版本库中。向版本库提交代码无须连接远程版本库,而是记录在本地的版本库中。

1.2 版本库中存储什么

项目开发所必需的所有内容:

  • 项目源代码
  • 构建文件(Makefile、Rakefile及Ant的build.xml等)
  • 配置文件样例
  • 各类文档
  • 程序使用的图片
  • 单元测试脚本等

例外:

项目中使用的开发工具,通常不用放到版本控制中去。

1.3 工作目录树

工作目录树(Working Tree),也就是程序员进行程序开发的地方。

工作目录树是版本库的一个"断面视图"。它包括了开发该项目所需要的全部文件,包括源代码文件、构建文件、单元测试文件等。一些版本控制系统把工作目录树称为工作拷贝(Working Copy)。

在Git中,版本库不在服务器上,而存储在本地工作目录树的".git"目录中。这意味着,要想知道历史信息,只和本地的版本库打交道即可,无须与服务器上的版本库通信。

工作目录树的创建

  • 第一个方法是用Git相关命令初始化版本库,也就是生成".git"目录,于是".git"目录的父目录就成了工作目录树。
  • 第二个方法是克隆(Clone)一个已有的版本库,也就连带创建了相应的工作目录树。克隆一个已有的版本库,就是创建该版本库的一个拷贝,并把版本库中主分支(Master Branch)的内容检出(Check out)到工作目录树。

在Git中,检出是指把工作目录树更新,使其内容与版本库中某个特定的历史版本相同。

1.4 代码修改与文件同步

在修改了文件内容之后,须要进行单元测试以保证这次修改不会有任何负面影响,然后提交(Commit)这些改动。

每次提交操作都使得版本库中新增一个版本(Revision)。除了记录改动内容本身外,版本库还记录改动的日志信息(Log Message)或称提交留言(Commit Message),以便将来能够很方便地查询为什么要做这个改动,并能够很方便地查找某个缺陷是何时引入的。

使用像Git这样的分布式版本控制系统时,除了把改动提交到本地版本库之外,还要通过某种方式将改动共享,以便其他程序员能够得到。因此,须要把改动推入(Push)上游版本库(upstream repository)

上游版本库是一个公共版本库。一般来说,程序员们都把自己的改动推入到这里。

这里所说的推入,是指把自己锁在版本库中的内容,推入带另一个版本库中。把改动推入公共版本库后,其他程序员就能"看到"了。

把远程版本库中的改动拿到本地版本库中,需要两步操作。

  • 第一步,把改动取来(Fetch),把远程版本库中的版本和分支复制到本地版本库中。这有点像是推入操作的反操作:推入操作时把本地版本库中的改动发送给另一个版本库,而取来操作是把远程版本库中的改动取到本地版本库中。
  • 第二步,在本地版本库中,把从远程版本库里取来的改动与自己本地的改动合并(Merge)。Git工具包提供了这样的合并工具。

一般来说,取来操作额合并操作总是先后执行的。因此,在Git中可以用一个命令完成这两步操作:拖入(Pull)

1.5 跟踪项目、目录和文件

Git记录和跟踪版本库中组成文件的各部分内容。Git并不把整个文件作为不可分的整体来记录和跟踪,而是记录和跟踪组成该文件的各部分内容,也就是若干字符和代码行(它们构成了变量和函数)。Git为这些内容添加一系列元数据,比如所在文件的文件名、文件属性,以及该文件是否为符号链接等。

这样做具有许多优势

  • 首先,它能显著降低版本库存储全部历史版本所需的磁盘空间。
  • 其次,它使得"判断某个函数或类在文件间移动和拷贝的情况"之类的操作变得快捷容易。

而对这些文件的修改操作,则与寻常无异。所有的修改都在工作目录树中完成。工作目录树由目录和文件组成,它们是版本库中的一个"断面视图"。

版本库中的文件和目录结构的组织方式是对应于实际项目的。大部分项目遵循特定的目录组织结构。Git本身并不规定如何在版本库中组织这些模块。Git支持任意的组织方式。

1.6 使用标签跟踪里程碑

使用标签能够记录下版本库在特定历史时刻的"断面视图",以便于日后查找和恢复。

标签以一个简单的名称(即标签名)来标记版本库历史中某个特定的点。

本质上,标签是一个对于使用者来说易于理解易于记忆的名字,用来标识版本库中一个难读难记的内部版本号,以此帮助使用者跟踪版本历史。

1.7 使用分支来跟踪并行演进

上图展示了分支原理。主分支(Master Branch)是研发的主线。

一些版本控制工具也把主分支称作主干(trunk)

分支可以长期存在,也可以仅存在数小时。分支可以合并到别的分支,但并非所有的分支都必须合并。

有些情况下,分支不应该合并,譬如用分支来记录项目的不同发布版本的开发时;用分支来记录试验性的工作时也是这样,也许试验结束后分支就删除了。

分支也可以在本地创建,并留作私用。创建本地分支并留作私用是有意义的。在完成试验性的工作后,如果有价值,再让大家拿到也不迟,而如果没价值,那就把它消无声息地删除。

1.8 合并

合并操作把两条或两条以上的分支合并到一起。

Git会自动处理分支合并,当Git不能自动合并时,就会提示冲突(conflict)。Git有好几种解决冲突的方法。

Git也提供自动记录和跟踪合并的功能,称为合并跟踪(merge tracking)

1.9 锁机制

当程序员从版本库检出某个文件时,版本库禁止任何其他人修改这个文件,直到该程序员捡入(check in)为止。这种锁机制称为严格锁(strict locking)

另一种锁机制,乐观锁(optimistic locking),允许多个程序员同时修改同一文件。乐观锁机制基于一个假定:大多数时候,这种并发修改不会引起冲突。

第1章 Git的版本控制之道的更多相关文章

  1. 复习宝典之Git分布式版本控制

    查看更多宝典,请点击<金三银四,你的专属面试宝典> 第三章:Git分布式版本控制 1)git文件状态 git中的文件有以下几种状态: 未跟踪(untrack):表示文件为新增加的. 已修改 ...

  2. Java开发工程师(Web方向) - 01.Java Web开发入门 - 第5章.Git

    第5章--Git 版本控制简介 VCS (version control system) 版本控制系统:记录若干文件的修订记录的系统,帮助查阅/回到某个历史版本 LVCS本地 CVCS集中式(Cent ...

  3. Git分布式版本控制教程

    Git分布式版本控制Git 安装配置Linux&Unix平台 Debian/Ubuntu $ apt-get install git Fedora $ ) $ dnf and later) G ...

  4. Visual Studio Code 使用Git进行版本控制

    Visual Studio Code 使用Git进行版本控制 本来认为此类教程,肯定是满网飞了.今天首次使用VS Code的Git功能,翻遍了 所有中文教程,竟没有一个靠谱的.遂动笔写一篇. 请确保你 ...

  5. git分布式版本控制玩法

    git分布式版本控制玩法 Git distributed version control play github的配置安装步骤:1.下载git bash(从http://www.git-scm.com ...

  6. 第三章 Git的入门 - 读书笔记

    Android驱动月考3 第三章 Git的入门 - 读书笔记 对于Github,这是全世界最大的开源平台,你可以把你做的项目在这里开源,把你发现的一些新技术在这里开源,向全世界的开发者们分享,大家都彼 ...

  7. 第一章 git指令与设置

    相关指令: 1.从远程的master分支上创建新的分支,此时新分支内容与master分支内容相同: git checkout master; git branch newbranch; git che ...

  8. VSC 使用Git进行版本控制

    Visual Studio Code 使用Git进行版本控制 请确保你安装了最新的VS Code.http://code.visualstudio.com/ 请确保安装了最新版的Git.https:/ ...

  9. Git本地版本控制备忘

    首先git是一个版本控制工具,类似于SVN 笔记包括两部分,git本地版本控制和git远程协助 一.Git本地版本控制 以git windows版本msysgit为例,下载地址http://msysg ...

随机推荐

  1. 利用OPENSSL 实现MD5加密。

    #include <stdio.h> #include "openssl/evp.h" #include "openssl/md5.h" #incl ...

  2. Halcon C++混合编程学习之Qt 实现检测焊接点

    1 # include "HalconCpp.h" # include "HDevThread.h" # include <X11/Xlib.h> ...

  3. linux-redhat5找回root密码

    我在虚拟机里装了个redhat(RedhatEnterpriseLinuxASv5.4-x64),也不经常用,偶尔进去用用吧,又把密码忘记了,哎...脑子不好使啊 不知道像ubuntu是不是一样的,还 ...

  4. 关于VMware桥接的注意事项

    VMware 使用桥接  想固定住虚拟机的IP的同时还可以访问外网. 通过Linux的可视化操作界面固定设置IP,网关,子网掩码等配置信息,如下图: 附录本地Windows中的IP地址信息: 虚拟机和 ...

  5. 利用SCI做的一个足球答题系统

    SCI,异步串行通信接口,内置独立的波特率产生电路和SCI收发器,可以选择发送8或9个数据位(其中一位可以指定为奇或偶校验位). SCI是全双工异步串行通信接口,主要用于MCU与其他计算机或设备之间的 ...

  6. hdu 2709 Sumsets

    Sumsets Time Limit: 6000/2000 MS (Java/Others)     Memory Limit: 32768/32768 K (Java/Others) Total S ...

  7. Android 侧滑菜单的简单实现(SlidingMenu)

    在我还没有学习Android的时候就用过侧滑菜单的APP,当时第一个感觉是:哇塞,这效果不错!当然,现在自己都已经学Android了,这效果当然也要做出来啊~ SlidingMenu是一种比较新的设置 ...

  8. 【网络收集】MySql中IS NOT NULL与!=NULL的区别

    在mysql中,筛选非空的时候经常会用到is not null和!=null,这两种方法单从字面上来看感觉是差不多的,其实如果去运行一下试试的话差别会很大!为什么会出现这种情况呢?null 表示什么也 ...

  9. PullToRefreshListView手动刷新问题

    1.第一次进入界面刷新无效,需要延时刷新 new Handler().postDelayed(new Runnable() { @Override public void run() { // TOD ...

  10. 日常bug及解决方法记录

    工作中经常会遇到一些Bug,时间长了有时候就忘记了,这样不好. 特地在这加一个随笔,把以后出现的有价值一点的bug记录在这里,提醒自己,也可以给刚入门的同学一些参考,避免这些坑. 1:界面已经销毁,代 ...