По умолчанию в базе данных SQLite не получится увидеть изменения через привычный git diff
git diff
diff --git a/db.sqlite3 b/db.sqlite3
index f622eb24..6e44fa5 100644
Binary files a/db.sqlite3 and b/db.sqlite3 differ
Если запустить nano db.sqlite3
, то увидим кучу тарабарщины, которая не похожа на структурированные данные. Потому что данные хранятся в бинарном виде. Существует изящный трюк, который можно использовать для решения этой проблемы: используем встроенный в git механизм textconv для снятия дампа базы данных sqlite3 на лету, чтобы отслеживать изменения, используя стандартную команду git diff
.
Добавьте в конфигурацию тип diff под названием “sqlite3”. Самый простой способ - просто выполнить эти команды:
git config diff.sqlite3.binary true
git config diff.sqlite3.textconv "sh -c 'sqlite3 \$0 .dump'"
Также вы можете добавить этот фрагмент в ~/.gitconfig
или .git/config
в вашем репозитории:
[diff "sqlite3"]
binary = true
textconv = "sqlite3 \$0 .dump"
Далее создайте файл .gitattributes
, если его еще нет, и добавьте в него эту строку:
*.sqlite3 diff=sqlite3
Расширение имени файла
*.sqlite3
может отличаться в зависимости от софта
Теперь при запуске git diff
для sqlite-файла, увидим красиво оформленный diff с изменениями.
Проверим на примере
Создаем новую папку и инициируем пустой репозиторий:
mkdir new-database
cd new-database
git init
Создаем конфигурацию, описанную выше:
git config diff.sqlite3.textconv "sh -c 'sqlite3 \$0 .dump'"
echo '*.sqlite3 diff=sqlite3' > .gitattributes
Далее создаем sqlite3 базу данных, используя интерактивный режим командной строки инструмента sqlite3
:
sqlite3 database.sqlite3
Создаем структуру базы:
CREATE TABLE users (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL,
email TEXT NOT NULL
);
Далее продолжая в интерактивном режиме, добавим двух пользователей:
INSERT INTO users (name, email) VALUES ('Alice', 'alice@ordinatus.ru');
INSERT INTO users (name, email) VALUES ('Bob', 'bob@ordinatus.ru');
Используем оператор SELECT
, чтобы убедиться, что они есть:
SELECT * FROM users;
Такой должен быть результат:
1|Alice|alice@ordinatus.ru
2|Bob|bob@ordinatus.ru
We exit the interactive sqlite3 mode with:
.exit
Теперь делаем коммит базы данных в репозиторий:
git add database.sqlite3
git commit -m "Add database"
Теперь у нас есть git-репозиторий с sqlite3 бинарным файлом, содержащим нашу базу данных. Добавим еще одного пользователя и посмотрим, что произойдет, когда запустим git diff
на репозитории.
Переходим в интерактивный режим базы данных sqlite3:
sqlite3 database.sqlite3
Добавляем пользователя:
INSERT INTO users (name, email) VALUES ('Charlie', 'charlie@ordinatus.ru');
Выходим из интерактивного режима:
.exit
Теперь можем запустить и увидеть git diff
:
git diff
diff --git a/database.sqlite3 b/database.sqlite3
index 0da3892..1caaa60 100644
--- a/database.sqlite3
+++ b/database.sqlite3
@@ -7,4 +7,5 @@ CREATE TABLE users (
);
INSERT INTO users VALUES(1,'Alice','alice@ordinatus.ru');
INSERT INTO users VALUES(2,'Bob','bob@ordinatus.ru');
+INSERT INTO users VALUES(3,'Charlie','charlie@ordinatus.ru');
COMMIT;
Видим, что в нашей базе данных появился новый пользователь - как раз то, что нужно.
Если сделать коммит, сможем использовать git log -p
, чтобы посмотреть, что именно изменилось между ревизиями. Обратите внимание, что не получится использовать git add -p
для добавления изменений: git бвыдаст ошибку, что изменился только двоичный файл.