我在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
它可以工作,如果我愿意,我可以编写脚本。但是有什么“好”的方法可以用钩子做到这一点吗?
答案 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)
您可以使用HEAD
和HEAD^
来访问之前和当前的修订版;请参阅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
获得正确的输出,基本上有两种方法可以比较各个文件:
textconv
将文件转换为纯文本,如Biran Minton的答案所示。我将使用sqlite随附的sqldiff
概述下面的第二种方法。
与textconv
方法一样,需要更改属性和配置文件。
属性:
*.sql* diff=sqldiff
config:
[diff "sqldiff"]
command = gitsqldiff
上面的gitsqldiff
字符串是指一个包装器脚本,该脚本需要安排git给定的参数以供sqldiff
使用。
它必须是可执行文件,并且可以通过PATH
环境变量来访问(将其放在~/bin
中应该可以)。
因为(到目前为止)sqldiff
的退出值始终为0,因此无济于事,我们必须检查它的打印内容以提供用户反馈-特别是在数据库中没有根据{{1 }}根本不产生任何输出。
为此,我们使用trick将输出重定向到其他文件描述符,并通过sqldiff
将stdout
重定向给用户。
tee
:
gitsqldiff
这当然不会使sql文件成为git存储库中的一等公民,但可能会促进仍然有效的工作流程。