关于git:保姆级教程-Merge-Request-分支合并请求

17次阅读

共计 8202 个字符,预计需要花费 21 分钟才能阅读完成。

保姆级教程 | Merge Request 分支合并申请

What is it ?

首先我想先来讲讲 什么是 分支合并申请 Merge Request(也可叫Pull Request,下文中全用Merge Request 或其缩写 MR 指代),以及它 有什么作用(如果你对此概念有所理解,你齐全能够跳过What is it)。

MR(或者 PR) 就是指将你开发的代码的内容以一种申请合并的形式来合并到它想去的分支上,这个申请的接管人 (Reviewer) 个别是我的项目、团队的负责人或者其余成员。

一般来讲,开发团队都对 Code Review(代码复审 / 审查 / 检视)的器重水平比拟高。因为Code Review 的的确可能晋升代码的品质以及缩小 BUG 的产生率。

Merge RequestCode review 中就是重要的一环。如果应用 MR 来发动合并申请,那么在代码审查时就齐全能够以你本次申请的合并内容为单元进行代码审查,如果审查通过那么就胜利合并。审查交由 Reviewer 进行,他能够是申请的接管人。如果团队多个成员坐在一起来看你的本次合并内容,那么天然 Reviewer 就是这些人了。一份代码通过多人的审查,代码问题发生率天然会升高,开发者在开发时也会保持良好的编码习惯,毕竟没人想被他人 指导 本人的代码。

不过有些团队可能并不器重 Merge Request,最多也就是在dev 分支(大家共用的开发分支)上检出一个新分支,而后在新分支上进行开发,而后 commit -> push 最初 mergedev 分支上就完事了。

上面咱们将以 Merge Request 为指标,从建设仓库开始讲述一个残缺的 git 工作流以及其中的 git 操作。

How to do?

接下来咱们从 0 开始,以 Gitee(码云)代码托管和研发合作平台为例,来讲讲如何在失常的git 工作流程中应用Merge request

1. 创立一个近程仓库,默认创立 master 分支

2. 创立本地仓库,并关联近程仓库

初始化本地仓库后,轻易创立一个文件,而后提交到近程仓库的 master 分支。

git init
touch README.md
git add README.md
git commit -m "first commit"
git remote add origin https://gitee.com/yaodao666/git-merge-requet.git
git push -u origin master

git push -u的作用就是关联并推送内容到上近程仓库的分支。(前面还有别的关联近程分支的办法。)

3. 以 master 分支为终点创立一个 dev 分支

咱们前面就将以 dev 分支作为开发分支(仓库成员共用的一个分支)。

4. 仓库中再增加另一个成员

该成员将在前面作为 Reviewer 来解决本人的Merge Request,看咱们的提交内容,从而达到代码审查的目标。

而后为该用户设置为代码审查人员:

以上的操作都在 Gitee 仓库的治理设置选项中。

4. 本地切换到 dev 分支,并连贯近程 dev 分支

此时本地是没有 dev 分支的。能够用

git branch -a

命令来查看所有分支。

当初就用

git checkout -b dev

来创立一个 dev 的本地分支。如果此时执行该命令时没有加 - b 参数:

git checkout dev
error: pathspec 'dev' did not match any file(s) known to git

会报错如上。因为该命令是只是切换分支,而此时并没有 dev 分支,天然无奈切换过去会报错。

OK,当初咱们创立了本地 dev 分支,当初咱们让他关联上近程仓库的 dev 分支吧。(只有这样能力进行 pullpush 操作啊!)

git branch --set-upstream-to=origin/dev

这样子就好啦!

执行上面的命令

git pull
Already up to date.

呈现上述信息,阐明链接上近程的 dev 了。

其实还有一种链接近程仓库分支的形式,比方咱们又在 近程仓库 上以 dev 分支为终点,创立了 test 分支,那么咱们在本地创立 test 分支时,就能够执行:

git checkout -b test origin/test

创立本地 test 分支的同时又链接到近程的 test 分支上。

在后文中 5. 新建一个 feature(个性)分支 中还会有另一种形式来连贯近程仓库分支。

5. 新建一个 feature(个性)分支

在理论开发中,咱们往往会新建一个个性分支,该分支专门为你服务,并且它专门用于解决某个 bug,或者开发某个新的性能。即当有个新性能须要开发或者有 bug 以及优化重构局部代码时,咱们就应该独自拿出一个新分支来专门解决这些事件。

与下面创立 dev 的形式雷同,不过咱们这次不先在近程仓库创立分支了,而是 在本地间接创立分支后,再将该分支推送到近程

咱们先切换到 dev 分支,失常工作中,你必须要 pull 一下,保障你之后写的代码将是建设在 dev 上最新的代码的根底上,以防止一些不必要的麻烦。

