学习目标
- 了解Git基本概念
- 能够概述git工作流程
- 能够使用Git常用命令
- 熟悉Git代码托管服务
- 能够使用idea操作git
1 Git的基本概念
1.1 开发过程中的场景
程序员开发项目是一个不断迭代的过程,需要不断的对代码进行编写和更改,这就会引起多个版本问题,在以下场景中有所表现:
-
场景一:备份。小明负责的模块就要完成了,就在即将
Release之前的一瞬间,电脑突然蓝屏,硬盘光荣牺牲! 几个月来的努力付之东流 -
场景二:代码还原。这个项目中需要一个很复杂的功能,老王摸索了一个星期终于有眉目了,可是这被改得面目全非的 代码已经回不到从前了。什么地方能买到哆啦A梦的时光机啊?
-
场景三:协同开发。小刚和小强先后从文件服务器上下载了同一个文件:
Analysis.java。小刚在Analysis.java文件中的第30行声明了一个方法,叫count(),先保存到了文件服务器上;小强在Analysis.java文件中的 第50行声明了一个方法,叫sum(),也随后保存到了文件服务器上,于是,count()方法就只存在于小刚的记 忆中了 -
场景四:追溯问题代码的编写人和编写时间! 老王是另一位项目经理,每次因为项目进度挨骂之后,他都不知道该扣哪个程序员的工资!就拿这 次来说吧,有个
Bug调试了30多个小时才知道是因为相关属性没有在应用初始化时赋值!可是二胖、王东和正经牛都不承认是自己干的!
因此,我们要对代码版本进行管理。
1.2 版本控制器的方式
管理代码版本的方式有2种,一种是集中式控制,另外一种是分布式控制。
-
集中式版本控制工具
集中式版本控制工具,版本库是集中存放在中央服务器的,
team里每个人work时从中央服务器下载代码,是必须联网才能工作,局域网或互联网。个人修改后然后提交到中央版本库。 举例:SVN和CVS -
分布式版本控制工具
分布式版本控制系统没有“中央服务器”,每个人的电脑上都是一个完整的版本库,这样工作的时候,无需联网了,因为版本库就在你自己的电脑上。多人协作只需要各自的修改推送给对方,就能互相看到对方的 修改了。举例:
Git
1.3 SVN
SVN是企业早期使用的一种集中式版本工具。
1.4 Git
Git是分布式的,不需要有中心服务器,我们每台电脑拥有的东西都是一样的。我们使用的Git有个中心服务器,仅仅是为了方便交换或者修改大家的代码而存在的。没有它大家一样可以工作,只不过“交换”或修改不方便而已。
Git是一个开源的分布式版本控制系统,可以有效、高速地处理从很小到非常大的项目版本管理。Git是Linus Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软件,具有两个大优势:
- 优势一:通过
Git可以跟踪代码的状态,也可以在修改代码后对代码状态进行存储,还可以在需要时将已经修改过的代码恢复到之前存储的状态。 - 优势二:更强大的是使用
Git管理代码时,可以创建代码分支(branch),代码分支相当于一段独立的代码记录,我们可以在分支上对代码进行任意的修改,而这个修改只会影响当前分支,不会对其他分支产生影响。同时,可以对分支进行合并,合并后一个分支的修改便可在另一分支上生效。
总之,Git是当今最优秀的版本控制工具!
1.5 Git工作流程图
命令如下:
-
clone(克隆): 从远程仓库中克隆代码到本地仓库 -
checkout(检出):从本地仓库中检出一个仓库分支然后进行修订 -
add(添加): 在提交前先将代码提交到暂存区 -
commit(提交): 提交到本地仓库。本地仓库中保存修改的各个历史版本 -
fetch(抓取) : 从远程库,抓取到本地仓库,不进行任何的合并动作,一般操作比较少。 -
pull(拉取) : 从远程库拉到本地库,自动进行合并(merge),然后放到到工作区,相当于
fetch+merge
push(推送) : 修改完成后,需要和团队成员共享代码时,将代码推送到远程仓库
2 Git下载与安装
2.1 前置知识
Git命令例子都是在Git Bash Here中演示的,会用到一些基本的linux命令,列举如下:
-
clear清屏 -
ls/ll查看当前目录 -
cat查看文件内容 -
touch创建文件 -
vi进入vi编辑器 -
按
C键,直至编辑器显示“插入”字样,才可以编辑vi编辑器。 -
按
ESC键,输入:➕q退出vi编辑器
2.2 下载Git
🌐Git 下载地址:git-scm.com/downloads
下载完成后可以得到如下安装文件:
2.3 安装Git
双击下载的安装文件来安装Git。安装完成后在电脑桌面(也可以是其他目录)点击右键,如果能够看
到如下两个菜单则说明Git安装成功。
-
Git GUI Here:Git提供的图形界面工具 -
Git Bash Here:Git提供的命令行工具
2.4 配置Git环境·
-
查看系统的环境变量:安装完毕后,在系统的环境变量可以看到
Git的bin目录已经自动添加。 -
在
cmd命令行中,输入命令git --version,查看工具的版本号。
3 Git的基本配置
3.1 全局配置
当安装 Git 后首先要做的事情是设置用户名称和email地址。这是非常重要的,因为每次Git提交都会使用该用户信息。
-
第1步 桌面右键,打开
Git Bash Here命令行 -
第2步 在
Git Bash Here命令行中,设置用户信息:-
设置用户名称:
git config --global user.name "<your username>" -
设置用户邮箱:
git config --global user.email "<your emali>"
-
-
第3步 在
Git Bash Here命令行中,查看配置信息:-
查看用户配置信息:
git config --global user.name -
查看邮件配置信息:
git config --global user.email -
查看配置列表信息:
git config --list
-
-
第4步
Git的用户配置信息文件🗋.gitconfig在当前用户的根目录下:
注意:上面设置的
user.name和user.email并不是我们在注册码云账号时使用的用户名和邮箱,此处可以任意设置。
3.2 为常用指令配置别名(可选)
有些常用的指令参数非常多,每次都要输入好多参数,我们可以使用别名。
-
打开用户目录,创建
.bashrc文件
在用户根目录,打开Git Bash Here,执行命令touch ~/.bashrcGit命令简化别名文件 🗋.bashrc放置于当前用户的根目录下: -
在
.bashrc文件中输入如下内容:
# 用于输出`Git`提交日志
alias git-log='git log --pretty=oneline --all --graph --abbrev-commit'
# 用于输出当前目录所有文件及基本信息
alias ll='ls -al'
- 在用户根目录,打开
Git Bash Here,执行source ~/.bashrc
部分windows系统不允许用户创建点号开头的文件
3.3 解决Git Bash Here乱码问题
-
打开
Git Bash Here执行命令:git config --global core.quotepath false -
${git_home}/etc/bash.bashrc文件最后加入下面两行:
export LANG="zh_CN.UTF-8"
export LC_ALL="zh_CN.UTF-8"
4 项目Git初始化
默认情况下,磁盘中的文件并不由Git管理,我们必须要对代码目录进行初始化,初始化后Git才能正常的管理文件。
4.1 方法一:本地仓库初始化
- 在任意目录下创建一个空目录(例如:在
D盘新建一个文件夹learn_git) - 进入这个目录中,点击邮键打开
Git Bash Here窗口 - 执行命令
git init - 如果在目录中看到隐藏的
.git文件夹,则说明Git仓库创建成功。
4.2 方法二:克隆远程仓库项目
初始化后目录中会多出一个.git目录,这个目录用来存储代码的版本信息,有了.git就意味着项目现在已经开始被.git管理了,不希望项目被Git管理时,只需删除项目中的.git即可。
一个目录只能有一个直属的
.git文件
5 Git的基本操作
Git工作目录下对于文件的修改(增加、删除、更新)会存在几个状态,这些修改的状态会随着我们执行Git的命令而发生变化。
以下内容主要讲解如何使用命令来控制这些状态之间的转换:
-
git add(工作区 --> 暂存区) -
git commit(暂存区 --> 本地仓库)
5.1 查看修改的状态(status)
Git中的文件有两种状态:未跟踪和已跟踪。未跟踪指文件没有被Git所管理,已跟踪指文件已被Git管理。已跟踪的文件又有三种状态:未修改、修改和暂存。
-
暂存,表示文件修改已经保存,但是尚未提交到
Git仓库。 -
未修改,表示磁盘中的文件和
Git仓库中文件相同,没有修改。 -
已修改,表示磁盘中文件已被修改,和
Git仓库中文件不同。
可以通过git status来查看文件的状态
-
作用:查看的修改的状态(暂存区、工作区)
-
命令形式:
git status
在D:/learn_git目录下,打开Git Bash Here,执行git status命令,查看当前仓库状态
如果你输入git命令后看见了下面的黄色文字,可以执行消除命令:git config --global core.fsmonitor true
5.2 添加工作区到暂存区(add)
-
作用:添加工作区一个或多个文件的修改到暂存区
-
命令形式:
git add 单个文件名|通配符 -
将所有修改加入暂存区:
git add .
第1步 在D:/learn_git目录下创建一个hello.txt文件,输入一些内容。
第2步 打开Git Bash Here,执行git status命令,hello.txt文件刚刚添加进目录,所以现在文件处于未跟踪(untracked)的状态:
第3步 打开Git Bash Here,执行git add hello.txt命令,将文件修改为已跟踪状态:
第4步 执行git status查看当前仓库状态,发现hello.txt显示在master分支上,还没有提交:
add命令是一个多功能的命令,如果对没有未跟踪的文件调用它会将其设置为已跟踪,并将其转换为暂存状态。如果对已跟踪的文件调用,它就仅仅会将文件设置为暂存状态。
5.3 提交暂存区到本地仓库(commit)
-
作用:提交暂存区内容到本地仓库的当前分支
-
命令形式:
git commit -m '注释内容'
第1步 在Git Bash Here中,执行 git commit -m 'add Hello.txt'
第2步 继续使用git status查看仓库状态,可以看到没有内容需要提交了
第3步 继续按照上述步骤在该目录下放入一张图片,进行添加到暂存区和提交操作
5.4 查看提交日志(log)
如果配置了命令别名,就可以使用命令别名。
-
作用:查看提交记录
-
命令形式:
git log [option]-
options-
--all显示所有分支 -
--pretty=oneline将提交信息显示为一行 -
--abbrev-commit使得输出的commitId更简短 -
--graph以图的形式显示
-
-
第1步 在Git Bash Here中,执行git log查看提交日志。
第2步 也可以通过git log --pretty=oneline,简略在一行显示日志。
5.5 版本回退
-
作用:版本切换
-
命令形式:
git reset --hard commitID(commitID可以使用git log指令查看,commitID写前六七位即可。)
在Git Bash Here中,执行git reset --hard 2fa3754回到只提交hello.txt的版本,放置于该仓库的avatr.jpg图片也消失了。
5.6 查看已经删除的记录
-
作用:查看已经删除的提交记录
-
命令形式:
git reflog
在Git Bash Here中,执行git reflog查看已删除的记录。
5.7 添加文件至忽略列表
一般我们总会有些文件无需纳入Git 的管理,也不希望它们总出现在未跟踪文件列表。 通常都是些自动
生成的文件,比如日志文件,或者编译过程中创建的临时文件等。 在这种情况下,我们可以在工作目录
中创建一个名为 .gitignore 的文件(文件名称固定),列出要忽略的文件模式。下面是一个示例:
# no .a files
*.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
5.8 删除文件
- 命令:
git rm <filename>表示从磁盘里删除,再经过提交就可以把仓库里的东西也删除掉。 - 命令:
git rm <filename> -f表强制删除
6 Git分支
几乎所有的版本控制系统都以某种形式支持分支。 使用分支意味着你可以把你的工作从开发主线上分离开来进行重大的Bug修改、开发新的功能,以免影响开发主线。
6.1 查看本地分支
- 命令:
git branch
打开Git Bash Here,执行git branch:
执行命令:git log --pretty=oneline,观察master分支提交情况:
6.2 创建本地分支
- 命令:
git branch 分支名打开git branch second,创建一个名为second的分支:
6.3 切换分支(checkout)
- 命令:
git checkout 分支名
第1步 执行命令:git branch second,切换到一个名为second的分支:
第2步 在second分支下,执行命令:git log --pretty=oneline,观察second分支提交情况:
第3步 在D:/learn_git目录下创建一个名为second_test.txt的文本文件,并在second分支下完成添加以及提交:
第4步 在second分支下,执行命令git log --pretty=oneline,可以发现second_test.txt提交情况:
第5步 在master分支下,执行命令git log --pretty=oneline,可以发现没有second_test.txt:
我们还可以直接切换到一个不存在的分支(创建并切换)
- 命令:
git checkout -b 分支名
执行命令:git branch -b third,创建并切换到一个名为third的分支:
6.4 合并分支(merge)
一个分支上的提交可以合并到另一个分支
- 命令:
git merge 分支名称
使用git checkout master切换到master分支,把second分支下的提交内容添加到master分支上,使master分支,可以看见second_test.txt文件:
6.5 删除分支
不能删除当前分支,只能删除其他分支
-
命令:
git branch -d 分支名删除分支时,需要做各种检查 -
命令:
git branch -D 分支名不做任何检查,强制删除
切换至master分支,并在master分支下,删除second分支以及third分支:
6.6 解决冲突
当两个分支上对文件的修改可能会存在冲突,例如同时修改了同一个文件的同一行,这时就需要手动解决冲突,解决冲突步骤如下:
-
处理文件中冲突的地方
-
将解决完冲突的文件加入暂存区(add)
-
提交到仓库(commit)
第1步 打开Git Bash Here命令行,创建一个other分支。切换到该分支下,执行命令touch math.txt,创建math.txt文件。然后执行命令vi math.txt,打开vi编辑器器,编辑内容为:count=3,按住【ESC】,输入:wq,再按【回车键】,就完成了一个math.txt的编辑。
第2步 在master分支下,添加并提交math.txt,并打印提交日志:
第3步 切换到master分支,按照同样的方法创建一个math.txt,并编辑该math.txt的内容为count=2,
第4步 将masth.txt添加提交到master分支,在该分支下打印日志:
第5步 在master分支下,执行命令git merge other,将other分支合并到master分支下,将发生冲突,如红框所示:
第6步 冲突的原因是因为两者math.txt中的count不一致:
第7步 打开math.txt文件,把内容修改为我们想要的样子,如:删除文件里面原来的内容,并写上count=5。
第8步 把修改后的math.txt文件,添加到暂存区,并提交到修改区,就解决了合并分支的冲突:
6.7 开发中分支使用原则与流程
几乎所有的版本控制系统都以某种形式支持分支。 使用分支意味着你可以把你的工作从开发主线上分离开来进行重大的Bug修改、开发新的功能,以免影响开发主线。
在开发中,一般有如下分支使用原则与流程:
-
master(生产) 分支
线上分支,主分支,中小规模项目作为线上运行的应用对应的分支; -
develop(开发)分支
是从master创建的分支,一般作为开发部门的主要开发分支,如果没有其他并行开发不同期上线要求,都可以在此版本进行开发,阶段开发完成后,需要是合并到master分支,准备上线。 -
feature/xxxx分支
从develop创建的分支,一般是同期并行开发,但不同期上线时创建的分支,分支上的研发任务完成后合并到develop分支。 -
hotfix/xxxx分支
从master派生的分支,一般作为线上bug修复使用,修复完成后需要合并到master、test、develop分支。 -
还有一些其他分支,在此不再详述,例如
test分支(用于代码测试)、pre分支(预上线分支)等等。
7 远程仓库概念
众所周知,Git中存在两种类型的仓库,即本地仓库和远程仓库。那么我们如何搭建Git远程仓库呢?我们可以借助互联网上提供的一些代码托管服务来实现,其中比较常用的有GitHub、Gitee、GitLab等。
-
GitHub( 地址:github.com/ )是一个面向开源及私有软件项目的托管平台,因为只支持Git作为唯一的版本库格式进行托管,故名GitHub -
Gitee(地址: gitee.com/ )是国内的一个代码托管平台,由于服务器在国内,所以相比GitHub速度会更快 -
GitLab(地址: about.gitlab.com/ )是一个用于仓库管理系统的开源项目,使用Git作为代码管理工具,并在此基础上搭建起来的web服务,一般用于在企业、学校等内部网络搭建Git私服。
7.1 GitHub
-
第1步 用配置
Git的邮箱来注册github账号:github.com -
第2步 进入用户主目录,启动
Git Bash Here,输入命令:ssh-keygen -t rsa -C “注册GitHub的邮箱地址”,一路回车,会生成公钥。将在用户根目录下生成一个.ssh文件 -
第3步 进入
GitHub的个人设置页面 github.com/settings/ ,也可以在首页上点击头像选择settings,选择SH and GPG keys -
第4步 添加一个
SSH key -
第5步 把刚才本地复制的公钥粘贴进去,
title随便填 -
第6步 确认一下密码,就添加成功了。
7.2 Gitee
-
打开Gitee,填写邮箱、密码以及其它用户信息,进行注册。
-
创建远程仓库
远程仓库的地址,可以从下面看到:
-
配置远程仓库的公钥
-
第1步 打开
Git Bash Here,输入命令:ssh-keygen -t rsa”,不断回车,会生成公钥。若公钥已经存在,则自动覆盖。命令执行结束后,将在用户根目录下生成一个存放公钥的文件夹📁
.ssh。 -
第2步 在
Git Bash Here中,输入命令:cat ~/.ssh/id_rsa.pub获取公钥。 -
第3步 在
Gitee中使的SSH公钥中,粘贴公钥,确认密码即可。 -
第4步 验证公钥是否配置成功。在
Git Bash Here中输入命令:ssh -T git@gitee.com
-
8 远程仓库的操作
8.1 创建远程仓库
此操作是先初始化本地库,然后与已创建的远程库进行对接。
-
命令:
git remote add <远端名称> <仓库路径> -
远端名称:默认是
origin,取决于远端服务器设置 -
仓库路径:从远端服务器获取此
URL
第1步 在远程仓库终端创建仓库study
第2步 在D:/study目录下,打开Git Bash Here,输入命令:git init初始化本地仓库,再执行命令:git remote add origin git@gitee.com:nangon1234/study.git连接远程仓库
8.2 查看远程仓库
- 命令:
git remote
8.3 推送到远程仓库
-
命令:
git push [-f] [--set-upstream] [远端名称 [本地分支名][:远端分支名] ]-
如果远程分支名和本地分支名称相同,则可以只写本地分支:
git push origin master -
f表示强制覆盖 -
--set-upstream推送到远端的同时并且建立起和远端分支的关联关系。git push --set-upstream origin master
-
如果当前分支已经和远端分支关联,则可以省略分支名和远端名。
git push将master分支推送到已关联的远端分支。
-
第1步 在D:/study目录下,打开Git Bash Here,输入命令touch hello.txt,创建hello.txt,并将hello.txt先添加至暂存区,再提交至本地仓库。
第2步 执行命令:git push origin master,将本地仓库中的内容推送到远程仓库中
第3步 查看远程仓库中出现hello.txt
8.5 本地分支与远端分支的关系
- 命令:
git branch -vv
第1步 在D:/study目录下,打开Git Bash Here,输入命令git branch dev,创建dev分支。
第2步 执行命令:git push --set-upstream origin master:master 设置本地分支master与远程分支master的对应关系。
第3步 执行命令:git branch -vv,查看本地分支与远程分支的关系。
第4步 执行命令:git push,可以推送内容至远程仓库
8.6 从远程仓库克隆
如果已经有一个远端仓库,我们可以直接clone到本地。
- 命令:
git clone <仓库路径> [本地目录](本地目录可以省略,会自动生成一个目录。)
第1步 在D盘创建一个文件夹📁clone。
第2步 在D:/clone中,打开git bash here,执行命令git clone git@gitee.com:nangon1234/study.git,将在该目录下出现文件夹📁study
第3步 原仓库与克隆后的仓库的区别主要是分支不同,如下图:
8.7 从远程仓库中抓取
远程分支和本地的分支一样,我们可以进行merge操作,只是需要先把远端仓库里的更新都下载到本地,再进行操作。
- 抓取命令:
git fetch [remote name] [branch name]- 抓取指令就是将仓库里的更新都抓取到本地,不会进行合并
- 如果不指定远端名称和分支名,则抓取所有分支。
第1步 在D:/clone/study中,打开Git Bash Here,创建一个文件words.txt,将其添加至暂存区,并提交至仓库。
第2步 将words.txt推送至远程仓库
第3步 执行命令:git log --pretty=oneline --all --graph --abbrev-commit,查看当前仓库提交情况。
第4步 在D:/study中,打开Git Bash Here,执行git fetch,拉取新的内容
第5步 在D:/study中,打开Git Bash Here,执行命令:git log --pretty=oneline --all --graph --abbrev-commit,查看当前仓库提交情况,发现当前的master分支只有hello.txt,没有words.txt。
第6步 在D:/study中,打开Git Bash Here,执行命令git merge,将远程仓库origin/master分支合并至本地仓库中的master分支上。
第7步 在D:/study中,打开Git Bash Here,执行命令:git log --pretty=oneline --all --graph --abbrev-commit,查看合并后当前仓库提交情况,发现当前的master分支有words.txt。
8.8 从远程仓库中拉取
-
拉取命令:
git pull [remote name] [branch name]-
拉取指令就是将远端仓库的修改拉到本地并自动进行合并,等同于
fetch+merge -
如果不指定远端名称和分支名,则抓取所有并更新当前分支。
-
第1步 在D:/study中,打开Git Bash Here,创建一个文件my.txt,将其添加至暂存区,再提交至修改区,然后再推送至远程仓库。
第2步 执行命令:git log --pretty=oneline --all --graph --abbrev-commit,查看当前仓库提交情况。
第3步 先执行命令:git pull,再执行命令:git log --pretty=oneline --all --graph --abbrev-commit,查看当前仓库master分支上有my.txt。
8.9 解决合并冲突
在一段时间,甲、乙用户修改了同一个文件,且修改了同一行位置的代码,此时会发生合并冲突。甲用户在本地修改代码后优先推送到远程仓库,此时乙用户在本地修订代码,提交到本地仓库后,也需要推送到远程仓库,此时甲用户晚于乙用户,故需要先拉取远程仓库的提交,经过合并后才能推送到远端分支,如下图所示。
在乙用户拉取代码时,因为甲、乙用户同一段时间修改了同一个文件的相同位置代码,故会发生合并冲突。远程分支也是分支,所以合并时冲突的解决方式也和解决本地分支冲突相同。
甲用户(D:/study)操作:
- 第1步 执行
vi my.txt,在vi编辑器中,修改内容为count=2。 - 第2步 将
my.txt存储至本地仓库,并推送到远程仓库中。
乙用户(D:/clone/study)操作一:
- 第1步 执行
vi my.txt,在vi编辑器中,修改内容为count=3。 - 第2步 将
my.txt存储至本地仓库,并推送到远程仓库中,将出现推送错误。
乙用户(D:/clone/study)操作二
-
第1步 执行
vi my.txt,在vi编辑器中,修改内容为count=3。 -
第2步 将
my.txt加入到暂存区,再加入到修改区: -
第3步 先执行命令:
git fetch进行抓取,再执行git log --pretty=oneline --all --graph --abbrev-commit,查看当前仓库提交情况。 -
第4步 执行命令:
git pull,出现合并冲突。 -
第5步 修改
my.txt中的内容,先将其添加至暂存区,再将其添加至修改区,并推送至远程仓库。