多个编程任务的代码管理

103 天前
 FatSheep2020

大家好,

虽然已经工作 6 年了,但是这个任务还是经常困扰我。 我司的工作比较多,每个程序员手头都是 3 到 4 个任务同步在处理。不可避免地,两个任务会修改同一个 cpp 文件。 但是我司的代码 review 要求,上传的代码只能有对应任务的代码,其余的修改必须删除掉。所以就经常出现,为了任务 A 的 review ,把任务 B 的代码删了。要做任务 B 的 review 时,又把删除的代码加回来这样尴尬的事情。

之前用 Perforce 的时候,shelve 功能可以解决一大部分的问题。但是现在切成 SVN 了,shelve 功能就不好使了。

所以想请问大家平日遇到此类问题,是如何管理自己的本地工程的。

谢谢。

1083 次点击
所在节点    问与答
10 条回复
ilovey482i
103 天前
git 的分支管理
Maboroshii
103 天前
写过多线程代码的都知道,要并行改串行。那么解决办法就是:把人都开掉,留一个程序员,按顺序写代码,就不会冲突了。 ( doge

为什么不用 git 啊。。。
FatSheep2020
103 天前
@Maboroshii 用什么不由我说了算,公司的代码放在 SVN 上
tool2dx
103 天前
写点脚本生成 review 专用代码呗。

本质上就是 review 要求太多,需要同一个文件里,进行不同任务的代码隔离。
whitefable
103 天前
其实 svn 也有 shelve 功能但的确不太好用,而且事实上我这边也有类似的问题,虽然我司没那么严格的 review 机制。方法也是有的,我这边有 2 种做法吧:
1. A 、B 任务同时开发,那提交记录必然是两者有互相交错;那就在 review A 之前将所有 B 的提交都 revert ,而将 B 加回来也很简单,前面那次 revert 之后会产生一次提交,只需要将这次提交再 revert 一次就 ok 了,这么做就是来回比较麻烦而且提交记录上有比较多这种 revert 再 revert 的记录
2. svn 的分支给我感觉上相比 git 的确是没那么好,但也有适合于 svn 的方式。那就是你在本地开发的时候,假设 svn 当前 head 的版本号在 1000 ,那就任务 A 和任务 B 分别建立两个不同的文件夹都 checkout 1000 这个版本(并不是开新的分支),然后在这两个文件夹内开发。这么做的缺点就是每个任务开发过程中就不好提交了,不然就和 1 其实是类似的,提交记录总是一堆交错。一个折中的方法是文件夹内可以自己用 git 本地管理,然后差不多了再提交一波大的到公司的 svn 去,这样子记录相对干净一点。
其实基于 2 当然也可以用分支的方式,分支的话 A 提交了啥到时候直接将相应提交 merge 到 B 即可。不过 svn 的分支+合并并不像 git 那么清晰;之前也和领导讨论过 svn 的分支比较舒服就是本地直接搞多个文件夹,然后文件夹内开发就是了
FatSheep2020
103 天前
@whitefable 感谢您的回答。

> 那就是你在本地开发的时候,假设 svn 当前 head 的版本号在 1000 ,那就任务 A 和任务 B 分别建立两个不同的文件夹都 checkout 1000 这个版本(并不是开新的分支),然后在这两个文件夹内开发

请问这两文件夹内都包含了工程的所有代码是吗?
meeop
103 天前
用 git,git 分支就是专门针对你这个问题给出的解决方案,兵法修改 git 会提示有冲突,然后解决冲突正确合并代码

公司不让用但你自己可以用,本地代码使用 git 管理,使用 svn 合并代码到本地,然后用 git 工具观察变更并合理合并,最后再把合并好的结果提交 svn

另一个优化是对被修改的源码文件拆分子模块,一般来除了核心代码,一个公司会是一个人/小组负责一部分业务逻辑,你把你负责的业务逻辑尽可能独立出来,这样就能减少别人修改你负责模块造成冲突的可能性
purringpal
103 天前
是不是也间接说明代码耦合太严重了
whitefable
103 天前
@FatSheep2020 #6 是的,多个任务就多个文件夹,每个文件夹都是等同于项目全量备份。其实这么做和在 svn 服务器上拉一条新的分支区别在于:
a) 如此做法只是在本地将两个开发分开,但实际的提交历史还是同一条,且 A 提交完后 B 再提交前必须要先强制将 svn 服务器上的新的提交都 update 到本地才能提交(其实也等同于一次合并过程)。但服务器上不用说改了任务 A 一部分,后续还要记得将变更 merge 到任务 B 这里,毕竟提交都是在同一条线上的
b) 服务器上拉分支就是服务器上先给你全量 copy 一份项目,然后将两个提交分开在 2 条线上而已。这么做的话可以令 AB 在开发过程中怎么提交都 OK ,可以保留更多的细节(相当于 a 在同一条线上提交可能就会不提交太细节了避免太多多余信息),最终再进行合并。这种做法和 git 大概有点类似?但我一直也没找到什么好方法可以很好在 svn 的线性提交历史里面找到正确的合并点

