git 是一种版本控制系统,是一个命令,是一种工具。Github与Gitee是一类,属于代码托管服务,在云端,两者的区别是Github是国外的,Gitee是国内的。通过git将代码上传到 gitee 和 github 中。现在的项目多人协同开发,首选git,开发工具idea用的比较多,所以,如何在idea上操作git成为了一个需要学会的小技能。本文主要介绍 IDEA开发工具与 git 的集成实战,帮助有需要的兄弟姐妹少走弯路,更多的专注于业务。
1、Git、Gitee、GitHub介绍
1.1 Git
Git是一个免费的、开源的分布式版本控制系统(在Git中并不存在主库这样的概念,每一份复制出的库都可以独立使用,任何两个库之间的不一致之处都可以进行合并),快速高效的处理各种类型的项目
- 特点:占用空间小,性能快,含有本地分支、分段区、多个工作流等特性
- gitlab 类似 github,一般用于在企业内搭建git私服,要自己搭环境。
- 某些视源代码如生命的商业公司来说,既不想公开源代码,又舍不得给GitHub交保护费,那就只能自己搭建一台Git服务器作为私有仓库使用。
1.2 Gitee(码云)
Gitee是(开源中国推出的)基于Git的代码托管服务(还集成了代码质量检测、项目演示等功能),主要面向国人。
- gitee 即码云,是 oschina 免费给企业用的,不用自己搭建环境。
- 版本:社区版、企业版和高校版
- git-ce 是社区版,gitlab-ee是企业版,收费版。
- 归属:中国
1.3 GitHub
GitHub是一个面向开源以及私有项目的托管平台,只支持Git作为唯一的版本库格式进行托管,面向全球,内容比gitee丰富,因为是全球,所以有时候有些东西在中国访问不到。
- 归属:微软公司
- GitHub如果使用私有仓库,是需要付费的
开源含义,也称开源代码。开源是要用户利用源代码在其基础上修改学习的。开源系统本身有版权。
开源的特点:免费,开放(任何人都可以得到软件的源代码,在版权的范围内进行修改和发布)
1.4 Gitee和GitHub的区别
1.归属以及语言:
- GitHub归属为微软,语言为英文。
- Gitee归属为中国,语言为中文。
2.用户以及库
- GitHub用户基数多,知名的库多。。
- Gitee用户大多数国人,优秀的库相较于GitHub少。
3.稳定性:
- GitHub进行访问时有时会有不稳定的情况。
- Gitee进行访问时稳定性很好。
1.5 Git的几个概念
Git和其他版本控制系统如SVN的一个不同之处就是有暂存区的概念。
工作区(Working Directory)
就是你在电脑里能看到的目录,比如我的learngit文件夹就是一个工作区。
版本库(Repository)
工作区有一个隐藏目录 .git
,这个不算工作区,而是Git的版本库。
暂存区(stage或者叫index)
Git的版本库里存了很多东西,其中最重要的就是称为stage(或者叫index)的暂存区,还有Git为我们自动创建的第一个分支master,以及指向master的一个指针叫HEAD。
我们把文件往Git版本库里添加的时候,是分两步执行的:
- 第一步是用git add把文件添加进去,实际上就是把文件修改添加到暂存区;
- 第二步是用git commit提交更改,实际上就是把暂存区的所有内容提交到当前分支。
因为我们创建Git版本库时,Git自动为我们创建了唯一一个master分支,所以,现在,git commit就是往master分支上提交更改。
你可以简单理解为,需要提交的文件修改通通放到暂存区,然后,一次性提交暂存区的所有修改。
一旦提交后,如果你又没有对工作区做任何修改,那么工作区就是“干净”的:
$ git status
On branch master
nothing to commit, working tree clean
2、Git安装
2.1 Git的下载
Git.exe 分32和64位,可以在git官网下载:https://git-scm.com/downloads
- git下载地址:支持Linux/Unix、macOS、Windows
- windows的下载链接:https://git-scm.com/download/win
2.2 Git的安装
双击安装包,开始安装,可以单击“更改”修改目标文件夹
下一步,完成安装,安装成功后,关闭安装界面。
安装成功后,使用快捷键win+r, cmd, 打开控制台,然后输入git命令,看到如图所示的画面即表示安装成功了。
3、IDEA配置
idea只是做了可视化界面,所有操作其实内部还是会委托给git.exe去执行。所以,如果你是高手,直接用命令行操作git会更加畅快。
3.1 IDEA配置git环境
默认情况下,IDEA是不自带git运行程序的,所以需要定位到 File | Settings | Version Control | Git
配置页面,找到 >Path to Git executable
配置项,点击右侧的 ...
选择指定git安装目录的 git.exe
文件,选好后,单击【Apply】。
可以点击右侧的 Test
按钮测试git配置是否正确,若显示git版本号,则配置无误。
3.2 注册Git账号及仓库创建
1)注册账号
注册一个git账号,登录gitee或GitHub创建远程git仓库,并复制地址。
- gitee注册地址:https://gitee.com/signup
2)创建仓库
单击右上角“+”新建仓库,在下图中,仓库名称和路径可以自定义修改。填好信息后,单击【创建】
创建成功后如下图所示,可以复制好地址,后面会用到。
3)环境配置
在桌面右键选择Git bash进行环境配置
分别输入下列命令后回车:
git config --global user.name "username" --username是自己账号名
git config --global user.email username@email.com
使用命令查看上一步结果
git config --global –list
4)生成ssh
输入命令:ssh-keygen -t rsa
回车,提示输入保存key路径,不输入内容,直接回车,系统会自动在 C:\Users\kongzi\.ssh
目录下创建 id_rsa.pub
文件。再次回车输入密码和确认密码。
- 该步骤也可以不用配置
- ssh指secure shell(一种安全的网络协议),git使用这种协议进行远程加密登录。
- ssh登录安全性由非对称加密保证,产生密钥时,一次产生两个密钥,一个公钥,一个私钥,在git中一般分别命名为id_rsa.pub, id_rsa
- ssh方式单独使用非对称的秘钥进行认证和加密传输,和账号密码分离开来,不需要账号也可以访问repo。
- git基于多种传输协议,其中最常用的就是https和ssh。都是为了数据传输安全,设置ssh密钥的目的是为了节省输入用户名密码的过程,同时保证传输安全。并不是必须设置。
建好后,打开 C:\Users\kongzi\.ssh\id_rsa.pub
文件,将其内容拷贝到云端。
3.3 IDEA关联Git项目
3.3.1 IDEA下载Git项目
可以通过2种方式下载Git项目。
1)通过 File>New>Project from Version Control>Git
菜单打开关联窗口。
2)通过 VCS>Checkout from Version Control>Git
菜单打开关联窗口。
在克隆资源窗口输入上一步赋值的仓库地址 https://gitee.com/kongzi/demo.git
,选择本地保存目录,点击 Clone
按钮。这时候会弹出用户名和密码输入框,输入后确定即可。资源下载完成后会在IDEA中显示出来。
3.3.2 IDEA关联Git项目
1)将该项目设置为git资源库
如果在本地已经存在的项目,需要关联到Git仓库,在idea的 VCS
菜单下选择 import into Version Control
-> Create Git Repository...
。
在弹窗中选中需要设置的项目(即当前项目),点击 OK
设置为git资源库。
- 本方式处理后的项目,仔细观察你会发现项目内的文件名是红色的,表示文件还没有添加git索引,需要通过后续4.2的步骤(
Git>Add
)添加git索引。而上一步下载的Git项目是默认加入到了本地库的。
2)设置远程git地址
登录gitee或GitHub创建远程git仓库,并复制地址,然后在idea中设置。在idea的 VCS
菜单下选择 Git
-> Remotes
, 选择已有的地址或添加新的远程地址。
4、编写代码并推送至仓库
4.1 编写代码
1)新建maven模块
在demo项目上右键新建一个maven模块。
2)新建包和类
创建包和类的时候会弹出 Add File to Git
的提示框,点击 Add
按钮表示将,该文件加入到git索引中(git会跟踪状态),此时文件的颜色显示为绿色。如果点击 Cancel
按钮该文件不会加入到git索引中,文件的颜色显示为红色。
如果文件名为绿色的表示该文件加入到git索引中(git会跟踪状态),如果文件名不是绿色的(红色)表示没有加入到git索引中。
4.2 提交代码至本地仓库
1)add将数据暂存
在项目demo上右键,选择 Git>Add
,这时git会将demo下所有未加git索引的文件都加入到git索引中。
- 注意:仔细观察你会发现文件的字体颜色变成绿色了,表示文件添加到暂存区了。
2)commit提交数据到本地仓库
在项目demo上右键,选择 Git>Commit Directory...
,这时会弹出 Commit Changes
窗口,在 Commit Message
写入注释 test
, 然后点击 Commit
按钮,git会将demo下所有变更的文件提交到本地仓库。
- 对于IDEA的项目管理文件,比如*.imp,可以通过ignore文件进行忽略,不进行版本控制。
- 这时候所有文件的颜色为白色
4.3 push推送代码至远程仓库
在项目demo上右键,选择 Git->Repository->Push
之后弹出 Push Commits
窗口。
- 如果项目不是第一次推送,需要先
Git->Repository->Pull
,确保本地仓库是是最新的。
在 Push Commits
窗口,可以选择需要提交到的分支,然后点击 Push
按钮,git会将demo本地仓库的变更文件推送至远程仓库。如果是第一次配置推送需要输入gitee的用户名和密码。
如果第一次提交项目的话,这里是没有远程地址。点击蓝色的字,定义远程地址。
4.4 提交代码至本地仓库同时推送至远程仓库
在项目demo上右键,选择 Git->Commit Directory
之后弹出 Commit Changes
窗口,在 Commit Message
输入 test
, 然后点击 Commit And Push
按钮。该步骤为前2个步骤的合并操作。
变更的代码首先会提交到本地仓库,然后会弹出一个 Push Commits
窗口,点击 Push
将代码推送至远程仓库。
4.5 到gitee网站验证
到gitee网站上查看,可以看到代码已提交。
4.6 从服务器拉取代码
1)pull方式1
一般的提交代码之前,先将服务器代码进行拉取同步到本地,以免出现冲突,之后才会进行代码提交。在项目demo上右键,选择 Git->Repository->Pull
之后弹出 Pull Changes
窗口,选择远程仓库及需要更新的分支,点击 Pull
按钮拉取代码。
2)pull方式2
在idea的 VCS
菜单下选择 Git
-> Pull
, 选择要更新远程地址和对应分支。
- 选中分支,进行pull,非常重要,否则push的时候找不到对应分支
5、git实战
首先假设我们的开发流程是这样的:
1、开发人员a从远端git仓库的master分支克隆一份到本地,本地的分支名称为branch-a,随后开发a提交修改到本地;同样的开发人员b从远端git仓库克隆一份到本地,本地的分支名称为branch-b,随后开发b提交修改到本地;
2、每次推送到远程分支的时候,最好先拉取远端master分支,将其最新的更改合并到本地分支,然后再推送本地分支到自己的远端分支。这样的操作是为了减少有代码冲突时不能合并分支的情况。冲突在拉取master合并到本地分支的时候去解决。所以开发a在将自己的代码推送到远端分支的时候,先拉取master分支,由于这个时候没有人将自己的分支合并到master,所以不会有任何冲突和问题。现在开发a放心的把自己的本地分支branch-a推送到远端分支branch-a。
3、开发a发起了合并代码的请求:将远端分支branch-a合并到master分支。
4、开发组长收到合并请求,代码审核通过之后,并通过对比没有发现冲突和问题,于是将远端的branch-a合并到了master分支。
5、这个时候开发b也想要推送修改到远端分支,所以他先拉取master分支,然后发现代码冲突了,因为开发a和开发b都对同一个文件的同一行代码进行了不同的修改。开发b解决了冲突,将修改推送到远端分支branch-b,并发起合并请求。
6、开发组长审核之后,合并远端分支branch-b到master分支。
7、继续各自修改代码,提交,拉取,推送,发起合并请求。
接下来我们按照假设的流程逐步演示。
5.1 在gitee上建立仓库
这里用我们之前步骤创建的demo仓库。需要注意的是,该仓库需要首先放入一些文件,然后才会有master分支。这样其余人员才可以克隆并操作。
5.2 开发a克隆仓库,使用分支branch-a
通过 VCS>Checkout from Version Control>Git
克隆仓库(检出项目到本地),下拉下来的本地分支名称默认是 master
,通过 Rename
将其修改为branch-a
。(idea右下角),这样做的目的是,便于本地分支切换,否则分不清哪个分支对应远端的分支了。
修改完成后,可以看到本地分支branch-a
,对应的远端分支为 origin/master
分支。
5.3 开发b克隆仓库,使用分支branch-b
为了演示方便,我在本地新建分支 branch-b
。(idea右下角)。开发a在分支branch-a上开发,开发b在分支branch-b开发,互相不影响。
5.4 开发a在branch-a分支进行开发
5.4.1 切换到branch-a,开发a进行开发
1)切换分支
点击 branch-a > checkout
。这个操作的意思是:从本地的 .git
文件中检出branch-a
分支,工作目录的文件就会变成 branch-a
的文件。然后开发a在这个基础上进行开发。
2)代码开发
在branch-a
中我们添加文件A.java
,编写内容。
3)代码提交到本地仓库
通过 add
和 commit
将代码提交到本地仓库。
4)拉取远程代码到本地仓库
在将代码推送到远端分支之前,先拉取远端 master
分支的代码,在拉取的时候,会自动合并到本地当前分支上去。
上图选中的区域说明,没有什么需要更改和冲突的文件,可以放心推送。
5)推送代码到远程仓库
push代码到远程仓库。
上图显示本地分支是 branch-a
, 推送到远端的分支为master
,而我们想要将数据推送至远端的 branch-a
,这时候将 master
改为 branch-a
, 点击修改分支名称,推送。
5.4.2 开发a发起合并请求
现在开发a推送代码到了远端分支 branch-a
。开发a需要发起合并请求:
- 在仓库中找到分支,可以看到有
master
分支、branch-a
分支、branch-b
分支,我们需要将branch-a
分支合并到主分支master
: - 点击
Pull Requests
,然后新建Pull Request
。 - 源分支选择
branch-a
分支,目标分支选择master
分支。填写合并请求的标题和内容,点击创建 Pull Request
按钮提交合并请求。
5.4.3 开发组长进行代码审查和合并
在合并请求详情页面,可以看到审核通过按钮,点击审核通过按钮。
点击 审核通过
按钮后发现并没有出现合并按钮,原因是 测试通过
按钮还没有点击。
测试通过
点击后,页面出现 合并
按钮。
- 这里没有冲突,如果有冲突,需先解决冲突。
点击 合并
按钮右侧的下拉箭头,选择 合并分支
,点击 接受 Pull Request
,分支成功合并。
5.5 开发b在branch-b分支进行开发
5.5.1 切换到branch-b,开发b进行开发
现在开发b也是一样的进行文件添加,不过在a.txt中第一行添加的是:心情很丧
1)切换分支
点击 branch-b > checkout
。这个操作的意思是:从本地的 .git
文件中检出branch-b
分支,工作目录的文件就会变成 branch-b
的文件。然后开发b在这个基础上进行开发。
- 注意观察,现在的代码是
branch-b
分支,没有文件A.java
。
2)代码开发
在branch-b
中我们添加文件A.java
,编写内容,要注意内容要和 branch-a
分支中的有区别。
3)代码提交到本地仓库
通过 add
和 commit
将代码提交到本地仓库。
4)拉取远程代码到本地仓库
在将代码推送到远端分支之前,先拉取远端 master
分支的代码,发现了冲突。
根据错误提示,需要进行分支合并 merge
处理。
5)将master
分支的代码 merge
到当前分支branch-b
IDEA右下角点击 Git:branch-b
,弹出菜单中选择 origin/master -> Merge into Current
,合并master
分支的代码到当前分支branch-b
。
在弹出的 Git Merge Problem
窗口中点击 Smart Merge
按钮。
在弹出的 Conflicts
冲突窗口中点击 Merge...
按钮手动合并冲突。
Accept Yours
: 按钮代表以本地自己的代码为准解决冲突Accept Theirs
按钮代表以远程代码(即更新下来的文件)为准解决冲突merge
: 按钮代表手动合并
在 Merge 页面可以看到冲突的内容:
将需要的内容点击:">>"即可以合并内容到result中,不需要的内容点击“x”即可,最终将所有的“x >>” 和 “<< x”符号处理完,合并完成后点击apply即可。
处理完冲突,点击apply。也可以去文件夹下手动解决冲突。我解决完情况如下图。
6)提交并推送代码到远端分支,合并分支
将解决完冲突的文件提交到本地git。然后推送到远端分支branch-b。最后合并分支。由于步骤类似,我就不详细说明了
5.6 开发a、开发b拉取远端master代码
开发a、开发b现在拉取远端master,看到的是一样的内容了。可以继续后续的开发。
6、处理冲突
在上述实战过程中,我们发现了冲突并进行了处理。接下来详细了解下冲突是什么,它是怎么产生的,以及处理冲突的方式。
6.1 冲突的概念
冲突是指当你在提交或者更新代码时被合并的文件与当前文件不一致。冲突是发生在同一个文件上的。
6.2 冲突的生产场景
常见冲突的生产场景如下:
- 更新代码
- 提交代码
- 多个分支代码合并到一个分支时
- 多个分支向同一个远端分支推送代码时
git的合并中产生冲突的具体情况:
- <1>两个开发者(分支中)修改了同一个文件(不管什么地方)
- <2>两个开发者(分支中)修改了同一个文件的名称
注意:两个分支中分别修改了不同文件中的部分,不会产生冲突,可以直接将两部分合并。
总结:上面各种情况的本质都是,当前文件与合并文件不一致,因此不论哪种情况其解决冲突的方法是一样的。
6.3 idea中解决冲突
冲突的产生
- 假如 01号程序员先上传文件conflict.txt,并继续在conflict.txt上写代码;
- 02号程序员更新项目代码,并在conflict.txt上写代码,写完后,在提交到远程服务端;
- 当01号程序员把写完后,准备提交代码了,这时的正规操作手法,先更新在提交,但是在更新的时候必然会冲突,
- 因为这时候更新的代码conflict.txt与本地仓库代码conflict.txt不一致
解决方案如下:
将需要更新分支的代码 merge
到当前分支,idea 会弹出Merge 页面,可以看到冲突的内容,这时候有以下几种处理方式:
- accept yours:代表以自己的为准;
- accept theris:代表以更新下来的文件为准;
- merge:代表手动合并;
一般解决冲突我们都是选择merge,亦可以综合使用以上几种方法。
重点:
- 提交的时候一定要保持清醒,先搞清楚自己要提交的文件之间的关系,然后再提交,这样才不会有文件缺失的问题。
- 发现冲突了,千万不要擅自拉别的分支去试图解决冲突,或找文件覆盖,更或者以自己的文件为准,一定要明白为什么冲突,然后再去针对性的结局。
- 冲突解决了之后,要
add
和commit
最后push
; - 如果任务比较多,又开了多个分支,分别进行开发,一定要清楚自己在各个分支上做了什么,自己要提交的是什么,最好是能做个详细的笔记。
6.4 idea中实现项目回滚
1)查看历史记录
选择 VCS>Git>Show History
菜单打开git的提交日志,可以看到所有的提交记录。
- 也可以在需要回滚的项目上右键,在弹出菜单中选择
Git>Show History
2)复制回滚的版本号
选择需要回滚的记录,然后右键,选择 Copy Revision Number
可以拷贝出一串字符串,如 06c35e49626c1652eec659cfe143625da7685881
。
3)设置回滚版本号
鼠标右击项目,选择 Git>Repository>Reset Head...
菜单。
在弹窗中的 To Commit
部分,将其中的 HEAD
内容删除,粘贴上刚才拷贝的版本号字符串 06c35e49626c1652eec659cfe143625da7685881
, 点击 Reset
就会回滚到这个版本。
7、IDEA配置.gitignore
在工程中,并不是所有文件都需要保存到版本库中的,例如“target”目录及目录下的文件就可以忽略。在Git工作区的根目录下创建一个特殊的 .gitignore
文件,然后把要忽略的文件名填进去,Git就会自动忽略这些文件或目录。
7.1 Git 忽略规则优先级
在 .gitingore
文件中,每一行指定一个忽略规则,Git 检查忽略规则的时候有多个来源,它的优先级如下(由高到低):
- 从命令行中读取可用的忽略规则
- 当前目录定义的规则
- 父级目录定义的规则,依次递推
- $GIT_DIR/info/exclude 文件中定义的规则
- core.excludesfile中定义的全局规则
7.2 Git 忽略规则匹配语法
在 .gitignore
文件中,每一行的忽略规则的语法如下:
* 空格不匹配任意文件,可作为分隔符,可用反斜杠转义
* 开头的文件标识注释,可以使用反斜杠进行转义
* ! 开头的模式标识否定,该文件将会再次被包含,如果排除了该文件的父级目录,则使用 ! 也不会再次被包含。可以使用反斜杠进行转义
* / 结束的模式只匹配文件夹以及在该文件夹路径下的内容,但是不匹配该文件
* / 开始的模式匹配项目跟目录
* 如果一个模式不包含斜杠,则它匹配相对于当前 .gitignore 文件路径的内容,如果该模式不在 .gitignore 文件中,则相对于项目根目录
* ** 匹配多级目录,可在开始,中间,结束
* ? 通用匹配单个字符
* * 通用匹配零个或多个字符
* [] 通用匹配单个字符列表
7.3 常用匹配示例
bin/: 忽略当前路径下的bin文件夹,该文件夹下的所有内容都会被忽略,不忽略 bin 文件
/bin: 忽略根目录下的bin文件
/*.c: 忽略 cat.c,不忽略 build/cat.c
debug/*.obj: 忽略 debug/io.obj,不忽略 debug/common/io.obj 和 tools/debug/io.obj
**/foo: 忽略/foo, a/foo, a/b/foo等
a/**/b: 忽略a/b, a/x/b, a/x/y/b等
!/bin/run.sh: 不忽略 bin 目录下的 run.sh 文件
*.log: 忽略所有 .log 文件
config.php: 忽略当前路径的 config.php 文件
7.4 .gitignore
规则不生效的问题
.gitignore
只能忽略那些原来没有被track的文件,如果某些文件已经被纳入了版本管理中,则修改.gitignore
是无效的。
解决方法就是先把本地缓存删除(改变成未track状态),然后再提交,注意:以下命令需要在你项目中右键点击 Git Bash Here
进行命令窗口输入:
git rm -r --cached .
git add .
git commit -m 'update .gitignore'
7.5 被.gitignore
的文件强制添加到git
你想添加一个文件到Git,但发现添加不了,原因是这个文件被.gitignore忽略了:
$ git add App.class
The following paths are ignored by one of your .gitignore files:
App.class
Use -f if you really want to add them.
如果你确实想添加该文件,可以用-f强制添加到Git:
$ git add -f App.class
或者你发现,可能是 .gitignore
写得有问题,需要找出来到底哪个规则写错了,可以用git check-ignore
命令检查:
$ git check-ignore -v App.class
.gitignore:3:*.class App.class
Git会告诉我们, .gitignore
的第3行规则忽略了该文件,于是我们就可以知道应该修订哪个规则。
7.6 Java项目中常用的 .gitignore
文件
# Compiled class file
*.class
# Eclipse
.project
.classpath
.settings/
# Intellij
*.ipr
*.iml
*.iws
.idea/
# Maven
target/
# Gradle
build
.gradle
# Log file
*.log
log/
# out
**/out/
# Mac
.DS_Store
# others
*.jar
*.war
*.zip
*.tar
*.tar.gz
*.pid
*.orig
temp/
8、IDEA操作技巧
8.1 切换分支
idea右下角有个当前分支的名称,点击会弹出所有分支的信息,如果你想切换分支,选中分支,点击左键选择checkout即可。
8.2 更新和提交
idea项目关联git后,idea左上角会出现一些小的图标,可以用来更新相关的文件或者直接commit相关的文件
9、总结
git操作本身不难,但是要对git的基本概念有一个了解才行。如果觉得idea的操作有点难以理解,可以试试sourceTree这个可视化工具。它可以看到所有本地和远程分支,随意切换,拉取,删除分支。可以看到每次提交的修改点,历史记录的每个人的提交都可以去查看并比较。使用这个软件基本上是无脑操作,但缺点就是安装起来需要一点耐心。各位看官仁者见仁,智者见智吧。把工作完成是第一位的,工具能够达到目的就行了。
参考:https://www.liaoxuefeng.com/wiki/896043488029600/896067074338496
官网教程:https://git-scm.com/book/zh/v2
评论区