Git教程 · 合并小型项目
在项目的初始阶段,往往需要针对重要的设计决策和技术实现原型实验。当原型评估结束后,需要将那些成功的原型合并起来称为整个项目的初始版本。
在这样的情景中,各个原型会分散在不同的版本库中有不同的版本。当整个项目启动时,最好建立一个公共版本库,将不同原型中的文件合并到这个版本库中。
考虑另外一种情景,项目的初始版本过分模块化并且版本独立。随后会出现相同的修改需要在不同的版本库中同步执行,并且修改文件需要在不同版本库中相互转移。将它们合并到同一版本库也可以解决这个问题。
本章的工作流会演示在Git 中合并多个版本库,同时:
- 保留所有文件的历史版本;
- 保留所有版本库的标签。
1️⃣ 概述
这段工作流可执行的基础是Git支持使用fetch
命令将提交从多个版本库导入同一版本库中 。Git 并不要求被合并导入的提交拥有共同的源版本。
如图顶部所示后端 (backend) 和前端 (ui) 两个版本库将作为待合并的项目示例。
将所有提交导入到同一版本库之后,将会产生两套不同提交历史。如果切换至后端或者前端项目某一个特定的历史版本提交,那么工作区只会显示被选取项目的文件。
创建公共项目中重要的一步是使用 merge
命令合并那些不相关的历史提交。为了准备合并,有必要为现有的每个项目创建一个新的根目录,并把它们当前所有文件移到该根目录下(新文件目录分别命名为backend 和 ui) 。合并之后,公共项目的根目录将包
含两个子目录 ( backend 和 ui), 如图底部所示。
2️⃣ 使用要求
不同的标签:每个项目都需要有不同的标签名。如果不同的项目中含有相同的标签,必须将它们删除或者重新创建一个独特唯一的标签名。
许多项目,每一个都有独立的版本库,需要将它们合并到一个公共的版本库中,并保留各自的提交历史。
3️⃣ 执行过程及其实现
随着接下来的操作步骤,将演示两个版本库 (前端和后端) 的合并。合并前每个版本库都有一个主分支。合并后将只有一个版本库和一个主分支。
第1步:创建一个主版本库
首先,克隆后端版本库而创建一个新的公共版本库,并切换至新的工作区。> git clone backend common > cd common
第2步:将文件移到该项目专属文件目录下
创建一个名为 backend 的后端项目文件目录,可以避免合并前端项目时的文件冲突。> mkdir backend
接着,将所有的文件移到这个文件夹中,可以使用
mv
命令来执行这一操作。文件和文件目录的整理属于操作系统层面的操作,也需要在Git系统中使用add
和rm
命令,将添加和删除文件的操作纳入到待提交修改中。> git mv src test backend
最后,操作完成,使用
commit
命令提交修改。> git commit -m "backend directory created"
第3步:导入另一个版本库
为了导入前端版本库,首先在公共版本库中创建一个新的远程端点。> cd common > git remote add ui ../ui/
使用
fetch
命令,将前端版本库所有的Git 对象(包括分支、标签、版本提交)导入公共版本库中。> git fetch ui
注意! 如果待导入的前端版本库中的标签已经在公共版本库中存在同名标签,那后导入的标签将被忽略。
第4步:将导入的文件移到该项目专属文件目录下
下一步,为导入的项目文件创建一个名为ui 的前段项目文件目录。由于首先导入的后端项目已存在 master 分支,需要为前端项目中同名的 master分支另外创建一个本地分支名,在 此命名为 uimaster。> git checkout -b uimaster ui/master
上述参数分别代表如下含义。
-b
: 创建一个新分支并设为活动分支。uimaster
: 本地分支名。ui/master
: 引用远程版本库ui 中的 master 分支。
如同上文第 2 步中操作步骤,创建前端项目文件目录并将项目文件移至该目录下。
> mkdir ui > git mv src test ui > git commit -m "ui directory created"
第5步:合并项目
在两个项目分别导入了公共版本库,并有各自独立的项目文件目录,接下来执行合并操作。
合并操作在 master 分支上执行,将其设为活动分支。> git checkout master
使用
merge
命令将uimaster
分支合并入master
分支。因为两个分支中文件在不同的两个文件目录下,所以合并不会发生冲突。> git merge uimaster
合并的结果可以由图形化日志 ( log) 命令查看,可以方便地查看到两个独立发展的项目原提交历史。
> git log --graph --oneline e40fcb2 Merge branch 'uimaster' |\ | \\ | * ace51c9 ui directory created | * 40feb24 foo and bar added * f8bd134 backend directory created * fa1482a bar added * bddfa53 foo added
删除专门用来的执行合并操作的临时分支 uimaster。
> git branch -d uimaster
这样就完成了,合并得到一个公共分支,包含两个项目的全部历史和标签。
可不可以跳过第2步和第4步呢? 为什么要为每个项目创建项目独立的文件目录呢?
如果不创建新的文件目录,那么合并命令执行时将尝试合并两个项目的根目录到一个根目录,并合并其中文件。两个项目中相同的文件将被合并至一个文件并且需要解决冲突。
如果要合并两个前期不相关的项目,那同名同目录文件需要被合成一个文件的情况可能很少见。大多数情况遇到同名文件,需要移动或者重名其中一个来解决冲突。文件系统层面的操作在合并开始前执行比合并过程中执行要容易一些。
本章上述流程阐述了合并项目文件是可以通过为不同的项目创建专属的子文件目录并分别版本化管理来实现的。
《【Git教程】(十八)拆分大项目 — 概述及使用要求,执行过程及其实现,替代解决方案 ~》