Git-基础

最近重新学了一遍Git工具的使用,在此记录一下。

Git是什么?

Git是属于分布式版本控制系统,同属于的还有Mercurial、Bazaar等。
Subversion(svn)属于集中式的版本控制系统,同属于的还有CVS、Perforce等。

两种类型版本控制系统有什么区别?

集中式的版本控制系统,以单台中央服务器为中心,将所有的版本控制历史都集中放在这台服务器上,而各个协同开发者的计算机上只保存着一个快照版本,在这种情况下,开发者每次想要提交或者查看文件的历史等,都需要请求网络,向刚刚所说的中央服务器获取或者提交数据。
分布式版本控制系统与集中式版本控制系统不同,它在本地计算机上建立代码仓库,保存着所有的版本控制历史的数据,在合适的时机与远程服务器代码仓库同步。在这种情况下,开发者每次想要提交或者查看文件的历史等,无需请求网络,直接向本地获取或者提交数据即可,因为本地保存着所有的版本历史数据。
分布式版本控制系统的优点:
开发者所有的Git操作都在本地代码仓库进行,不用依赖于网络。
不用担心代码仓库服务器宕机或者数据丢失等情况,因为每个开发者计算机上都保存有完整的版本历史数据,可以随时将开发者主机上的数据恢复至服务器代码仓库。


限于篇幅,本文接下去的内容不讨论svn等集中式的版本控制系统与分布式版本系统的用法差异。
为了更加贴近于实际的开发,我们将从Git仓库的创建到版本的提交为顺序讲述,最后还简述一下分支的用法和概念。
注意:本文是在本地代码仓库上的操作,还未涉及到远程仓库的连接,读者先不要将远程仓库的思想混进来,容易造成混乱。
先介绍几个Git中的基本概念。

Git中的文件区域

18333fig0106-tn.png

在git中总共有三个区域。分别是工作区、暂存区、git仓库区。
我们所有的文件修改以及变更都是在工作区进行的,然后保存至暂存区(git add命令),最后保存到git仓库区(git commit命令)。可能有读者会问git为什么要设计一个暂存区,为什么不支持从工作区直接将文件保存至git仓库区。这是因为这个暂存区作为一个中间区域,它的作用就是存放即将要提交到git仓库的文件。
有这个区域的存在,开发者可以将想要提交到仓库的文件保存到暂存区,不想提交的文件可以继续存放在工作区,这样子下次执行提交操作的时候,Git只会将暂存区所有的文件提交到仓库中。
开发者提交文件更加灵活。开发者假如后悔不想要提交某个文件(此时这个文件已经在暂存区),那么开发者可以将此文件从暂存区中移出(git reset HEAD <file>命令),下次提交就不会提交这个文件。

Git中的文件状态

image.png

在git中,文件有四种状态。未跟踪、未修改、已修改、已暂存。
已跟踪的文件是指本来就被纳入版本控制管理的文件,在上次快照中有它们的记录,工作一段时间后,它们的状态可能是未修改,已修改或者已暂存。
未跟踪文件既没有在git仓库中存有快照,也还未将文件快照保存到当前的暂存区域。初次克隆某个仓库时,工作目录中的所有文件都属于已跟踪文件,且状态为未修改。

Git仓库的创建

Git仓库的创建非常简单,在本地设备有安装Git情况下,直接在项目根目录下运行shell命令git init即可。

$ git init

git status

git status这个命令是用来检查当前文件的状态的。为什么我这么早就介绍这个命令?因为这个命令能给我们提供很多有用的信息,帮助我们了解Git。这个命令应该算是有git最常用的命令了,它能够显示当前工作区文件的状态(已跟踪或未跟踪)、暂存区文件状态、文件冲突状态、当前所在的分支等。

$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        new file:   README

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

        modified:   benchmarks.rb

从输出中可以看到当前处于master分支,新创建的文件README已经被保存至暂存区域,benchmarks.rb在工作区域已被修改,但是还没被保存至暂存区域,下次提交时候只会提交README文件到代码仓库。
括号中的文本是git的辅助提示信息。比如这里git告诉你使用git reset HEAD <file> ...可以将文件从暂存区域移除。git add <file> ...用来添加或者更新文件到暂存区域等到下次提交。用git checkout --<file>命令来还原工作区文件的改变,其实就是将工作区某个或某些文件还原为未修改的状态。

git add

git add的作用是将工作区的文件保存至暂存区。
重要是事情说三遍!
git 保存的不是文件差异或者变化量,而只是一系列文件快照。
git 保存的不是文件差异或者变化量,而只是一系列文件快照。
git 保存的不是文件差异或者变化量,而只是一系列文件快照。

这个命令的后面可以带有文件或者文件夹路径作为参数,当参数为目录时候,git add的效果会递归至目录下所有的文件。

  • 如果文件在工作区域已被跟踪,那么直接将文件快照保存至暂存区。
  • 执行git add命令后,git会计算该文件的校验和,生成该文件快照,将校验和保存到暂存区,这里是保存文件快照。
    注意:如果执行所要执行git add的目标文件处于未跟踪状态,此命令会先将目标文件标识为已跟踪文件。

在仓库建立之后,因为此时本地代码仓库和暂存区都是空的,并没有任何文件的快照。所以此时所有的文件状态都是未跟踪状态。
此时执行git status命令:

