Gitlab

image-20230915152518079

GitLab是什么

GitLab 是一个用于仓库管理系统的开源项目,使用Git作为代码管理工具,并在此基础上搭建起来的Web服务,可通过Web界面进行访问公开的或者私人项目,它拥有与Github类似的功能,能够浏览源代码,管理缺陷和注释。

维基百科:https://zh.m.wikipedia.org/zh-hans/GitLab

about.gitLab:https://about.gitlab.com/

安装GitLab

搭建GitLab

该安装使用的是centos7来进行安装的

参看:https://about.gitlab.com/install/#centos-7 在线安装

离线安装:https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/yum/

环境确认

1
2
uname -a
cat /etc/system-release

image-20220330185656149

1
2
3
4
(1)CentOS 6或者7    (此处使用7)
(2)2G内存(实验)生产(至少4G),不然会很卡
(3)安装包:gitlab-ce-13.7.3-ce.0.el7.x86_64.rpm (或者按照下面的步骤在线安装)
(4)禁用防火墙,关闭selinux

安装依赖

安装GitLab需要一些依赖环境

1
sudo yum install -y curl policycoreutils-python openssh-server postfix

在线安装(外网)

使用外网方式进行安装,需要到外网现在仓库,有一些镜像是在国内速度稍慢可能需要重试几次

1
curl https://packages.gitlab.com/install/repositories/gitlab/gitlab-ce/script.rpm.sh | sudo bash

image-20220330190055331

如果出现The repository is setup! You can now install packages.表示仓库已经安装成功

image-20220330190245525

仓库下载成功后就可以通过yum进行安装了

1
sudo yum install -y gitlab-ce

image-20220330190414632

因为网络原因可能会切换到不同的镜像进行多次尝试,如果出现如下界面表示已经安装成功

image-20220330190520029

初始化配置

配置目录介绍

GitLab默认的配置文件路径:/etc/gitlab/

  • /etc/gitlab/gitlab.rb:主配置文件,包含外部URL、仓库目录、备份目录等
  • /etc/gitlab/gitlab-secrets.json:(执行gitlab-ctl reconfigure命令行后生成),包含各类密钥的加密信息

初始化配置

配置首页地址(需将设置的域名DNS解析到服务器IP,或者修改本地host将域名指向服务器IP)

1
2
3
4
5
6
7
8
# 查看external_url参数配置
cat /etc/gitlab/gitlab.rb |grep -v "#" |grep -Ev "^$"
external_url 'http://gitlab.example.com'

# 编辑将该gitlab.rb的该配置改为宿主机地址
vi /etc/gitlab/gitlab.rb
# 需要修改成自己的ip
external_url 'http://192.168.200.200:8888'

tips:不改配置,需要通过 http://gitlab.example.com 访问,为了快速学习,改成支持IP访问,生产建议域名访问

重新应用配置文件

在这一阶段花费时间会比较长

1
gitlab-ctl reconfigure

image-20220330191017591

如果出现以下界面说明已经配置成功

image-20220330191108053

查看Gitlab运行状态

可以通过以下命令查看Gitlab的运行状态

1
gitlab-ctl status

image-20220330191217596

登录测试

通过:http://192.168.200.200:8888/ 地址访问Gitlab服务,查看服务是否正常启动,注意这个地址就是上面配置的external_url

image-20220331095631493

安装Gitlab(docker)

我们使用 Docker 来安装和运行 GitLab 中文版,由于新版本问题较多,这里我们使用目前相对稳定的 10.5 版本,docker-compose.yml 配置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
version: '3'
services:
web:
image: 'twang2218/gitlab-ce-zh:10.5'
restart: always
hostname: '192.168.75.145'
environment:
TZ: 'Asia/Shanghai'
GITLAB_OMNIBUS_CONFIG: |
external_url 'http://192.168.75.145:8080'
gitlab_rails['gitlab_shell_ssh_port'] = 2222
unicorn['port'] = 8888
nginx['listen_port'] = 8080
ports:
- '8080:8080'
- '8443:443'
- '2222:22'
volumes:
- /usr/local/docker/gitlab/config:/etc/gitlab
- /usr/local/docker/gitlab/data:/var/opt/gitlab
- /usr/local/docker/gitlab/logs:/var/log/gitlab

安装完成后的工作

  • 访问地址:http://ip:8080
  • 端口 8080 是因为我在配置中设置的外部访问地址为 8080,默认是 80
  • 初始化安装完成后效果如下:

image-20230915201203483

  • 设置管理员初始密码,这里的密码最好是 字母 + 数字 组合,并且 大于等于 8 位
  • 配置完成后登录,管理员账号是 root

image-20230915201158446

注意: 如果服务器配置较低,启动运行可能需要较长时间,请耐心等待

Gitlab配置

安装完成Gitlab后就需要对Gitlab进行一系列的配置

