什么是git
git是一个 分布式版本控制软件,最初由林纳斯·托瓦兹(Linus Torvalds)创作,于2005年以GPL发布。
最初目的是为更好地管理Linux内核开发而设计。应注意的是,这与GNU Interactive Tools(一个类似Norton Commander界面的文件管理器)有所不同。
git最初的开发动力来自于BitKeeper和Monotone。git最初只是作为一个可以被其他前端(比如Cogito或Stgit)包装的后端而开发的,但后来git内核已经成熟到可以独立地用作版本控制。
很多著名的软件都使用git进行版本控制,其中包括Linux内核、X.Org服务器和OLPC内核等项目的开发流程。 ——维基百科
为什么使用git
- 传输速度快, 查看历史版本快
- 登录认证更安全 - SSH RSA认证
- 分支合并更方便
- Git版本库占用空间小
- 代码托管更安全 - 分布式托管
- 大量文件add, submit不会奔溃
- 更强大的功能: git bash
git安装
Ubantu/Debian
apt-get install git
Mac/Windows
在官网下载相对应平台的git版本, 如果需要GUI客户端, 可在这个链接下载: GUI Clients
很多IDE, 比如VSCode WebStormd等都集成git面板, 可以代替git客户端来执行git操作
补充: Windows平台VSCode终端集成git bash
VSCode默认的终端是cmd/power shell, 我们可以在上面的链接下载安装git后, 将VSCode的终端设置为bash
安装完git后, 找到
bash.exe
的路径打开VSCode用户设置, 修改终端使用路径
1
2
3{
"terminal.integrated.shell.windows": "C:\\Program Files\\Git\\bin\\bash.exe" // 你的bash.exe路径
}ctrl + `打开VSCode控制台, 看到你的终端是bash说明设置已经成功
git基本操作
代码托管平台Gitlab
Gitlab是一个类似Github的基于Ruby on Rails开源版本管理系统, 实现一个自托管的Git项目仓库, 可通过Web界面访问公开或私人项目.
操作入门
LDAP方式登录Gitlab
明确自己的name和email
在git bash中执行生成ssh key
ssh-keygen -t rsa -C "your.email@example.com"
Gitlab SSH Keys管理
cat ~/.ssh/id_rsa.pub
把公钥发布到Gitlab平台的SSH Keys上测试ssh的rsa免密码认证是否成功
ssh -T -vvv git@[Gitlab域名].com
git全局设置
1
2
3
4
5
6
7
8
9
10git config --global push.default simple
git config --global core.quotepath false
git config --global core.autocrlf false
git config --global core.longpaths true
git config --global user.name "$name"
git config --global user.email "$email"
git config --global alias.st status
git config --global alias.ci commit
git config --global alias.co checkout
git config --global alias.br branch按不同的Gitlab域名或用户来选择证书
vi ~/.ssh/config
1
2
3
4
5
6
7Host gitlab1
HostName git1.xxx.com
IdentityFile C:/Users/myuser1/.ssh/id_rsa
User git
Host git2.xxx.com
IdentityFile C:/Users/myuser2/.ssh/id_rsa
User git创建新的仓库(repository)
在Gitlab创建好一个project, 接着执行1
2
3
4
5
6git clone git@xxx.com/:author/hello-world.git
cd hello-world
cd touch README.md
git add README.md
git commit -m "Add README"
git push -u origin master上面操作主要做了:
- 从远程git仓库拷贝(clone)到本地仓库, 然后进入项目目录
- 创建一个README markdown文件, 该文件一般是保存对项目的说明和操作流程等等需要告知使用着的信息
- 将README.md添加(add)到索引中, 并提交(commit)
- 最后推送(push)到远程master分支
本地项目关联到远程仓库
1
2
3
4
5
6cd existing_folder
git init
git remote add origin git@xxx.com/:author/hello-world.git
git add .
git commit -m "Add all files"
git push -u origin master上面操作主要做了:
- 进入项目目录, git初始化
- 添加远程仓库关联
- 接下来就是做提交推送的操作
Git与Gitlab协同开发
仓库(Repository)
源仓库(线上版本库)
在项目的开始, 项目的发起人构建一个项目的最原始的仓库, 成为origin. 用于汇总参与项目的各个开发者的代码和存放趋于稳定和可发布的代码.
源仓库应该是受保护的, 开发者不应该直接对其进行开发工作. 只有项目管理者能对其进行较高权限的操作
开发者仓库(本地仓库)
任何开发者都不会对源仓库进行直接操作, 源仓库建立后, 每个开发者需要将源仓库fork到自己日常开发的仓库. 每个开发者fork后的仓库都是完全独立, 互不干扰的. 当开发工作完成后, 开发者可以向源仓库发送pull request, 请求源仓库管理员把自己的代码合并到源仓库中, 这样就实现了分布式工作和集中式管理.
分支
master(主分支)
主分支从项目开始就一直存在, 它存放经过测试后已经稳定的代码, 在项目开发以后的任何时刻, master存放的代码应该是作为产品供用户使用的代码
master分支的代码应该保持代码整洁和稳定, 确保入库前都应该通过完全测试和code review.
master分支是所有分支中最不为活跃的分支, 大概每个月或每两个月更新一次, 每次更新的时候都应该用git打上tag来说明产品有新版本发布.
develop(开发分支)
develop分支一开始从master分支分离出来, 用于开发者存放基本稳定的代码.
每个开发者的仓库相当于源仓库的一个镜像, 每个开发者自己的仓库上也有master和develop. 开发者完成功能后, push到自己的develop分支, 测试完成后, 向源仓库发起pull request, 请求管理员将自己的develop分支merge到源仓库的develop分支中.
所有开发者开发的功能都会在源仓库的develop分支中汇总. 当develop分支的代码不断测试, 逐渐趋于稳定接近产品目标, 这时就可以将develop分支merge到master分支, 发布新版本.
注: 任何人都不应该向master分支进行无意义的push/merge操作. 正常情况下, master只接受来自develop的合并.
feature(功能分支)
feature分支用于开发项目的功能分支, 存放各个功能的代码.
开发者在本地仓库从develop分支开多一个功能分支, 在该分支下进行开发, 完成之后再merge到develop分支上, 这时候功能性分支已经完成任务, 可以将其删除.
功能分支一般将其命名为feature-, 为功能名称.
集中式工作流(适用于1-3人协同开发)
当两个开发者从中心仓库clone代码下来, 同时作了一些代码更改, 只有在第一个开发者已经成功push代码到远程仓库中, 第二个开发者在push前, 必须先下载并合并远程仓库代码, 解决冲突后才能进行push到远程仓库.
创建源仓库
由项目发起人进行操作, 假设源仓库为mygroup/myproject, 并初始化两个分支develop和master.clone源仓库到本地
git clone git@git.xxx.com:mygroup/myproject.git
创建功能分支进行开发
假设现在要开发一个”资产收集”功能- 首先切换到develop分支
git checkout develop
- 分出一个功能分支
git checkout -b feature-gather_facts
- 假设gather-facts.js是完成功能的文件
1
2git add gather-facts.js
git commit -m "Finished gather-facts feature"
- 首先切换到develop分支
feature-gather_facts分支的功能已经完成, 切换回develop
git checkout develop
从源仓库pull下来最新的代码, 如果有合并冲突先解决冲突
1
2
3git pull
// or
git fetch && git merge将feature-gather_facts分支merge到develop分支
git merge --no-ff feature-gather_facts
删除feature-gather_facts
git branch -d feature-gather_facts
将本地develop分支push到远程仓库
git push origin develop
集成管理员工作流(适用于3人以上协同开发)
由于git允许多个远程仓库, 开发者可以建立自己的公共仓库, 往里面写数据并共享给他人, 同时又可以从别人的仓库中提取他们的更新. 这种情况下通常有个官方发布的项目仓库, 开发者们由此仓库克隆出一个自己的公共仓库, 然后将自己的提交推送上去, 请求官方仓库的维护者拉取更新合并到主项目. 维护者在自己的本地也有克隆仓库, 他可以将你的公共仓库作为远程仓库添加进来, 经过测试无误以后合并到主分支, 然后再推送到官方仓库.
创建源仓库
开发者fork源仓库
源仓库建立后, 每个开发者都可以fork到自己的gitlab上, 作为自己开发所用的仓库. 假设我的gitlab账号是myuser, 我从源仓库mygroup/myproject fork到myuser/myprojectclone源仓库到本地
git clone git@git.xxx.com:myuser/myproject.git
开发功能, 推送到自己的远程仓库等步骤参考上一个标题
向管理员提交pull request
经过测试之后, 在myuser/myproject中发起pull request, 请求源仓库管理员把自己的develop分支合并到源仓库的develop分支管理员测试, 合并
管理员需要对开发者的pull request进行code review, 然后新建测试分支, 测试开发者的代码- 进入管理员本地的develop分支
git checkout develop
- 从develop分支分出一个manager-develop的测试分支测试开发者代码
git checkout -b manager-develop
- 把开发者代码pull到测试分支中进行测试
git pull git@git.xxx.com:myuser/myproject.git develop
- 进入管理员本地的develop分支
管理员测试, 合并
经过测试没问题, 管理员可以将开发者代码合并到源仓库的develop中1
2
3
4git checkout develop
git merge --no-ff manager-develop
git branch -d manager-develop
git push origin develop
Gitlab权限控制
授权形式
只能对整个project授权, 不能针对project内的目录或文件精确授权授权原则
- 注意控制gitlab中project的权限
- 普通开发者给予Developer角色
- 只有Owner角色才能删除project, 不要随意授权其他人Owner权限
- 集成管理员工作流一般需要Master角色, 集中式工作流通常无需创建Master角色
- Developer角色无法直接将代码合并到master分支, 但可以发起pull request, 通知Master角色或Owner角色处理, 保障master分支的代码是完整的, 正确的, 及时拦截Developer角色提交存在的问题