利用git来管理项目代码
1.实验目的
1)在Linux 4.0上做开发。为了简化开发,我们假设只需要修改Linux 4.0根目录下面的Makefile,如下所示。
VERSION = 4PATCHLEVEL = 0SUBLEVEL = 0EXTRAVERSION =NAME = Hurr durr I'ma sheep //修改这里,改成 benshushu
2)把修改推送到Gitee上。
3)过了几个月,这个项目需要变基(rebase)到Linux 4.15的内核,并且把之前做的工作也变基到Linux 4.15内核,并且更新到Gitee上。如果变基时遇到冲突,需要修复。
4)在这个实验里,会学习到如何合并一个分支以及如何变基到最新的主分支上。
5)在合并分支和变基分支的过程中,可能会遇到冲突,在本实验中可以学会如何修复冲突。
2.实验步骤
在实际项目开发过程中,分支的管理是很重要的。以现在这个项目为例,项目开始时,我们会选择一个内核版本进行开发,比如选择Linux 4.0内核。等到项目开发到一定的阶段,比如Beta阶段,其需求发生变化。这时需要基于最新的内核进行开发,如基于Linux 4.15。那么就要把开发工作变基到Linux 4.15上了。这种情形在实际开源项目中是很常见的。
因此,分支管理显得很重要。master分支通常是用来与开源项目同步的,dev分支是我们平常开发用的主分支。另外,每个开发人员在本地可以建立属于自己的分支,如feature_a_v0分支,表示开发者甲在本地创建的用来开发feature a的分支,版本是v0。
$ git branch -a* dev-linux-4.0 feature_a_v0 master remotes/linux/master remotes/origin/masterremotes/origin/dev-linux-4.0
(1)把开发工作推送到dev-linux-4.0分支
下面就是基于dev-linux-4.0分支进行工作了,比如这里实验中要求修改Makefile,然后生成一个提交并且将其推送到dev-linux-4.0分支上。
首先修改Makefile。
修改的内容如下:
diff --git a/Makefile b/Makefileindex fbd43bf..2c48222 100644--- a/Makefile+++ b/Makefile@@ -2,7 +2,7 @@ VERSION = 4 PATCHLEVEL = 0 SUBLEVEL = 0 EXTRAVERSION =-NAME = Hurr durr I'ma sheep+NAME = benshushu # *DOCUMENTATION* # To see a list of typical targets execute "make help"@@ -1598,3 +1598,5 @@ FORCE: # Declare the contents of the .PHONY variable as phony. We keep that # information in a variable so we can use it in if_changed and friends. .PHONY: $(PHONY)++#demo for rebase by benshush //在最后一行添加,为了将来变基制造冲突
生成一个提交。
$ git add Makefile$ git commit –s demo: modify Makefile modify Makefile for demo v1: do it base on linux-4.0
把这个修改推送到远程仓库。
$ git push origin dev-linux-4.0Counting objects: 3, done.Delta compression using up to 8 threads.Compressing objects: 100% (3/3), done.Writing objects: 100% (3/3), 341 bytes | 0 bytes/s, done.Total 3 (delta 2), reused 0 (delta 0)remote: Resolving deltas: 100% (2/2), completed with 2 local objects.remote: Checking connectivity: 3, done.To https://gitee.com/benshushu/ben-linux-test.git c67cf17..f35ab68 dev-linux-4.0 -> dev-linux-4.0
(2)新建dev-linux-4.15分支
首先从远程仓库(remotes/linux/master)分支上新建一个名为linux-4.15-org的分支。
$ git checkout -b linux-4.15-org linux/master
然后把这个linux-4.15-org分支重新放到 v4.15的标签上。
$ git reset v4.15 --hardChecking out files: 100% (21363/21363), done.HEAD is now at d8a5b80 Linux 4.15
接着切换到主分支。
$ git checkout master Checking out files: 100% (57663/57663), done.Switched to branch 'master'Your branch is up-to-date with 'origin/master'.
然后把linux-4.15-org分支上所有的提交都合并到主分支上。
figo@figo:~ben-linux-test$ git merge linux-4.15-org
合并完成之后,查看主分支的日志信息,如下所示。
figo@figo ~ben-linux-test$ git log --oneline 749d619 Merge branch 'linux-4.15-org'c67cf17 Merge branch 'linux-4.0'f85279c first commitd8a5b80 Linux 4.15
最后,把主分支的更新推送到远程仓库,这样我们的远程仓库的主分支就是基于Linux 4.15内核了。
figo@figo:~ben-linux-test$ git push origin master
(3)变基到Linux 4.15上
首先基于dev-linux-4.0分支创建一个dev-linux-4.15分支。
figo@figo:~ben-linux-test$ git checkout dev-linux-4.0figo@figo:~ben-linux-test$ git checkout -b dev-linux-4.15
因为我们已经把远程仓库主分支更新到Linux 4.15,所以接下来把主分支上所有的提交都变基到dev-linux-4.15分支上。这个过程可能有冲突。
$ git rebase master First, rewinding head to replay your work on top of it...Applying: demo: modify MakefileUsing index info to reconstruct a base tree...M MakefileFalling back to patching base and 3-way merge...Auto-merging MakefileCONFLICT (content): Merge conflict in Makefileerror: Failed to merge in the changes.Patch failed at 0001 demo: modify MakefileThe copy of the patch that failed is found in: .git/rebase-apply/patchWhen 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".
这里显示在合并“demo: modify Makefile”这个补丁时发生了冲突,并且告诉你冲突的文件是Makefile。接下来就可以手工修改Makefile文件并处理冲突。
# SPDX-License-Identifier: GPL-2.0VERSION &#61; 4PATCHLEVEL &#61; 15SUBLEVEL &#61; 0EXTRAVERSION &#61;<<<<<<<749d619c8c85ab54387669ea206cddbaf01d0772NAME &#61; Fearless Coyote&#61;&#61;&#61;&#61;&#61;&#61;&#61;NAME &#61; benshushu>>>>>>> demo: modify Makefile
手工修改冲突之后&#xff0c;可以通过git diff命令看一下变化&#xff0c;通过git add命令添加修改的文件&#xff0c;然后通过git rebase --continue命令继续做变基。当后续遇到冲突时还会停下来&#xff0c;让你手工修改&#xff0c;继续通过git add来添加修改后的文件&#xff0c;直到所有冲突被修改完成。
$ git add Makefile $ git rebase --continue Applying: demo: modify Makefile
当变基完成之后&#xff0c;我们通过git log --oneline命令查看dev-linux-4.15分支的状况。
figo&#64;figo:~ben-linux-test$ git log --oneline344e37a demo: modify Makefile749d619 Merge branch &#39;linux-4.15-org&#39;c67cf17 Merge branch &#39;linux-4.0&#39;f85279c first commitd8a5b80 Linux 4.15
最后我们把dev-linux-4.15分支推送到远程仓库来完成本次项目。
figo&#64;figo:~ben-linux-test$ git push origin dev-linux-4.15
(4)合并(merge)和变基(rebase)分支的区别
在本实验中使用了merge和rebase来合并分支&#xff0c;有些读者可能有些迷惑。
$ git merge master$ git rebase master
上述两个命令都是将主分支合并到当前分支&#xff0c;结果有什么不同呢&#xff1f;
我们假设一个git仓库里有一个主分支&#xff0c;还有一个dev分支&#xff0c;如图2.9所示。
图2.9 执行合并分支之前
每个节点的提交时间如表2.8所示。
表2.8 节点提交时间表
在执行git merge master命令之后&#xff0c;dev分支变成图2.10所示的结果。
图2.10 执行git merge master合并之后的结果
我们可以看到执行git merge master命令之后&#xff0c;dev分支上的提交都是基于时间轴来合并的。
执行git rebase master命令之后&#xff0c;dev分支变成图2.11所示的结果。
图2.11 执行git rebase master合并之后的结果
git rebase命令用来改变一串提交基于哪个分支&#xff0c;如git rebase master就是把dev分支的D、F和G这3个提交基于最新的主分支上&#xff0c;也就是基于E这个提交之上。git rebase的一个常见用途是保持你正在开发的分支(如dev分支)相对于另一个分支(如主分支)是最新的。
merge和rebase命令都是用来合并分支&#xff0c;那分别在什么时候用呢&#xff1f;
- 当你需要合并别人的修改&#xff0c;可以考虑使用merge命令&#xff0c;如项目管理上需要合并其他开发者的分支。
- 当你的开发工作或者提交的补丁需要基于某个分支之上&#xff0c;就用rebase命令&#xff0c;如给Linux内核社区提交补丁。