修改管理员密码

gitlab默认的管理员账号是:root

查看root密码

gitlab-ce初装以后,把密码放在了一个临时文件中了,文件路径是/etc/gitlab/initial_root_password

1
cat /etc/gitlab/initial_root_password

image-20220331101909397

其中红框中的就是密码,注意:这个文件将在首次执行reconfigure后24小时自动删除

登录后并修改密码

拿到这个密码后需要尽快登录web界面进行密码修改

image-20220331102040784

将文件中的密码复制到密码框后进行登录

image-20220331102152555

登录完成后就需要进行密码修改了,选择用户下的Edit profile进行属性设置

image-20220331110502901

在弹出的页面选择password,在下面页面进行密码设置

image-20220331110547966

偏好设置

gitlab是我们国内非常好用的git工具,有很多偏好设置可以进行设置

操作步骤

选择用户下的Preferences进入偏好设置

image-20220331103238010

导航栏主题

者第一个Navigation theme选项可以选择对应的导航栏主题

image-20220331103439498

代码主题设置

在Idea中可能习惯了一些代码的主题设置,而在gitlab中也可以设置代码预览的主题,这里可以进行设置

image-20230915222932289

设置中文

Gitlab默认是英文的,很多小伙伴看起来比较麻烦,我们可以设置为简体中文模式

image-20220331105233768

这里简体中文的翻译度达到了95%,基本上够日常使用了,注意需要重新登陆后才会生效

image-20220331105426234

添加账号

在Gitlab添加账号是需要管理员进行审核的

注册账号

可以点击Register now进行账号注册

image-20220331100930872

点击后进入有账号注册页面,可以填写用户名密码进行账号的注册

image-20220331101041179

这里:需要注册两个账号:zs , ls

审核账号

新注册的账号是不可以直接进行登录的,需要管理员进行审核,通过菜单-管理员来进行设置

image-20220331111030043

在新打开的页面选择用户,在打开的页面选择批准相关注册的账号

image-20220331111136163

对于需要进行注册的账号选择批准即可

image-20220331111237738

审核通过的账号可以进行登录

新增账号

除了可以进行手动注册,管理员还可以进行批量新增用户,在管理员的用户管理,管理员可以进行手动新增

image-20220331111434906

点击新增用户后就可以进行手动新增了

image-20220331111509830

连接Gitlab

一般情况下我们连接Gitlab都是使用的ssh key进行连接的,下面我们看下如何进行配置

配置用户信息

参考上文的配置Git

查看配置的用户信息

可以通过一下命令查看配置的用户信息

1
2
git config user.name
git config user.email

image-20220331113142371

生成SSH key

通过以下命令可以生成相应的ssh key

1
2
# 注意这里的xxx@qq.com要替换为git配置的邮箱名称
ssh-keygen -t rsa -C "zx@itcast.cn"

tips:在201机器上演示zs

具体生成过程如下

image-20230915201243176

获取SSH key

通过如下命令可以获取对应的ssh key

1
cat ~/.ssh/id_rsa.pub

image-20220331113451880

Gitlab的sshkey配置

1,可以通过编辑用户资料来配置来进行配置ssh key

2,每个用户需要自己单独配置一下个性化,比如中文

image-20220630153515666

接下来打开ssh key配置页面将我们配置的ssh key配置到我们的gitlab中

image-20230915223300122

点击完成就可以完成配置了

image-20220331114119927

验证测试

我们配置完成后还需要进行验证测试

1
2
3
4
5
6
7
8
# ssh -T git@192.168.200.200
The authenticity of host '192.168.200.200 (192.168.200.200)' can't be established.
ECDSA key fingerprint is SHA256:4Ze/q+QQ5942NjyhwQiGLZCceB9mcbC759CiyjWzHYU.
ECDSA key fingerprint is MD5:61:8b:1a:f7:db:19:a8:17:bb:70:e8:f7:62:f3:a1:2d.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.200.200' (ECDSA) to the list of known hosts.
Welcome to GitLab, @zs!

出现如下界面就表示我们配置成功了

image-20220331114601764

使用流程

最小配置

1
2
3
git config --global user.name 'tans'
git config --global user.email 'tans@itcast.cn'
git config --list

config作用域

1
2
3
git config --local #针对当前仓库有效 缺省值
git config --global # 对当前用户所有仓库有效
git config --system #对系统所有登录的用户有效

展示 : –list

1
2
3
git config --local --list
git config --global --list
git config --system --list

基本操作

在201节点上操作,模拟不同用户在不同机器上的行为

1,已有项目纳入git管理

1
2
3
4
5
6
7
8
[root@k8-controller demo]# mkdir -p /root/git/demo
[root@k8-controller demo]# git init
[root@k8-controller demo]# ll -a
total 0
drwxr-xr-x. 3 root root 18 Jun 28 23:23 .
drwxr-xr-x. 3 root root 19 Jun 28 23:04 ..
drwxr-xr-x. 7 root root 119 Jun 28 23:23 .git

