Подтвердить что ты не робот

Возможно ли сохранить файл без вершин в репозитории git

Вот проблема:

Я создал голый репозиторий git на моем месте партнера-партнера, который я использую в качестве ссылочного репозитория со всех местоположений/компьютеров, на которых я поддерживаю свой проект.

Дело в том, что в моем проекте используется файл sqlite db, который постоянно растет (сейчас он составляет около 150 МБ). По прошествии времени моя папка .git становится все больше и больше (в последнее время около 1 ГБ). И мое пространство для хостинга ограничено.

Мне нужен голый репозиторий, содержащий HEAD-версию этого файла db, но мне действительно не нужно сохранять историю его версий.

Итак, чтобы получить некоторое пространство, время от времени я удаляю db файл из истории, очищаю репозиторий и воссоздаю голую версию. Это работает, но это довольно боль.

Есть ли способ сообщить git сохранить только последнюю версию файла и удалить его историю?

4b9b3361

Ответ 1

Короткий ответ: нет.

Более полезный ответ: Git не отслеживает файлы по отдельности, поэтому попросить его выбросить историю одного файла означает, что он должен будет полностью переписать всю свою историю на каждую фиксацию, и это приведет к все виды уродливых проблем.

Вы можете сохранить файл в аннотированном теге, но это не очень удобно. В основном это происходит следующим образом:

ID=`git hash-object -w yourfile.sqlite`
git tag -a -m "Tag database file" mytag $ID

Никоим образом это не удобно обновлять (или даже создавать) файл базы данных в рабочем дереве для вас... вам нужно будет использовать скрипты hook для имитации этого.

Полное раскрытие: я не совсем уверен, действительно ли можно нажимать метки, которые не покрываются обычной историей. Я подозреваю, что это не так, и в этом случае этот рецепт был бы намного менее полезным.

Ответ 2

Похоже, вы ищете решение неправильной проблемы.

Большие двоичные файлы часто нужно хранить в репозиториях, но я не думаю, что база данных SQLite - это то, что вам действительно нужно хранить в своей двоичной форме в репозитории.

Скорее, вы должны сохранить схему в управлении версиями, и если вам тоже нужно хранить данные, сериализуйте ее (в XML, JSON, YAML...) и версию тоже. Конструкция script может создавать базу данных и при необходимости деактивировать данные в ней.

Поскольку текстовый формат сериализации можно эффективно отслеживать с помощью Git, вы не будете беспокоиться о нехватке места для хранения прошлых версий, даже если вы не думаете, что вам нужен доступ к ним.

Ответ 3

Вы всегда можете использовать конфигурационный файл .gitignore для этого - с самого начала.

И... (из эта тема: kudos для Björn Steinbrink!)

Использовать фильтр-ветку, чтобы отбросить родителей на первой фиксации, которую вы хотите сохранить, а затем отбросить старый рывок.

Скажем, $drop является хешем последняя фиксация, которую вы хотите сбросить. к держите вещи здравомыслящими и простыми, убедитесь, что первая фиксация, которую вы хотите сохранить, то есть. ребенок $drop, не является слиянием совершить. Затем вы можете использовать:

git filter-branch --parent-filter "sed -e 's/-p $drop//'" \ 
    --tag-name-filter cat -- \ 
    --all ^$drop 

Вышеизложенное переписывает родителей всех совершает то, что приходит после "$drop.

Проверьте результаты с помощью gitk.

Затем, чтобы очистить весь старый рывок.

Во-первых, резервные ссылки из Фильтрация:

git for-each-ref --format='%(refname)'refs/original | \ 
    while read ref 
    do 
            git update-ref -d "$ref" 
    done 

Затем очистите свои логги:

git reflog expire --expire=0 --all 

И, наконец, переупаковать и отбросить все старые недостижимые объекты: git repack -ad git prune # Для объектов, которые repack -ad может оставить около

В этот момент все, что ведет до и включая $drop должно быть ушел.

Ответ 4

Если я понимаю ваш вопрос, я думаю, что у меня есть простое решение.

  • Сначала создайте резервную копию файла,
  • Удалить его из рабочего дерева/дерева. Не git rm, просто rm.
  • Сделайте фиксацию.
  • Убедитесь, что файл добавлен в .gitignore.

При последующих коммитах git больше не будет пытаться добавить этот файл. Обратите внимание, что у вас все еще будет файл, сохраненный в предыдущих фиксациях. Это просто, что вы не будете добавлять его к каждой фиксации, которую вы совершаете в будущем. Чтобы удалить его из предыдущих коммитов, вам понадобится совет от кого-то, у кого больше опыта git, чем у меня.

Ответ 5

Добавьте sqlite.db в свой .gitignore.

Чтобы проверить текущий db для (потенциального) нажатия текущей ветвью:

branch="$(sed 's,.*refs/heads/,,' "$(git rev-parse --git-dir)"/HEAD)"
objectname=$(git hash_object -w "$(git rev-parse --show-toplevel)/sqlite.db")
git tag -f db_heads/$branch $objectname

при нажатии ветки:

git push origin $branch +db_heads/$branch

При извлечении ветки:

git fetch origin $branch tags/db_heads/$branch:tags/db_heads/$branch

при проверке ветки:

git checkout $branch
git cat-file -p db_heads/$branch >"$(git rev-parse --show_toplevel)/sqlite.db"

И это должно сделать это, я думаю.