【问题标题】:Django migrations files for large project in git (Best Practice)git 中大型项目的 Django 迁移文件(最佳实践)
【发布时间】:2022-01-04 01:19:45
【问题描述】:

我与 Django 项目中的一个团队合作,在本地 git 中使用相同的数据库。 我们发现 django 迁移有很多问题,特别是当团队很大时。

所以我们决定为每个开发者制作数据库,有时开发者会删除他们的迁移文件以解决迁移的一些问题。

我们在 Django 迁移文件中遇到了很多冲突,我们决定将迁移文件添加到 gitignore。

然后所有的工作变得更加顺利。但是我们遇到了一些问题,我们丢失了迁移文件的 git 历史记录,这给从特定 git 标签更新项目版本带来了问题。此外,每次我们在 git 中“结帐”时,它都会删除迁移文件。

我提出了以下建议,但我确实找到了答案

使迁移文件由本地存储库跟踪并在远程存储库中被忽略。

有人强迫这个问题吗?

【问题讨论】:

  • 我们正在使用 git 和 5 个开发人员维护一个大型 Django 项目。对我们来说唯一可行的解​​决方案是将迁移文件推送到主远程 git。生产服务器也从 git repo 中检出文件,但维护自己的迁移文件。每个开发人员都有他/她自己的分支,包括迁移文件。合并到 master 分支时,迁移被忽略。
  • @DavidBuck 感谢您的建议。好的,我不能将迁移文件添加到“.gitignore”,但我必须“自动”解决以下问题:1)在“更改”或“阶段”区域停止看到的迁移文件。 2)在合并时自动接受所有当前的迁移文件。

标签: django git gitignore


【解决方案1】:

linked possible duplicate 很好地回答了是否应提交迁移文件的问题。这个答案与此无关:它与您提出的解决方案有关。

让某些特定的存储库“跟踪”某些文件的想法有些荒谬。在 Git 中,当且仅当该文件当前在 Git 的索引中时才会跟踪文件。因此我们需要解决这个问题:

文件何时在 Git 的索引中?

简单的答案很简单——简单——而且令人困惑且无益:当文件在 Git 的索引中时,该文件在 Git 的索引中。不过,文件总是在 Git 的索引中进出。

Git 索引的目的是帮助您构建您将进行的下一次提交 现在在 Git 的索引中的文件——并且从一个时间点到下一个时间点都会发生变化——是 在你的 下一次提交中的文件。

git add 命令将在适当的条件下复制一个文件来自您的工作树——您可以查看和处理/使用的文件在您的工作树——到 Git 的索引。如果在 Git 的索引 in 中已经有一些具有该名称的文件,则该副本将被踢出索引,以便可以复制工作树副本。如果有 no 在 Git 的索引中具有该名称的文件,该文件现在已添加到 Git 的索引中。此副本一旦复制到 Git 的索引中,即使您更改或删除工作树副本,也会保留在 Git 的索引中:这些是单独的副本。1

在其他情况下,git add 将什么都不做,甚至会删除文件的索引副本。使用git rm --cached 将删除文件的索引副本,使用git rm 将删除索引副本和工作树副本。所以你有几个 Git 命令可以影响索引副本:git add,可以替换或删除索引副本,git rm,可以删除它。

git add 做这些事情的条件有点复杂,但是意味着简单易用:

  • git add 的一个全新文件将其添加到 Git 的索引中;
  • git add of an updated-in-working-tree file 踢出旧副本并添加新副本;和
  • 已删除文件的git add - 您从工作树中删除但未使用git rm 执行此操作的文件 - 删除索引副本。

所以git add“意味着”使索引副本与工作树副本匹配

git add什么都不做的条件(除了可能发出警告说它没有添加文件)发生在文件 (a) 不已经在索引中 和 (b) 列在 .gitignore 中。条件 (b) 的意思是即使我告诉你添加文件也不要添加它。这不会影响索引中 的文件——参见条件 (a)——因为,好吧,文件 在索引中。不管它可能已经到达那里,它就在那里现在,所以git add 将更新它以匹配工作树。

但文件进入 Git 索引还有另一种关键方式,那就是:每当您提取git checkoutgit switch整个提交 , Git 将提交读入索引,作为将提交文件提取到工作树的一部分。 这意味着签出具有迁移文件的提交会将该文件放入 Git 的索引中。 commits 控制索引中的文件 em>。

commits 是两个 Git 存储库共享的内容,当您将它们与 git fetchgit pull 和/或 git push 连接时。一旦提交,永远不能以任何方式更改。因此,如果某人(任何人)曾经提交了一些迁移文件,而你 git checkout那个提交了,那个文件会出现在你的工作树中和 Git 的索引。如果您随后将该提交切换到该文件不在该提交中的其他提交,Git将从两个Git中删除该文件索引和你的工作树。

简而言之,一旦提交,文件就永远存在。拥有文件的提交转移到没有文件的提交 em> 文件,意思是删除文件。从没有文件的提交移到有文件的提交,意味着添加文件。这不是可选的。它总是发生,每次。文件进入 Git 的索引或从 Git 的索引中出来;它现在被相应地跟踪或取消跟踪。

您可以在切换到或退出此类提交后,随后使用git add 和/或git rm 更改 Git 的索引。这将改变文件的跟踪性。但是切换到 另一个 提交会更新 Git 的索引,从而改变文件的可跟踪性。


1然而,索引副本以 Git 的压缩和去重格式存储,准备好进入下一次提交。这意味着,如果您使用各种 Git 调试工具来定位内部对象并转储其字节,它们将与工作树副本的字节不匹配。这是一种无损压缩方案,所以字节都在那里。只是由于 Git 使用的压缩和重复数据删除技巧,它们可能占用很少甚至不占用磁盘空间。


底线

您应该从所有这些中得出的结论是文件的“可跟踪性”不取决于存储库。这取决于个人提交。每个提交都有一些文件。提取该提交提取那些现在被跟踪的文件。每个提交都没有其他文件。如果这些文件位于您的工作树中,则提取该提交将删除这些文件,因为它们是从确实拥有它们的提交中提取的。

这一切都由 Git 索引的内容控制,所以有可能——但非常痛苦——检查一些提交,得到一堆被跟踪的文件,然后使用 git rm --cached 来从 Git 的索引中删除其中一些文件,以便 Git 忘记它们来自该提交。切换到缺少这些文件的一些other提交会将这些文件留在你的工作树中。但是重复这样做非常容易出错。不要这样做!你会后悔的。

【讨论】:

  • 非常感谢。请问我可以使用“--bare”存储库中的钩子来忽略来自迁移文件的传入更改。如果可以的话,你有一个相关的话题。
  • 不,你不能忽略任何关于提交的事情。您要么拥有提交,然后拥有全部,要么没有。如果您不喜欢您确实拥有的某个提交,您可以进行一个在某种程度上与该提交不同的新提交。您通常不会使用 Git 钩子来执行此操作,因为那是错误的地方;您可以在一个使用 Git 作为其底层存储设施的系统中执行此操作,但它位于 Git 之上,人们使用这个系统而不是直接使用 Git。
猜你喜欢
  • 1970-01-01
  • 2019-01-01
  • 2016-02-20
  • 1970-01-01
  • 1970-01-01
  • 2011-03-29
  • 2015-01-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多