创建一个新项目并纳入git管理

1
2
git init your_project
cd your_project

2,创建local 用户

1
2
3
4
5
6
7
8
9
10
[root@k8-controller demo]# git config --local user.name 'zs'
[root@k8-controller demo]# git config --local user.email 'zs@itcast.cn'
[root@k8-controller demo]# git config --local --list
core.repositoryformatversion=0
core.filemode=true
core.bare=false
core.logallrefupdates=true
user.name=ts
user.email=ts@itcast.cn

3,创建readme

1
[root@k8-controller demo]# touch readme

4,提交

1
2
3
4
5
6
7
8
9
10
[root@k8-controller demo]# git commit -m 'add reademe'
# On branch master
#
# Initial commit
#
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
# readme
nothing added to commit but untracked files present (use "git add" to track)

5,添加到暂存区查看状态

1
2
3
4
5
6
7
8
9
10
11
12
[root@k8-controller demo]# git add readme
[root@k8-controller demo]# git status
# On branch master
#
# Initial commit
#
# Changes to be committed:
# (use "git rm --cached <file>..." to unstage)
#
# new file: readme
#

6,提交

1
2
3
4
5
[root@k8-controller demo]# git commit -m 'add reademe'
[master (root-commit) 0b75d17] add reademe
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 readme

7,查看日志

1
2
3
4
5
6
[root@k8-controller demo]# git log
commit 0b75d17d3692f96909f1b58605000dbde8c19e82
Author: zs <zs@itcast.cn>
Date: Tue Jun 28 23:28:31 2022 -0400

add reademe

结论:优先使用local级别的配置

远程仓库创建项目

一般我们不会在本地使用git创建项目,而是直接在远程仓库(gitlab,github)创建项目然后克隆到本地进行开发的

GitLab新建项目

我们可以通过选择项目–>新建项目来创建一个新的项目

image-20220331135451583

在这里选择一个空的项目

image-20220331135702575

配置项目

我们还需要对项目做一些配置,比如项目名称等

image-20220331140118192

然后点击新建项目就可以创建项目了

image-20220331140317855

添加项目成员

image-20220629184650228

直接邀请成员,把 zs ,ls 添加进去

image-20220629184807625

找到项目地址

我们可以点击克隆复制项目的克隆地址

image-20220331140541055

下载项目到本地

一般开发需要将项目先克隆到本地然后进行修改等操作,通过如下命令就可以将项目克隆到本地

idea直接下载新项目

Idea是可以直接拉取项目的,比较简单,通过新建项目就可以完成,选择通过版本控制新建项目

image-20220331141315410

然后输入刚刚复制的git地址即可

image-20220331141415260

git clone 新项目

在200节点上用ls用户进行操作,模拟不同用户在不同机器上的行为。

有时候我们还是需要通过命令进行clone的

​ 我们一般需要创建一个项目相关的文件夹将项目克隆到本地,windows我们可以在对应的文件夹中通过右键-git bash here来打开git bash进行操作,然后执行如下命令

首先ls用户需要生产ssh key

1
2
3
[root@k8-controller git]# ssh-keygen -t rsa -C "ls@itcast.cn"
[root@k8-controller git]# cat ~/.ssh/id_rsa.pub

然后ls用户登录,添加SSH key,

image-20220629222236941

接下来执行如下命令:

1
2
3
4
5
6
7
[root@work-node1 demo]# cd /root/git
[root@work-node1 demo]# git clone git@192.168.200.200:gitlab-instance-faefd22f/git-test.git
[root@work-node1 demo]# cd git-test/
[root@work-node1 demo]# git config --local user.name 'ls'
[root@work-node1 demo]# git config --local user.email 'ls@itcast.cn'
[root@work-node1 demo]# git config --list --local

和本地仓库关联

用201节点上自己初始化的项目去关联远程项目

1
2
3
4
5
[root@work-node1 demo]# cd /root/git/demo/
[root@work-node1 demo]# git remote add origin git@192.168.200.200:gitlab-instance-faefd22f/git-test.git
[root@work-node1 demo]# git remote -v
origin git@192.168.200.200:gitlab-instance-faefd22f/git-test.git (fetch)
origin git@192.168.200.200:gitlab-instance-faefd22f/git-test.git (push)

常规操作

接下来就是Git的一些常规操作

在200节点上使用ls账号操作

本地文件修改

在clone下来的项目中修改。

克隆下来项目后,我们就可以对项目进行修改,这里我们简单创建几个文件

image-20220401152706755

