git合并分支

查这个问题的朋友一般是刚入行,所有先说几个版本控制的常用命令,如果是其他情况,大家跳过前面的常用命令介绍就行。

版本管理常用相关命令

1、使用git的时候,想要在不同版本之间转换,你就要知道版本号,git有两个命令可以帮助你查询版本号

git log

log命令会把你截至当前版本之前的,提交记录展示出来,注意重点有两个截至当前版本提交,说的明白一点就是它的展示结果,只有截至到你当前所在的版本为止commit过的版本记录,由于展示结果中最新的版本就是你当前的操作版本,而你又恰好回退了版本,那么之后的版本你是看不到的。

git reflog

reflog会把当前项目所有操作的git记录都展示出来,想要使用这个命令并且对你自己有帮助,最好是每次git一个版本的时候都要对版本添加描述,不然你根本分不清你要操作的版本是哪个,而且该命令的结果由于是展示了所有操作记录,不止都是版本信息,还存在很多过程类日志。

git合并分支_第1张图片

2、很多时候一个项目不止有一个master主分支,还有其他分支,在不同分支之间转换需要借助下面的两个命令

git branch #查看所有分支
git checkout 分支 #切换到某个分支

git合并分支_第2张图片

3、我们最常见的一个问题,就是需要回退某个版本的代码,这常常发生在你的最新版本还没有某个历史版本写的好的时候,或者是某个历史版本存在致命Bug想要重写某些代码。这种情况就需要操作一波了。

首先你要用log或者reflog查看截至当前,你提交过的版本,并找到你需要的版本,然后使用回退命令
git合并分支_第3张图片
版本列出后,你就要开始找,但你要认识展示的信息有什么,每一条记录中开头的7位值是这个版本的版本号,该序列号全展开后很长,我们后面回退的时候可以用这7位也可以用log命令展示的那种40位左右的版本号,那个方便用那个。推荐用log,log只有各提交版本信息,好找,这里是需要给git不熟练的朋友说一下reflog展示的信息

版本号后面括号中表示的是每次新版本生成时操作者是谁以及操作的分支是那个,一般情况下多是HEAD->分支,代表这个版本通常做的是commit操作,并且会生成commit开始和commit完成两条针对同一版本的记录,而HEAD是git中的一个指针,该指针用来代表该版本生成时的上一个版本,当你Push生成远程版本的时候,HEAD就会变成具体提交人。

HEAD@{数字}是版本顺序,从当前版本开始,自0计数

顺序的后面跟的是该版本记录生成的原因和系统生成的描述,系统描述的后面跟的是我们操作git时人为赋予的描述

注意如图42de801这个版本是个特例,当某个版本记录是生成一个新分支或者在项目刚生成git记录的时候,则该记录你可以理解为它是一条初始化记录,所以它的操作记录中描述的是initial,操作者是HEAD指针

4、当你找到了你需要回退的版本号,运行如下命令

git reset --hard 版本号

回退版本后你就可以正常的修改代码,如果当你想要再次提交的时候,我们一般用的开发工具是idea,你发现项目中Git选项没有了,你需要在settings中找到如下配置,选中灰色内容,点击加号,git就可以使用了
git合并分支_第4张图片
但你再推的时候,会提示你远程库中的版本比当前版本新,让你先pull,这个时候你在push命令中添加-f强推就行

5、过多的提交操作会生成很多记录,不利于项目的版本管理,因此要时常考虑对不必要存在的版本记录做删除,注意git删除提交记录是一种软删除,并不是物理上直接删了,可以理解为,为了log结果方便查看和维护而做的一种隐藏设置

例如当前某项目的git log提交记录如下

git合并分支_第5张图片
我们的目的是删除测试提交时生成的记录,此时你需要拿着该记录的上一条记录id运行如下命令

git rebase -i dd491e6f5f3879ce24374b3d97cf89e15936d5f8

此时会进入vim编辑器,展示的内容是命令中对应的记录之后的所有提交记录,不含命令中的记录,使用i进入编辑模式,将要删除的记录前pick改为drop,随后Shift+ZZ或者:wq保存并退出,再次log时可以发现对应的记录已删除
git合并分支_第6张图片
不过通过reflog你还可以看到被删除的记录,并在需要的时候回退

