Git ( 目标 + 概述 + 安装与常用命令 + 远程仓库 + IDEA 中使用 )
Git 分布式
1、目标
- 了解 Git 基本概念
- 能够概述 Git 工作流程
- 能够使用 Git 常用命令
- 熟悉 Git 代码托管服务
- 能够使用 idea 操作 Git
2、概述
2.1 开发中的实际场景
- 备份
- 防止不可控因素如电脑突然爆掉,硬盘玩活,使得所有代码无法找回
- 代码还原
- 多次尝试性编写代码导致面目全非,回不去从前
- 协同开发
- 大项目多个人同时维护一个项目更方便
- 追溯问题代码的编写人和编写时间
- 追责代码问题的负责人
2.2 版本控制器的方式
集中式版本控制工具
集中式版本控制工具,版本库是集中存放在中央服务器的,team里每个人work时从中央服务器下载代码,是必须联网才能工作,局域网或互联网。个人修改后然后提交到中央版本库。
举例:SVN和CVS(相对来说已过时)
分布式版本控制工具
分布式版本控制系统没有“中央服务器”,每个人的电脑上都是一个完整的版本库,这样工作的时候就不需要联网了,因为版本库就在你自己的电脑上。多人协作只需要各自的修改推送给对方,就能互相看到对方的修改了。
举例:Git
2.3 Git
Git是分布式的,Git不需要有中心服务器,我们每台电脑拥有的东西都是一样的。我们使用Git并且有个中心服务器,仅仅是为了方便交换大家的修改,但是这个服务器的地位和我们每个人的PC是一样的。我们可以把它当做一个开发者的PC就可以,就是为了大家代码容易交流不关机用的。没有它大家一样可以工作,只不过“交换”修改不方便而已。
Git是一个开源的分布式版本控制系统,可以有效、高速地处理从很小到非常大的项目版本管理。Git是Linus Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软件。制订目标:
速度
简单的设计
对非线性开发模式的强力支持(允许成千上万个并行开发的分支)
完全分布式(每个人电脑上都拥有相同东西)
有能力高效管理类似 Linux 内核一样的超大规模项目(速度和数据量)
2.4 Git工作流程图
- 命令如下:
- clone (克隆):从远程仓库中克隆代码到本地仓库
- checkout (检出):从本地仓库中检出一个仓库分支然后进行修订
- add (添加):在提交前先将代码提交到暂存区
- commit (提交):提交到本地仓库。本地仓库中保存修改的各个历史版本
- fetch (抓取):从远程库,抓取到本地仓库,不进行任何的合并动作,一般操作比较少
- pull (拉取):从远程库拉到本地库,自动进行合并 (merge),然后放到到工作区,相当于 fetch+merge
- push (推送):修改完成后,需要和团队成员共享代码时,将代码推送到远程仓库
3、Git安装与常用命令
- 本篇里的 git 命令例子都是在 Git Bash 中演示的,会用到一些基本的 linux 命令,在此为大家提前列举:
- ls / ls -al:查看当前目录 ( ls -al 相比 Is 可以看到隐藏文件,一般都起一个别名,直接用 ll 代替 ls -al )
- 别名方式在 3.1.3 解释
- cat:查看文件内容
- touch:创建文件
- ls / ls -al:查看当前目录 ( ls -al 相比 Is 可以看到隐藏文件,一般都起一个别名,直接用 ll 代替 ls -al )
3.1 Git 环境配置
3.1.1 下载与安装
-
安装后查看
-
Git GUI:Git 提供的图形界面工具
-
Git Bash:Git 提供的命令行工具
3.1.2 基本配置
- 打开 Git Bash
- 设置用户信息
- git config --global user.name “用户名”
- git config --global user.email “邮箱”
- 邮箱并不要求一定存在
- 查看配置信息
- git config --global user.name
- git config --global user.email
3.1.3 为常用指令配置别名
-
有些常用的指令参数非常多,每次都要输入好多参数,我们可以使用别名。
-
打开用户目录,创建 .bashrc 文件
-
用户目录
-
部分 windows 系统不允许用户创建点号开头的文件,那就打开 gitBash,执行
touch ~/.bashrc
-
~ 波浪符:表示当前用户的根目录
-
-
在 .bashrc 文件中输入如下内容:
#用于输出git提交日志 alias git-log='git log --pretty=oneline --all --graph --abbrev-commit' #用于输出当前目录所有文件及基本信息 alias ll='ls -al'
- 其中第一条
git-log
是下面 3.3 基础指令中所用 - 第二条
ll
是上面 3、中常用指令部分所提
- 其中第一条
-
保存后打开 gitBash,执行 source ~/.bashrc
-
3.2 获取本地仓库
-
要使用 Git 对我们的代码进行版本控制,首先需要获得本地仓库
-
在电脑的任意位置创建一个空目录,作为我们的本地 Git 仓库
-
进入这个目录中,点击右键打开 Git bash 窗口
-
执行命令 git init
-
如果创建成功后可在文件夹下看到隐藏的 .git 目录
- 如果查看时
ll
看不到可以用原ls -al
ll
是别名设置成功后的简化的ls -al
-
3.3 基础操作指令
-
Git 工作目录下对于文件的修改 ( 增加、删除、更新 ) 会存在几个状态,这些修改的状态会随着我们执行 Git 的命令而发生变化
- 工作目录:在本地仓库中,除了 .git 外的都在工作目录下
3.3.1 创建、查看状态、提交、查看提交历史
- 在新建的本地仓库里,右键打开 Git Bash
clear
清除页面touch
创建git status
查看文件状态git add
提交到暂存区- 此处 add 后面可以选择输入文件名,如:
git add file01.txt
- 也可以直接用一个点,表示提交当前目录的所有文件,如:
git add .
- 此处 add 后面可以选择输入文件名,如:
-
git commit -m "编写注解"
- 旧版本的话中文可能会乱码
- 此处
-m "编写注解"
不写的话,就会弹出类似前面 vi 主动打开的页面让你编写,编写完后还是先 esc,再 :wq 退出
-
git log
查看提交历史 ( 提交人、提交时间、提交编写的描述 )-
git log [option]
中的 option 处: -
--all 显示所有分支
-
--pretty=oneline 将提交信息显示为一行
-
--abbrev-commit 使得输出的 commitId 更简短 ( 即下图的 e0cf5bc......a7c4 )
-
--graph 以图的形式显示 ( 会多一些斜线、缩进,会更直观一些 )
-
而每次查看都输入上述的长串代码会很麻烦,所以用上面 3.1.3 配置的别名就会方便很多,所以此处可以直接输入
git-log
即可:
-
-
输入
vi file01.txt
编写 file01.txt 文本文件 ( 为方便观看这里使用 vi 编辑器 ) -
输入
i
进入 insert 可编写状态 ( 或者按键盘的 insert 键 ) -
编写完成后按键盘
esc
,然后输入:wq
保存退出 -
这样 file01.txt 打开后内容就是:txt 文件内容
3.3.2 版本回退
-
作用:版本切换
- 注意:非重点,日后一般不会这样回退使用,而且随意回退容易出问题
-
命令形式:
git reset --hard commitID
- commitID 可以使用 git-log 或 git log 指令查看
-
对于已删除的记录:
git reflog
这个指令可以看到已经删除的提交记录
-
示例:
-
注意:Git 指令里没有 ctrl + c、ctrl + v,在其中想要复制 commitID 就直接双击选中 ( 或者括起来选中 ) 即可,粘贴就是按一下滚轮 ( 也可以选择右键 Paste )
- 想要找回 “ 更改了file01.txt ” 的话就同样粘贴上更改的 commitID 即可
-
若是回退了又
clear
找不到原来的 commitID 了的话-
git reflog
可以查看所有的操作,类似历史日志,在其中可以找到 commitID
-
-
3.3.3 添加文件至忽略列表
-
一般我们总会有些文件无需纳入 Git 的管理,也不希望它们总出现在未跟踪文件列表。 通常都是些自动生成的文件,比如日志文件,或者编译过程中创建的临时文件等。在这种情况下,我们可以在工作目录 中创建一个名为 .gitignore 的文件 ( 文件名称固定 ),列出要忽略的文件模式。下面是一个示例:
touch .gitignore
创建文件后 vi 编辑器 insert 内容:*a
就表示 .a 结尾的文件都不让 git 管理了
# no .a files (.a结尾的文件都不让git管理了) *.a # but do track lib.a, even though you're ignoring .a files above !lib.a # only ignore the TODO file in the current directory, not subdir/TODO /TODO # ignore all files in the build/ directory build/ # ignore doc/notes.txt, but not doc/server/arch.txt doc/*.txt # ignore all .pdf files in the doc/ directory doc/**/*.pdf
3.4 分支
- 几乎所有的版本控制系统都以某种形式支持分支。 使用分支意味着你可以把你的工作从开发主线上分离开来进行重大的 Bug 修改、开发新的功能,以免影响开发主线
- 分支可以理解为一条道路上的岔路口,是基于主分支已有操作
3.4.1 常用分支命令
-
查看本地分支
-
命令:git branch
-
很多时候也是直接用
git-log
( 前面起的别名 ) 查看 -
注意,当前分支:
git branch
查看是星号绿色的;git-log
查看是 HEAD 指向的 -
若是在当前分支做了一些提交操作,在其他分支里是没有任何影响的。同理,在其他分支创建的文件虽然可以在文件夹中看到,但切换回主分支后,创建的文件就会消失
-
在其他分支时:
-
切回 master 分支:
-
-
-
创建本地分支
- 命令:git branch 自定义分支名
-
切换分支 ( checkout )
- 命令:git checkout 分支名
-
直接切换到一个不存在的分支 ( 即创建并切换 )
- 命令:git checkout -b 自定义分支名
-
合并分支 ( merge )
-
一个分支上的提交可以合并到另一个分支
-
命令:git merge 其他分支名称
-
在 master 分支上执行
git merge test01
,就会都统一到 master,且无 test01 分支 -
例:( test01 即为此图的 dev01 )
-
-
-
删除分支
- 不能删除当前分支,只能删除其他分支
- git branch -d b1:删除分支 b1 时,需要做各种检查
- git branch -D b1:不做任何检查,强制删除 b1 分支
- 强制情况:要删除的分支在
git-log
时处在最上面的 ( 在 master 的上面,比 master 还新 ),在当前为其他分支上就不能进行普通删除,只能强制删除
- 强制情况:要删除的分支在
3.4.2 解决冲突
-
如果两个分支都改了一个地方并且都提交了 ( 都改了 file01 )
-
则显示:
-
并且合并时出现错误:
-
file01 内容则变成:
- HEAD 一直到 ==== 为当前分支内容,再到 >>>> 的为合并分支 test 内容
-
这时候就可以选择自行手动解决冲突,打开 file01.txt 删去不想要的,然后保存再加入提交,就会发现冲突解决了
-
-
上述文字总结:
- 当两个分支上对文件的修改可能会存在冲突,例如同时修改了同一个文件的同一行,这时就需要手动解决冲突,解决冲突步骤如下:
- 处理文件中冲突的地方
- 将解决完冲突的文件加入暂存区 ( add )
- 提交到仓库 ( commit )
- 当两个分支上对文件的修改可能会存在冲突,例如同时修改了同一个文件的同一行,这时就需要手动解决冲突,解决冲突步骤如下:
3.4.3 开发中分支使用原则与流程
- 几乎所有的版本控制系统都以某种形式支持分支。 使用分支意味着你可以把你的工作从开发主线上分离开来进行重大的 Bug 修改、开发新的功能,以免影响开发主线。在开发中,一般有如下分支使用原则与流程:
- master ( 生产 ) 分支
- 线上分支,主分支,中小规模项目作为线上运行的应用对应的分支
- develop ( 开发 ) 分支
- 是从 master 创建的分支,一般作为开发部门的主要开发分支,如果没有其他并行开发不同期上线要求,都可以在此版本进行开发,阶段开发完成后,需要是合并到 master 分支,准备上线
- feature / xxxx分支
- 从 develop 创建的分支,一般是同期并行开发,但不同期上线时创建的分支,分支上的研发任务完成后合并到 develop 分支
- hotfix / xxxx分支
- 从 master 派生的分支,一般作为线上 bug 修复使用,修复完成后需要合并到 master、test、 develop 分支
- 还有一些其他分支,在此不再详述,例如 test 分支 ( 用于代码测试 )、pre 分支 ( 预上线分支 ) 等等
- master ( 生产 ) 分支
3.4.4 合并方式
-
在两个将要合并的分支都有做修改的话,合并后就会出现斜线构成的梯形拱桥,如果只有一个 test 分支做了修改的话 ( master 分支没有做任何操作 ),在合并为 master 分支后就不会出现梯形拱桥,即为 git 自带的快进方式 ( 可以理解为直接把 master 和 test 放一起了 ),即快进模式
-
下图上面的红框就是快进模式,下面的为梯形拱桥
4、Git 远程仓库
- 比较常用的有 GitHub、码云、GitLab等
- 普通的个人代码资料本人使用码云 Gitee
4.1 准备工作
-
注册后,如图新建仓库
-
打开 GitBash 在 3.1.2 基本配置后可以一个个查看,也可以直接输入
git config -l
进行查看-
然后配置 SSH 密钥,使用命令查看是否存在密钥:
cat ~/.ssh/id_rsa.pub
,出现类似此样式就表示已存在: -
不存在的话就输入:
ssh-keygen -t rsa -C "您的密钥注释"
- 在上述公钥显示时,末尾就是你加的注释
-
然后就会显示:
- 如果设置密码,则生成的私钥文件是加密后存储的
- 如果直接回车,不输入密码,则生成的私钥文件 id_rsa 是明文存储在本地的
-
-
在 Gitee 里打开个人主页的个人设置,左边列找到 SSH 公钥,将上面是密钥粘贴到此,加以标题确定即可 ( 会让输入密码验证 )
-
看是否成功,就输入
ssh -T git@gitee.com
显示如下即可:
-
4.2 本地到远程实现连接
-
在 Gitee 中创建完成仓库后,选择 SSH 并复制
4.2.1 添加远程仓库
-
命令:git remote add <远端名称> <仓库路径>
- 远端名称,默认是 origin,取决于远端服务器设置
- 仓库路径,从远端服务器获取此URL
-
在本地的 ( 之前一直学习使用各命令的本地 ) 仓库的 Git Bash 中输入
git remote add origin git@gitee.com.....(刚才复制的仓库SSH后部分)
- remote add 远程添加一个远程仓库,远程仓库地址为复制的 SSH 地址,起名 origin
- 若是报错,尝试输入
git init
再回车再输入就不会报错了
- 若是报错,尝试输入
- remote add 远程添加一个远程仓库,远程仓库地址为复制的 SSH 地址,起名 origin
4.2.2 查看远程仓库
- 输入
git remote
回车查看就会发现多了一个 origin
4.2.3 推送到远程仓库
-
命令:git push [-f] [--set-upstream] [远端名称 [本地分支名:远端分支名] ]
- 如果远程分支名和本地分支名称相同,则可以只写本地分支:
git push origin master
- 同
git push origin master:master
- -f:表示强制覆盖 ( 一般用不到 )
- --set-upstream:推送到远端的同时并且建立起和远端分支的关联关系
git push --set-upstream origin master
- 如果当前分支已经和远端分支关联,则可以省略分支名和远端名
- 直接
git push
:将 master 分支推送到已关联的远端分支
- 直接
- 如果远程分支名和本地分支名称相同,则可以只写本地分支:
-
此处仅简单推送,输入
git push origin master
推送:- 就有了本地仓库内容
-
若想之后直接
git push
即可,就要加--set-upstream
远程关联上,让其明白此 master 就是彼 master-
git bransh -vv
专门查看本地分支与远程分支的对应关系 -
origin/master 就是远端的 master,类似快进模式的提交端
-
4.3 从远程仓库到本地克隆
4.3.1 从远程仓库克隆
-
若是桌面上直接右键 Git Bash,输入命令
git clone git@gitee.com......(要复制仓库的SSH后部分)
-
SSH:
-
-
就会发现桌面上新建了这个远程拉下来的仓库:
4.3.2 从远程仓库中抓取和拉取
-
并不是每次获取跟新后的代码仓库都靠克隆操作,一般都是一开始用克隆,之后都是抓取和拉取
- 远程分支和本地的分支一样,我们可以进行 merge 操作,只是需要先把远端仓库里的更新都下载到本地,再进行操作
-
抓取命令:
- git fetch [remote name] [branch name]
- 抓取指令就是将仓库里的更新都抓取到本地,不会进行合并
- 如果不指定远端名称和分支名,则抓取所有分支
-
拉取命令:
- git pull [remote name] [branch name]
- 拉取指令就是将远端仓库的修改拉到本地并自动进行合并,等同于 fetch + merge
- 如果不指定远端名称和分支名,则抓取所有并更新当前分支
-
实际操作
-
若是在一端仓库做了文件新增与提交、推送操作,则另一端仓库
git-log
看到的还是旧的,需要git fetch
抓取,然后查看就会发现所在 master 与远端仓库最新的 master 不一致,即 -
然后
git merge 其他分支名(这里指远程仓库master)
即可 -
上述两个 fetch 与 merge 的操作可以合并为一个操作,即拉取
-
4.3.3 解决合并冲突
-
在一段时间,A、B 用户修改了同一个文件,且修改了同一行位置的代码,此时会发生合并冲突
-
A 用户在本地修改代码后优先推送到远程仓库,此时 B 用户还在本地修改代码 ( 包括与 A 修改相同处 ),提交到本地仓库后,也需要推送到远程仓库,此时 B 用户晚于 A 用户,故需要先
git pull
拉取远程仓库的提交,经过合并后才能推送到远端分支 -
但由于与 A 的修改重复出现冲突,所以会产生冲突,就类似之前冲突情况,会把 A 和 B 的修改都留下来待更改,此时在 B 中
git-log
查看就类似 ( head 指向与 origin 远程不同出现分支 ): -
想解决就是自行手动更改后再次
git add .
、git commit -m "..."
,此时再git push
、git-log
就会解决冲突且合并完成 -
A 端同样再
git push
、git-log
就可获取最新的无冲突的
-
5、在 IDEA 中使用 Git
5.1 在 idea 中配置 git
-
安装好 IntelliJ IDEA 后,如果 Git 安装在默认路径下,那么 idea 会自动找到 Git 的位置,如果更改了 Git 的安装位置则需要手动配置下 Git 的路径
-
选择 File ——> Settings 打开设置窗口,找到 Version Control 下的 Git 选项
-
5.2 在 idea 中配置 git 并提交到远程仓库
-
获取新项目后自动导入包
-
选择创建
-
idea 上方点击对号就是 commit 提交,选择想要提交的部分 ( 若是配好了 .gitignore 就会在选择时自行筛选掉不需要的部分,就可以直接全选了,如:.idea 等 )
-
第一次没有远程仓库,就只能选择 commit,在后面完成配置推送,以后再 Commit 时可以选择 Commit and Push
-
可查看已提交的部分,之后再提交,右边内容点击可以查看有何更改
-
在上方导航栏找到 Git ( 或 VSC ) 找到 Push
-
此处显示 Define remote 就表示没关联远程仓库,需要将复制的 gitee 仓库的地址,粘贴到下方的 URL,点击 OK 确定无误后 Push
-
显示 Push successful 即表示成功
5.3 远程仓库克隆到本地
-
在 idea 导航栏部分选择 clone
-
粘贴仓库 SSH 的 URL,自行选择目录进行克隆
-
-
在任何时候将修改代码提交前都要先 pull 下,即上方的蓝色箭头
-
下方 Git 再查看时就会显示梯形拱桥图示:
-
-
若是在提交时出现之前讲过的冲突,可以选择简单粗暴的方式,直接关闭 Conflicts 弹出页面,报错部分在项目目录中找到红色的报错的手动打开,会显示报错的冲突代码 ( 仍是 <<<< .... ==== .... >>>> 的形式 ),手动修改后将此红色文件右键 Add 添加回蓝色
- 再选择绿色对号进行提交,并 Push 即可 ( 注解会自行填写英文说明 )
5.4 分支查看创建
-
idea 右下角有分叉图标即为分支,最初只有 master 分支,上为 new 可自行创建分支,下方 Remote 查看远程分支
-
想要切换分支,merge 分支也在此操作
-
-
一般常在 Git 的 Log 部分右键某条记录便可选择创建,自定义名后便创建完成
5.5 改 Terminal
-
默认打开 idea 下方的 Terminal 为:
-
可以自行修改为:
-
这样再使用时就是 Git Bash 样式:
-