开发工具——Git,开发者的贴心小棉袄

Git 是 linux内核创始人 Linus Torvalds 为了维护 linux 源码便利而开发的一款工具。发展到今天,已经成为全球通用的分布式版本控制系统。在 Git 中,每一份复制出来的库都可以独立使用和维护,并且,任意两个不同的库都可以合并。
GitHub 是一个开源库和私有软件项目的托管平台,因为只支持 Git 作为唯一的版本库格式进行托管,所以叫 GitHub。现在,开源代码几乎都是放在 GitHub 上。另外,还有从 GitHub fork 出去独立开发出的收费版叫 Gitlab,支持企业内项目的托管平台,相信用过的人一定明白有多便利。

简介

Git作者

git当前最新版本为:2.12.2,官网地址

  • Git图形化软件:git是开源的命令行工具,随着git的普及,市面上也出现了很多。最著名的有:TortoiseGit、Source Tree、GitUp、SmartGit等。参考
    TortoiseGit 是 TortoiseSVN 的 Git 版本,Windows平台下的Git图形化软件;
    SourceTree是Windows和Mac系统下的git客户端,支持绝大多数git常用操作,界面美观,很方便管理多个项目;
    GitUp 是最新出来的 Mac OS X 下的全功能开源 Git 客户端,提供快速、安全的操作,可以直接在硬盘上与 Git 仓库交互,不过,操作库的是图而不是操作命令;
    SmartGit是一款古老的git图形化软件,支持的系统包括Windows、Mac OS以及Linux系统;
    当然还有很多其他的Git图形化软件,基本没玩过就不介绍了。

  • 代码托管平台:随着使用git的开发者越来越多,代码托管平台基本成了大大小小项目的标配。参考
    Github,很多著名的开源软件像Apache Tomcat/Maven/ant/hadoop/、Eclipse,浏览器内核webkit/v8等、当然了还有git。
    Gitlab,跟GitHub类似,相比于GitHub,Gitlab可以免费创建私有项目,拥有更高的安全性和灵活性,所以它更适合企业开发团队托管项目。可以说,Gitlab是企业版的GitHub。
    Bitbucket,支持免费创建私有项目,但同一个私有项目最多支持5个开发者。
    OSChinaCODINGCSDN是国内的项目托管平台,这几年发展也不错。

Git 设计思想和原理

Git 版本控制系统中,其通过文件对象记录所有文件,并通过缓存所有历史和元数据,实现对代码版本的控制。

Git 中的对象类型

使用 git 命令操作过程中,你会经常遇到长度为40字符的串,像这样:


40字符长度串.png

你第一反应是,这些不就是 commit id 嘛~是的,没错,但不准确。其实它真正表示的是一个项目历史信息的文件对象,这个值是通过对文件内容进行 SHA1 哈希计算得到的,就像一个 md5 值唯一标识一个文件内容一样,任意两个不同的文件
SHA1 值一定不同。

每个文件对象包括三个部分:类型,大小,内容。有四种类型对象:blob、tree、commit、tag,每一种类型的对象你都可以通过 git show xxxx 命令查看详细信息。

  • “blob”:存储文件数据的类型,通常记录一个文件的内容;
  • “tree”:存储一些“tree”或 “blob”类型文件的类型(类似目录,便管理子目录和文件),git ls-tree xxxxxx 可以查看详细的 tree 对象;
  • “commit”:存储"tree"类型文件数据的类型,同时包含一些描述信息,还标记了项目某一个特定时间点的状态。它包括一些关于时间点的元数据,如时间戳、最近一次提交的作者、指向上次提交的指针等,也就是大家常说的 commit id;
  • “tag”:指向“commit” 对象类型的类型,实际就是标记了一个特殊的 commit 对象。与其他几种类型还有一个区别,一个 tag 对象还可能包含了签名创建者签名相关的信息,你可以通过 git cat-file tag xxx 来查看。

每次提交都会给每个文件创建 blob 类型的对象,给每个目录创建 tree 类型的对象,最后创建一个 commit 对象用于指向根 tree 对象,因此,每个一个 “commit id” 就表示了一次提交的所有内容。

因此,上面举例的字符串实际上是指向 commit 类型的文件对象。从这些类型的定义或叫说明上也能看出,blob 类型是最基础的文件对象类型,而 tag 是记录某一个次重要节点的文件对象类型。

Git 如何存储对象

Git 中存在两种对象,一种是松散对象,一种是打包对象。

  • 松散对象:每一个对象对应磁盘上的一个文件,每个文件存储着压缩的数据。
    例如,一个 git 对象的 SHA1 值e0a0df73be6cb4e841de84c0450058ab927b60,那么,在 .git 目录的 object 子目录下,就会存在这样的一个文件。
  • 打包对象:Git 会把每个文件对象的每个版本都作为一个单独的对象,如果所有的 git 对象都使用松散对象的形式存储,就会导致效率低下,所以,为了节约空间 Git 通过两个对象指针来表示一个修改的文件对象,一个指针指向第二个文件中改变的部分,一个指针指向相似的那个文件。
SHA1

SHA1(Secure hash algorithm),即安全的hash算法,用于计算文本的校验和,常作为摘要算法对签名进行校验。它的特点是计算出的SHA1值是不可逆性切不重复的,也就是根据SHA1值无法反解出原始内容,并且对于相同的内容,每次计算得到的SHA1都相同。正因为这样的特性,它常用于验证数据的完整性以及消息的验证。SHA1算法可以得到160位二进制数,也就是40位16进制数。我们做一个简单的实验。mac下通过这个命令可以安装一个sha1算法的工具:

