git及gitlab实操教程
git命令大全
https://www.ruanyifeng.com/blog/2015/12/git-cheat-sheet.html
git及gitlab教程
https://www.bilibili.com/video/BV1NK421Y7XZ/?spm_id_from=333.337.search-card.all.click&vd_source=353000f23d853514bafd04fb97ce5920
规范链接
大厂都在用的Git代码管理规范: https://juejin.cn/post/7275595571733233701
1、预备知识
1.1 群组和项目
1)从目录结构上看,group类比于文件夹, group用于分类、分层级,group中可以包含subgroup,project类比文件,存放在group中;
2)个人帐号也可以创建project,project在个人空间下,group和个人帐号全局唯一,可以理解gitlab为根目录/,用户和group是根目录下的文件夹,不能同名
1.2 权限和角色
官方文档(权限和角色):https://docs.gitlab.com/ee/user/permissions.html,gitlab权限可分为访问权限和行为权限
1.2.1 访问权限
创建群组或项目时,需要为其设置访问权限,即这个群组或项目能被哪些用户看到或查询到。该权限有3种,分别是private、internal以及public。
1)群组访问权限如下所述:
- private: 只有群组成员能访问
- internal: 除外部用户之外的任何登录的用户都可以查看群组及群组内的internal项目
- public: 开源,任何用户都能查看该群组以及该群组内的public项目
2)项目访问权限如下所述:
- private: 只有项目成员能访问
- internal: 除外部用户之外的任何登录的用户都可以查看
- public: 任何用户都能查看
群组中的项目或者子组的访问权限受到父级群组的限制,如果父级群组访问权限是internal,则项目或子组只能设置为internal或者private
如果用户同时被添加到群组和群组中的项目,则用户的访问权限取两者最大。比如群组A访问权限是public,群组中A中的项目b访问权限为internal,则:1)任何人都能看到这个群组A,看不到项目b,2)只有登录验证的用户才能看到项目b
1.2.2 行为权限
当邀请用户加入到一个群组或者项目时,可以设置这个用户在群组或项目的角色,这里的角色决定了该用户对群组和项目的行为权限,项目和群组的角色可分为:
- Guest 访客
- Reporter 报告人,可以理解为测试员、产品经理等,一般负责提交issue等
- Developer 开发者 (如果是协同开发,邀请其他人一般设置这个角色)
- Maintainer 维护者,一般是组长,负责对Master分支进行维护
- Owner 项目/群组所有者,一般是项目经理
- Minimal Access (available for the top-level group only)
参考链接:https://gist.github.com/AgoniNemo/ebbb33e757e8261f2531c90e28ea71c3#file-gitlab-md
项目权限
行为 | Guest | Reporter | Developer | Maintainer | Owner |
---|---|---|---|---|---|
创建issue | ✓ | ✓ | ✓ | ✓ | ✓ |
留言评论 | ✓ | ✓ | ✓ | ✓ | ✓ |
更新代码 | ✓ | ✓ | ✓ | ✓ | |
下载工程 | ✓ | ✓ | ✓ | ✓ | |
创建代码片段 | ✓ | ✓ | ✓ | ✓ | |
创建合并请求 | ✓ | ✓ | ✓ | ||
创建新分支 | ✓ | ✓ | ✓ | ||
提交代码到非保护分支 | ✓ | ✓ | ✓ | ||
强制提交到非保护分支 | ✓ | ✓ | ✓ | ||
移除非保护分支 | ✓ | ✓ | ✓ | ||
添加tag | ✓ | ✓ | ✓ | ||
创建wiki | ✓ | ✓ | ✓ | ||
管理issue处理者 | ✓ | ✓ | ✓ | ||
管理labels | ✓ | ✓ | ✓ | ||
创建里程碑 | ✓ | ✓ | |||
添加项目成员 | ✓ | ✓ | |||
提交保护分支 | ✓ | ✓ | |||
使能分支保护 | ✓ | ✓ | |||
修改/移除tag | ✓ | ✓ | |||
编辑工程 | ✓ | ✓ | |||
添加deploy keys | ✓ | ✓ | |||
配置hooks | ✓ | ✓ | |||
切换visibility level | ✓ | ||||
切换工程namespace | ✓ | ||||
移除工程 | ✓ | ||||
强制提交保护分支 | ✓ | ||||
移除保护分支 | ✓ |
群组权限
行为 | Guest | Reporter | Developer | Maintainer | Owner |
---|---|---|---|---|---|
浏览组 | ✓ | ✓ | ✓ | ✓ | ✓ |
编辑组 | ✓ | ||||
创建项目 | ✓ | ✓ | |||
管理组成员 | ✓ | ||||
移除组 | ✓ |
2、基础配置
2.1 添加ssh key
gitlab有http和ssh两种方式进行项目推送和拉取,ssh方式首先需要先将自己的ssh公钥填写到gitlab上;http方式每次push和pull都需要输入帐号密码,比较繁琐,所以最好使用ssh方式
创建ssh密钥
~$ ssh-keygen -t rsa -C "your_emial@examle.com" # 这里的邮箱帐号只是起到一个标识作用
Generating public/private rsa key pair.
Enter file in which to save the key (/home/xxx/.ssh/id_rsa): # 直接回车或填写保存路径
Enter passphrase (empty for no passphrase): # 直接回车
Enter same passphrase again: # 直接回车
Your identification has been saved in /home/xxx/.ssh/id_rsa
Your public key has been saved in /home/xxx/.ssh/id_rsa.pub
~$ cat ~/.ssh/id_rsa.pub # 会显示公钥,将公钥内容复制到粘贴版
gitlab填写公钥
- 点击头像,弹出的下拉框中选择Preferences,
- 找到侧边栏的SSH Keys,点击
- 填写公钥内容
2.2 配置git帐号邮箱
帐号邮箱一个用途是用于记录git提交。
如果没有在项目的git配置文件中设置帐号邮箱,则项目使用全局帐号邮箱,如果在项目中设置了帐号邮箱,则优先使用项目中设置的帐号邮箱。
全局配置
# 查看全局git配置
$ git config --global user.name
$ git config --global user.email
# 设置全局git配置
$ git config --global user.name "zhangsan"
$ git config --global user.email "zhangsan@example.com"
项目配置
首先要保证已经在项目中进行了git初始化,git初始化后会在当前项目目录的.git中产生config文件,该文件保存了项目的配置信息,项目中的配置信息优先级高于全局配置
$ cd project
$ cat .git/config # 查看项目配置
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
$ git config user.name "zhangsan"
$ git config user.email "zhangsan@example.com"
$ cat .git/config # 再次查看
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
[user]
name = zhangsan
email = zhangsan@example.com
3、创建群组和项目
3.1 创建群组
创建组的步骤如下:
1)打开创建群组的界面,首先填写群组名
2)选择群组的访问权限
3)个性化定制,填写Role(这里的Role和之前说的角色不是同一个概念)、用途以及group的目的,这个可填可不填,对项目没有影响,填了这个,gitlab给一些推荐提示。
3.2 创建空项目
创建空项目,自带readme文档
步骤如下:
1) 在群组中打开项目创建页面,填写项目名
2) 选择项目的访问权限
3)项目配置,默认选中”初始化仓库以及readme文档“
点击按钮创建项目,项目配置中选中了“初始化仓库以及readme”时,创建后的项目会有一个readme文档,该文档会给一些建议,告知如何拉取推送以及其他内容
3.3 创建项目并初始化已有项目
有时候我的项目已经写好了代码,但并没有进行版本管理,因此这种方式则是帮助你将已有项目推送到gitlab
步骤如下:
1) 在群组中打开项目创建页面,填写项目名
2) 选择项目的访问权限
3)项目配置,取消勾选 "初始化仓库以及readme文档"
点击按钮创建项目,此时创建了一个空项目,该项目并没有readme文件以及初始化,但是在gitlab上点进该项目后,会有建议提示内容,告知你如何推送已有代码。
举例
1)gitlab页面中创建不带readme的空项目example
2)创建并初始化本地项目
mkdir example && cd example && touch main.cpp # 在main.cpp中写入任意内容
git init --initial-branch=master # 初始化仓库
# 保证设置了帐号和邮箱,下面两种方式按需执行
# 方式1)设置全局帐号邮箱
git config --global user.name "zhangsan"
git config --global user.email "zhangsan@example.com"
# 方式2)设置项目的帐号邮箱
git config user.name "zhangsan"
git config user.email "zhangsan@example.com"
git remote add origin git@gitlab.example.com:sky/example.git # 关联远端仓库
git add .
git commit -m "首次提交"
git push --set-upstream origin master # 推送代码到远端
现在就可以在gitlab上看到推送的代码了
3.4 项目配置
3.4.1 保护分支
master分支不允许直接push,应该由其他分支进行合并(merge),保护分支设置步骤如下所示:
1)进入项目页面,点击侧边栏最下方的settings(如果没有settings,可能当前帐号没有权限),settings展开项中选择Repository
2)展开Protected branches选项,添加保护分支,如下图所示。
3.5 邀请成员
选择需要添加成员的group或者project,点击侧边栏的Manager中的Members,点击"邀请"按钮。成员加入group或者project,可以为其设置角色,控制加入成员的权限。
4、常见问题处理
4.1 合并冲突
例子
李四和王五同时拉取了最新的dev分支,然后修改main.cpp,提交到本地仓库。main.cpp代码为:
#include <stdio.h>
void main(void) {
printf("hello");
}
李四修改代码后提交并push,李四修改的代码
#include <stdio.h>
void main(void) {
printf("hello 李四");
}
同时王五也修改了代码.
#include <stdio.h>
void main(void) {
printf("hello 王五");
}
假设李四先push到远端,然后王五再push,此时王五提交会显示错误,无法push。
$ git push
To gitlab.example.com:sky/example.git
! [rejected] dev -> dev (fetch first)
error: 无法推送一些引用到 'gitlab.example.com:sky/example.git'
提示:更新被拒绝,因为远程仓库包含您本地尚不存在的提交。这通常是因为另外
提示:一个仓库已向该引用进行了推送。再次推送前,您可能需要先整合远程变更
提示:(如 'git pull ...')。
提示:详见 'git push --help' 中的 'Note about fast-forwards' 小节。
这就是代码冲突,此时解决冲突的方法是将远端的代码同步到本地,在本地解决代码冲突,然后再推送到远端。冲突解决方法有多种方式,可参考git同一分支代码冲突
解决方法
1)如果王五的代码已经commit到了本地仓库,则需要先将本次commit的代码撤销
git reset HEAD^ # 撤销本次代码提交,重置当前分支代码为上一个提交,同时重置暂存区,但工作区不变
git stash # 将上一次提交开始,改动的文件暂存下来
git pull # 同步远端李四提交的代码
git stash pop # 将改动的文件恢复,此时会提示代码冲突,需要手动修改文件解决冲突
vim main.cpp # 修改main.cpp文件
main.cpp文件内容如下:
#include <stdio.h>
void main(void) {
<<<<<<< Updated upstream
printf("hello 李四");
=======
printf("hello 王五");
>>>>>>> Stashed changes
}
删除文件标志,解决冲突,解决冲突后的文件如下所示:
#include <stdio.h>
void main(void) {
printf("hello 王五");
}
最后将解决冲突的文件加入暂存区,提交
git add .
git commit -m "王五提交"
git push