$ vim README
$ git status
On branch master
Untracked files:
  (use "git add <file>..." to include in what will be committed)

        README

nothing added to commit but untracked files present (use "git add" to track)

我们工作目录下有一个名为README文件,此时显示它的状态就是未跟踪的。同时git也提示我们可以使用git add来跟踪以及保存到暂存区。

此时我们执行git add *命令(git 命令支持通配符,*表示将当前工作目录下所有的非忽略文件提交至暂存区,包括所有子文件夹的下的所有文件,当前这里你也可以直接使用git add README命令,指定只作用于README文件)。然后再次执行git status

$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        new file:   README

从输出中我们可以看到暂存区已经保存着README文件的快照,并且等待提交。

git commit

git commit这个命令是用来将文件提交到本地代码仓库的。
当你用Git commit命令执行一个新的提交时候,Git只保存一个指向这次提交快照的索引。

18333fig0105-tn.png

可以看到这里有三个文件,file A、file B、file C。这里以在提交一个新的版本后,git会遍历一边所有的文件的指纹信息,如果发现新版本的文件指纹信息与上一个版本不一致,说明该文件发生了变化,此时git会将新的文件快照索引保存至本地的微型数据库中,如果文件未发生变化,那么会将上个版本的保存的快照索引直接复用写入微型数据库中。

注:git所有的数据都保存在本地项目仓库的.git文件夹下,这个文件夹默认为隐藏文件夹。

实际上,我们执行一次提交操作就是保存一个提交对象。
当执行git commit命令后,git会先计算每一个子目录的校验和(注意,git add是计算文件的校验和),然后在git仓库中将这些目录保存为树对象,然后git会创建一个提交对象,这个提交对象出了包含相关的提交信息以外,还包含着指向这个树对象的指针,如此它就可以在将来需要的时候,重现此次快照的内容了。git commit会将暂存区的所有文件提交到本地数据库中。保存的内容如下。

image

多次提交之后:


image

分支

分支应该算是版本控制系统最强大的功能之一了。
前面我们说了,在执行git提交时,git会创建并且生成一个提交对象,该对象包含一个指向文件树的指针,包含本次提交的作者等相关附属信息,包含零个或者多个指向该提交对象的父对象指针:首次提交时没有直接祖先的,普通提交有一个祖先,由两个或者多个分支合并产生的提交则有多个祖先。
其实分支的概念很简单,分支本质上仅仅是个指向某个提交对象的可变指针。
在创建一个新的代码仓库时,git会默认创建一个名为master的分支。我们的每次提交操作,都是基于某个分支的基础上进行的。在若干次提交操作之后,分支会自动向前移动。
分支的创建很简单。

 git branch testing

这会在当前的提交对象上新建一个新的分支指针。如下:

image

那么,git是如何知道我们当前是在哪个分支上工作的呢?其实git保存着一个名为HEAD的特别指针。每当我们切换执行切换分支操作的时候,git其实只是将HEAD指针移动到目标分支上,这样子我们接下去的提交等操作都是针对于这个分支进行的。
在上面命令中,我们执行了git branch命令,这个命令仅仅是创建一个分支,而不会切换到新建的这个分支中。要切换分支,可以执行一下命令。

git checkout testing

这样子,HEAD就指向了testing分支。这样子就完成了分支的切换。


image

此时我们如果进行修改一个文件,然后提交。结果如下。

vim test.rb
git commit -a -m 'made a change'

注意,git commit 后面-a表示直接跳过保存至暂存区,直接提交到数据库。


image

好了。我们把分支切回master。然后再次修改一个文件,最后提交。

vim test.rb
git commit -a -m 'made other changes'

结果如下:

image

可以看到,我们的项目提交历史产生了分叉。这是因为我们的master和testing分支的父提交对象都是f30ab,我们后面可以在合适的时机将两个分支合并。

关于分支的合并见下章,未完待续。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 200,783评论 5 472
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,396评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 147,834评论 0 333
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,036评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,035评论 5 362
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,242评论 1 278
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,727评论 3 393
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,376评论 0 255
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,508评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,415评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,463评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,140评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,734评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,809评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,028评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,521评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,119评论 2 341

推荐阅读更多精彩内容

  • Git 基础 基本原理 客户端并不是只提取最新版本的文件快照,而是把代码仓库完整的镜像下来。这样一来,任何一处协同...
    __silhouette阅读 15,851评论 5 147
  • Git 命令行学习笔记 Git 基础 基本原理 客户端并不是只提取最新版本的文件快照,而是把代码仓库完整的镜像下来...
    sunnyghx阅读 3,900评论 0 11
  • Git常用语法 [TOC] Git简介 描述 ​ Git(读音为/gɪt/。)是一个开源的分布式版本控制系统,...
    君惜丶阅读 3,487评论 0 13
  • 仲秋的请柬一签 白露便马不停蹄地赶来 邀清风明月为伴 与金黄共同弹奏“丰收”的喜悦 (2020.9.7.) 白云悠...
    一剪红梅阅读 587评论 4 23
  • CocoaPods基于Ruby语言开发而成,因此安装CocoaPods前需要安装Ruby环境。幸运的是Mac系统默...
    男神已认证阅读 1,172评论 0 2