Git-хук для таблицы различий sqlite

У меня есть база данных Sqlite в репозитории Git. Сегодня я хотел сделать diff представления в двух разных коммитах. Я сделал это следующим образом:

$ 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

Это работает, и я могу написать это, если захочу. Но есть ли какие-нибудь «хорошие» способы сделать это с помощью хуков?


person Niclas Nilsson    schedule 07.11.2012    source источник


Ответы (3)


Вы должны использовать HEAD и HEAD^ для доступа к предыдущей и текущей ревизиям; см. git post-commit hook - скрипт для зафиксированных файлов для пример.

Используйте git show для извлечения файлов во временную каталог без перезаписи рабочей копии.


Я бы не стал хранить двоичные файлы в git без крайней необходимости. Вы можете избежать многих неприятностей, если создадите текстовый файл команд SQL с sqlite3 file.sqlite .dump и поместите это в git, имея двоичную базу данных только как сгенерированный файл. (Но тогда вам придется позаботиться о регенерации файла SQL, когда это необходимо.)

person CL.    schedule 07.11.2012
comment
Могу ли я поместить свой db-файл в файл .gitignore, а затем использовать pre-commit-hook для вывода содержимого и в файл, который я добавляю в свой репозиторий git? И затем я использую какой-то pre-pull-hook для создания двоичного файла sqlite из этого дампа содержимого? - person Niclas Nilsson; 07.11.2012
comment
Да (но я думаю, вы хотите post-checkout). - person CL.; 07.11.2012
comment
То, что вы говорите, действительно имеет смысл, и я думаю, что это действительно правильный способ ведения дел. У меня нет времени, чтобы действительно реализовать это сейчас. Но я отмечаю ваш ответ как принятый. - person Niclas Nilsson; 08.11.2012

здесь описано, как использовать Функция 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.

person Brian Minton    schedule 14.02.2014
comment
Я думаю, что в любом случае это просто хорошая практика - сохранять его в текстовом формате. Но это хорошее решение, тем более нервное. +1 - person Niclas Nilsson; 17.02.2014

Если кто-то действительно хочет отслеживать бинарные файлы базы данных в git, есть некоторые проблемы. Поскольку базы данных sqlite могут отличаться без данных, хранящихся в них, с изменением вывода git status не очень полезно определить, следует ли фиксировать, а git diff показывает только что-то вроде Binary files a/foo.sql and b/foo.sql differ. Чтобы получить правильный вывод из git diff, есть два основных подхода к сравнению соответствующих файлов:

  1. Используйте textconv для преобразования файлов в обычный текст, как показано в ответе Биран Минтон.
  2. Настройте пользовательское приложение для сравнения, которое может напрямую создавать различия.

Ниже я опишу второй подход, используя sqldiff, который поставляется с sqlite. Как и в случае с подходом 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, но может облегчить рабочий процесс, который, тем не менее, работает.

person stefanct    schedule 02.02.2020