【问题标题】:Git hook for diff sqlite tablediff sqlite 表的 Git 钩子
【发布时间】:2012-11-07 14:22:05
【问题描述】:

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

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

【问题讨论】:

    标签: git sqlite githooks


    【解决方案1】:

    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
    【解决方案2】:

    您可以使用HEAD 和HEAD^ 访问以前和当前的修订;示例见git post-commit hook - script on committed files。

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


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

    【讨论】:

    • 我可以将我的 db 文件放入 .gitignore 文件中,然后使用 pre-commit-hook 将内容转储到我添加到我的 git repo 的文件中吗?然后我使用某种 pre-pull-hook 从这个转储的内容创建 sqlite 二进制文件?
    • 是的(但我猜你想要post-checkout)。
    • 你说的很有道理,我想这确实是正确的做事方式。我现在没有时间真正实现这一点。但我将您的回答标记为已接受。
    • @NiclasNilsson 回复了一个非常古老的款待,但你能做到吗?如果是这样,如果你能包括这些步骤会很好
    【解决方案3】:

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

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

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

    属性:

    *.sql* diff=sqldiff
    

    配置:

    [diff "sqldiff"]
        command = gitsqldiff
    

    上面的gitsqldiff 字符串是指一个包装脚本,它需要安排git 给出的参数以供sqldiff 使用。 它必须是可执行的并且可以通过PATH 环境变量访问(将它放在~/bin 中应该没问题)。 因为(截至目前)sqldiff 的退出值始终为 0,因此相当无用,我们必须检查它打印的内容以向用户提供反馈 - 特别是在数据库中没有根据产生的 sqldiff 更改的情况下根本没有输出。 为此并向用户显示完整的输出,我们使用trick 将输出重定向到一个附加的文件描述符和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 存储库中的一等公民,但可能会促进仍然有效的工作流程。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-01-02
      • 1970-01-01
      • 2019-09-21
      • 2013-12-24
      • 1970-01-01
      • 2013-07-17
      • 2012-02-02
      • 2011-01-04
      相关资源
      最近更新 更多