git合并分支_第7张图片

6、git的核心目的就是版本控制,在这个过程中难免遇到分支合并问题,所以git提供了两个命令,mergerebase,这两个命令有些区别。

注意:在工作中涉及不同的分支操作时,一定不要直接动master上的代码,一是因为master是生产环境用的无论从哪方面说都应该保持稳定且保持在提交后的状态不能也不应该被随意修改,二是不同分支操作时如果你当前分支被修改,在没有提交版本时,是不允许切换分支的,会报如下错误让你先提交。

------------- MINGW64 ~/Desktop/test (master)
$ git checkout fea
error: Your local changes to the following files would be overwritten by checkout:
        t.txt
Please commit your changes or stash them before you switch branches.
Aborting

所以不要直接改master代码,你要想改的话,应该是创建一个master代码的新分支。这种情况常见于,在开发中,master上的代码在服务器上运行发现了bug需要更改时,就需要对你当前开发中的分支先提交,之后回到master,生成一个基于master的新分支修改完bug后和master分支合并,最后回到你先前开发的分支同步master。

言归正传,首先rebase命令常用格式如下

git rebase [-i | --interactive] [options] [--exec <cmd>] [--onto <newbase>]
    [<upstream> [<branch>]]
git rebase [-i | --interactive] [options] [--exec <cmd>] [--onto <newbase>]
    --root [<branch>]
git rebase --continue | --skip | --abort | --quit | --edit-todo

--------------------常用------------------------
#将master分支的版本,合并到fea分支
git rebase master fea

#上面的命令也可以如下操作
git checkout fea
git rebase master

merge命令格式如下

git merge [-n] [--stat] [--no-commit] [--squash] [--[no-]edit]
    [-s <strategy>] [-X <strategy-option>] [-S[<keyid>]]
    [--[no-]allow-unrelated-histories]
    [--[no-]rerere-autoupdate] [-m <msg>] [<commit>…​]
git merge --abort
git merge --continue

---------------------常用-------------------------
#合并分支fixes和enhancements
git merge fixes enhancements

#合并obsolete分支到当前分支,使用ours合并策略:
git merge -s ours obsolete

#将分支maint合并到当前分支中,但不要自动进行新的提交:
git merge --no-commit maint

#将分支dev合并到当前分支中,自动进行新的提交:
git merge dev

两条命令在使用上的区别在于,合并分支Git会找一个两个分支共有的一个提交点做为父提交点,当你以A分支为基点,被合并的B分支,仍然处于两条分支产生时的提交点时,此时无论你使用merge还是rebase,合并操作都会中断并提示Current branch XX is up to date.,这是因为B分支的所有提交没有超出A分支的范围。

如果B分支超出父提交点一个提交,那么这种情况下,两条命令的运行结果是没有差别的。

如果B分支超出父提交点大于一个提交,那么merge会直接跳过B分支最新提交点和父提交点之间的所有提交,就是说A分支只合并B分支最新的提交点,这是一个很危险的操作。而rebase会把B分支上父提交点之后的所有提交全部对比合并,在效果上是将被合并的所有提交点拼接到了A分支的后面,这中效果也被业内称为rebase在使用上对历史记录的隐患,但其实没有太大影响,反而可以保存B分支的所有提交。但是应当注意rebase在git中有一个专业的名词叫做变基,指的就是,A分支后面拼接B分支合并过来的所有提交点时,这些提交点是从A分支的最新提交点开始做的代码对比,而不是从父提交点开始的代码。

所以工作中合并分支优先使用rebase,当然合并的时候参与合并的分支,可能不是同一个父提交点出来的,这更应该使用rebase,这种情况下git会找一个两个分支都有的父提交点。


第一种合并思路:命令合并

当被合并分支任然处于合并双方产生时的父提交点,就是说被合并分支的代码对你来说已经完全没有用了,你当前的分支完完全全就处在被合并分支之前,中途没有被合并分支继续提交的这种情况,你可以考虑此方法,但是注意这种情况下你直接运行git的合并命令是不会有任何结果的,git会给你如下提示并中断合并

---------- MINGW64 ~/Desktop/test (tmp)
$ git rebase master
Current branch tmp is up to date.

