用于diff sqlite表的Git钩子

时间:2012-11-07 14:22:05

标签: git sqlite githooks

我在Git存储库中有一个Sqlite数据库。今天我想在两个不同的提交中做一个视图的差异。我是这样做的:

$ sqlite3 -list file.sqlite "SELECT * FROM contact_list_detailed" >/tmp/newlist
$ git checkout 51c24d13c file.sqlite
$ sqlite3 -list file.sqlite "SELECT * FROM contact_list_detailed" >/tmp/oldlist
$ git checkout -- file.sqlite
$ diff /tmp/oldlist /tmp/newlist

它可以工作,如果我愿意,我可以编写脚本。但是有什么“好”的方法可以用钩子做到这一点吗?

3 个答案:

答案 0 :(得分:14)

Here是如何使用git的textconv功能来显示sqlite文件版本之间的差异。它只是进行转储,因此对于大型数据库来说可能不是非常有效。没有必要的钩子。

该链接似乎已不再可用,因此我使用的是已存档的版本。

它的要点是,在git属性文件(.gitattributes.git/info/attributes)中,添加模式匹配以强制sqlite3差异(假设您的数据库文件具有扩展名.sqlite3 ):

*.sqlite3 diff=sqlite3

然后在你的git配置文件(~/.gitconfig.git/config)中:

[diff "sqlite3"]
    binary = true
    textconv = "echo .dump | sqlite3"

如果您只想跟踪架构更改,请使用.schema代替.dump

答案 1 :(得分:4)

您可以使用HEADHEAD^来访问之前和当前的修订版;请参阅git post-commit hook - script on committed files以获取示例。

使用git show将文件解压缩到临时目录,而不会覆盖工作副本。


除非绝对必要,否则我不会在git中存储二进制文件。 如果使用sqlite3 file.sqlite .dump创建SQL命令的文本文件并将 放入git,将二进制数据库仅作为生成的文件,则可以避免许多麻烦。 (但是你必须在必要时关心重新生成SQL文件。)

答案 2 :(得分:0)

如果真的要在git中跟踪二进制数据库文件,则存在一些问题。 由于sqlite数据库可能会有所不同,而其中存储的数据没有更改,因此git status的输出对于确定是否应该提交,git diff仅显示类似Binary files a/foo.sql and b/foo.sql differ的内容并没有真正的帮助。 为了从git diff获得正确的输出,基本上有两种方法可以比较各个文件:

  1. 使用textconv将文件转换为纯文本,如Biran Minton的答案所示。
  2. 设置一个自定义的diff应用程序,该应用程序可以直接创建diff。

我将使用sqlite随附的sqldiff概述下面的第二种方法。 与textconv方法一样,需要更改属性和配置文件。

属性:

*.sql* diff=sqldiff

config:

[diff "sqldiff"]
    command = gitsqldiff

上面的gitsqldiff字符串是指一个包装器脚本,该脚本需要安排git给定的参数以供sqldiff使用。 它必须是可执行文件,并且可以通过PATH环境变量来访问(将其放在~/bin中应该可以)。 因为(到目前为止)sqldiff的退出值始终为0,因此无济于事,我们必须检查它的打印内容以提供用户反馈-特别是在数据库中没有根据{{1 }}根本不产生任何输出。 为此,我们使用trick将输出重定向到其他文件描述符,并通过sqldiffstdout重定向给用户。

tee

gitsqldiff

这当然不会使sql文件成为git存储库中的一等公民,但可能会促进仍然有效的工作流程。