7

我正在开展一个项目,人们可以提交故事并让其他人做出贡献。与其简单地编辑数据库中的条目,我更愿意存储人们所做的更改而不是整个新的更改集。然后,如果人们想恢复到以前的版本,我可以动态应用差异。我还可以轻松地向编辑用户展示仅修改过的文本,以便他们可以直接跳转到更改。

我知道如何获取差异文件并用它们修补其他文件。但是我正在使用 Python 和 Django 制作一个 Web 应用程序,并且我会将所有这些差异存储在 MySQL 数据库中。鉴于性能不是这个应用程序的主要问题,我准备从数据库中提取数据,制作文件,然后在这些文件上运行git diff和运行。patch

有没有比每次我想创建新版本或应用新差异时构建新文件并删除它们更好的方法?有没有办法在纯文本而不是文件上运行差异?例如。将 bash 中的变量设置为(什么是)文件的内容(但实际上是来自数据库的数据),并git diff在它们上运行?我想在用户提交表单后从 Python 文件控制这些操作。

我真的只是在寻找一个开始解决这个问题的好方法,所以任何帮助将不胜感激。

谢谢你的时间,

典范RG

4

2 回答 2

6

我已经做了很多寻找解决方案的工作。Python 的 difflib是相当合法的,但不幸的是,它倾向于要求 diff 字符串包含整个原始字符串以及更改的记录。这与 git diff 不同,在 git diff 中您只能看到更改的内容和一些额外的上下文。difflib 还提供了一个名为unified_diff 的函数,它确实提供了一个更短的diff,但它没有提供从一个字符串和一个diff 重建字符串的函数。例如。如果我从 text1 和 text2 中创建了一个差异,称为 diff1,那么我无法从 text1 和 diff1 中生成 text2。

因此,我制作了一个简单的 Python 模块,它允许从单个字符串及其相关差异中向前和向后重建字符串。它称为 merge_in_memory,可以在https://github.com/danielmoniz/merge_in_memory找到。只需拉动存储库并运行 setup.py。

一个简单的用法示例:

import merge_in_memory as mim_module

str1 = """line 1
line 2"""
str2 = """line 1
line 2 changed"""

merger = mim_module.Merger()
print merger.diff_make(str1, str2)

这将输出:

--- 
+++ 
@@ -1,2 +1,2 @@
 line 1
-line 2
+line 2 changed

diffs 只是字符串(而不是 tan 生成器,因为它们在使用 difflib 时)。您可以使用该函数创建多个 diffs 并一次应用它们(即快进历史或回溯)diff_apply_bulk()

要反转到历史记录,只需确保在调用或reverse时将属性设置为 True 。例如:diff_bulk()diff_apply_bulk

merge = self.inline_merge.diff_apply_bulk(text3, [diff1, diff2], reverse=True)

如果您从 text1 开始并使用 diff1 和 diff2 生成 text2 和 text3,则使用上面的代码行重建 text1。请注意,差异列表仍按升序排列。“合并”,即。将差异应用于字符串本身就是一个字符串。

所有这些都允许我将差异存储在数据库中作为简单的 VARCHAR(或你有什么)。只要我有一个起点,我就可以将它们按顺序拉出并在任一方向应用以生成我想要的文本。

请随时对此发表评论,因为这是我的第一个 Python 模块。

谢谢,

典范RG

于 2012-05-05T02:39:17.483 回答
1

看看libgit。它是一个 C(和所有其他语言)接口,可让您以各种方式操作 git 存储库。

它看起来相当低级,所以让它实际提交、diff 等可能很乏味,但它至少有一个功能可以将 blob 添加到 repo 而不需要放在 disk 上

os.system当然,另一种选择是创建一个普通的基于文件的存储库和工作副本,并使用调用在数据库和文件系统之间来回反弹。

于 2012-05-04T15:41:06.363 回答