5、Git的协作模式(一)
1、分布式工作流程
与传统的集中式版本控制系统(CVCS)相反,Git 的分布式特性,使开发者间的协作变得更加灵活多样。 在集中式版本控制系统中,每个开发者就像是连接在集线器上的节点,彼此的工作方式大体相像。 而在 Git 中,每个开发者同时扮演着节点和集线器的角色。也就是说, 每个开发者既可以将自己的代码贡献到其他的仓库中,同时也能维护自己的公开仓库, 让其他人可以在其基础上工作并贡献代码。 由此,Git 的分布式协作可以为你的项目和团队,衍生出种种不同的工作流程, 接下来会介绍几种常见Git工作流程。 你可以选择使用其中的某一种,或者将它们的特性混合搭配使用。
2、集中式工作流
Git为了便于客户机之间的协同工作,Git版本控制系统一般会设置一个中央版本库服务器,目的是让所有客户机都从该主机更新版本,提交最新版本,该工作模式下的客户机地位都平等。 集中式工作流像SVN 一样,以中央仓库作为项目所有修改的单点实体,所有修改都提交到?Master分支 上。这种方式与 SVN 的主要区别就是开发人员有本地库,但是Git 很多特性并没有用到。 如下图:
上图说明:
- 一个远程仓库,
- 一个主分支master,
- 团队每个成员都有一个本地仓库,在本地仓库中进行代码的编辑、暂存和提交工作。
集中式工作流总结:
- 适用人群:小型开发小团队,习惯使用SVN工具的小团队。
- 工作方式:
- 团队组长创建远程仓库,创建一个master分支,组员可读可写。
- 每个开发人员都
git clone 远程仓库到本地仓库,在master分支上开发。 - 每次开发都要
git pull 更新远程仓库的master分支版本到本地。 - 每次开发完成就
git commit 到本地仓库, 接着git push 到远程仓库。
- 缺点:
- 忘了
git push ,一直会提交到本地仓库,没有推送到远程仓库。 - 忘了
git pull ,导致本地仓库与中央仓库不一致,发生文件冲突。 - 大量操作
git pull ,导致增加Git分支合并次数,增加了Git变基次数,降低了Git的性能。
3、分支工作流
功能分支工作流在集中式工作流的基础上,为各个新功能分配一个专门的分支来开发,即在master主分支外在创建一个分支,程序员开发的新功能全部push到此分支上,等到功能成熟的时候,再把此分支合并到主分支master上。 如下图:
分支工作流总结:
- 适用人群:小型开发团队,熟悉Git分支的团队。
- 工作方式:
- 团队组长创建远程仓库,创建一个master分支,组员可读不可写。
- 每个开发人员都
git clone 远程仓库到本地仓库。 - 每个开发人员创建自己的feature分支,在feature分支上开发。(记住,feature分支是基于master分支)
- 每个开发人员每次开发完成就
git commit 到本地仓库中自己的feature分支, 接着git push 到远程仓库。 - 通过
pull request 提醒团队组长,浏览组员提交feature分支。 - 组长把feature分支拉下来,然后合并到自己本地仓库的master分支上测试。
- 组长测试feature分支通过之后,由组长负责把feature分支合并到远程仓库的master分支上。
- 组长在远程仓库把合并过的feature分支删除。
- 组员在本地仓库把合并过的feature分支删除。
- 组员将本地仓库分支切换为master分支,然后
git pull 将本地仓库的master分支更新到远程仓库的master分支版本。
- 缺点:
PS:Pull Request 作用是可以让其他组员或组长可以查看你的代码,并可以提出代码修改意见或者讨论。
4、GitFlow 工作流(最流行)
Gitflow工作流没有用超出上面功能分支工作流的概念和命令,而是为不同的分支,分配一个很明确的角色,并定义分支之间如何交互,和什么时候进行交互。
- 除了有master主分支(用于存储正式发布的历史版本)外,还有一个作为功能集成分支的develop分支。
当初始化完成后,某个程序员想要开发一个功能,并不是直接从master分支上拉出新分支,而是使用develop分支作为父分支来拉出新分支。 当新功能完成后,再合并回父分支,新功能的提交并不与master分支直接交互。 - 一旦develop分支上有了做一次发布(或者说快到了既定的发布日)的足够功能,就从develop分支上checkout一个发布分支。
新建的发布分支用于开始发布循环,所以从这个时间点开始之后新的功能,不能再加到这个分支上,该分支只应该做Bug修复、文档生成和其它面向发布任务。 一旦对外发布的工作都完成了,发布分支合并到master分支,并分配一个版本号打好Tag。 另外,这些从新建发布分支以来的做的修改,要合并回develop分支上。 - 维护分支或说是热修复(hotfix)分支用于,快速给产品发布版本(production releases)打补丁,这是唯一可以直接从master分支fork出来的分支。
修复完成,修改应该马上合并回master分支和develop分支(当前的发布分支),master分支应该用新的版本号打好Tag。 为Bug修复使用专门分支,让团队可以快速处理掉问题,而不用打断其它工作或是等待下一个发布循环。 你可以把维护分支想成是一个直接在master分支上处理的临时发布。
总结就是:Gitflow ?工作流通过为功能开发、发布准备和维护设立了独立的分支,让发布迭代过程更流畅,充分的利用了分支的特点。严格的分支模型也为大型项目提供了一些非常必要的结构。 下图是完整的Gitflow ?工作流开发方式图,但实际开发工作环境可能会精简:
Gitflow工作流总结:
- 适用人群:任何开发团队,熟悉Git分支的团队。
- 工作方式:
- 项目维护者创建项目维护者的远程仓库,创建master分支与develop分支,贡献者可读不可写。
- 每个贡献者
git clone 远程仓库中的develop分支到本地仓库。(记住,develop分支相当于master的分支,包括功能开发,修改,测试。master分支相当于最终分支) - 每个贡献者在本地仓库创建自己的feature分支,在feature分支上开发。
- 在feature分支又可以创建多个feature分支,继续开发项目。
- 每个贡献者每次开发完成就
git commit 到本地仓库中自己的feature分支, 接着git push 到远程仓库。 - 通过
pull request 提醒项目维护者,浏览贡献者提交feature分支。 - 项目维护者把feature分支拉下来,然后合并到自己本地仓库的develop分支上测试。
- 组长测试feature分支通过之后,由组长负责把feature分支合并到远程仓库的develop分支上。
- 项目维护者会release分支上
git tag 打上版本号。 - 项目维护者可以从develop分支创建release分支,接着把release分支合并到master分支上,同时master分支同步到develop分支。
- 项目维护者在远程仓库把合并过的feature分支删除。
- 每个贡献者在本地仓库把合并过的feature分支删除。
- 每个贡献者将本地仓库分支切换为develop分支,然后
git pull 将本地仓库的master分支更新到远程仓库的develop分支版本。
PS:Gitflow工作流是
Vincent Driessen 工程师提出的多分支工作流。
5、Forking 工作流(偶尔使用)
分叉(Forking)工作流也可以叫做分布式工作流,是在 GitFlow工作流的基础上的衍生,充分利用了Git在分支和克隆上的优势,再加上pull request ?的功能,以达到代码审核的目的。既可以管理大团队的开发者(developer)的提交,也可以接受不信任贡献者(contributor)的提交。 这种工作流使得每个开发者都有一个服务端仓库(此仓库只有自己可以push推送,但是所有人都可以pull拉取修改),每个程序员都push代码到自己的服务端仓库,但不能push到正式仓库,只有项目维护者才能push到正式仓库,这样项目维护者可以接受任何开发者的提交,但无需给他正式代码库的写权限。 这种工作流适合开源社区的开源项目,大家统一对项目做贡献,但是有一个人或一个团队作为开发者来管理项目,所有的贡献者的代码由开发者审核,其功能完善之后再由开发者push到正式仓库中。 总结:
- 分叉(Forking)工作流更适合安全可靠地管理大团队的开发者,而且能接受不信任贡献者的提交。
- 在实际工作中,如果偶尔有需要团队外的成员帮我们解决问题时,可能会用到。
- 这种工作流程并不常用,只有当项目极为庞杂,或者需要多级别管理时,才会体现出优势。 利用这种方式,项目总负责人(即主管)可以把大量分散的集成工作,委托给不同的小组负责人分别处理,然后在不同时刻将大块的代码子集统筹起来,用于之后的整合。
提示:
- 每个成员都可以从中央版本库中拉取代码。
- 每级成员都只能向上一级提交代码。
- 上一级合并代码之后继续向上级提交代码。
- 最后只有独裁者才能向中央版本库提交代码。
分叉工作流(分布式仓库工作流)总结: - 适用人群:大型开发团队,熟悉Git分支的团队。
- 工作方式:
- 主项目维护者创建远程仓库,创建一个master分支,从项目维护者可读不可写。
- 从项目维护者通过fork主项目维护者的远程仓库的副本,到自己的远程仓库,包括master分支。(记住,从项目维护者的远程仓库独立于主项目维护者的远程仓库)
- 从项目维护者
git clone 主项目维护者的远程仓库的副本到本地仓库。 - 从项目维护者创建自己的feature分支,在feature分支上开发。
- 从项目维护者每次开发完成就
git commit 到本地仓库中自己的feature分支, 接着git push 到远程仓库。 - 通过
pull request 命令,从项目维护者合并自己feature分支,到从项目维护者的远程仓库的master分支上。 - 从项目维护者在远程仓库把合并过的feature分支删除。
- 从项目维护者在本地仓库把合并过的feature分支删除。
- 从项目维护者在远程仓库通过
pull request 向主项目维护者的远程仓库的推送。 - 主项目维护者通过
pull request 获取从项目维护者的远程仓库的推送。 - 主项目维护者进行从项目维护者的远程仓库代码审查,测试。
- 主项目维护者确认无误后,可以直接合并到主项目维护者的远程仓库。
6、总结
上面介绍了在Git分布式系统中经常使用的工作流程,但是在实际的开发中,你会遇到许多可能适合你的特定工作流程的变种,你可以按照实际的情况,灵活的进行组合和拓展。
6、Git操作流程
1、Git的基本操作流程
- 初始化一个本地版本库,每个版本库仅需要执行一次。
- 将中央版本库内容克隆到本地版本库,每个客户机仅需要执行一次。
- 添加指定文件到版本控制管理(这一步只是添加到Git暂存区)。
- 将添加、修改等操作,提交到本地版本库(将暂存区的内容提交到本地版本库)。
如果远程仓库的内容被别人修改了,需要先同步远程的内容,直接git pull 就可以更新本地的文件,然后再提交。再这过程中可能需要解决冲突。 在修改完成后,如果发现错误,可以撤回提交并再次修改并提交。 - 将本地版本库中的修改内容“推送”到中央版本库,客户机需要在一阶段性工作完成之后,或在某些时间点(下班,周五),将修改过的内容备份到中央版本库,方便他人更新到最新的代码。
- 将中央版本库中的变化内容“拉取”本地版本库,客户机需要不定时的更新才可以获取最新的内容。
提示:实际工作中的很多功能和操作都在第3、4步中。
如下图:
说明: 上面内容涉及到Git中的几个区域:
workspace :工作区。staging area :暂存区/缓存区。local repository :版本库或本地仓库。remote repository :远程仓库。
2、工作区、暂存区、版本库的区别
我们先来理解下Git 工作区、暂存区和版本库概念,这对以后我们学习Git命令会有非常大的帮助。 (1)工作区 就是你在电脑里能看到的目录。 一般我们执行git init 命令,就能把一个目录初始化成Git本地版本库。 而这个目录就是该Git本地版本库的工作区。 如下图:git-demo1 目录就是一个本地仓库。
具体结构如下图:
(2)版本库 版本库:工作区(项目根目录)有一个隐藏目录.git ,这个目录就是版本库,而该目录不算工作区。
具体结构如下图:
(3)暂存区 暂存区:
- 暂存区从字面上去理解就是用来暂时保存文件的地方,实际上它的作用和它的名字是一致的,暂存区可以起到过渡的作用,当我们写代码修改了一些文件的时候,可以把修改的代码提交到暂存区保存,然后接着写代码,接着再提交到暂存区保存,写完某些代码觉得没什么可以修改的时候,可以将暂存区里面的文件一次性提交到版本库。
- 暂存区英文叫stage, 或index。
- 暂存区是包含在版本库中的,一般存放在
.git 目录下的index文件 (.git/index)中,所以我们把暂存区有时也叫作索引(index)。
暂存区位置如下图:
具体结构如下图:
说明: 版本库又存在两个很重要的区域:暂存区与分支区。 分支区:该区域中可以包含很多分支,而每个分支都可以记录当前工作区中文件状态的快照。 如下图:
即:分支区就相当于本地版本库。 (4)通过新增文件理解三个区的关系 1)工作区新加文件?index.html
2)将index.html提交到暂存区
3)将暂存区内的内容提交到版本库
4)将本地版本推送到Github上
(5)说明 我们只要知道Git的整体操作流程即可,脑子中有一个宏观的概括就可以。关于每一步是如何操作的,和具体使用的命令,我们以后会一步一步的进行详解。
7.设置Git Bash默认路径
如果您不熟悉Git命令,推荐使用Windows TortoiseGit客户端的可视化操作界面,如果您熟悉常用的Git命令,Git Bash将会是您Windows上更加简洁、高效的客户端。(其中运行的是Linux命令)
1、Git Bash默认路径
在windows系统上操作Git的客户端是Git Bash 。 安装完Git Bash 之后,双击打开,如下图:
使用pwd 命令查看当前路径:
每次打开Git Bash 都进入默认的目录中。
- win7系统就是Git安装目录的根目录。
- win10系统在系统盘的用户目录中,例如:C:\Users\L。
2、如何查看Git Bash终端默认路径
右键Git Bash 图标,点击属性。
起始位置就是Git Bash 打开时默认所在的位置,和Git安装目录的位置是一样的。
提示: windows10系统,Git版本:2.25.0 ,Git Bash 终端默认路径是在系统盘的个人用户目录中。
在Git Bash 终端中查看默认路径
3、如何修改Git Bash终端的默认路径
日常工作中,如果你需要管理过个Git本地版本库时,修改Git Bash 终端的默认路径,就不需要每次切换目录了。 在Git Bash 终端图标上,右键 —> 属性,下面图片的”起始位置:”直接输入你需要Git Bash 终端的默认路径即可。如下:
然后重启Git Bash 终端,就可以查看到默认路径发生改变了。
提示: windows10系统,Git版本:2.25.0 ,修改和win7系统不同。 去掉”目标”中的?--cd-to-home ,将“起始位置”的内容改为你需要的Git Bash 终端的默认路径。
重启Git Bash 终端,查看就可以了
4、拓展:指定目录进入Git Bash终端
在我们电脑中的任何目录下,右键 —>?Git Bash Here ,例如在桌面:
通过这种方式进入到Git Bash 终端,我们可以看到下图,进入终端的目录,就是你右键点击Git Bash Here 的目录。
这样的方式进入指定的目录也很方便。
5、注意事项
- 版本控制文件类型:对于版本控制系统,无论是CVS、SVN、GIT都只能控制文本文件,对二进行制文件是无法控制。不幸的是,微软的office文件都属于二进行制文件,不能使用版本系统进行控制。
- 字符编码与记事本:建议使用UTF-8编码。(windows系统中记事本编码默认不是UTF-8编码,可以使用Notepad++等记事本工具修改)。
9、初始化本地版本库
1、Git版本库介绍
每个Git版本控制系统的主机中,都可以包含若干个本地版本库,一般情况下一个本地版本库对应一个项目,用于对某个特定项目中的本地文件进行版本管理。其实,你可以简单理解成一个目录,这个目录里面的所有文件都可以被Git管理起来,每个文件的修改、删除等操作Git都能跟踪到,以便任何时刻都可以追踪历史,或者在将来某个时刻可以进行“还原”。 Git中版本库又名仓库,英文名Repository ,使用命令git init 来创建并初始化一个本地版本库。 初始化后,在当前目录下会出现一个名为.git 的目录,所有Git需要的数据和资源都存放在这个目录中。包括暂存区文件,版本记录文件,配置文件等。换句话说,如果你想从项目中删除Git的版本控制,但又要保留项目原文件,那么只需要将这个.git 目录删除即可。这样话,这个项目就与Git没有任何关系。
2、创建本地版本库
在日常工作当中,创建Git本地版本库的场景有两种。 场景一:创建一个空的本地版本库 介绍: 这种情况是项目还没有代码,需要先创建一个Git本地版本库的时候。 在你专门存放Git版本库的文件夹中,执行git init your_project(项目名) ,这个时候Git会在当前路径下,创建一个和项目名称同名的文件夹,这个文件夹就是一个Git的裸仓库,里面的会有一个隐藏的.git 文件夹。 要进行开发的时候,只要进入到这个文件夹里面就可以了。 步骤: 直接用Git管理新建的项目
- 进入到Git本地版本库管理目录
git-repository 。 - 查看目录内容。
- 执行
$ git init your_project ,创建Git本地版本库。 - 查看Git本地版本库是否创建。
- 进入到刚刚创建的Git本地版本库。
- 查看Git本地版本库中的内容。
- 进入
.git 目录,进行查看。
演示:
说明
当我们执行完
$ git init first_git_repo 命令之后,会出现下面一行提示。
Initialized empty Git repository in J:/git-repository/first_git_repo/.git/
意思是:初始化一个空的Git仓库,然后是仓库的路径。
.git 目录:这个文件夹是Git的核心内容,这个目录是Git来跟踪管理版本库的,没事千万不要手动修改这个目录里面的文件,不然改乱了,就把Git仓库给破坏了。这个文件夹以后我们会详细的讲解。
提示:
我们也可以在
git-repository 目录中,先通过
mkdir first_git_repo ,创建一个仓库目录,然后在进入这个目录中,执行
git init 命令,和上边是一样的,这里就不演示了。
如果你使用Windows系统,为了避免遇到各种莫名其妙的问题,请确保目录名(包括父目录)不包含中文。
场景二:项目中以存在文件时创建该项目的本地版本库 介绍: 这种情况就是在创建仓库之前,项目中已经有一些代码文件了。换种方式说,在本地创建Git仓库,把代码纳入到Git管理中,提交到 GitHub。 针对这种情况,我们只需要进入到已有的项目代码所在的文件夹,然后执行git init 命令就可以了。 步骤: 把已有的项目文件的目录纳入Git管理
second_git_repo 目录是一个已有文件的项目目录。- 进入
second_git_repo 目录,查看内容。 - 执行
git init 命令,把该目录纳入Git管理。 - 该目录纳入Git管理后,查看目录以有
.git 目录。 - 进入
.git 目录,进行查看。
演示:
以上就是Git在本地创建版本库常用的两种情况。 场景三:在 GitHub 网站上进行仓库创建,克隆到本地。 1、进入GitHub网站,点击右上角的加号,选择穿件仓库。
2、进入到创建Git仓库页面
Public:公有的,就是大家谁都能看得到的仓库,也能下载你仓库中的代码。 Private:私有的,你可以选择让谁看到,需要花钱 其他的不用管直接点击创建(Create repository)。
3、查看创建的仓库,选择认证方式
会有一个仓库列表,点击你刚刚创建的仓库。
https和ssh验证方式的区别 | |
---|
https基于用户名密码的验证方式 | 。 | Ssh基于公钥私钥的验证方式(sshkey的方式),之前讲过。 | |
4、克隆仓库到本地
- 执行
git clone + 选择认证方式-图4中的clone路径
- 查看git-repository-temp目录中,已经clone出GitHub上创建的仓库了。
里边也有.git文件夹,说明也被Git管理。
以上就是三种创建Git的形式。
10.创建Git仓库--补充
版本库又名仓库,英文名repository,你可以简单理解成一个目录,这个目录里面的所有文件都可以被Git管理起来,每个文件的修改、删除,Git都能跟踪,以便任何时刻都可以追踪历史,或者在将来某个时刻可以“还原”。
一、创建一个版本库
第一步:选择一个合适的地方,创建一个空目录:
$ mkdir learngit
$ cd learngit
$ pwd
/Users/michael/learngit
pwd命令用于显示当前目录位置。 如果你使用Windows系统,为了避免遇到各种莫名其妙的问题,请确保目录名(包括父目录)不包含中文。 第二步:通过git init 命令把这个目录变成Git可以管理的仓库:
$ git init
Initialized empty Git repository in /Users/michael/learngit/.git/
瞬间Git就把仓库建好了,而且告诉你是一个空的仓库(empty Git repository),细心的读者可以发现当前目录下多了一个.git的目录,这个目录是Git来跟踪管理版本库的,没事千万不要手动修改这个目录里面的文件,不然改乱了,就把Git仓库给破坏了。 如果你没有看到.git目录,那是因为这个目录默认是隐藏的,用ls -al命令就可以看见。
二、把文件添加到版本库
1、首先这里再明确一下
- 所有的版本控制系统,其实只能跟踪文本文件的改动,比如TXT文件,网页,所有的程序代码等等,Git也不例外。版本控制系统可以告诉你每次的改动,比如在第5行加了一个单词“Linux”,在第8行删了一个单词“Windows”。
- 而图片、视频这些二进制文件,虽然也能由版本控制系统管理,但没法跟踪文件的变化,只能把二进制文件每次改动串起来,也就是只知道图片从100KB改成了120KB,但到底改了啥,版本控制系统不知道,也没法知道。
- 不幸的是,Microsoft的Word格式是二进制格式,因此,版本控制系统是没法跟踪Word文件的改动的,如果要真正使用版本控制系统,就要以纯文本方式编写文件。
- 因为文本是有编码的,比如中文有常用的GBK编码,日文有Shift_JIS编码,如果没有历史遗留问题,强烈建议使用标准的UTF-8编码,所有语言使用同一种编码,既没有冲突,又被所有平台所支持。
2、使用Windows的童鞋要特别注意:
- 千万不要使用Windows自带的记事本编辑任何文本文件。原因是Microsoft开发记事本的团队使用了一个非常弱智的行为来保存UTF-8编码的文件,他们自作聪明地在每个文件开头添加了0xefbbbf(十六进制)的字符,你会遇到很多不可思议的问题,比如,网页第一行可能会显示一个“?”,明明正确的程序一编译就报语法错误,等等,都是由记事本的弱智行为带来的。
- 建议你下载Notepad++代替记事本,不但功能强大,而且免费!记得把Notepad++的默认编码设置为UTF-8 without BOM即可:
Notepad++设置编码 3、把文件添加到版本库 编写一个readme.txt文件,一定要放到learngit目录下(子目录也行),因为learngit目录是上边刚刚用git init 命令创建的一个Git仓库,放到其他地方Git再厉害也找不到这个文件。 和把大象放到冰箱需要3步相比,把一个文件放到Git仓库只需要两步。
- 第一步,用命令git add告诉Git,把文件添加到仓库:
$ git add readme.txt
执行上面的命令,没有任何显示,这就对了,Unix的哲学是“没有消息就是好消息”,说明添加成功。
- 第二步,用命令git commit告诉Git,把文件提交到仓库:
$ git commit -m "wrote a readme file"
[master (root-commit) eaadf4e] wrote a readme file
1 file changed, 2 insertions(+)
create mode 100644 readme.txt
- 简单解释一下git commit命令,-m后面输入的是本次提交的说明,可以输入任意内容,当然最好是有意义的,这样你就能从历史记录里方便地找到改动记录。
- git commit命令执行成功后会告诉你,1 file changed:1个文件被改动(我们新添加的readme.txt文件);2 insertions:插入了两行内容(readme.txt有两行内容)。
为什么Git添加文件需要add,commit一共两步呢?因为commit可以一次提交很多文件,所以你可以多次add不同的文件,比如:
$ git add file1.txt
$ git add file2.txt file3.txt
$ git commit -m "add 3 files."
三、总结:
- 1、初始化一个Git仓库,使用
git init 命令。 - 2、添加文件到Git仓库
分两步: |
---|
使用命令git add <file>,注意,可反复多次使用,添加多个文件; | 使用命令git commit -m <message>,完成。 |
序号 | Git命令 | 说明 |
---|
1 | git init | 把一个目录变成Git可以管理的仓库 | 2 | git add | 可以将跟踪到的更新放到暂存区(更新包括新增、修改、删除等操作) | 3 | git commit -m 'add Test_text' | 提交更新到仓库 |
重点:配套学习资料和视频教学
那么在这里我也精心准备了上述大纲的详细资料在下方链接如下
|