git checkout dev
git pull

用上面的命令创立一个新的个性分支,咱们就命名为 feature-beer 吧。

git checkout -b feature-beer

6. 在 feature-beer 分支上开发,并推送到近程。

轻易在 readme.md 文件上改点货色。而后执行:

git add -A
git commit -m "这是我第一次在 feature-beer 分支上提交。"

最初将内容推送到近程的仓库上,

git push -u origin feature-beer

这时候再去近程仓库上看,就会有 feature-beer 分支了,并且提交内容也有了。所以 git push -u 的作用不仅仅是关联并推送内容到上近程仓库的分支,当没有近程分支时还会创立该分支!

7. 间接合并到 dev 上。

很多时候,有些开发团队基本就在乎应用 Merge Request 来在合并时进行 Code review,那么他们就会间接合并代码到 dev 分支。

切换到 dev 分支执行 merge 命令。

git checkout dev
git pull                # 在合并前同样先 pull 一下 dev
git merge feature-beer    # 这里的合并是本地合并,将 feature-beer 中的内容合并到 dev 中
git push                # 将本地内容推送到近程仓库

此时再去近程 dev 分支上看一下:

咱们在 feature-beer 上的批改内容曾经放在 dev 上了。

8. Merge Request

不过这种简略粗犷的形式往往会带来很多问题,比方没有人去留神你往 dev 上合并了什么内容,这种 没人关注本人写的代码 情景往往就会导致开发人员在开发时不留神代码标准,甚至会提交上很显著的 bug,也懒得去测试,更有甚者则会上传使得我的项目启动失败的代码。

这时候如果能有一个人来帮你再把把关,看看你写的代码咋样,则会促使本人写代码时更加留神代码标准和代码健壮性,毕竟谁也不想被他人批评,要是因为代码写的好被褒扬就更好了。而 Merge Request 就能够达到这种成果。

当初,咱们就模仿启动一个 Merge Request 的过程。

从新切换到 feature-beer 分支上写点内容,并分两次提交,并 push 到近程分支上。

git checkout feature-beer
# 改点内容:这是我第二次在 feature-beer 上进行开发工作,当初是早晨十一点五十一分了。git add -A
git commit -m "这是第二次在 feature-beer 上的开发的第一次提交。"
# 改点内容:这是我第二次在 feature-beer 上进行开发工作,当初是早晨十一点五十二分了。git add -A
git commit -m "这是第二次在 feature-beer 上的开发的第二次提交。"
git push

这样近程上的分支就能看到这次开发的两次提交啦。

Gitee 上提供了 Pull Request 操作来实现 Merge Request。

在创立的 Pull Request 中,你必须选中源分支、指标分支。还能看到提交记录和文件改变信息。

点击创立后,Beer Bear成员就会收到这个申请。

他能够在提交和文件中看到提交的内容。审查通过后,就能够合并了。在后面创立时咱们勾选了删除提交分支(不过截图中未勾选,实际操作上是勾选了的),合并后就没有这个分支了

这时候再看分支和分支内容,发现 feature-beer 没了,dev 中有了合并过去的内容。

9. 删除本地分支和近程分支

这个时候咱们就应该删除这个本地分支了。

git checkout dev            # 先切换到 dev 分支
git pull
git branch -d feature-beer

如果这个命令报错,往往是

  • 很有可能是你正处于该分支上。
  • 该分支蕴含了还未合并的工作,能够先合并或者应用 - D 参数强制删除。

如果你的近程分支还没有删除(在本文中,近程分支在 Merge Request 通过时就一起删除了),能够应用:

git push origin --delete feature-beer

当然你也能够登录到 Gitee 的网页上删除近程分支。

为啥要删除呢?持续用不行么?

其实能够持续用,然而不举荐,因为咱们创立这个分支的目标就是为了开发一个新模块或者修复一个 BUG,当开发工作实现后删除该分支,解决别的事件时再新建一个就好了。

Some Questions

1. 如果本地 dev 有批改内容,是否能够把这些批改内容带到新分支上

比方有一天,你困意十足,关上编译器间接开始干活了,干了半天才发现这是 dev 分支,这时候曾经有很多代码的改变了,咋整?

当初咱们在 dev 分支上新增一行,不提交。

而后切换到新分支:feature-new-beer.

git checkout -b feature-new-beer

再关上文件会发现会有这行信息的。所以这个未提交的信息是能够 带过去的

那我要是不想带过去怎么办?咱们先删除这个分支换一个分支看一下如何做到不带过去。

git checkout dev
git branch -d feature-new-beer

咱们应用

git stash

将 dev 分支上的内存暂存起来,这时 dev 上就看不到这一行了。

而后咱们再次切换到新分支:feature-new-beer.

git checkout -b feature-new-beer

