共计 7743 个字符,预计需要花费 20 分钟才能阅读完成。
Git 简介
Git 是一个开源的分布式版本控制系统。
什么是版本控制?
版本控制是一种记录一个或若干文件内容变动,以便未来查阅特定版本订正状况的零碎。
什么是分布式版本控制系统?
介绍分布式版本控制系统前,有必要先理解一下传统的集中式版本控制系统。
集中化的版本控制系统,诸如 CVS,Subversion 等,都有一个繁多的集中管理的服务器,保留所有文件的订正版本,而协同工作的人们都通过客户端连到这台服务器,取出最新的文件或者提交更新。
这么做最不言而喻的毛病是地方服务器的单点故障。如果宕机一小时,那么在这一小时内,谁都无奈提交更新,也就无奈协同工作。要是地方服务器的磁盘产生故障,碰巧没做备份,或者备份不够及时,就会有失落数据的危险。最坏的状况是彻底失落整个我的项目的所有历史更改记录。
分布式版本控制系统的客户端并不只提取最新版本的文件快照,而是把代码仓库残缺地镜像下来。这么一来,任何一处协同工作用的服务器产生故障,预先都能够用任何一个镜像进去的本地仓库复原。因为每一次的提取操作,实际上都是一次对代码仓库的残缺备份。
可参考:Git 从入门到精通
Git vs SVN
Git 和 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 分支低廉
在版本治理里,分支是很常应用的性能。在公布版本前,须要公布分支,进行大需要开发,须要 feature 分支,大团队还会有开发分支,稳固分支等。在大团队开发过程中,经常存在创立分支,切换分支的求。
Git 分支是指针指向某次提交,而 SVN 分支是拷贝的目录。这个个性使 Git 的分支切换十分迅速,并且创立老本非常低。
而且 Git 有本地分支,SVN 无本地分支。在理论开发过程中,常常会遇到有些代码没写完,然而需紧急解决其余问题,若咱们应用 Git,便能够创立本地分支存储没写完的代码,待问题解决完后,再回到本地分支持续实现代码。
更多关注 Git 与 Svn 的比拟请参阅:通俗易懂|用好 Git 和 SVN , 轻松驾驭版本治理
Git 工作原理
文字不好了解,请看 图文详解 Git 工作原理
Git 装置
- Debian/Ubuntu 环境装置
如果你应用的零碎是 Debian/Ubuntu,装置命令为:
$ apt-get install libcurl4-gnutls-dev libexpat1-dev gettext \
> libz-dev libssl-dev
$ apt-get install git-core
$ git --version
git version 1.8.1.2
- Centos/RedHat 环境装置
如果你应用的零碎是 Centos/RedHat,装置命令为:
$ yum install curl-devel expat-devel gettext-devel \
> openssl-devel zlib-devel
$ yum -y install git-core
$ git --version
git version 1.7.1
- Windows 环境装置
在 Git 官网下载地址下载 exe 安装包。依照装置向导装置即可。
倡议装置 Git Bash 这个 git 的命令行工具。
- Mac 环境装置
在 Git 官网下载地址下载 mac 安装包。依照装置向导装置即可。
Git 配置
Git 自带一个 git config 的工具来帮忙设置管制 Git 外观和行为的配置变量。这些变量存储在三个不同的地位:
/etc/gitconfig 文件: 蕴含零碎上每一个用户及他们仓库的通用配置。如果应用带有 --system 选项的 git config 时,它会从此文件读写配置变量。\~/.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 中,你的文件可能会处于三种状态之一:
- 已批改(modified) – 已批改示意批改了文件,但还没保留到数据库中。
- 已暂存(staged) – 已暂存示意对一个已批改文件的以后版本做了标记,使之蕴含在下次提交的快照中。
- 已提交(committed) – 已提交示意数据曾经平安的保留在本地数据库中。
- 工作区域
与文件状态对应的,不同状态的文件在 Git 中处于不同的工作区域。
- 工作区(working)– 当你 git clone 一个我的项目到本地,相当于在本地克隆了我的项目的一个正本。工作区是对我的项目的某个版本独立提取进去的内容。这些从 Git 仓库的压缩数据库中提取进去的文件,放在磁盘上供你应用或批改。
- 暂存区(staging)– 暂存区是一个文件,保留了下次将提交的文件列表信息,个别在 Git 仓库目录中。有时候也被称作 `‘索引’’,不过个别说法还是叫暂存区。
- 本地仓库(local) – 提交更新,找到暂存区域的文件,将快照永久性存储到 Git 本地仓库。
- 近程仓库(remote) – 以上几个工作区都是在本地。为了让他人能够看到你的批改,你须要将你的更新推送到近程仓库。同理,如果你想同步他人的批改,你须要从近程仓库拉取更新。
- 分支(Branch)
分支是为了将批改记录的整个流程离开存储,让离开的分支不受其它分支的影响,所以在同一个数据库里能够同时进行多个不同的批改
主分支(Master)后面提到过 master 是 Git 为咱们主动创立的第一个分支,也叫主分支,其它分支开发实现后都要合并到 master
- 标签(Tag)
标签是用于标记特定的点或提交的历史,通常会用来标记公布版本的名称或版本号(如:publish/0.0.1),尽管标签看起来有点像分支,但打上标签的提交是固定的,不能随便的改变,参见上图中的 1.0 / 2.0 / 3.0
- HEAD
HEAD 指向的就是以后分支的最新提交图片
以上概念理解的差不多,那就能够持续往下看。
Git 命令
- 创立仓库
克隆一个已创立的仓库:
# 通过 SSH
$ git clone ssh://user@domain.com/repo.git
#通过 HTTP
$ git clone http://domain.com/user/repo.git
创立一个新的本地仓库:
$ git init
-
增加批改
增加批改到暂存区:# 把指定文件增加到暂存区 $ git add xxx # 把以后所有批改增加到暂存区 $ git add . # 把所有批改增加到暂存区 $ git add -A
提交批改到本地仓库:
# 提交本地的所有批改 $ git commit -a # 提交之前已标记的变动 $ git commit # 附加音讯提交 $ git commit -m 'commit message'
- 储备
有时,咱们须要在同一个我的项目的不同分支上工作。当须要切换分支时,偏偏本地的工作还没有实现,此时,提交批改显得不谨严,然而不提交代码又无奈切换分支。这时,你能够应用 git stash 将本地的批改内容作为草稿储备起来。
官网称之为储备,但我集体更喜爱称之为存草稿。
# 1. 将批改作为以后分支的草稿保留
$ git stash
# 2. 查看草稿列表
$ git stash list
stash@{0}: WIP on master: 6fae349 :memo: Writing docs.
# 3.1 删除草稿
$ git stash drop stash@{0}
# 3.2 读取草稿
$ git stash apply stash@{0}
- 撤销批改
撤销本地批改:
# 移除缓存区的所有文件(i.e. 撤销上次 git add)$ git reset HEAD
# 将 HEAD 重置到上一次提交的版本,并将之后的批改标记为未增加到缓存区的批改
$ git reset <commit>
# 将 HEAD 重置到上一次提交的版本,并保留未提交的本地批改
$ git reset --keep <commit>
# 放弃工作目录下的所有批改
$ git reset --hard HEAD
# 将 HEAD 重置到指定的版本,并摈弃该版本之后的所有批改
$ git reset --hard <commit-hash>
# 用远端分支强制笼罩本地分支
$ git reset --hard <remote/branch> e.g., upstream/master, origin/my-feature
# 放弃某个文件的所有本地批改
$ git checkout HEAD <file>
删除增加.gitignore 文件前谬误提交的文件:
$ git rm -r --cached .
$ git add .
$ git commit -m "remove xyz file"
撤销近程批改(创立一个新的提交,并回滚到指定版本):
$ git revert <commit-hash>
彻底删除指定版本:
# 执行上面命令后,commit-hash 提交后的记录都会被彻底删除,应用需谨慎
$ git reset --hard <commit-hash>
$ git push -f
- 更新与推送
更新:
# 下载近程端版本,但不合并到 HEAD 中
$ git fetch <remote>
# 将近程端版本合并到本地版本中
$ git pull origin master
# 以 rebase 形式将远端分支与本地合并
$ git pull --rebase <remote> <branch>
推送:
# 将本地版本推送到近程端
$ git push remote <remote> <branch>
# 删除近程端分支
$ git push <remote> :<branch> (since Git v1.5.0)
$ git push <remote> --delete <branch> (since Git v1.7.0)
# 公布标签
$ git push --tags
- 查看信息
显示工作门路下已批改的文件:
$ git status
显示与上次提交版本文件的不同:
$ git diff
显示提交历史:
# 从最新提交开始,显示所有的提交记录(显示 hash,作者信息,提交的题目和工夫)$ git log
# 显示某个用户的所有提交
$ git log --author="username"
# 显示某个文件的所有批改
$ git log -p <file>
-
显示搜寻内容:
# 从当前目录的所有文件中查找文本内容 $ git grep "Hello" # 在某一版本中搜寻文本 $ git grep "Hello" v2.5
- 分支
增删查分支:
# 列出所有的分支
$ git branch
# 列出所有的远端分支
$ git branch -r
# 基于以后分支创立新分支
$ git branch <new-branch>
# 基于近程分支创立新的可追溯的分支
$ git branch --track <new-branch> <remote-branch>
# 删除本地分支
$ git branch -d <branch>
# 强制删除本地分支,将会失落未合并的批改
$ git branch -D <branch>
切换分支:
# 切换分支
$ git checkout <branch>
# 创立并切换到新分支
$ git checkout -b <branch>
标签
# 给以后版本打标签
$ git tag <tag-name>
# 给以后版本打标签并附加音讯
$ git tag -a <tag-name>
合并与重置
merge 与 rebase 尽管是 git 罕用性能,然而强烈建议不要应用 git 命令来实现这项工作。
因为如果呈现代码抵触,在没有代码比对工具的状况下,切实太艰巨了。
你能够思考应用各种 Git GUI 工具。
合并:
# 将分支合并到以后 HEAD 中
$ git merge <branch>
重置:
# 将以后 HEAD 版本重置到分支中,请勿重置已公布的提交
$ git rebase <branch>
更多命令参考:三年 Git 应用心得 & 常见问题整顿
Git 分支开发
Git 是目前最风行的源代码管理工具。为标准开发,放弃代码提交记录以及 git 分支构造清晰,不便后续保护,现标准 git 的相干操作。
分支命名
1、master 分支
master 为主分支,也是用于部署生产环境的分支,确保 master 分支稳定性,master 分支个别由 develop 以及 hotfix 分支合并,任何工夫都不能间接批改代码
2、develop 分支
develop 为开发分支,始终保持最新实现以及 bug 修复后的代码,个别开发的新性能时,feature 分支都是基于 develop 分支下创立的。
- feature 分支
开发新性能时,以 develop 为根底创立 feature 分支。
分支命名: feature/ 结尾的为个性分支,命名规定: feature/user_module、feature/cart_module
- release 分支
release 为预上线分支,公布提测阶段,会 release 分支代码为基准提测。当有一组 feature 开发实现,首先会合并到 develop 分支,进入提测时会创立 release 分支。如果测试过程中若存在 bug 须要修复,则间接由开发者在 release 分支修复并提交。当测试实现之后,合并 release 分支到 master 和 develop 分支,此时 master 为最新代码,用作上线。
- hotfix 分支
分支命名: hotfix/ 结尾的为修复分支,它的命名规定与 feature 分支相似。线上呈现紧急问题时,须要及时修复,以 master 分支为基线,创立 hotfix 分支,修复实现后,须要合并到 master 分支和 develop 分支
更多开发标准请参阅:全网最全的 Git 分支开发标准手册 | 把握这 10 条标准,轻松搞定 Git!
Git 这些高级用法,喜爱就拿去用!
Git 提交标准
为什么须要标准?
无规矩不成方圆,编程也一样。
如果你有一个我的项目,从始至终都是本人写,那么你想怎么写都能够,没有人能够干涉你。可是如果在团队合作中,大家都张扬共性,那么代码将会是一团糟,好好的我的项目就被糟践了。不论是开发还是日后保护,都将是劫难。
这时候,有人提出了何不统一标准,大家都依照这个规范来。于是 ESLint,JSHint 等代码工具如雨后春笋般涌现,成为了我的项目构建的必备良品。
Git Commit 标准可能并没有那么夸大,但如果你在版本回退的时候看到一大段糟心的 Commit,恐怕会懊恼不已吧。所以,严格遵守标准,利人利己。
具体请参阅:你可能会疏忽的 Git 提交标准
Git 应用技巧
只有在遇到问题的时候,才领会到技巧带来的益处!
常见企业工作流程
次要介绍,企业中罕用的 Git 工作流程!
- Git Flow
- 骨干分支
- 稳固分支
- 开发分支
- 补丁分支
- 批改分支
Github Flow
- 创立分支
- 增加提交
- 提交 PR 申请
- 探讨和评估代码
- 部署检测
- 合并代码
Gitlab Flow
- 带生产分支
- 带环境分支
- 带公布分支
日常应用最佳实际
总结日常工作中应该遵循的 Git 应用形式和办法!
- 应用命令行代替图形化界面
- 应用命令行来操作,简洁且效率高
- 提交应该尽可能的表述提交批改内容
- 辨别 subject 和 body 内容,应用空行隔开
- subject 个别不超过 50 个字符
- body 每一行的长度管制在 72 个字符
- subject 结尾不须要应用句号或者点号结尾
- body 用来具体解释此次提交具体做了什么
- 应用 .gitignore 文件来排除无用文件
- 可应用模板文件,而后依据我的项目理论进行批改
- 基于分支或 fork 的开发模式
- 不要间接在骨干分支下面进行开发
- 在新建的分支上进行性能的开发和问题的修复
- 应用 release 分支和 tag 标记进行版本治理
- 应用 release 分支公布代码和版本保护(release/1.32)
- 应用 tag 来标记版本(A- 大 feature 性能.B- 小 feature 性能.C- 只修 bug)
常用命令汇总整顿
日常应用只有记住 6 个命令就能够了。
# 工作区 -> 暂存区
$ git add <file/dir>
# 暂存区 -> 本地仓库
$ git commit -m "some info"
# 本地仓库 -> 近程仓库
$ git push origin master # 本地 master 分支推送到近程 origin 仓库
# 工作区 <- 暂存区
$ git checkout -- <file> # 暂存区文件内容笼罩工作区文件内容
# 暂存区 <- 本地仓库
$ git reset HEAD <file> # 本地仓库文件内容笼罩暂存区文件内容
# 本地仓库 <- 近程仓库
$ git clone <git_url> # 克隆近程仓库
$ git fetch upstream master # 拉取近程代码到本地但不利用在以后分支
$ git pull upstream master # 拉取近程代码到本地但利用在以后分支
$ git pull --rebase upstream master # 如果平时应用 rebase 合并代码则加上
# 工作区 <- 本地仓库
$ git reset <commit> # 本地仓库笼罩到工作区(保留回退文件内容批改)
$ git reset --mixed <commit> # 本地仓库笼罩到工作区(保留回退文件内容批改)
$ git reset --soft <commit> # 本地仓库笼罩到工作区(保留批改并加到暂存区)
$ git reset --hard <commit> # 本地仓库笼罩到工作区(不保留批改间接删除掉)
更多对于 Git 的应用技巧介绍请查阅:学会这 11 条,你离 Git 大神就不远了!
Git 常识体系动静更新看这里