说到 b)中的合并点也不得不说 svn 的 merge 和 git 还是有点区别的。git 的合并总是会强制自动产生一个提交;而 svn 的合并并不会,本质上来说 svn 的 merge 只是很简单的将另一个分支上你所选择的提交所记录的变动直接应用在本地文件夹,本身就是基于文件/文件夹操作的,所以在提交的 log 里面是记录着哪些提交被合并了,而不是像 git 一样是一个单一的合并点。另一个核心点在于 svn 的提交记录是必须线性的,所以你可以看到有一个全局 svn 号,可以直接唯一定位到哪次提交;而 git 本身就是非线性的,从而对于多分支做法有自身的优势; svn 的线性意味着你要像 git 一样去理解操作的时候,其实最终提交到 svn 服务器上都会有一个类似于 git 中的 rebase 的操作 => 将分支的变更需要将原来分支点转成基于当前最新提交作为分支点再进行提交,从而线性化。

只能说 svn 和 git 其实底层是有一些逻辑不太一样吧,反正怎么舒服怎么来。我现在做法一般是本地可能扔一个 git ,用来维护日常的变动甚至非常小的变动,从而使得新版本在机器上万一改出问题比较好回退,同时 svn 上不会产生特别大量的信息。对于上述 a) b)两种情况其实我这里也是有混用的,一般例如说如果是机器硬件产生比较底层的变化,但大体上逻辑是一致的,那需要维护两个版本则我们会用 b)从服务器直接拉分支,并且更改时总是基于一条分支做主要变更,另一条分支不断用 merge 将变更同步过去就是了;而一般临时性或短期性的多个需求点的开发则会采用 a)这种方式,一个需求点搞完了本地这个文件夹就可以扔掉直接清理掉不管了。

说了这么多就顺便说到另一个问题就是像你正在开发任务 A ,但又有一个 bug 要改的 hotfix B 。在 git 里面也是直接拉分支比较方便的,但 svn 我倒是遇到一个问题在于 A 已经提交一部分了,这时候改 B 就不可避免在提交历史上 A 和 B 是穿插的。所以这里 svn 其实本身也提供了另一种工作流:项目一开始就建立发布分支和开发分支(当然还可以再建立多一个 hotfix 分支)。然后开发分支上做开发工作,这时候 hotfix 修复 bug 的话其实你提交在开发分支也没关系。基于 svn 的 merge ,那你需要 review 其实是发布分支,当你完成一部分功能或者修复了一个 bug 直接只需要将需要的提交挑选出来,直接 merge 到发布分支就完事了。这也是一种方法
FatSheep2020
102 天前
@whitefable 非常感谢您的耐心留言。我目前先尝试一下 git svn 命令来管理本地工作目录。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1071616

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX