8

我在 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

它有效,如果我愿意,我可以编写脚本。但是有没有任何“好”的方法可以用钩子做到这一点?

4

3 回答 3

26

以下是如何使用 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.

于 2014-02-14T20:42:56.980 回答
4

您将使用HEADHEAD^访问以前和当前的修订;有关示例,请参见git post-commit hook - 已提交文件上的脚本。

用于git show将文件提取到临时目录而不覆盖工作副本。


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

于 2012-11-07T16:18:28.223 回答
2

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

  1. 用于将文件转换为纯文本,如Biran Mintontextconv的答案所示。
  2. 设置一个能够直接创建差异的自定义差异应用程序。

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

属性:

*.sql* diff=sqldiff

配置:

[diff "sqldiff"]
    command = gitsqldiff

上面的gitsqldiff字符串是指一个包装脚本,它需要安排 git 给定的参数以供sqldiff. 它必须是可执行的并且可以通过PATH环境变量访问(放入它~/bin应该没问题)。因为(截至目前)的退出值sqldiff始终为 0,因此相当无用,我们必须检查它打印的内容以向用户提供反馈 - 特别是在数据库中没有任何更改的情况下,根据sqldiff它根本不会产生任何输出。为此并向用户显示完整的输出,我们使用了一种技巧,将输出重定向到附加的文件描述符并stdout通过tee.

gitsqldiff

#!/bin/sh
echo "$1:"

# Duplicate sqldiff's output for consumption by wc and stdout.
# This enables us to check for an empty output but still see
# sqldiffs messages if there are any.
sqldiff "$2" "$5" 2>&1 | {
    tee /dev/fd/3 |
        if [ $(wc -c) -eq 0 ]; then
            echo "  nothing changed according to sqldiff"
        fi
} 3>&1

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

于 2020-02-02T14:57:31.457 回答