1
2
3
4
5
6
7
8
9
[root@work-node1 ~]# cd /root/git/git-test
[root@work-node1 git-test]# echo "hello world" > a
[root@work-node1 git-test]# echo "king of juan" > b
[root@work-node1 git-test]# ll
total 16
-rw-r--r--. 1 root root 12 Jun 29 09:33 a
-rw-r--r--. 1 root root 13 Jun 29 09:33 b
-rw-r--r--. 1 root root 6251 Jun 29 06:48 README.md

添加修改文件

我们接下来就需要将修改的文件添加到暂存区

添加命令

add有多种形式,可以add某个文件,某个文件夹,或直接add当前仓库下所有文件

1
2
3
git add 单个文件
git add 文件夹1/ 文件夹2/ ……多个文件夹之间空格隔开
git add .

执行添加并查看状态

1
2
3
4
5
6
7
8
9
[root@work-node1 git-test]# git add a b
[root@work-node1 git-test]# git status
# On branch main
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# new file: a
# new file: b
#

拉取远程仓库

在每次提交之前需要先拉取远程仓库的内容,防止冲突

拉取命令

git fetch 命令用于从远程获取版本库。该命令执行完后需要执行 git merge 远程分支到你当前所在的分支。

1
2
git fetch [alias]
git merge [alias]/[branch]

tips:示例如下:

1
2
3
4
5
6
[root@work-node1 git-test]# git fetch origin
[root@work-node1 git-test]# git branch -v
* main 9f2a4f7 Initial commit
[root@work-node1 git-test]# git merge origin/main
Already up-to-date.

另外;

git pull 命令用于从远程获取代码并合并本地的版本。

git pull 其实就是 git fetchgit merge FETCH_HEAD 的简写

git pull 命令用于从远程获取代码并合并本地的版本。

1
git pull <远程主机名> <远程分支名>:<本地分支名>

如果本地分支和远程分支一样的话:后面的内容可以忽略

1
git pull <远程主机名> <远程分支名>

拉取变更

1,首先在远端直接提交一个变更

image-20220629215723034

然后提交:

image-20230915201521643

然后我们在拉取变更

下面我们就是用命令拉取以下远程变更,因为gitlab默认的主分支是main

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
[root@work-node1 git-test]# git pull origin main
remote: Enumerating objects: 4, done.
remote: Counting objects: 100% (4/4), done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (3/3), done.
From 192.168.200.200:gitlab-instance-faefd22f/git-test
* branch main -> FETCH_HEAD
Updating 9f2a4f7..1d14d36
Fast-forward
test | 1 +
1 file changed, 1 insertion(+)
create mode 100644 test
[root@work-node1 git-test]# ll
total 20
-rw-r--r--. 1 root root 12 Jun 29 09:33 a
-rw-r--r--. 1 root root 13 Jun 29 09:33 b
-rw-r--r--. 1 root root 6251 Jun 29 06:48 README.md
-rw-r--r--. 1 root root 14 Jun 29 09:59 test

提交修改

完成操作后就可以进行提交修改了到仓库了,这样仓库就可以进行永久变更了

提交命令

可以通过如下的命令进行提交变更

1
git commit -m "注释"

具体注释的格式每一个公司都是不一样的,可以按照公司规范来做

提交修改

1
2
3
4
5
6
[root@work-node1 git-test]# git commit -m 'add a and b'
[main 300089b] add a and b
2 files changed, 2 insertions(+)
create mode 100644 a
create mode 100644 b

推送远程仓库

因为git是分布式的版本管理工具,我们要让变更让其他的同事看到就需要推送到远程仓库

推送命令

推送远程仓库的命令如下

1
git push <远程主机名> <本地分支名>:<远程分支名>

如果本地分支名与远程分支名相同,则可以省略冒号

1
git push <远程主机名> <本地分支名>

查看远程仓库

有的时候如果忘记远程仓库地址可以使用如下命令查看远程仓库地址

1
git remote -v

image-20220401155552375

通过该命令可以打印出来我们远程仓库的地址,这里的orgin是默认的远程仓库地址,如果推送到这里的远程仓库,我们可以使用orgin来代替远程仓库

推送提交

下面我们就将修改推送到gitlab

1
2
3
4
5
6
7
8
9
[root@k8-controller git-test]# git push origin main
Counting objects: 5, done.
Delta compression using up to 6 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (4/4), 340 bytes | 0 bytes/s, done.
Total 4 (delta 0), reused 0 (delta 0)
remote: GitLab: You are not allowed to push code to protected branches on this project.To git@192.168.200.200:gitlab-instance-faefd22f/git-test.git
! [remote rejected] main -> main (pre-receive hook declined)
error: failed to push some refs to 'git@192.168.200.200:gitlab-instance-faefd22f/git-test.git'

gitlab的main分支(master分支)默认是处于被保护状态下的,develop 角色是没有权限提交到 master 分支的,有两种解决办法:

1,联系管理员分配Maintainer角色权限

2,临时解决的方式是 Setting中 => Protected branches 启用 master 分支可被 develop 角色提交即可

选择2,如下:

image-20220629223750020

然后再次尝试

1
2
3
4
5
6
7
8
9
[root@k8-controller git-test]# git push origin main
Counting objects: 5, done.
Delta compression using up to 6 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (4/4), 340 bytes | 0 bytes/s, done.
Total 4 (delta 0), reused 0 (delta 0)
To git@192.168.200.200:gitlab-instance-faefd22f/git-test.git
e602b65..98bb81d main -> main

其他人拉取变更

回到201节点,用zs用户从远程拉取变更

1
2
3
4
5
6
[root@work-node1 demo]# git remote -v
origin git@192.168.200.200:gitlab-instance-faefd22f/git-test.git (fetch)
origin git@192.168.200.200:gitlab-instance-faefd22f/git-test.git (push)
[root@work-node1 demo]# git pull origin main:master
From 192.168.200.200:gitlab-instance-faefd22f/git-test
! [rejected] main -> master (non-fast-forward)

采用fetch + merge

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
[root@work-node1 demo]# git fetch origin
[root@work-node1 demo]# git branch -a
* master
remotes/origin/main

# 将远程main分支内容合并到当前master分支

[root@work-node1 demo]# git merge origin/main
Merge made by the 'recursive' strategy.
README.md | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
a | 1 +
b | 1 +
test | 1 +
4 files changed, 95 insertions(+)
create mode 100644 README.md
create mode 100644 a
create mode 100644 b
create mode 100644 test
[root@work-node1 demo]# ll
total 20
-rw-r--r--. 1 root root 12 Jun 30 00:43 a
-rw-r--r--. 1 root root 13 Jun 30 00:43 b
-rw-r--r--. 1 root root 0 Jun 29 11:06 readme
-rw-r--r--. 1 root root 6251 Jun 30 00:43 README.md
-rw-r--r--. 1 root root 18 Jun 30 00:43 test

同时将本地master分支上的变更推送到远程main分支

1
2
3
4
5
6
7
8
9
[root@work-node1 demo]# git push origin master:main
Counting objects: 6, done.
Delta compression using up to 6 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (5/5), 480 bytes | 0 bytes/s, done.
Total 5 (delta 1), reused 0 (delta 0)
To git@192.168.200.200:gitlab-instance-faefd22f/git-test.git
98bb81d..e8ef10e master -> main

分支操作

https://www.runoob.com/git/git-branch.html

在200节点上使用ls

创建分支

一般我们很少从头开始做一个项目,都是中途接手的,这个时候我们一般开发一个功能就需要新建分支了,并且分支也是我们最重要的一个功能

查看分支

我们要查看本地分支列表,可以通过如下命令进行查询

1
2
[root@k8-controller git-test]# git branch
* main

我们发现这里面现在只有一个main分支

image-20220401162539052

这里main分支有一个*标识是当前活动分支

创建分支

我们一般开发一个功能是需要创建分支的,创建分支命令也非常简单,执行git branch (branchname)即可

1
2
3
4
[root@k8-controller git-test]# git branch master
[root@k8-controller git-test]# git branch
* main
master

我们创建一个master分支,并查看当前分支列表

image-20220401163251478

切换分支

1,我们可以通过git checkout (branch)进行切换分支

1
2
3
4
5
[root@k8-controller git-test]# git checkout master
Switched to branch 'master'
[root@k8-controller git-test]# git branch
main
* master

切换分支后我们发现活动分支已经变成了master

2,我们在当前分支做一些变更,当我们还原回到原来的分支后就会被还原回去

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[root@k8-controller git-test]# echo 'hello master' > master
[root@k8-controller git-test]# git add .
[root@k8-controller git-test]# git commit -m 'add master'
[master acd81b3] add master
1 file changed, 1 insertion(+)
create mode 100644 master
[root@k8-controller git-test]# ll
total 24
-rw-r--r--. 1 root root 12 Jun 29 10:24 a
-rw-r--r--. 1 root root 13 Jun 29 10:24 b
-rw-r--r--. 1 root root 13 Jun 29 11:18 master
-rw-r--r--. 1 root root 6251 Jun 29 10:23 README.md
-rw-r--r--. 1 root root 18 Jun 29 10:23 test

3,我们切换回到main分支查看下效果

1
2
3
4
5
6
7
8
9
[root@k8-controller git-test]# git checkout main
Switched to branch 'main'
[root@k8-controller git-test]# ll
total 20
-rw-r--r--. 1 root root 12 Jun 29 10:24 a
-rw-r--r--. 1 root root 13 Jun 29 10:24 b
-rw-r--r--. 1 root root 6251 Jun 29 10:23 README.md
-rw-r--r--. 1 root root 18 Jun 29 10:23 test

我们发现刚才创建的文件已经看不到了,已经被移除了

删除分支

当某个分支完成功能,一行不需要的时候可以选择删除分支,可以通过git branch -D (branchname)删除

注意不能够删除当前活动分支

1
2
3
4
5
6
7
8
[root@k8-controller git-test]# git checkout main
[root@k8-controller git-test]# git branch -d master
error: The branch 'master' is not fully merged.
If you are sure you want to delete it, run 'git branch -D master'.
[root@k8-controller git-test]# git branch -D master
Deleted branch master (was acd81b3).
[root@k8-controller git-test]# git branch
* main

分支合并-merge

如果我们已经将一个功能分支开发完成后,一般需要将该分支合并到master主分支,下面我们说下分支合并

继续在200节点上用ls操作

创建分支

我们先创建几个用于合并的分支,然后再来合并

1
2
3
4
5
[root@k8-controller git-test]# git checkout -b master
Switched to a new branch 'master'
[root@k8-controller git-test]# git branch
main
* master

提交文件

1,现我们在各个不同的分支提交文件,这里我们都是只创建文件

1
2
3
echo "master" > master
git add .
git commit -m 'add master'

这里我们在master分支提交了文件

2,基于master 创建一个feature分支,然后后继续提交文件

1
2
3
4
git checkout -b feature
echo "feature" > feature
git add .
git commit -m "add feature"

3,现在已经有了两个不同的分支,并且两个不同的分支提交的文件也是不同的,但是并没有冲突,查看两个分支内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[root@k8-controller git-test]# ll
total 28
-rw-r--r--. 1 root root 12 Jun 29 10:24 a
-rw-r--r--. 1 root root 13 Jun 29 10:24 b
-rw-r--r--. 1 root root 8 Jun 29 12:02 feature
-rw-r--r--. 1 root root 7 Jun 29 11:49 index
-rw-r--r--. 1 root root 6251 Jun 29 10:23 README.md
-rw-r--r--. 1 root root 18 Jun 29 10:23 test
[root@k8-controller git-test]# git checkout master
Switched to branch 'master'
[root@k8-controller git-test]# ll
total 24
-rw-r--r--. 1 root root 12 Jun 29 10:24 a
-rw-r--r--. 1 root root 13 Jun 29 10:24 b
-rw-r--r--. 1 root root 7 Jun 29 11:49 index
-rw-r--r--. 1 root root 6251 Jun 29 10:23 README.md
-rw-r--r--. 1 root root 18 Jun 29 10:23 test

分支合并

下面我们操作下无冲突情况下和分支合并,这种情况下合并可以使用如下命令进行合并

1
git merge 分支名

该命令是将一个分支合并到当前分支,如果我们要将feature合并到master分支,需要执行以下命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[root@k8-controller git-test]# git checkout master
[root@k8-controller git-test]# git merge feature
Updating e097f5b..a685b10
Fast-forward
feature | 1 +
1 file changed, 1 insertion(+)
create mode 100644 feature
[root@k8-controller git-test]# ll
total 28
-rw-r--r--. 1 root root 12 Jun 29 10:24 a
-rw-r--r--. 1 root root 13 Jun 29 10:24 b
-rw-r--r--. 1 root root 8 Jun 29 12:04 feature
-rw-r--r--. 1 root root 7 Jun 29 11:49 index
-rw-r--r--. 1 root root 6251 Jun 29 10:23 README.md
-rw-r--r--. 1 root root 18 Jun 29 10:23 test

可以看到feature分支上的文件已经过来了,目前来说没有冲突比较简单。

查看提交日志

我们可以通过日志来查看合并的信息

1
2
3
4
5
6
7
8
9
10
11
12
13
[root@k8-controller git-test]# git log -2
commit a685b10e90a8f44b50565500421e0bb75973d9e9
Author: ls <ls@itcast.cn>
Date: Wed Jun 29 11:55:39 2022 -0400

add feature

commit e097f5bb904914cc3b848b078799b020e4184ebd
Author: ls <ls@itcast.cn>
Date: Wed Jun 29 11:49:27 2022 -0400

add index

这样看起来不是特别容易看懂,我们可以通过图形化工具来查看

image-20220406164110044

制造冲突并查看

1,切换回feature分支,来制造一些冲突

1
git checkout feature

2,我们在该分支做一些变更,将master.txt的内容做一些变更并且提交

1
2
3
4
echo "feature-append" >> master
git add .
git commit -m "modify feature branch , add to master"
cat master

3,切换回master分支对文件做一些变更并提交

1
2
3
4
5
git checkout master
echo "master-append" >> master
git add .
git commit -m "modify master branch , add to master"
cat master

合并-产生冲突

现在我们可以切换到master分支,将feature分支合并到master分支

1
2
3
4
5
[root@k8-controller git-test]# git checkout master
[root@k8-controller git-test]# git merge feature
Auto-merging master
CONFLICT (content): Merge conflict in master
Automatic merge failed; fix conflicts and then commit the result.