这个时候该分支上也不会有这一行信息了。但如果此时执行:

git stash pop

会发现那一行又呈现了,并且再切换到 dev 时,dev上也又呈现这一行了。

为啥会呈现下面的景象呢,其实是因为 git 中存在工作区和暂存区,这两个区都是被所有本地分支共享的。

当有内容批改时,批改信息就会放在工作区中,此时如果间接检出一个新的分支,就会把工作区的内容都带过来。

而如果把批改信息暂存(stash)到暂存区时,都暂存起来了天然就不会带过来,然而因为该区也是共享的,当 pop 出暂存内容时,所有分支又同时复原了这些批改内容。

如果我在 dev 上进行 stash 后,检出新分支,又加了一行,再 pop 会怎么呢?

git stash pop

会提醒报错:你的本地更改(新分支上的更改)会被笼罩。

这个时候如果:

git stash
git stash pop

那么本地更改将笼罩掉 dev 的批改,即 dev 上也是上面的信息了。

就像该问题结尾说的那样,如果你在 dev 上写了不少货色了,那么就先 pull 一下最新的代码,而后检出到新分支上持续开发就能够了。

你能够在任意工夫回到 dev 上 间接进行 discard changed(回滚到最后的未修改的版本) 操作。

如果切实不释怀就等新分支代码都写完了提交了你再到 dev 上删除。

2. 如果我在新分支上有很屡次提交,我是否能够合并这些提交到一个提交上再提交

这是能够的,并且很多时候咱们举荐这么做,比方一个模块须要三天去实现,这三天你可能提交了六七次,而实际上你只是实现了一个新模块的开发而已。

如果在你的几次提交中,有人往 dev 推送了代码,那么当你最初向 dev 发动合并申请并且胜利通过后,commit的记录会是怎么呢?上面一起来试一下。

咱们先把 Question1 中的在 dev 分支上的批改 discard changes 一下(回到未修改的状态,即上一个版本),而后删除刚刚那个分支并创立一个新分支feature-many-commits

# use "git checkout -- <file>..." to discard changes in working directory 这是官网提醒
git checkout -- README.md        # 该文件回到未修改的状态
git branch -d feature-new-beer
git checkout -b feature-many-commits

当初咱们在新分支上轻易写点内容并提交。

# 轻易加一行:我在 feature-many-commits 分支上写货色。当初是早晨 22:25, 写完这行立马提交。git add -A
git commit -m"feature-many-commits, 早晨 22:25"

当初咱们再到 dev 分支上写点货色并提交和 push(模仿这是 另一个人 提交上来的代码),不过为了防止抵触,咱们就不在 README 文件中写了,新建一个 txt 文件。

当初咱们再回到 新分支 上轻易写点内容并提交,而后 push 到近程,并去 Gitee 上进行MergeRequest

# 轻易加一行:我在 feature-many-commits 分支上写货色。当初是早晨 22:34, 写完这行立马提交。git add -A
git commit -m"feature-many-commits, 早晨 22:34"
git push -u origin feature-many-commits

这里提供两个选项,一个是合并分支一个是扁平化分支。看看解释应该能猜出啥意思,第一个的意思是指间接合并,后者则是先把 feature-many-commits 上的提交合并成一个新的commit——这就是咱们想要的指标,而后再合并到 dev 上。

不过咱们先来看一下 间接合并

当初咱们依据该图显示的提交记录就能够答复结尾的那个问题了:“如果在你的几次提交中,有人往 dev 推送了代码,那么当你最初向 dev 合并并胜利后,commit的记录会是怎么呢?”。

正如图中展现的那样,dev的提交记录夹在了新分支上的两次的提交记录两头,这样的确凌乱、不美观。

所以咱们在很多时候应该采纳 扁平化分支 的形式来合并。

写点内容提交,再用扁平化的形式试一次:

# 轻易加一行:我在 feature-many-commits 分支上写货色。当初是早晨 22:43, 写完这行立马提交,心愿这个提交最初会与接下来的 commit 被合并到一个 commit 中。git add -A
git commit -m"feature-many-commits, 早晨 22:43"

# 轻易加一行:我在 feature-many-commits 分支上写货色。当初是早晨 22:44, 写完这行立马提交,心愿这个提交最初会与之前的 commit 被合并到一个 commit 中。git add -A
git commit -m"feature-many-commits, 早晨 22:44"
git push

发现的确胜利将那两次 commit 合并成一个了!并且提交的工夫就是通过 Merge Request(Pull Request) 的工夫。

总结一下这个问题:间接合并分支会让两个分支的每一次提交都依照 commit 的工夫进行排序,这样看起来会比拟凌乱。咱们能够通过 gitee 上扁平化分支的形式通过MR