brew install md5sha1sum

操作如下:

# A.txt:A:version 1
sha1sum A.txt
# result:
# 2d8954f9fbf90f6da74b728bf3dfe4ad459865fe  A.txt
  • 摘要加密算法
  • 特性:不可逆,不重复
  • 用途:验证数据完整性与消息验证
  • 160位二进制数(或40位16进制数)

Git 基本用法

git init

以当前目录为根目录,初始化一个新的仓库,实际这条命令主要创建一个名为 .git 的隐藏目录。

git根目录.png
git clone https://github.com/iThinkerYZ/GPUImgeDemo.git

从已有仓库中复制/拷贝一份到本地,因此我们需要知道一个项目的仓库地址,Git 支持多种协议,因此,这些 url 可以是ssh://、http(s)://,、git:// 等。一般情况,clone 下来的仓库根目录名就是 url 最后的文件名。例如上面就会得到名为
GPUImgeDemo 的目录。

git status

查看当前 Git 目录(.git)的状态,可以列举出所有已经修改文件的状态。

git branch

查看本地所有分支,*号表示所在分支,-r 参数可以指定查看远程的所有分支。

git checkout some-branch/some-tag/some-commit

切换分支,其实就是切换到某个 commit 对象(根节点)

git add some-file

创建指定修改文件内容的文件对象(SHA1),同时添加文件对象到暂存区。可以 add 一个文件,也可以通过","分隔添加多个文件,还可以通过"."来匹配本地的所有修改文件。

git commit -m 'xxxxx'

提交暂存区的修改到本地仓库,同时添加注释内容。可以使用 git commit -am 'xxxxx' 进行add和commit

git pull

拉取远程到本地,其实完整的命令是 git pull origin current-branch。不过需要注意,如果本地文件有修改,拉取的内容可能跟本地的内容有冲突需要处理一下。

git push

推送本地提交到远程仓库。完整的命令是 git push origin current-branch。注意,如果远程有更新而本地没有拉取,会阻止本地的 push 动作并提示。

git reset

重置 HEAD 部分的修改到指定状态,通常该命令结合3种参数使用,--soft/--mixed/--hard。--hard 将会删除本地所有修改但没有提交的记录。

git revert

回滚本地的代码到指定某个提交的状态,同时将回滚内容作为一个新的修改进行提交。效果跟
reset相同,但是跟 reset 不同点在于,reset 是直接删除某个提交记录,但是 revert 不会。

git merge some-branch

将某个分支内容与当前分支合并。

git rebase

将从开始 merge 的那个状态以来的所有提交,以补丁的形式一个一个重新达到目标分支上,看起来就像一条线一样的工作流。

git stash

暂存当前分支的所有修改到临时区域,保持 HEAD 为最后一次 commit 状态。

git show

显示某个git 对象的详细信息

git diff

对比工作区与暂存区内容的不同,方便对比做了哪些修改。一般,在 commit 内容前最好检查一下,确保没有问题。

git tag

展示本地所有的 tag,另外,也可以通过 git tag new-tag 来新建一个 tag,通过 git tag -d some-tag 来删除本地的 tag。通过命令 git push --tag(s) 来推送本地更新的 tag 到远程仓库。一般,我们会在发版前更新 tag 作为稳定版本。

Git 中级用法

.gitignore

开发中,经常需要忽略一些文件的修改,既不追踪,也不会被加入到暂存区中,即保证 git commit、git add、git status 命令都不会处理这些文件的变化,保证高效完成版本文件管理。.gitignore文件就是用于解决这个问题。该文件需要手动创建和添加(有的git系统会自动创建并且是初始化好的),并加入现文件来告诉 Git 系统会略哪些文件。

GitHub 官方提供了各种语言对应项目的通用.gitignore模板,大家可以直接复用。
点这里

该文件的存放位置决定该目录及其子目录使用的忽略文件,因此,可以针对不同目录定制对应的.gitignore文件,当然了,一般做法是只在根目录(与 .git 目录同级)保存一份。

rebase

由于 git 是分布式的版本控制系统,因此少不了要处理不同并行分支合并的场景。在初级用法中简单介绍了该命令。
与 merge 的主要区别:merge 最终将合并的结果作为一次新的commit提交,当前分支修改以及已经提交的部分作为历史保留,rebase 首先将当前分支的提交以补丁的形式缓存,然后更新本地分支到最新,最后将缓存的补丁依次合到当前分支,最终分支历史看起来就像没有经过合并一样。
当遇到冲突的时候,rebase 命令会被暂停,等待冲突解决,解决玩冲突后,你只需要 git add 而无需 git commit,直接执行 git rebase --continue 继续处理;另外,任何时候,开发者都可以执行 git rebase --abort 命令终止 rebase 的动作,然后恢复至 rebase 开始前的状态。

rebase 除了让 Git 系统自动完成合并外,还可以交互式的进行。git rebase -i origin/master,输入命令后如下图:


交互式rebase.png

图中表示当前分支的暂存区只有一次提交,并且格式满足:

(action) (partial-sha) (short commit message)

pick对应的是 git 将采用并合并这次提交,如果用 squash 表示与上一个提交合并为一次提交,如果 为 edit,则当 git 处理到此次提交之后,返回命令行让你对提交进行修改,比如将提交拆分为多个等。最后,如果不采用任何一个 action 而是直接把某次提交删除,那么 git 就会直接从历史中移除该提交。

stash

git stash
git stash apply
git stash pop
git stash list
git stash pop stash${id}
git stash clear

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

推荐阅读更多精彩内容