解决冲突并提交

1
2
3
4
5
6
7
8
[root@k8-controller git-test]# cat master
master
<<<<<<< HEAD
master-append
=======
feature-append
>>>>>>> feature

手动解决冲突,留下谁由自己来定

然后提交

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
[root@k8-controller git-test]# git status
# On branch master
# You have unmerged paths.
# (fix conflicts and run "git commit")
#
# Unmerged paths:
# (use "git add <file>..." to mark resolution)
#
# both modified: master
#
no changes added to commit (use "git add" and/or "git commit -a")
[root@k8-controller git-test]# git add .
[root@k8-controller git-test]# git status
# On branch master
# All conflicts fixed but you are still merging.
# (use "git commit" to conclude merge)
#
# Changes to be committed:
#
# modified: master
#
[root@k8-controller git-test]# git commit -m 'fixed conflic'
[master e57d4d2] fixed conflic
[root@k8-controller git-test]# git status
# On branch master
nothing to commit, working directory clean
[root@k8-controller git-test]# git log -3
commit e57d4d2c531a2d0a7a03cd0c65a2dbcf976fcfeb
Merge: 64ae4e0 366e30f
Author: ls <ls@itcast.cn>
Date: Wed Jun 29 23:22:47 2022 -0400

fixed conflic

commit 64ae4e02d8f82e354cb9e72023c1e5c38d5a1eaf
Author: ls <ls@itcast.cn>
Date: Wed Jun 29 23:14:50 2022 -0400

modify master branch , add to master

commit 366e30f54e825845235f8b33d8017097c7652fe3
Author: ls <ls@itcast.cn>
Date: Wed Jun 29 23:12:14 2022 -0400

modify feature branch , add to master

查看log

查看log

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
[root@k8-controller git-test]# git log --graph --decorate --all
* commit e57d4d2c531a2d0a7a03cd0c65a2dbcf976fcfeb (HEAD, master)
|\ Merge: 64ae4e0 366e30f
| | Author: ls <ls@itcast.cn>
| | Date: Wed Jun 29 23:22:47 2022 -0400
| |
| | fixed conflic
| |
| * commit 366e30f54e825845235f8b33d8017097c7652fe3 (feature)
| | Author: ls <ls@itcast.cn>
| | Date: Wed Jun 29 23:12:14 2022 -0400
| |
| | modify feature branch , add to master
| |
* | commit 64ae4e02d8f82e354cb9e72023c1e5c38d5a1eaf
|/ Author: ls <ls@itcast.cn>
| Date: Wed Jun 29 23:14:50 2022 -0400
|
| modify master branch , add to master
|
* commit 787d85bf2c81e7b3808eabaaf2a932d84da38249
| Author: ls <ls@itcast.cn>
| Date: Wed Jun 29 23:10:04 2022 -0400
|
| add feature
|
* commit 4851824c26ce34286bf9af8aab1ff09ea9e83ea3
| Author: ls <ls@itcast.cn>
| Date: Wed Jun 29 23:09:46 2022 -0400
|
| add master
|
* commit 98bb81d264185ca4b4998387229d817ff3877fcf (origin/main, origin/HEAD, main)

–graph:图形展示

–decorate:让git log显示每个commit的引用(如:分支、tag等)

–all :表示显示所有的branch

–oneline :一行显示

合并分支-rebase

使用merge合并会产生很多交叉树,如果交叉很多的情况下很不容易看懂,如果想比较简单的方式合并可以选择rebase方式

创建fixbug分支

继续在200节点上,先准备一些环境,创建一个新分支 fixbug

1
2
git checkout master
git branch fixbug

fixbug上提交文件

1
2
3
4
5
6
[root@k8-controller git-test]# git checkout -b fixbug
[root@k8-controller git-test]# echo "fixbug branch ,fix1604bug" >> master
[root@k8-controller git-test]# git add .
[root@k8-controller git-test]# git commit -m 'on fixbug branch ,fixed master '
[fixbug 3d6704c] on fixbug branch ,fixed master
1 file changed, 1 insertion(+)

master分支提交

回到master分支,同样做出改动

1
2
3
4
5
6
7
8
9
10
11
12
13
[root@k8-controller git-test]# git checkout master
Switched to branch 'master'
[root@k8-controller git-test]# echo "master king" >> master
[root@k8-controller git-test]# git add .
[root@k8-controller git-test]# git commit -m 'on master branch ,add master king'
[master 24efd9a] on master branch ,add master king
1 file changed, 1 insertion(+)
[root@k8-controller git-test]# cat master
master
master-append
feature-append
master king

合并并解决冲突

