从Django迁移到Git版本管理的那些坑

前端小茶馆
2026-08-31 11:42
阅读 287

上周五晚十点,我又对着终端发呆。屏幕上一串红色merge conflict提示,像地铁早高峰的人流——挤在一起,谁也不让谁。这已是本月第三次因代码冲突加班。

我们团队用Django做后端,七八个人共用一套代码库。最初靠手动复制粘贴同步代码,后来用FTP共享。有天下午,同事小张改的登录接口被另一个同事的"最新版"直接覆盖了。那一刻我意识到:版本管理不是可选项,是生存技能。

我们到底在管什么

版本管理的核心很朴素:记录每次改动,让你能回到过去。但Django项目的文件类型特别杂——Python代码、HTML模板、静态资源、迁移文件、配置文件,每种文件对"版本"的理解都不一样。

拿迁移文件来说。Django的migrations目录里,每个文件都有编号,如0001_initial.py。一旦两个人同时生成,编号就会撞车。我踩过这个坑:我和另一个后端同时改了模型,各自生成0003开头的迁移文件,合并时Django直接报错:

django.db.migrations.exceptions.InconsistentMigrationHistory:
Migration admin.0001_initial is applied before its dependency
users.0001_initial on database 'default'.

后来团队定了规矩:谁改模型,先在群里喊一声,迁移文件生成后立刻提交,其他人rebase之后再生成自己的。

Git不是银弹,但比没有强

我们选了Git,理由很朴素:免费、资料多、生态好。但Git入门容易,用好难。太多人把Git当"高级网盘"用——每次git add . && git commit -m "update" && git push完事。三个月后翻历史记录,跟看天书一样。

有次线上出bug需要回滚,git log翻出一百多条"update",根本不知道哪条是稳定版。那次之后,我们强制要求commit message遵循简单格式:

[类型] 简短描述

详细说明(可选)

类型包括feat、fix、refactor、docs、chore。例如:

[fix] 修复登录接口在并发请求下的session冲突

问题:多个请求同时刷新token时,session被覆盖
解决:引入redis存储session,Django默认的数据库session改为缓存

这个习惯养成后,回看代码轻松很多。

分支策略的实战教训

一开始所有人都在master上直接开发,每天早上pull代码像拆盲盒。后来改成Git Flow,开了develop、feature、release、hotfix一堆分支。但对七八人的小团队来说,这套流程太重了——一个简单bug修复要走完从feature到develop再到release的完整流程,光合并请求就要提两次。有次紧急线上修复,等走完流程,用户已经骂了一下午。

现在的策略简单粗暴:master作为主分支,永远保持可部署状态。每个开发从master拉自己的feature分支,功能做完提PR,至少一人review通过后合并。紧急修复直接从master拉hotfix分支,修完合并回master,再cherry-pick到开发中的feature分支上。

这套流程跑了半年,冲突率明显下降。重点在于:分支越短命越好。一个feature分支活超过三天,合并时大概率要处理一堆冲突。

那些让人头大的冲突

Django项目里最麻烦的冲突不是Python代码,而是模板文件和迁移文件。

Python代码冲突逻辑清晰,手动解决即可。模板文件就恶心了——HTML结构嵌套深,冲突标记经常把标签截断,改完一渲染页面直接崩。有次一个base.html冲突,我解决了半小时,结果把同事新加的导航栏删了。

迁移文件冲突更隐蔽。两个迁移文件都依赖同一个父迁移,合并后Django能跑,但数据库状态可能不一致。有次测试环境正常,生产直接报错,查了半天是迁移文件合并顺序错了。

现在的做法:遇到迁移文件冲突,先看谁的分支先合,后合的人重新生成迁移文件。麻烦点,但不出幺蛾子。

一些让生活好过点的技巧

git stash是救命稻草。 有次我正改到一半,产品经理说线上有紧急bug要立刻修。我直接git stash暂存改动,切新分支修bug,修完git stash pop恢复,全程不到五分钟。

rebase和merge,我选rebase。 merge会产生额外的合并提交,历史记录像蜘蛛网;rebase让历史更线性,但会改写提交历史。现在的规矩是:自己的feature分支随便rebase,公共分支只用merge

tag是版本的锚点。 每次发布生产都打tag,如v1.4.2-20260831。线上出问题,对比两个tag之间的代码差异,十分钟定位问题。

忽略文件要趁早。 Django项目里__pycache__.envstaticfiles都不该进版本库。我们一开始没配好.gitignore,结果有同事把.env提交上去了,数据库密码明文躺在GitHub上。还好是私有仓库,不然就是安全事故。

版本管理之外的东西

搞了这么久,最大的感受是:工具只是工具,关键是人

总有人觉得版本管理麻烦,"我改完直接传上去不行吗?"我们组之前有个实习生,每次提交都不写message,说"懒得写"。后来让他整理发布文档,他翻了半天git log啥也看不懂,最后自己乖乖写规范message了。

另外,版本管理不只是代码。Django项目里的requirements.txt、环境配置、部署脚本都得管起来。我们曾遇到:测试环境Django版本3.2,生产是4.1,代码在测试跑得好好的,上生产就报错。查了半天,是有人升级了生产依赖但没同步requirements文件。现在requirements.txt锁死版本,每次升级走变更流程。

写在最后

版本管理是"怎么做"里的基本功,平时不觉得,没了就完蛋。它管的不仅是代码版本,更是团队的协作方式和项目的生命线。搞懂了它,加班都少了不少。

如果你也在用Django做项目,建议把迁移文件的处理流程先定好。这玩意儿看着不起眼,坑起来真要命。

评论 0

最热最新
暂无评论
前端小茶馆Lv.1
0
影响力
0
文章
0
粉丝