GIT版本控制

版本控制

在公司中,一般以团队的形式进行项目的开发。在一个团队中,每一个团队成员都需要一份相同的代码,而大家又都基于这份代码去开发着不同的功能,过程中就会产生相当多的问题,针对这些问题,我们可以采用版本控制的方式来解决,也因此诞生了很多的版本控制工具,如市面上比较常见的 cvs/svn/git 等等

团队开发中的问题

  1. 小明负责的模块就要完成了,就在即将Release之前的一瞬间,电脑突然蓝屏,硬盘光荣牺牲!几个月来的努力付之东流——需求之一:备份!

  2. 这个项目中需要一个很复杂的功能,老王摸索了一个星期终于有眉目了,可是这被改得面目全非的代码已经回不到从前了。什么地方能买到哆啦A梦的时光机啊?需求之二:代码还原!

  3. 小刚和小强先后从文件服务器上下载了同一个文件:Analysis.java。小刚在Analysis.java文件中的第30行声明了一个方法,叫count(),先保存到了文件服务器上;小强在Analysis.java文件中的第50行声明了一个方法,叫sum(),也随后保存到了文件服务器上,于是,count()方法就只存在于小刚的记忆中了——需求之三:协同修改!

  4. 老许是一位项目经理,他需要把每一个版本的项目都保存一份, 而且这些工程里其实有很多文件都是重复的,导致电脑空间经常不足 , 要找某个版本的时候也很麻烦——需求之四:多版本项目文件管理!

  5. 老王是另一位项目经理,每次因为项目进度挨骂之后,他都不知道该扣哪个程序员的工资!就拿这次来说吧,有个该死的Bug调试了30多个小时才知道是因为相关属性没有在应用初始化时赋值!可是小强、小明、小刚和小军都不承认是自己干的!——需求之五:追溯问题代码的编写人和编写时间!

  6. 小温这两天幸福的如同掉进了蜜罐里,因为他成功的得到了前台MM丽丽的芳心,可他郁闷的是这几天总是收到QA小组的邮件,要求他修正程序中存在的Bug,可他自己本地电脑上是没有这些Bug的,“难道我的代码被哪个孙子给改了?”。是的,小温没来的时候,丽丽是QA小组小郑的女朋友啊!——需求之六:权限控制!

版本控制概述

版本控制: 版本控制(Revision control)是维护工程蓝图的标准做法,能追踪工程蓝图从诞生一直到定案的过程。是一种记录若干文件内容变化过程,以便将来查阅特定版本修订情况的系统。

版本控制深入程序员在团队配合中,如果你的项目没有版本控制: 一、 代码管理混乱。 二、 解决代码冲突困难。 三、 在代码整合期间引发BUG。 四、 无法对代码的拥有者进行权限控制。 五、 项目不同版本发布困难。 ......


Git

简介

很多人都知道,Linus1991年创建了开源的Linux,从此,Linux系统不断发展,已经成为最大的服务器系统软件了。

Linus虽然创建了Linux,但Linux的壮大是靠全世界热心的志愿者参与的,这么多人在世界各地为Linux编写代码,那Linux的代码是如何管理的呢?

事实是,在2002年以前,世界各地的志愿者把源代码文件通过 diff 的方式发给Linus,然后由Linus本人通过手工方式合并代码!

你也许会想,为什么Linus不把Linux代码放到版本控制系统里呢?不是有CVSSVN这些免费的版本控制系统吗?因为Linus坚定地反对CVSSVN,这些集中式的版本控制系统不但速度慢,而且必须联网才能使用。有一些商用的版本控制系统,虽然比CVSSVN好用,但那是付费的,和Linux开源精神不符。

不过,到了2002年,Linux系统已经发展了十年了,代码库之大让Linus很难继续通过手工方式管理了,社区的弟兄们也对这种方式表达了强烈不满,于是Linus选择了一个商业的版本控制系统BitKeeperBitKeeper的东家BitMover公司出于人道主义精神,授权Linux社区免费使用这个版本控制系统。

安定团结的大好局面在2005年就被打破了,原因是Linux社区牛人聚集,不免沾染了一些梁山好汉的江湖习气。开发SambaAndrew试图破解BitKeeper的协议(这么干的其实也不只他一个),被BitMover公司发现了(监控工作做得不错!),于是BitMover公司怒了,要收回Linux社区的免费使用权。

Linus可以向BitMover公司道个歉,保证以后严格管教弟兄们,嗯,这是不可能的。实际情况是这样的:

Linus花了两周时间自己用C写了一个分布式版本控制系统,这就是Git!一个月之内,Linux系统的源码已经全部交由Git管理了!牛是怎么定义的呢?大家可以体会一下。

Git迅速成为最流行的分布式版本控制系统,尤其是2008年,GitHub网站上线了,它为开源项目免费提供Git存储,无数开源项目开始迁移至GitHub,包括jQueryPHPRuby等等。

历史就是这么偶然,如果不是当年BitMover公司威胁Linux社区,可能现在我们就没有免费而超级好用的Git了。

集中式vs分布式

Linus一直痛恨的 CVS 及 SVN 都是集中式的版本控制系统,而 Git 是分布式版本控制系统,集中式和分布式版本控制系统有什么区别呢?

集中式版本控制系统

先说集中式版本控制系统,版本库是集中存放在中央服务器的,而干活的时候,用的都是自己的电脑,所以要先从中央服务器取得最新的版本,然后开始干活,干完活了,再把自己的活推送给中央服务器。中央服务器就好比是一个图书馆,你要改一本书,必须先从图书馆借出来,然后回到家自己改,改完了,再放回图书馆。

缺点: 集中式版本控制系统最大的毛病就是必须联网才能工作,如果在局域网内还好,带宽够大,速度够快,可如果在互联网上,遇到网速慢的话,可能提交一个10M的文件就需要5分钟,这还不得把人给憋死啊。

分布式版本控制系统

分布式版本控制系统与集中式版本控制系统有何不同呢?首先,分布式版本控制系统根本没有“中央服务器”,每个人的电脑上都是一个完整的版本库,这样,你工作的时候,就不需要联网了,因为版本库就在你自己的电脑上。既然每个人电脑上都有一个完整的版本库,那多个人如何协作呢?比方说你在自己电脑上改了文件A,你的同事也在他的电脑上改了文件A,这时,你们俩之间只需把各自的修改推送给对方,就可以互相看到对方的修改了。

和集中式版本控制系统相比,分布式版本控制系统的安全性要高很多,因为每个人电脑里都有完整的版本库,某一个人的电脑坏掉了不要紧,随便从其他人那里复制一个就可以了。而集中式版本控制系统的中央服务器要是出了问题,所有人都没法干活了。

在实际使用分布式版本控制系统的时候,其实很少在两人之间的电脑上推送版本库的修改,因为可能你们俩不在一个局域网内,两台电脑互相访问不了,也可能今天你的同事病了,他的电脑压根没有开机。因此,分布式版本控制系统通常也有一台充当“中央服务器”的电脑,但这个服务器的作用仅仅是用来方便“交换”大家的修改,没有它大家也一样干活,只是交换修改不方便而已。

Git 的优势

当然,Git的优势不单是不必联网这么简单,后面我们还会看到Git极其强大的分支管理,把SVN等远远抛在了后面。

CVS作为最早的开源而且免费的集中式版本控制系统,直到现在还有不少人在用。由于CVS自身设计的问题,会造成提交文件不完整,版本库莫名其妙损坏的情况。同样是开源而且免费的SVN修正了CVS的一些稳定性问题,是目前用得最多的集中式版本库控制系统。

除了免费的外,还有收费的集中式版本控制系统,比如IBMClearCase(以前是Rational公司的,被IBM收购了),特点是安装比Windows还大,运行比蜗牛还慢,能用ClearCase的一般是世界500强,他们有个共同的特点是财大气粗,或者人傻钱多。

微软自己也有一个集中式版本控制系统叫VSS,集成在Visual Studio中。由于其反人类的设计,连微软自己都不好意思用了。

分布式版本控制系统除了Git以及促使Git诞生的BitKeeper外,还有类似GitMercurialBazaar等。这些分布式版本控制系统各有特点,但最快、最简单也最流行的依然是Git!

安装 Git

最早Git是在Linux上开发的,很长一段时间内,Git也只能在Linux和Unix系统上跑。不过,慢慢地有人把它移植到了Windows上。现在,Git可以在Linux、Unix、Mac和Windows这几大平台上正常运行了。

要使用Git,第一步当然是安装Git了。

https://git-for-windows.github.io下载(网速慢的同学请移步国内镜像),然后按默认选项安装即可。 安装完成后,在开始菜单里找到“Git”->“Git Bash”,蹦出一个类似命令行窗口的东西,就说明Git安装成功!

下载完成后,打开进行安装(按照下图进行配置)

接下来就只需要静静的等待安装完成了,完成以后在桌面或者任意文件夹的空白位置右键,出现下图所示的两个菜单栏即表示安装成功

初始化设置

因为Git是分布式版本控制系统,所以,每个机器都必须自报家门:你的名字Email地址。你也许会担心,如果有人故意冒充别人怎么办?这个不必担心,首先我们相信大家都是善良无知的群众,其次,真的有冒充的也是有办法可查的。

注意git config命令的--global参数,用了这个参数,表示你这台机器上所有的Git仓库都会使用这个配置,当然也可以对某个仓库指定不同的用户名和Email地址。

在命令行输入:

git config --global user.name "Your Name"
git config --global user.email "email@example.com"

初始化仓库

在空的目录下,通过git init命令把这个目录变成Git可以管理的仓库

运行成功后: 可以发现当前目录下多了一个.git的目录,这个目录是Git来跟踪管理版本库的,没事千万不要手动修改这个目录里面的文件,不然改乱了,就把Git仓库给破坏了。

添加文件到仓库

步骤一:创建一个普通文本文件

步骤二:使用git命令将文本添加到版本库中

在添加之前先做一个标记操作。真实情况:先将文件添加到缓存区, 然后再添加到版本库

命令解析:

第一步:用命令git add告诉Git,把文件交给 Git 进行管理:

git add readme.txt

执行上面的命令,没有任何显示,这就对了,Unix的哲学是“没有消息就是好消息”,说明添加成功。

第二步:用命令git commit告诉Git,把文件提交到本地仓库:

git commit -m "wrote a readme file"

简单解释一下git commit命令,-m后面输入的是本次提交的说明,可以输入任意内容,当然最好是有意义的,这样你就能从历史记录里方便地找到改动记录。 git commit命令执行成功后会告诉你,1个文件被改动(我们新添加的readme.txt文件),插入了两行内容(readme.txt有两行内容)。

为什么Git添加文件需要add,commit一共两步呢?因为commit可以一次提交很多文件,所以你可以多次add不同的文件,比如:

git add file1.txt
git add file2.txt file3.txt
git add .   当前文件夹下所有文件
git commit -m "add 3 files."

注意:在执行 commit 之前,都先执行一下 add 操作,避免有文件被漏掉了

工作区和暂存区

在git中进行 crud 操作时都需要执行 git add 文件这个操作,底层操作将操作文件添加一个叫缓存区区域中缓存,当操作完毕之后,使用 git commit 操作,进行统一提交,将编辑文件统一同步版本中

查看版本库状态

问题:如何查看项目目前的状态?我在电脑前写了一段时间代码,用Git管理,中途上厕所,然后又去吃了个苹果,继续回来工作,不记得之前用Git干了些什么了?

git status # 查看当前git版本库的状态(查看缓存区中的文件内容)

提交日志

实际工作中,我们脑子里怎么可能记得一个几千行的文件每次都改了什么内容,不然要版本控制系统干什么。版本控制系统肯定有某个命令可以告诉我们历史记录,在Git中,我们用git log命令查看:

git log

git log 命令显示从最近到最远的提交日志,如果嫌输出信息太多,看得眼花缭乱的,可以试试加上--pretty=oneline参数:

git log --pretty=oneline

为什么 commit id 要使用这么长一串字符而不是数字?