合并,使用rebase

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
[root@k8-controller git-test]# git branch
fixbug
main
* master
[root@k8-controller git-test]# git rebase fixbug
First, rewinding head to replay your work on top of it...
Applying: on master branch ,add master king
Using index info to reconstruct a base tree...
M master
Falling back to patching base and 3-way merge...
Auto-merging master
CONFLICT (content): Merge conflict in master
Failed to merge in the changes.
Patch failed at 0001 on master branch ,add master king
The copy of the patch that failed is found in:
/root/git/git-test/.git/rebase-apply/patch

When you have resolved this problem, run "git rebase --continue".
If you prefer to skip this patch, run "git rebase --skip" instead.
To check out the original branch and stop rebasing, run "git rebase --abort".

[root@k8-controller git-test]# ll
total 28
-rw-r--r--. 1 root root 12 Jun 30 00:53 a
-rw-r--r--. 1 root root 13 Jun 30 00:53 b
-rw-r--r--. 1 root root 8 Jun 30 00:58 feature
-rw-r--r--. 1 root root 137 Jun 30 01:12 master
-rw-r--r--. 1 root root 0 Jun 30 00:52 readme
-rw-r--r--. 1 root root 6251 Jun 30 00:52 README.md
-rw-r--r--. 1 root root 18 Jun 30 00:52 test
[root@k8-controller git-test]# cat master
master
master-append
feature-append
<<<<<<< HEAD
fixbug branch ,fix1604bug
=======
master king
>>>>>>> on master branch ,add master king
[root@k8-controller git-test]# vi master
[root@k8-controller git-test]# git add .
[root@k8-controller git-test]# git rebase --continue
master: needs merge
You must edit all merge conflicts and then
mark them as resolved using git add

查看日志

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[root@k8-controller git-test]# git log --graph --decorate --all
* commit 2fbcfedb4bb7237eb71ebd07031832fb8ba0cc03 (HEAD, master)
| Author: ls <ls@itcast.cn>
| Date: Thu Jun 30 01:11:07 2022 -0400
|
| on master branch ,add master king
|
* commit 3d6704cf59d410963cad2ff6746dc2b50eb9ddf2 (fixbug)
| Author: ls <ls@itcast.cn>
| Date: Thu Jun 30 01:09:02 2022 -0400
|
| on fixbug branch ,fixed master
|


不会产生新的提交,也没有多余的分叉

Merge vs Rebase

https://www.atlassian.com/git/tutorials/merging-vs-rebasing

Merge

通过命令将 master 分支合并到 feature 分支中:git merge feature master[简写形式],会在 feature 分支中创建一个新的 merge commit,它将两个分支的历史联系在一起,请看如下所示

image-20220630142049089

使用 merge 是很好的方式,因为它是一种 非破坏性的 操作。现有分支不会以任何方式被更改,

另一方面,这也意味着 feature 分支每次需要合并上游更改时,它都将产生一个额外的合并提交。如果master 提交非常活跃,这可能会严重污染你的 feature 分支历史记录

rebase

用以下命令将 master 分支合并到 feature分支上,git checkout feature; git rebase master

它会将整个 feature 分支移动到 master 分支的顶端,从而有效地整合了所有 master 分支上的提交。但是,与 merge 提交方式不同,rebase 通过为原始分支中的每个提交创建全新的 commits 来 重写 项目历史记录。

image-20220630142231658

rebase 的主要好处是可以获得更清晰的项目历史。首先,它消除了 git merge 所需的不必要的合并提交;其次,正如你在上图中所看到的,rebase 会产生完美线性的项目历史记录,你可以在 feature分支上没有任何分叉的情况下一直追寻到项目的初始提交。

但是,针对这样的提交历史我们需要权衡其「安全性」和「可追溯性」。

注意事项

  • 不要在公共分支使用rebase

​ 因为往后放的这些 commit 都是新的,这样其他从这个公共分支拉出去的人,都需要再 rebase,相当于你 rebase 东西进来,就都是新的 commit 了

举例说明

  • 1-2-3 是现在的分支状态
  • 这个时候从原来的master ,checkout出来一个prod分支
  • 然后master提交了4.5,prod提交了6.7
  • 这个时候master分支状态就是1-2-3-4-5,prod状态变成1-2-3-6-7
  • 如果在prod上用rebase master ,prod分支状态就成了1-2-3-4-5-6-7
  • 如果是merge则是 1-2-3-6-7–8 ………….. |4-5|
  • 会出来一个8,这个8的提交就是把4-5合进来的提交

rebasemerge 的基本原则

1,下游分支更新上游分支内容的时候使用 rebase

2,上游分支合并下游分支内容的时候使用 merge

例如现有上游分支 master,基于 master 分支拉出来一个开发分支 dev,在 dev 上开发了一段时间后要把 master 分支提交的新内容更新到 dev 分支,此时切换到 dev 分支,使用 git rebase master

等 dev 分支开发完成了之后,要合并到上游分支 master 上的时候,切换到 master 分支,使用 git merge dev