Git 开发模式
Git 小技巧
创建 Git 分支文件夹
当 Git 项目中的分支达到一定数量时,有时候就希望可以像操作系统中的文件系统一样,可以将某个文件放入文件夹中。在 Git 中同样可以创建分支文件夹,并将某个分支置于某个分支文件夹中。
实际上,在 Git 中这样做很简单,只需要在新建分支的时候,在分支名使用路径分隔符 /
即可。这样,在路径分隔符 /
前面的内容就会被视为文件夹名。
比如,如果想要创建分支文件夹 folder
,并将分支 branch
放入分支文件夹 folder
中,只需要创建名为 folder/branch
的分支名即可。
如图所示,这样在 IntelliJ IDEA 2021.3 (Ultimate Edition)
中就能显示出分支文件夹了。
Git 单体开发模式
引导
这里的 Git 单体开发模式
指的是一个人使用 Git 进行开发的模式。
为什么一个人使用 Git 开发这里也需要单独提及呢?这里针对的是一个 Git 的开源项目,其中,此 Git 项目的开发者只有一个人,但此 Git 项目在上传至 Git 仓库之后可令很多人看到。
这有什么问题呢?想象这样的一种情况,开发者每天进行一次 Git 提交(commit),当他推送(push)到远程开源仓库时,其他人(读者)就会看到他每天的提交信息。但是,对读者来说,作者每天的提交信息是不想去了解的,而且这其中可能还涉及作者的隐私。读者更希望想到精简整合过的信息,而不是众多细枝末节的信息。如果每次的提交都是一个新版本的发布就好了。但是对于作者而言,细节的提交信息可以更有利于作者进行修改与回滚。
这一矛盾怎么解决呢?
实际上,这可以通过创建多个分支来解决。这里创建了三个分支,分别为 dev、history、main。简介如下。
- dev:开发分支。每次只能在此分支上进行提交。此分支不会推送给远程仓库。
- history:储存原始提交信息的分支。此分支不会推送给远程仓库。
- main:对外展示的分支。只有此分支才会推送给远程仓库。
dev 是开发分支。通常进行编写代码、日常开发时,应当切换到此分支。每次进行提交时,也只在此分支上进行提交,日积月累,此分支上就会有一系列的原始提交信息。
当 dev 开发到一定程度时,这时候就需要对外发布一个版本了。前面有言,此时肯定不能直接将此 dev 分支直接推送到远端,因为此分支的提交中包含了很多不必要的细节信息。但是对于作者而言,这些细节信息很重要。这个时候,可以选择在 dev 上新建一个分支 history,这样分支 history 就会包含 dev 中所有细节的提交信息。
然后再切换到分支 dev。由于前面已经使用分支 history 备份了前面的这些细节的提交信息,现在就可以将这些细节的提交信息进行压缩,很多嵌入了 Git 的 IDE 都提供了压缩 Git 提交的功能。然后在压缩的分支 dev 上新建对外发布的分支 main,现在就可以将分支 main 当做对外发布的分支来向远程仓库发布了。
然后此时就可以再切换到分支 dev 上继续开发。
当 dev 又开发到一定程度时,这时候就又需要对外发布一个版本了。此时分支 history 将落后于分支 dev,如果想让分支 history 包含 dev 中所有细节的提交信息,就需要将现在分支 dev 的提交整合到分支 history 中。但是此处不能使用 Git 的 merge
命令,原因是,从概念上讲,分支 history 的提交信息应该是独立的,它的数据不应该来源于分支 dev,此时可以使用 cherry-pick
命令,将分支 dev 中新出现的这些提交信息不留痕迹地拷贝到分支 history 中。使用命令 cherry-pick
命令需要先切换到分支 history 之后才能进行。
由于分支 dev 之后也会和之前一样将其新出现的这些提交信息进行压缩,这会导致无法分辨分支 dev 与分支 history 的 Git 提交之间的联系,所以此处还应该在分支 history 上使用 merge
命令来合并分支 dev。这次的合并应该不会有任何实际的合并内容,仅仅是为了标记分支 dev 与分支 history 的 Git 提交之间的联系。
现在,和之前一样,切换到分支 dev,并对新出现的这些提交信息进行压缩。压缩之后,同样使用 cherry-pick
命令,将分支 dev 中新出现的这些提交信息不留痕迹地拷贝到分支 main 中。同样,此处使用命令 cherry-pick
命令需要先切换到分支 main 之后才能进行。
然后,现在就可以将分支 main 中新压缩的提交推送到远程仓库中了。当然,推送之后还需要再把当前分支切换到开发分支 dev 中才能进行下一步的开发。
改进
现在来考虑更复杂的问题。如果推送到远程仓库的文件含有一些敏感信息怎么办?可以选择每次在将提交转移到分支 main 时删除这些信息。总是要删除很麻烦,还容易有遗漏。另外,这里还希望每次推送时,分支 main 的最终的内容与分支 history 保持一致。这就不能单单使用分支 main 来解决一切问题。
另外,在很多情形中,敏感数据总是很早就初始化的而且之后也不再变化。这种情况下,每次使用 Git 命令 cherry-pick
进行合并时就不会有掺杂很久之间的敏感数据。
可以选择设立两个分支目录 local、public 来解决这个问题。其中,目录 local 是用于保存本地分支的提交信息,目录 public 是用于保存推送至远程仓库的目录信息。
这样一来,综合前面所谈到的内容,一共就只需要通过 6 个分支就可以实现这一功能。
首先,和前面一样,在分支 local/dev
下进行日常开发,然后借助 local/history
、local/main
实现保存原始提交、发布版本的功能。如图所示。
现在,发布分支 local/main
中可能包含敏感信息,此时,需要先将分支 local/main
迁移到分支 public/dev
中,然后在分支 public/dev
中清除掉这些信息。
最后,再通过类似的方法制成最终的发布分支 public/main
即可。然后就可以将最终的发布分支 public/main
推送到远程仓库中了,而分支目录 public 下的其它分支就不需要推送了,这样就能有效地避免敏感数据在远程仓库中泄露。
最后不要忘记了,推送之后还需要再把当前分支切换到开发分支 local/dev
中才能进行下一步的开发。现在,在 IntelliJ IDEA 中应该能看到如下结构的 Git 分支目录。