当两个人同时在一个代码上工作时候,分别往各自的本地的版本库提交时,相同的提交号对应着不同的修改,如果使用1,2,3这样的数字不能保证唯一性,所以Git使用SHA-1算法产生唯一标识符,保证全球唯一

比如程序员甲和乙负责共同开发一个聊天软件,使用Git来版本控制。 Git是分布式版本控制,每个人都有一个版本库。如果Git版本控制用1,2,3这样的数字来生成版本号,那么程序员甲和乙代码合并的时候就会出现问题。版本1到底是谁的?

SVN 是集中式的版本控制,只有一个版本库,所以版本号可以从1,2,3开始。Git是分布式版本控制,每个人都有一个版本库,所以不能从1,2,3开始。

<!--看不懂可以跳过去,以后用多了,就明白了-->

查看差异

如果一个文件知道被人修改了,但如果能看看具体修改了什么内容,自然是更好的 比如你休假两周从国外回来,第一天上班时,已经记不清上次怎么修改的readme.txt,所以,需要用git diff这个命令看看:

git diff # 查看不同版本之间的文件差异

版本回退

我们不断修改文件,不断的往版本库中提交文件。就好比玩RPG游戏时,每通过一关就会自动把游戏状态存盘,如果某一关没过去,你还可以选择读取前一关的状态。有些时候,在打Boss之前,你会手动存盘,以便万一打Boss失败了,可以从最近的地方重新开始。Git也是一样,每当你觉得文件修改到一定程度的时候,就可以“保存一个快照”,这个快照在Git中被称为 commit。一旦你把文件改乱了,或者误删了文件,还可以从最近的一个commit 恢复,然后继续工作,而不是把几个月的工作成果全部丢失。

如果想回到上一个版本,应该怎么做呢? 首先,Git必须知道当前版本是哪个版本,在Git中,用HEAD表示当前版本,上一个版本就是HEAD^,上上一个版本就是HEAD^^,当然往上100个版本写100个^比较容易数不过来,所以写成HEAD~100

现在,我们要把当前版本回退到上一个版本,就可以使用git reset命令:

git reset --hard HEAD^

回到指定版本

git reset --hard <commit id>

管理修改

操作方式1: 第一次修改 -> git add -> 第二次修改 -> git commit

操作方式2:推荐使用 第一次修改 -> git add -> 第二次修改 -> git add -> git commit

PS:建议在每次 commit 之前先检查是否有文件没有被 add

撤销修改

git checkout -- filename可以丢弃工作区的修改:-- 后面是一个空格

命令 git checkout -- readme.txt 意思就是,把 readme.txt 文件在工作区的修改全部撤销,这里有两种情况: 一:readme.txt 自修改后还没有被放到暂存区(git add),现在,撤销修改就回到和版本库一模一样的状态; 二:readme.txt 已经添加到暂存区后,又作了修改,现在,撤销修改就回到添加到暂存区后的状态。

总之,就是让这个文件回到最近一次 git commitgit add 时的状态。

注意: git checkout -- file 命令中的 -- 很重要,没有 -- ,就变成了“切换到另一个分支”的命令,我们在后面的分支管理中会再次遇到 git checkout 命令

删除文件

一般情况下,你通常直接在文件管理器中把没用的文件删了,或者用rm命令删了:

git rm test.txt

这个时候,Git知道你删除了文件,因此,工作区和版本库就不一致了,git status命令会立刻告诉你哪些文件被删除了:

删除完成后需要 commit

如果删除了想恢复,可以使用 reset 版本恢复

步骤1:本地删除没用的文件(查看状态)

步骤2:先 add 以下(查看状态与步骤1进行比较)

步骤3:提交删除文件

分支管理

Git 拥有强大的分支管理系统,且推荐在项目开发过程中大量的使用分支来解决各种项目中的问题

分支相关命令:

查看分支:git branch

创建分支:git branch <name>

切换分支:git checkout <name>

创建 + 切换分支:git checkout -b <name>

将某分支合并到当前分支:git merge <name>

删除分支:git branch -d <name>

git 文件冲突: 分支1中有个文件跟其他分支文件一样,如果同时发生修改了,进行合并,就出现文件冲突问题。

远程仓库