3. 除了 Merge Request 通过后合并时抉择扁平化分支(将屡次提交合并成一个 commit)还有啥办法也能实现这个成果么

的确,这个将屡次提交合并为一个提交的操作是在 gitee 上进行的,那要是我不去 gitee 上进行Pull Request,间接在本地进行merge,不就达不到这种成果了么?

须要阐明的一点是,实际上像 GiteeGitlab 这种代码托管平台是都具备这种性能的,所以如果在它们的平台上通过Merge Request(或Pull Request)去做的话,肯定能实现这种成果。

但如果我不去代码托管平台发动合并申请呢?我就想本地开发完了,而后合并到 dev 上(再由本地 dev 分支 push 到近程 dev 分支),那该怎么做呢?这时候一个 git rebase 命令就跃然纸上了。

这个命令的作用就是将某个分支的屡次 commit 合并成一个 commit,而后在merge 到另一个分支上的时候就会只有一个提交啦。

这个过程是这样的 (示例是将feature-many-commits 分支内容合并到 dev 上):

# 假如当初开发结束 并且曾经在 feature-many-commits 上提交了屡次
git checkout dev
git pull            # dev 放弃最新的代码
git checkout feature-many-commits
git rebase dev        # 将 feature-many-commits 上所有的 commit,从新在新的 dev 的 HEAD 上 commit 一遍
git checkout dev    # 再次切换到 dev 上
git merge feature-many-commits # 将 feature-many-commits 上的内容合并到 dev 上
git push            # 推送即可

这个过程还是比较简单的,很多人也在这样去做,在此就不演示了。

Summary

当初让咱们再来梳理一下整个 MR 的要害流程。

假如 dev 分支就是大家共用的分支,咱们要在此基础上检视出新分支进行开发工作,最初通过 Merge Request 的办法合并到近程分支。:

  1. 切换到 dev 分支

    git checkout dev
  2. 更新 dev 分支代码

    git pull
  3. 在 dev 分支的根底上,检视出一个新分支feature-beerbear

    git checkout -b feature-beerbear
  4. 进行开发并提交你的代码

    git add -A
    git commit -m"xxxxxx"
  5. 将本地 feature-beerbear 分支推送到近程

    git push -u origin feature-beerbear  # 会创立一个近程 feature-beerbear 分支

    如果不是第一次推送,能够间接应用

    git push

    4、5 步骤将在理论的开发工作中反复执行。

  6. 开发工作实现后,到代码托管平台上进行Merge Request(或Pull Request)操作。
  7. 合并申请通过后。就能够删除本地分支。

    git branch -b feature-beerbear
  8. 新的工作来了,从 1 再来。

在第六步时,可能会产生以下状况:

① 如果不通过,那么持续从 4 开始执行,不过不再须要新提出一个新的 MR(Merge Request) 了。

这时候可能会疑难,为啥不须要从新提一个了呢?

因为这个合并是指分支之间的合并,当你的近程 feature-beerbear 分支发生变化时,MR会感知到做出相应变动的。

实际上,如果你要新建的 MR 的源分支和指标分支和之前的 MR 中的雷同,这样的话是创立不了的。

你必须敞开掉之前的那个,当然齐全没这个必要。

② 发生冲突

尽管你在创立新分支时 pull 了一下 dev 分支,而后在此基础上创立新分支了,但毕竟你的 MR 可能是好几天后收回的,dev分支必定不是原来的状态了。所以就会导致在创立 MR 时揭示抵触。那当提醒发生冲突的时候,怎么办呢?只需以下几个命令即可:

git checkout dev
git pull
git checkout feature-many-commits
git merge dev                        # 如果在这一步发生冲突,那么手动解决抵触即可
git push

实际上就是将 dev 代码更新,而后将 dev 上的代码合并到 feature-many-commits 上来。

其实咱们齐全能够在提交 MR 之前就将下面的几行命令走一遍,这样就不会再提 MR 的时候报出抵触了。

总不至于你刚执行完下面的命令,在你筹备提出 MR 时,就又有人往 dev 上提交了代码,又恰好导致抵触了吧——如果有,能够买张刮刮乐试试运气了。

Thanks

这篇对于 Merge Request 的文章到此就算完结了!首先,谢谢你看完这篇文章!

其次,我非常心愿这篇文章能对你有所帮忙,或者帮忙不是很大。如果你喜爱这篇文章或者真的有一些播种,请也点赞或者珍藏,最好是在评论区留言通知我!

尽管付出了挺多精力来写这篇文章,但毕竟咱程度个别、能力无限,所以必定会有一些语句不畅、表意不明甚至谬误的中央。

如果你能指出问题、不吝赐教,我将非常感激,你的倡议和指教也将催促我始终欠缺此文!欢送敌对交换!

正文完
 0