---------- MINGW64 ~/Desktop/test (tmp)
$ git merge master
Already up to date.

正确的做法是当前分支提交一个版本后,再用merge去合并被合并分支


第二种合并思路:Pull请求

这种合并方法,用在某个开源项目不是你自己的,你只是这个项目的使用者,或者你是这个项目的代码贡献者之一,但是你发现了项目中的一个没有修复的bug,你修复了,这种情况下你需要发出Pull请求,这里说的Pull不是往下拉!!!

用我自己的项目,给大家做个例子。首先需要先把项目的主分支代码git clone下来,随后立马生成一个分支,因为这种场景下git不允许直接提交master主分支,你只能先提交到分支上,比如我生成了一个tmp_1109

注意:如果你已经是这个项目的贡献者,就是说你曾经提交过,那么就已经有了属于你的分支你就不需要新建了,而是在你的分支中pull或者合并一下主分支

--------- /d/developtool/IntelliJ IDEA 2021.2.2/iedaobj/worldmatter (master)
$ git checkout -b tmp_1109
Switched to a new branch 'tmp_1109'

此时你就可以在这个分支上修改代码了,如果出现意外,最多删掉再和主分支上生成一遍。

当你修改完bug,你需要commit一下,例如下面我提交之后新的版本提示我删除了Test.java

------------/d/developtool/IntelliJ IDEA 2021.2.2/iedaobj/worldmatter (tmp_1109)
$ git commit -m "远程分支合并测试"
[tmp_1109 3a5b629] 远程分支合并测试
 1 file changed, 18 deletions(-)
 delete mode 100644 src/main/java/com/wy/worldmatter/Test.java

此时你要把这个分支推送到这个项目的git远程库的分支上

------------- /d/developtool/IntelliJ IDEA 2021.2.2/iedaobj/worldmatter (tmp_1109)
$ git push origin tmp_1109:tmp_1109
Enumerating objects: 109, done.
Counting objects: 100% (109/109), done.
Delta compression using up to 20 threads
Compressing objects: 100% (95/95), done.
Writing objects: 100% (109/109), 5.52 MiB | 1.24 MiB/s, done.
Total 109 (delta 24), reused 0 (delta 0)
remote: Resolving deltas: 100% (24/24), done.
remote: Powered by GITEE.COM [GNK-6.4]
remote: Create a pull request for 'tmp_1109' on Gitee by visiting:
remote:     https://gitee.com/wangyang159/worldmatter/pull/new/wangyang159:tmp_1109...wangyang159:master
To gitee.com:wangyang159/worldmatter.git
 * [new branch]      tmp_1109 -> tmp_1109

推送上去之后,你就可以在看到你的分支,并且进入你的分支
git合并分支_第8张图片
在你的分支下找到Pull Request的面板,在gitee或者github上可以直接看到,点击新建,在新建页面确定源分支,就是你上传的分支,目标分支是主分支,并且填写你提交代码的目的和详细说明,填好后点击下面的创建
git合并分支_第9张图片
---------------分割线
git合并分支_第10张图片
到此就没你什么事了。项目的主作者会收到邮件,并审核你的代码,如果没问题就会同意合并


第三种合并思路:改bug

这种合并适用于,你在工作中正常开发的时候,你的boss突然告诉你目前生产环境用的主分支有个bug你要改,而这个时候你用的代码,通常你本地的代码已经是高于生产用的了。说句题外话,我在开头说合并命令的时候也提到过,不要上来直接就改master主分支的代码,要养成一个好习惯,建一个分支改,没问题了再和主分支合并。所以第三种思路主要就是解决日常开发与维护的。

命令上面都有,所以这里直接说思路:针对这种情况,你应该提交你当前分支的代码,保证代码不丢失的同时,也是git强制的,要不然不让你切换。提交后你回到主分支再生一个分支用来改bug,改完后和master主分支合并。最后回到你之前开发的分支用rebase同步master主分支的改动,然后继续你的日常开发就可以了。

不仅是主分支,如果其他的任意分支需要改动,保险起见均应副本一个新的分支再改代码,因为工作中你要改动的分支不一定只有你用

你可能感兴趣的:(编程常识,git,github)