到目前为止,我们已经掌握了如何在Git仓库里对一个文件进行时光穿梭,你再也不用担心文件备份或者丢失的问题了。

可是有用过集中式版本控制系统SVN的童鞋会站出来说,这些功能在SVN里早就有了,没看出Git有什么特别的地方。

Git的功能之一:远程仓库.

Git是分布式版本控制系统,同一个Git仓库,可以分布到不同的机器上。怎么分布呢?最早,肯定只有一台机器有一个原始版本库,此后,别的机器可以“克隆”这个原始版本库,而且每台机器的版本库其实都是一样的,并没有主次之分。

找一台电脑充当服务器的角色,每天24小时开机,其他每个人都从这个“服务器”仓库克隆一份到自己的电脑上,并且各自把各自的提交推送到服务器仓库里,也从服务器仓库中拉取别人的提交。

可以自己搭建一台运行Git的服务器,不过现阶段,为了学Git先搭个服务器绝对是小题大作。好在这个世界上有个叫 GitHub 的神奇的网站,从名字就可以看出,这个网站就是提供Git仓库托管服务的,所以,只要注册一个GitHub 账号,就可以免费获得Git远程仓库。

一般我们有可能接触到比较多的几种 Git 远程仓库平台:

GitHub:国外/免费创建公有仓库/私有仓库需要收费,在国际上来说 GitHub 是最活跃的开源社区

GitLab:国外/免费创建公有仓库/私有仓库需要收费,不过 GitLab 提供了开源版本的企业版本,企业可以部署一套 GitLab 的私服在自己的服务器中

Gitee:国内/免费创建公有|私有仓库/私有仓库限制成员不得超过5人

Gitee(码云)的使用

GitHub 虽然好,在国外的使用率也很高,但毕竟是国外的。在网速上效率还是比较低,经常会出现访问页面变得很慢,下载项目很慢的情况,于是国内慢慢发展起了一个类似 GitHubGit 开源平台 Gitee。我们之后的开发都使用 Gitee,一个是他是国内公司 CSDN 的产品,从访问效率上来讲要高很多,另一个是他的中文界面相对于 GitHub 来说对英文不好的同学也相对友好一些。但当你会用 Gitee 之后再想去用 GitHub,也基本上不会有太大区别。

要使用 Gitee,首先还是需要创建一个账户,下图是创建完成后登录进个人主页的页面

创建项目

点击右上角头像左边的 + 号,再点击新建仓库即可创建一个仓库

到此,仓库就创建成功啦。一般来说,在刚进公司的时候我们是不会接触创建仓库这种事情的,都是由项目经理或项目组长来进行创建,并且完成基础平台即可,所以我们主要需要知道怎么将项目从 git 仓库中下载到本地,并将其导入到开发工具中使用起来即可

项目初始化(新项目上传)

有的时候,可能我们有一个项目在本地已经创建好了,但是远程还没有仓库,此时我们即需要将本地仓库初始化为 git 仓库,并将其提交到远程仓库中去

首先进入到你需要进行初始化的项目根目录,并按照如下步骤进行操作:

步骤1:设置名字与邮箱

git config --global user.name "码云上的名称"
git config --global user.email "码云上面注册邮箱"

步骤2:进入到需要传送到远程的仓库目录中,初始化本地仓库

git init

步骤3:设置提交忽略文件 配置忽略提交文件 .gitignore

这一步的意义是为了避免项目中有些本地环境特有的文件被传入到远程仓库,这些文件每个人的电脑都有可能不一致,如果提交到远程仓库,可能会导致出现频繁冲突的问题

步骤4:在本地提交代码, 初始化项目

git  add .
git  commit -m “项目初始化”

步骤5:配置远程仓库路径(注意是自己建仓库路径)

git remote add origin https://gitee.com/leoen/crm.git

步骤6:将本地仓库master分支代码推送到远程仓库

git push -u origin master

完成以上步骤,就基本完成将本地仓库的项目初始化到远程仓库了,访问远程仓库查看

通过项目页面右边的“克隆”按钮,可以得到项目的 url 链接

添加团队成员

