大家好!我是农民工小哥。对于Git,相信大多数程序员都不陌生。作为世界上最先进的分布式版本控制系统(没有之一),Git是一款开源的分布式版本控制软件,用于高效、高速地处理从小到大的项目版本管理。Git最初是由LinusTorvalds设计和开发的,用于管理Linux内核开发。久而久之,Git发展到今天,已经成为很多开发者必备的开发工具。如果你平时学习Git的时候觉得无聊,不妨试试这个好玩的小游戏,换一种方式在娱乐中学习。以下是演示示例:需要这款游戏的读者可以点击下方的名片公众号回复关键词Git小游戏获取Git介绍Git是一个开源的分布式版本控制系统。什么是版本控制?版本控制是一种记录一个或多个文件内容变化的系统,以备将来参考特定的版本修订。什么是分布式版本控制系统?在介绍分布式版本控制系统之前,有必要了解一下传统的集中式版本控制系统。集中式版本控制系统,如CVS、Subversion等,有一个单一的集中管理服务器保存所有文件的修订,一起工作的人通过客户端连接到这个服务器,取出最新的文件或提交更新。这样做最明显的缺点是中央服务器的单点故障。如果有一个小时的停机时间,在这个小时内没有人可以提交更新,他们也不能一起工作。如果中央服务器的磁盘出现故障,你恰好没有备份,或者备份不够及时,你就有丢失数据的风险。最坏的情况是完全丢失整个项目的所有历史变更记录。分布式版本控制系统的客户端不仅提取了最新版本的文件快照,还完整地镜像了代码仓库。这样,如果任何一个用于协同工作的服务器发生故障,之后可以用任意一个本地镜像仓库进行恢复。因为每一次抽取操作其实都是对代码仓库的一次完整备份。可以参考:Git从入门到精通GitvsSVNGit和SVN哪个更好,每个人都有不同的体会。Git是分布式的,SVN是集中式的。这是Git和SVN最大的区别。如果能掌握这个概念,就基本能明白两者的区别了。因为Git是分布式的,Git支持离线工作,很多操作都可以在本地进行,包括接下来要推出的分支功能。而且SVN必须联网才能正常工作。Git有很多复杂的概念,而SVN简单易用。所有同时掌握Git和SVN的开发者都必须承认Git中的命令太多了。日常工作需要掌握add、commit、status、fetch、push、rebase等,要想精通掌握,还必须掌握rebase和merge的区别,fetch和pull的区别等。另外,还有cherry-pick,submodule,stash等函数,但是这些名词听上去很费解。在易用性上,SVN会更适合新手。但另一方面,更多的Git命令意味着更多的功能。如果我们能够掌握Git的大部分功能,了解其中的奥妙,就会发现我们再也回不去SVN的时代了。Git分支很便宜,SVN分支很贵在版本管理中,分支是一个非常常用的功能。在版本发布之前,大需求开发需要发布一个分支,这就需要一个特性分支,而一个大的团队也会有开发分支,稳定分支等。在大团队的开发过程中,经常会有创建分支和切换分支的需求。Git分支是指向提交的指针,而SVN分支是复制的目录。这个特性使得Git的分支切换非常快并且创建成本非常低。而Git有本地分支,SVN没有本地分支。在实际的开发过程中,经常会遇到一些代码没有写完,而另一些问题又需要紧急处理的情况。如果我们使用Git,我们可以创建一个本地分支来存放未完成的代码。问题解决后,我们可以回到本地分支继续完成代码。更多关于Git和Svn对比的关注请参考:通俗易懂|用好Git和SVN轻松掌控版本管理。Git的工作原理,文字很难理解。使用的系统为Debian/Ubuntu,安装命令为:$apt-getinstalllibcurl4-gnutls-devlibexpat1-devgettext\>libz-devlibssl-dev$apt-getinstallgit-core$git--versiongitversion1.8.1.2Centos/RedHat环境安装如果你使用的系统是Centos/RedHat,安装命令为:$yuminstallcurl-develexpat-develgettext-devel\>openssl-develzlib-devel$yum-yinstallgit-core$git--versiongitversion1.7.1Windows环境安装从Git官方下载地址下载exe安装包。按照安装向导进行安装。推荐安装git的命令行工具GitBash。Mac环境安装从Git官方下载地址下载mac安装包。按照安装向导进行安装。Git配置Git附带一个gitconfig工具来帮助设置控制Git外观和行为的配置变量。这些变量存储在三个不同的地方:/etc/gitconfig文件:包含系统上每个用户及其存储库的通用配置。将gitconfig与--system选项一起使用时,它会从此文件读取和写入配置变量。\~/.gitconfig或\~/.config/git/config文件:仅对当前用户有效。您可以传递--global选项让Git读写这个文件。当前使用的仓库的Git目录下的config文件(即.git/config):针对本仓库。每一层都会覆盖上一层的配置,所以.git/config中的配置变量会覆盖/etc/gitconfig中的配置变量。在Windows上,Git在$HOME目录(通常是C:\Users\$USER)中查找.gitconfig文件。Git也会查找/etc/gitconfig文件,但只在MSys的根目录下,这是安装Git时选择的目标位置。Git基本概念仓库当你在本地创建一个项目或者创建一个git项目时,项目目录下会有一个隐藏的.git子目录。这个目录是git用来跟踪和管理仓库的,所以不要手动修改。哈希值Git中的所有数据在存储之前都经过校验和,然后通过校验和引用。这意味着在Git不知情的情况下不可能更改任何文件内容或目录内容。这个功能是在Git的引擎盖下构建的,是Git哲学的一个组成部分。如果您在传输过程中丢失信息或损坏文件,Git会发现。Git用来计算校验和的机制称为SHA-1散列(hash)。这是一个由40个十六进制字符(0-9和a-f)组成的字符串,根据Git中文件或目录结构的内容计算得出。SHA-1散列看起来像这样:24b9da6552252987aa493b52f8696cd6d3b00373这个散列在Git中用得很多,你会经常看到它。事实上,Git数据库中存储的信息是通过文件内容的哈希值来索引的,而不是文件名。文件状态在Git中,您的文件可以处于以下三种状态之一:已修改-已修改意味着文件已被修改但尚未保存到数据库中。Staged-Staged意味着修改文件的当前版本被标记为包含在下一个提交的快照中。Committed-Committed表示数据已经安全地存储在本地数据库中。工作区对应文件的状态,不同状态的文件在Git中处于不同的工作区。工作区(working)——当你在本地gitclone一个项目时,相当于在本地克隆了一个项目的副本。工作区是项目版本的独立提取。这些文件是从Git存储库的压缩数据库中提取出来的,并放在磁盘上供您使用或修改。暂存区(staging)——暂存区是存放下次要提交的文件列表信息的文件,一般在Git仓库目录下。它有时也被称为“索引”,但通常被称为暂存区。本地仓库(local)——提交更新,在暂存区查找文件,永久存储快照到Git本地仓库。远程仓库(remote)——上面的工作空间都是本地的。为了让其他人看到您的更改,您需要将更新推送到远程存储库。同样,如果要同步其他人的修改,需要从远程仓库中拉取更新。分支(Branch)分支是将修改记录的整个过程分开存放,使得单独的分支不受其他分支的影响,所以可以在同一个数据库中同时进行多个不同的修改。前面提到的master主分支(Master)是Git自动为我们创建的第一个分支,也叫主分支。其他分支开发完成后,必须合并到主标签(Tag)中,标签用于标记特定的点或提交历史,通常用于标记发布版本的名称或版本号(如:publish/0.0.1),虽然标签看起来有点像分支,但是标签的commit是固定的,不能随意改变,见上图中的1.0/2.0/3.0HEADHEAD,它指向的是当前分支的最新提交图片。上面的概念理解的差不多了,可以继续往下看。创建仓库的Git命令克隆创建的仓库:#通过SSH$gitclonessh://user@domain.com/repo.git#通过HTTP$gitclonehttp://domain.com/user/repo.git创建新建本地仓库:$gitinit添加修改将修改添加到暂存区:#添加指定文件到暂存区$gitaddxxx#添加当前所有修改到暂存区$gitadd.#添加所有修改到暂存区$gitadd-A提交修改到本地仓库:#提交所有本地修改$gitcommit-a#提交之前标记的修改$gitcommit#附加消息提交$gitcommit-m'commitmessage'storage有时,我们需要在同一个项目的不同分支上工作。当需要切换分支机构时,本地工作尚未完成。这时候提交修改是不严谨的,但是不提交代码是不可能切换分支的。此时,您可以使用gitstash将本地更改存储为草稿。官方称之为存储,但我个人更喜欢称之为草稿。#1.将修改保存为当前分支的草稿$gitstash#2.查看草稿列表$gitstashliststash@{0}:WIPonmaster:6fae349:memo:Writingdocs.#3.1删除草稿$gitstashdropstash@{0}#3.2读取草稿$gitstashapplystash@{0}撤消修改撤消本地修改:#删除缓存区中的所有文件(即撤消最后一次gitadd)$gitresetHEAD#将HEAD重置为上面提交一次版本,将后面的修改标记为未加入缓存的修改$gitreset
