一、概述
1.介绍
- 源代码管理
- Git是目前世界上最先进的分布式版本控制系统
- Git诞生
2.版本控制工具
- 集中式版本控制工具
- CVS、SVN(Subversion)、VSS等
- 分布式版本控制工具
- Git、Mercurial、Bazaar、Darcs等
3.作用
- 冲突解决
- 代码备份
- 版本还原
- 权限管理
- 协同开发
- 历史追查
- 代码审查
- 版本记录
- 分支管理
4.git工作机制
5.代码托管中心
代码托管中心负责维护远程库
局域网:Gitlab
Internet:GitHub,码云(gitee)
6.集中式版本控制系统
SVN是集中式版本控制系统,版本库是集中放在中央服务器的,而工作的时候,用的都是自己的电脑,所以首先要从中央服务器下载最新的版本,然后开放代码,写完代码后需要把自己的代码推送到中央服务器。
缺点:
- 服务器单点故障
- 容错性差
7.分布式版本控制系统
Git是分布式版本控制系统(Distributed Version Control System,简称 DVCS)
仓库:
- 本地仓库:是在开发人员自己电脑上的Git仓库
- 远程仓库:是在远程服务器上的Git仓库
操作:
- clone:克隆,就是将远程仓库复制到本地
- push:推送,就是将本地仓库代码上传到远程仓库
- pull:拉取,就是将远程仓库代码下载到本地仓库
- commit:提交,就是将本地工作区代码上传到本地仓库中。
优点
- 容灾能力强
- 本地版本管理
- 异地协作
- 灵活分支
二、工具
1.命令行工具:Git for windows
2.操作系统中可视化工具:TortoiseGit
下载地址: tortoisegit.org/
TortoiseGit 2.8.0-64-bit
3.GitHub网站
三、安装环境搭建
1.安装
安装时选择环境建议选择Use Git from Git Bash only
,不推荐和windows的命令行窗口混用。
设置全局用户签名
- 安装完成后,在任意的文件目录下,右键都可以打开Git的命令行窗口——Git Bash Here
- Git是分布式版本控制系统,所以需要填写用户名和邮箱作为一个表示——即:用户签名
说明
签名的作用是区分不同操作作者身份。用户的签名信息在每一个本本的提交信息中能够看到,依次确认提交是谁做的。
注意
这里设置用户签名和抢来登录GitHub(或其他代码托管中心)的账号没有任何关系
命令
git config --global user.name "用户名"
git config --global user.email "用户邮箱"
--global表示全局属性,所有的git项目都会公用属性
查看配置信息:git config --list
在当前登录的系统用户路径下,生成 ~/.gitconfig隐含文件,里面可以看到刚刚设置的信息。如果不用命令设置,也可以直接打开文件进行设置。
四、相关概念
1.工作区vs版本库vs暂存区
- 工作区:就是我们自己电脑本地硬盘目录,一般是项目当前目录
- 版本库:工作区有一个隐藏目录.git,它就是Git的本地版本库
- 暂存区:一般存放在“git目录”下的index文件(.git/index)中,所以我们把暂存区有时也叫做索引(index)
- 分支(Branch):Git为我们自动创建的第一个分支master,以及指向master的一个指针叫head
2.提交Git版本库分两步执行
第一步:
用“git add”把文件纳入Git管理,实际是把本地文件修改添加到暂存区
第二步:
用“git commit”提交更改,实际上就是把暂存区的所有内容提交到当前分支
因为我们创建Git版本库时,Git自动为我们创建了唯一一个master分支,所以commit就i是网master分支上提交更改。
可以简单理解为,需要提交的文件膝盖统统放到暂存区,然后一次性提交暂存区的修改。一旦提交完之后,如果你又没有对工作区做任何修改,那么工作区就是“干净的”。
其他操作
①用“git diff HEAD -- filename”命令可以查看工作区和暂存区里面最新版本的区别。
②从先从缓存区中拉取版本还原,如果没有再到版本库中拉取还原到工作区:git checkout -- 文件名
③撤销已add未commit:先git reset [HEAD] 文件名,再git checkout -- 文件名
④撤销已add已commit:git reset --hard HEAD^
五、常用命令
命令名称 | 命令作用 |
---|---|
git init | 初始化本地库 |
git config --global user.name 用户名 | 设置用户签名的用户名部分 |
git config --global user.email 邮箱 | 设置用户签名的邮箱部分 |
git status | 查看本地库状态 |
git add 文件名 | 添加到暂存区 |
git commit -m "日志信息" 文件名 | 提交到本地库 |
git reflog | 查看历史记录 |
git reset --hard 版本号 | 版本穿梭 |
如何初始化版本库
要使用Git对我们的代码进行版本控制,首先要获得Git仓库,获取Git仓库通常有两种方式:
- 再本地初始化一个Git仓库
- 从远程仓库克隆
本地初始化操作步骤:
- 创建目录(用作本地版本库),例如:D:\DevRepository\GitRepository\oa,oa表示办公自动化项目名称
- 当前目录打开Git Bash窗口,初始化仓库。命令:git init
- 查看当前目录产生的.git隐藏文件夹
- 注意:当前的.git是一个隐藏文件夹,需要再电脑上面设置隐藏文件夹显示设置,否则,看不到这个.git目录
新建\提交\状态:
- 新建文件
- 命令:touch a.txt
- 命令:vim a.txt
- 查看文件状态
- 命令:git status
- On branch master :表示主分支
- Untracked files:表示未跟踪状态
- 说明
- git工作目录下的文件状态信息:
- Untracked:未跟踪(未被纳入版本控制)
- Tracked:已跟踪(被纳入版本控制)
- Unmodified :未修改状态
- Modified:已修改状态
- Staged:已暂存状态
- 这些文件的状态会随着我们执行git的命令发生变化
- 红色表示新建文件或者新修改的文件,都在工作区
- 绿色表示文件在暂存区
- 新建的文件在工作区,需要添加到暂存区并提交到仓库区
- 也可以使用git status -s使输入信息更加简洁
- ??:表示为跟踪状态
- git工作目录下的文件状态信息:
- 命令:git status
- 添加到暂存区
- 命令:
- git add [文件名称]
- 只是增加到占空间(index文件)中,还没有添加到本地库中。初始化时没有这个index文件。这还是一个新文件,需要将栈空间文件提交到本地仓库
- git add
- 添加项目中的所有文件
- git add hello.txt
- 添加未存在文件会出错:§ fatal: pathspec 'hello.txt' did not match any files
- git add [文件名称]
- 命令:
- 撤销暂存区的文件
- 命令:
- git reset [文件名称]
- 撤销后,查看文件状态(git status)文件由绿色变为红色
- git reset [文件名称]
- 命令:
- 将暂存区文件提交到本地库
- 命令:
- git commit
- 执行命令时需要填写提交日志,进入编辑模式
- git commit -m "注释内容"
- 直接用-m参数指定日志内容。推荐。
- commit会生成一条版本记录,add只是添加暂存区,不会生成版本记录,建议多次add后,一次性commit,避免每次add都commit产生版本信息爆炸
- git commit -am "注释内容"
- 代码编辑完成后即可进行add和commit操作
- 提示:添加和提交合并命令
- git commit
- 命令:
如何查看日志
命令:
- git log
- git log a.txt
- 查看文件日志(查看所有日志或某个文件日志)
- q退出
- git log --pretty=oneline
- 如果日志很多,可以在一行显示
- git reflog
- 查看历史操作
回退\穿梭\撤销
- 回退到历史版本
- git reset --hard HEAD^
- 一次回退一个版本,一个^代表一个版本输俩个
- git reset --hard HEAD~n
- 回退n次操作
- git reset --hard HEAD^
- 版本穿梭
- git reflog a.txt
- 查看历史操作
- git reset --hard 版本号
- 回到最新版本
- git reflog a.txt
- 撤销
- 未add,未commit
- vim修改文件,没有add和commit,进行撤销
- 命令:
- git checkout -- a.txt
- 撤销修改(还原原来的文件)
- git checkout -- a.txt
- 已add,未commit
- vim修改文件,添加add,但是没进行commit,进行撤销
- 命令
- git add a.txt
- git reset
- 软回退:
- 查看文件内容:cat a.txt
- 查看日志:git reflog a.txt
- 软回退:
- 未add,未commit
删除
命令:
- rm [文件名]
七、分支
几乎所有的版本控制系统都以某种形式支持分支。使用分支意为着你可以把你的工作从开发主线上分离开来,以免影响开发主线。Git的master分支并不是一个特殊分支。它跟其他分支没有区别。之所以几乎每一个仓库都有master分支,是因为git init命令默认创建它,并且大多数人都懒得去改动它。
1.概念
在使用版本控制工具开发的过程中,同时推进多个任务
2.好处
同时并行推进多个功能开发,提高开发效率。
各个分支在开发过程中,如果某一个分支开发失败,不会对其他分支有任何影响。失败的分支删除重新开始即可。
3.命令
命令名称 | 作用 |
---|---|
git branch 分支名 | 创建分支 |
git branch -v | 查看分支 |
git checkout 分支名 | 切换分支 |
git merge 分支名 | 把指定的分支合并到当前分支上 ,分支合并命令的本质就是把“目标分支”合并到“当前分支” |
八、版本冲突
1.冲突产生的表现
Git使用“<<<<<<<、=========、>>>>>>>>>>”符号帮我们标记出来,现在产生冲突的内容。
<<<<<<< HEAD
Hello Git!I am very happy! &&&&&&&&&&&&
Hello Git!I am very happy!
=======
表示HEAD指针指向的位置在冲突中的内容
复制代码
=======
Hello Git!I am very happy!
Hello Git!I am very happy! ************
>>>>>>> hotfix
表示hotfix指针指向的位置在冲突中的内容
复制代码
2.冲突产生的原因
合并分支时,两个分支在同一个文件的同一个位置有两套完全不同的修改。git无法替我们决定使用哪一个。必须人为决定新代码内容。
3.冲突的解决
①编辑有冲突的文件,删除特殊符号,决定要使用的内容
②添加到暂存区
③执行提交(注意:使用git commit命令时不能带文件名)
4.避免冲突
- 容易冲突的操作方式
- 多个人同时操作了同一个文件
- 一个人一直写不提交
- 修改之前不更新最新代码
- 提交之前不更新最新代码
- 擅自修改同事代码
- 减少冲突的操作方式
- 养成良好的操作习惯,先
pull
在修改,修改完立即commit
和push
- 一定要确保自己正在修改的文件是最新版本的
- 各自开发各自的模块
- 如果要修改公共文件,一定要先确认有没有人正在修改
- 下班前一定要提交代码,上班第一件事拉取最新代码
- 一定不要擅自修改同事的代码
九、github远程库
git分为两种类型的仓库,即本地仓库和远程仓库。
比较常用的有GitHub、码云、GitLab等
-
lgitHub( 地址:github.com/ )
是一个面向开源及私有软件项目的托管平台,因为只支持Git 作为唯一的版本库格式进行托管,故名gitHub
-
码云(地址: gitee.com/ )
是国内的一个代码托管平台,由于服务器在国内,所以相比于GitHub,码云速度会更快
- GitLab (地址: about.gitlab.com/ )
是一个用于仓库管理系统的开源项目,使用Git作为代码管理工具,并在此基础上搭建起来的web服务
1.简介
github是一个git项目托管网站。主要提供基于git的版本托管服务。
github是一个基于git的代码托管平台, Git 并不像 SVN 那样有个中心服务器。目前我们使用到的 Git 命令都是在本地执行,如果你想通过 Git 分享你的代码或者与其他开发人员合作。 你就需要将数据放到一台其他开发人员能够连接的服务器上。
2.命令
创建本地项目
新建文件夹作为项目目录。在目录下执行执行
- git init
- git config user.name "zhangsan"
- git config user.email "[email protected]"
- 打开.git\config文件可以看到我们自定义的name和email
提交代码到本地库
我们提交一个名为love.txt的文件到本地库
- touch love.txt
- vim love.txt
- git add love.txt
- git commit -m "love form zhangsanatguigu" love.txt
登录账号到github,创建远程仓库
①登录后没有任何项目情况下,会显示如下页面
②创建新的仓库
③填写创建新仓库信息
④创建后出现仓库地址,注意:点一下HTTPS,换下地址。
将本地项目推送到远程库
- 增加远程地址
- git remote add <远端代号> <远端地址>
- 远端代号是指远程连接的代号,一般直接用origin作为代号,也可以自定义
- 远端地址默认远程连接的url,也就是上一步创建远程仓库后的http仓库地址。
- git push <远端代号> <本地分支名称>
- 远端代号是指远程连接的代号
- 本地分支是指要提交的分支名字,比如master
- 例如:git push origin master
从GitHub上克隆一个项目
在我们的项目目录下打开客户端窗口,执行命令下载远端项目
- git clone <远端地址> <新项目目录名>
- 远端地址是指远程连接的地址
- 项目目录名是指给克隆的项目在本地新建的项目名称,可以不填,默认是GitHub的项目名
- 命令执行后,会自动为这个远端地址新建一个名为origin的代号
使用账户提交修改项目内容
配置另一组账号和邮箱
git config user.name "lisi"
git config user.email "[email protected]"
复制代码
使用这个账号执行下面操作
-
修改提交到本地库
#进入后修改 vim love.txt git add love.txt #提交时附上日志信息 git commit -m "lisi rep yes" 复制代码
-
发现本地库提交到远程库时,权限不够。
git push origin master 复制代码
注:
- clone会自动关联到远端地址为origin默认名称,所以不需要git remote
- lisi账户提交修改内容,访问被拒绝,权限不够
- 以上对项目的操作方式,必须是项目的创建者或者合作伙伴
- 合作伙伴添加方式:github官网,在项目中点击settings页签,然后点击Collaborators,然后在文本框中搜索合作伙伴的邮箱或者账号。点击添加。
-
设置权限
- setting->Collaborators->添加合作伙伴
- 邀请函已经发送到lisi账户的邮箱
- lisi登录邮箱,打开链接
- lisi接收邀请,则合作伙伴正式加入项目,获得直接提交代码的权限。
-
lisi重新提交,提交成功
更新本地文件
- 更新前查看,命令:ll,查看文件内容:cat 文件名
- 更新
- git pull origin master
- 更新后查看,cat 文件名
十、协作冲突
1.说明
在上传或同步代码时,由于你和他人都该了统一文件的同一位置的代码,版本关联软件无法判断以谁为准,就会报告冲突,需要程序员手动解决。
2.冲突演示
①zhangsan修改并提交到远端
cat love.txt
vim love.txt
#修改为冲突内容
git add love.txt
git commit -m "meet you tonight"
cat love.txt
git push origin master
复制代码
②lisi修改并提交到远端
cat love.txt
vim love.txt
#修改为冲突内容
git add love.txt
git commit -m "tonight lisi"
cat love.txt
git push origin master
复制代码
③lisi先pull,合并冲突,再push,OK
git pull origin master
git diff
cat love.txt
vim love.txt
cat love.txt
git add love.txt
git commit -m "解决冲突"
git push origin master
复制代码
git diff:当工作区有改动,临时区为空,diff的对比是“工作区与最后一次commit提交的仓库的共同文件”;当工作区有改动,临时区不为空,diff对比的是“工作区与暂存区的共同文件”。
十一、跨团队协作
1.fork
概念:
现在的情景是,用叉子把别人的东西(copy no cut)叉到你的碗里~
就是把别人的项目clone一份,但是owner变成自己,这样你就可以在遵守Open source license的前提下任意修改这个项目了。
相当于你在原项目的主分支上又建立了一个分支,你可以在该分支上任意修改,如果想将你的修改合并到原项目中时,可以pull request,
这样原项目的作者就可以将你修改的东西合并到原项目的主分支上去,这样你就为开源项目贡献了代码,开源项目就会在大家共同的努力下不断壮大和完善。
场景:
zhangsan和lisi是一个团队的人,wangwu是另一个团队的人。
流程:
第三方账号登录(wangwu),搜索某账号找到某项目(zhangsan),然后点击fork按钮,这样就将该项目克隆一份到当前的账号(wangwu)内,然后进行修改,提交pull request,告诉zhangsan已经修改了,请求合并;
zhangsan登录后,可以看到小铃铛中的消息提醒,查看到pull request,然后选择合并或者拒绝。
2.fork详细流程
①wangwu获取zhangsan的项目URL(可以进行搜索,也可以通过email发送url地址告知)
②wangwu点击fork,产生分支
③wangwu修改项目文件(可以拉取pull到本地后修改,也可以在github上直接进行修改)
④wangwu->new pull request
⑤wangwu->create pull request->填写pull request信息
⑥分支已提交到主分支
⑦zhangsan和lisi都可以看到wangwu提交的项目内容
⑧zhangsan合并项目,点击merge pull request->点击comfirm merge
⑨zhangsan可以查看合并完项目代码,合并完成
十二、问题
1.解决重复输入密码问题
两种模式:https VS ssh
ssh模式比https模式的一个重要好处就是,每次push,pull,fetch等操作时不用重复填写用户名密码。
前提是你必须是这个项目的拥有者或合作者,且配好了ssh key
如何配置ssh key
-
检查家电脑目录下是否已经生成了SSH key,如果有.ssh目录删除即可
-
创建SSH Key: ssh-keygen -t rsa -C lisi
-
成功的话(执行命令不需要输入任何内容),会在~/下生成.ssh文件夹,查看生成两个文件:
- id_rsa
- id_rsa.pub
打开id_rsa.pub,复制里面的内容到github上。
-
-
登录lisi账户,打开用户设置点击[SSH and GPG keys] 填写Title和Key,点击[Add SSH key]
测试
①复制SSH的url连接
②lisi重新建立github连接,如果之前配置过则删除重新配置。
命令:
git remote add originssh "SSH的url"
git push originssh master
修改文件,重新提交,不需要再输入用户名和密码了
注意
一个账户只能设置一个默认密码。
如果有多个账号存在的话,只能选择设置其中某一个。
2.配置git忽略文件
哪些文件要忽略?
.idea中的特定文件:项目下的*.iml文件和.idea文件夹
maven工程的target目录。
为什么忽略?
与项目的实际功能无关,不参与服务器上部署运行。把它们忽略掉能够屏蔽IDE工具之间的差异。
怎么忽略
1.创建忽略规则文件(git.ignore)
这个文件的存放位置原则上在哪里都可以,为了便于让~/.gitconfig文件引用,建议也放在用户家目录下
# Compiled class file
*.class
# Log file
*.log
# BlueJ files
*.ctxt
# Mobile Tools for Java (J2ME)
.mtj.tmp/
# Package Files #
*.jar
*.war
*.nar
*.ear
*.zip
*.tar.gz
*.rar
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
.classpath
.project
.settings
target
.idea
*.iml
复制代码
2.在.gitconfig文件中引用忽略规则文件
[user]
name = peter
email = [email protected]
[core]
excludesfile = C:/Users/Lenovo/git.ignore
复制代码
注意:这里要使用“正斜线(/)”,不要使用反斜线(\)
十三、idea集成git
1.定位git程序
setting->git->设置path to git executable定位到git.exe
2.初始化本地库
VCS->import into version control->create git repository->选择要创建git本地库的工程
3.添加到暂存区
右键选中要添加到暂存区的工程->Git->Add
4.提交到本地库
右键选中要提交到本地库的工程->Git->Commit Directory
5.创建分支
右键选中工程->Git->Repository->Branches...->new Branch ->填写新分支的名字。
5.切换分支
在idea窗口的右下角,点击Git :master->选择目标分支->checkout
6.合并分支
点击Git :master->选择合并的另一个分支->点击Merge into Current
8.解决冲突
在和远程库交互过程中也有可能发生冲突,因为解决办法一样,所以这里按照分支操作过程中产生的冲突来演示。
1.冲突的产生
仍然是同一个文件在同一个位置有不同内容。
2.合并分支
点击Git :master->选择合并的另一个分支->点击Merge into Current
3.看到冲突提示
这里可以直接点“Accept Yours”或者“Accept Theirs”来解决冲突。这代表完全使用我们的内容或完全使用他们的内容。
如果我们想要详细修改冲突内容则点击Close。此时IDEA会提示Resolve...。
4.冲突的表现
5.点击Resolve
点击Merge...->根据需要调整完成->点击“Save changes and finish merging”->提交到本地库,完成
十四、在idea中连接GitHub
1.保存GitHub账号
setting->搜索GitHub->add account->输入登录信息
2.分享工程到GitHub
VCS->import into version control ->share Project on GitHub->填写工程信息->share->idea显示Successfully shared project on GitHub,说明成功了
3.clone
VCS->Git->Clone...->填写github仓库URL和克隆工程的目录位置->clone->yes->提示你是否在当前窗口打开这个工程
4.Push
右键选中工程->Git->Repository->Push...
5.Pull
右键选中工程->Git->Repository->Pull...->勾选Branches to merge中要拉取哪一个分支的代码->Pull
十五、Git工作流
1.简介
简单来说就是,一个项目的成员们在工作中统一使用Git的工作方式。
Gitflow工作流通过为功能开发、发布准备和维护设立了独立的分支,让发布迭代过程更流畅。严格的分支模型也为大型项目提供了一些非常必要的结构。
2.分支种类
- 主干分支 master
主要负责管理正在运行的生产环境代码。永远保持与正在运行的生产环境完全一致。
- 开发分支 develop
主要负责管理正在开发过程中的代码。一般情况下应该是最新的代码。
- bug修理分支 hotfix
要负责管理生产环境下出现的紧急修复的代码。 从主干分支分出,修理完毕并测试上线后,并回主干分支。并回后,视情况可以删除该分支。
- 发布版本分支 release
较大的版本上线前,会从开发分支中分出发布版本分支,进行最后阶段的集成测试。该版本上线后,会合并到主干分支。生产环境运行一段阶段较稳定后可以视情况删除。
- 功能分支 feature
为了不影响较短周期的开发工作,一般把中长期开发模块,会从开发分支中独立出来。 开发完成后会合并到开发分支。
十六、Gitlab私服
注意:要使用CentOS7版本安装,CentOS6版本不行。
1.官网地址
安装说明:about.gitlab.com/installatio…
2.提前下载所需rpm
yum安装gitlab-ee(或ce)时,需要联网下载几百M的安装文件,非常耗时,所以应提前把所需RPM包下载并安装好。
下载地址是:packages.gitlab.com/gitlab/gitl…
下载好后上传到Linux系统,习惯上还是放在/opt目录下
3.安装步骤
sudo rpm -ivh /opt/gitlab-ce-10.8.2-ce.0.el7.x86_64.rpm
sudo yum install -y curl policycoreutils-python openssh-server cronie
#sudo yum install lokkit
sudo lokkit -s http -s ssh
sudo yum install postfix
#yum install keyutils-libs-devel libcom_err-devel libselinux-devel libverto-devel -y
#rpm -ivh mysql-community-libs-compat-5.7.28-1.el7.x86_64.rpm
sudo systemctl enable postfix.service
sudo chkconfig postfix on
curl https://packages.gitlab.com/install/repositories/gitlab/gitlab-ce/script.rpm.sh | sudo bash
sudo EXTERNAL_URL="http://gitlab.example.com" yum -y install gitlab-ce
复制代码
当前步骤完成后重启。
4.Gitlab服务操作
- 初始化配置:gitlab-ctl reconfigure
- 启动Gitlab服务:gitlab-ctl start
- 停止Gitlab服务:gitlab-ctl stop
5.浏览器访问
访问Linux服务器IP地址即可,如果想访问EXTERNAL_URL指定的域名还需要配置域名服务器或本地hosts文件。
初次登录时需要为gitlab的root用户设置密码。