创建好项目以后,就可以添加团队成员了,公司的项目通常都是私有仓库,大部分公司会利用类似 Gitlab 的开源平台搭建公司专属的 Git 远程仓库,其配置也基本都差不多,即进入项目管理/设置页面,找到成员管理并邀请成员,为其设置权限等等操作即可

进入管理页面后,找到左侧菜单栏的项目成员管理,点击所有进入所有成员管理页面

开发中使用 Git
在 Idea 中克隆远程仓库

通常来说,进入公司以后会发给你一个远程 Git 仓库的账号密码,以及仓库地址,当你得到仓库地址后,即可在开发工具当中将该仓库下载到本地

打开 Idea,在初始化界面克隆远程仓库

以上步骤就可以将项目从远程导入到 Idea 了

在成功导入项目以后,如果 idea 右上角弹出一个提示框,里面有 Add root 的字眼,直接点击即可,代表让 idea 识别这是一个 git 项目。

PS:需要注意的是,在微服务开发或者按模块开发的情况下,因为一个仓库下可能包含多个项目文件,因此建议使用命令 git clone 先将远程仓库克隆到本地,然后再将仓库中的项目一个个导入到 idea

分支切换与合并

在 idea 中,分支的相关操作都在 idea 项目界面的右下角最角落的位置,你可以通过这边去新建本地分支/切换本地或远程分支,创建/删除/合并分支等等操作

在公司里面,分支管理都会存在不同的规范,比如有的公司会按照标准的 dev -> test -> master 这样的分支流程去管理,也有按照不同的版本 dev1.2.0 dev2.1.0 之类的版本划分方式,甚至还会有每个开发人员自己创建一个自己的分支进行开发,最后合并到测试分支的情况。

在学习中,我们暂时先采用创建自己分支的形式,对代码进行管理

分支创建成功后,会自动将之前(master)所在分支的文件同步到新创建的分支上,此时新创建的分支与原来的分支文件内容是一致的,你可以直接从当前分支切换到某一个分支,也可以去选择将哪一个分支合并到当前分支

文件新增编辑和删除

在我们开发过程当中,经常会涉及到进行新增/编辑或删除文件的操作。在 idea 中,使用不同的颜色来标识文件的不同状态。

通常情况下,有这样几种颜色:

棕色:**色代表未被 Git 管理(未添加到暂存区)

绿色:代表新增的文件且已经被加入到暂存区了

蓝色:代表该文件已经提交到远程且该文件被编辑过了

黑色:代表该文件在当前版本与远程是一致的

灰色:表示该文件之前被提交到仓库过(不管是远程还是本地),但是他已经被删除了

红色:表示该文件的内容出现了冲突

创建新文件时,idea 会弹出一个提示框,确认是否要添加到 git 暂存区

如果此时点击 No 的话,该文件就不会被添加到暂存区,且颜色为棕红色

如果之前点了 No,但是后面又想把他添加到 Git,那么可以右键 -> Git -> Add 进行添加

添加完成后,文件会由棕色变为绿色,此时对一个远程的文件进行了更新,那么他就会从黑色变为蓝色

当你开发完成以后,可以点击工具栏中 ↑ 箭头进行提交操作

你所有的这些新增/编辑/删除操作的文件,只要之前是被 git 管理的,都会被一一记录下来,当你点击提交的时候,即可预览到你所有操作过的文件

在提交前,你需要填写提交信息,注意这里的提交信息一定要表达清楚你这一个提交做了什么事情,并且需要用最精简的语言表达出来

此处我们点击 Commit And Push,即先进行 commit 操作,提交完成后再进行 push,会出现如下界面

点击 push 即可将本次所有的提交推送到远程,提交成功后会在左下角 version control 处弹出如下提示

当你提交成功后,返回远程页面查看,会发现分支数量增加了一个,且分支选择处也可以看到我们本地新增的分支了,这里是因为我们在本地新增了分支,而直接对该分支的内容提交,则表示将该分支以及其中的所有操作提交到远程的这个分支去,若远程没有该分支,git 会自动为你创建一个

分支合并

