admin管理员组

文章数量:1531792

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的基本操作流程

  1. 初始化一个本地版本库,每个版本库仅需要执行一次。
  2. 将中央版本库内容克隆到本地版本库,每个客户机仅需要执行一次。
  3. 添加指定文件到版本控制管理(这一步只是添加到Git暂存区)。
  4. 将添加、修改等操作,提交到本地版本库(将暂存区的内容提交到本地版本库)。
    如果远程仓库的内容被别人修改了,需要先同步远程的内容,直接git pull就可以更新本地的文件,然后再提交。再这过程中可能需要解决冲突。
    在修改完成后,如果发现错误,可以撤回提交并再次修改并提交。
  5. 将本地版本库中的修改内容“推送”到中央版本库,客户机需要在一阶段性工作完成之后,或在某些时间点(下班,周五),将修改过的内容备份到中央版本库,方便他人更新到最新的代码。
  6. 将中央版本库中的变化内容“拉取”本地版本库,客户机需要不定时的更新才可以获取最新的内容。

提示:实际工作中的很多功能和操作都在第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管理新建的项目

  1. 进入到Git本地版本库管理目录git-repository
  2. 查看目录内容。
  3. 执行$ git init your_project,创建Git本地版本库。
  4. 查看Git本地版本库是否创建。
  5. 进入到刚刚创建的Git本地版本库。
  6. 查看Git本地版本库中的内容。
  7. 进入.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管理

  1. second_git_repo目录是一个已有文件的项目目录。
  2. 进入second_git_repo目录,查看内容。
  3. 执行git init命令,把该目录纳入Git管理。
  4. 该目录纳入Git管理后,查看目录以有.git目录。
  5. 进入.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上创建的仓库了。

  • 进入clone到本地的项目TestNG中查看

里边也有.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>,完成。
  • 3、文用到的Git命令
序号Git命令说明
1git init把一个目录变成Git可以管理的仓库
2git add可以将跟踪到的更新放到暂存区(更新包括新增、修改、删除等操作)
3git commit -m 'add Test_text'提交更新到仓库

 

本文标签: 详细介绍万字实战入门Git