由于我们上面的操作都是在自己分支或dev分支当面进行的,那么此时的内容并不在master上面,此时我们需要测试完成确定没问题后将自己分支合并到master分支上面去,操作流程如下

从当前分支切换到 master 分支 -> 对 master 分支进行更新,确保与远程 master 保持一致 -> 选中想要合并的分支 -> 点击合并按钮将其合并过来

合并成功后 master 分支上面就拥有开发分支的文件了,但注意,此时的变动任然是只存在本地的,也就是说此时跟远程上的 master 没有任何关系,任然需要在 master 将合并的内容重新 push 到远程的 master,这时合并才算完成

解决冲突

在开发当中,不可避免的会遇到代码冲突的问题,比如张三和李四同时修改 User.java 文件,李四先修改 User.java 并且已经提交,张三不知道李四修改了 User.java 文件,此时没有更新远程的代码,然后直接对 User.java 进行修改并提交,这时候就会出现冲突的问题了

模拟下该情况,首先通过远程编辑以下 User.java 文件,为其新增一个 name 字段

然后回到 idea,编辑 User.java 文件,新增 age 字段

新增完字段后,直接提交变动,并进行 push

此时 push 肯定会失败,因为远程与本地不一致,会出现冲突,弹出以下对话框,我们可以点击 Merge

按钮对冲突文件进行合并

此处为 idea 的冲突文件列表,一个 push/pull 操作可能会出现多个文件发生冲突,每一个文件都会出现再这个列表之中,选择你要合并的冲突文件,并点击 Merge 按钮来合并该文件的冲突

以下是 idea 的冲突解决界面,分为三块显示,最左侧为本地文件(你开发的文件),最右侧为远程更新到的文件(即你同事提交的文件),中间为你想要的结果,冲突解决完成以后,中间的文件内容会是最终的文件内容

解决完冲突以后,直接进行 push 即可把此次合并以及之前的 commit 提交到远程仓库

进行 push 的时候会发现多了一个 Merge 开头的 commit,这就是我们刚刚解决完冲突之后自动提交的内容,此时点击 push 按钮即可将这两个 commit 都提交到远程

可能出现冲突的几个操作:

pull 操作:更新的时候,可能出现本地代码与更新下来的代码不一致的情况,发生冲突

push 操作:与更新操作类似,push 上去的代码原型(修改前的代码)与远程的代码不一致,发生冲突

分支合并:例如 A 分支合并 B 分支的时候,B 分支的代码原型(修改前的代码)与 A 分支不一致,发生冲突

到此冲突就解决完成了,理一下冲突出现的原因

由于本地文件和远程文件不一致导致的冲突出现,这个不一致又可能会分为这几种情况:

  1. 修改本地文件前,远程已经与本地不一致了

  2. 修改本地文件时,文件还是一致的,修改的中途或修改后远程被修改了

对于第一种情况还是比较好处理的,修改前先 pull 一下,只要保证修改前本地与远程一致即可,但第二种情况就没办法了,这种情况是避免不了的,公司里面之所以要定义 git 管理规范,就是为了避免这样的情况出现,所以尽量做到自己要修改其他人也可能修改的文件之前,先确认一下有没有人会改,没有的话自己再去改,只要把两个人的修改操作错开,就可以避免冲突问题了,当然这只是理想情况,因此解决冲突的能力还是一定要会的

总结:完成一个小功能,确定没有问题就提交,有事没事更新一下可以最大程度的降低冲突的可能,关键还是要练好解决冲突的能力,即使冲突出现了,也要能够轻松解决

团队开发注意事项
  1. 组员每次开发,都先 push 到自己的远程分支

  2. 每次对 master 分支做合并或推送之前,原地备份代码

  3. 确保自己分支的代码与 master 分支都没有错误以后,将本地 master 推送到远程

  4. 开发前,先切换到 master 分支,更新代码,确保是最新版本,如果有更新下来内容,同样先对整个项目进行备份,再切换到自己的分支,然后将 master 合并到自己的分支上

  5. 除了将代码提交到自己的分支以外,都必须再将自己的代码合并到master

  6. 再次强调,每次合并或推送前,都先对项目进行备份,避免操作不熟练导致出错后代码丢失

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值