Дедупликация Git Forks на сервере
Есть ли способ жестко связать все дубликаты объектов в папке, содержащей несколько репозиториев GIT?
Объяснение: Я размещаю git-сервер на сервере моей компании (Linux Machine). Идея состоит в том, чтобы иметь основной канонический репозиторий, к которому каждый пользователь не имеет принудительного доступа, но каждый пользователь разветвляет канонический репозиторий (клонирует канонический в домашний каталог пользователя, тем самым фактически создавая жесткие ссылки).
/canonical/Repo / Dev1 / Repo (объекты, жестко связанные с /canonical/Repo при первоначальном клонировании) /Dev2/Repo (объекты, жестко связанные с /canonical/Repo при первоначальном клонировании)
Это все отлично работает. Проблема возникает, когда:
Dev1: помещает огромный коммит в свой форк на сервере (/Dev1/Repo) Dev2: выбирает это в своей локальной системе, вносит свои изменения и передает его в свой собственный форк на сервере (/ Dev2 / Repo)
(Теперь один и тот же "огромный" файл находится в обеих ветках разработчика на сервере, он не создает жесткую ссылку автоматически)
Это поглощает мое серверное пространство как сумасшедший!
Как я могу создать жесткие связи между объектами, которые являются дублирующими между двумя вилками или каноническими в этом отношении, чтобы экономить место на сервере, и каждый разработчик при клонировании с hi-fork на его локальной машине получает все данные.
2 ответа
Наконец я нашел решение, которое работает для меня! (Не тестируется в производстве!: P)
Благодаря этому посту я решил сделать следующее:
shared-objects-database.git/
foo.git/
objects/info/alternate (will have ../../shared-objects-database.git/objects)
bar.git/
objects/info/alternate (will have ../../shared-objects-database.git/objects)
baz.git/
objects/info/alternate (will have ../../shared-objects-database.git/objects)
Все вилки будут иметь и запись в своем файле objects/info/alternates, в которой будет указан относительный путь к хранилищу базы данных объектов.
Важно сделать объектную базу данных хранилищем, потому что мы можем сохранять объекты и ссылки разных пользователей, имеющих хранилище с одинаковыми именами.
Шаги: 1. git init --bare shared-object-database.git 2. Я запускаю следующие строки кода либо каждый раз, когда происходит переход на любой форк (через post-recieve), либо запускаю cronjob
for r in list-of-forks
do
(
cd "$r" &&
git push ../shared-objects-database.git "refs/*:refs/remotes/$r/*" &&
echo ../../shared-objects-database.git/objects >objects/info/alternates
# to be save I add the "fat" objects to alternates every time
)
done
Затем в следующем "git gc" все объекты в вилках, которые уже существуют в альтернативе, будут удалены.
git repack -adl
тоже вариант!
Таким образом, мы экономим пространство, так что два пользователя, помещающие одинаковые данные на свои соответствующие вилки на сервере, будут совместно использовать объекты.
Нам нужно установить gc.pruneExpire
переменная до never
в базе данных общего объекта. Просто чтобы быть в безопасности!
Чтобы иногда удалять объекты, добавляйте все ветвления в качестве удаленных к общему, выбирайте, сокращайте! Git сделает все остальное!
Мысли? Предложения?
Теперь один и тот же "огромный" файл находится в обеих ветках разработчика на сервере, он не создает жесткую ссылку автоматически
На самом деле, в Git 2.20 эта проблема может исчезнуть из-за дельта-островов, нового способа выполнения дельта-вычислений, так что объект, существующий в одном форке, не превращается в дельту против другого объекта, который не появляется в том же разветвленном репозитории.,
Смотрите коммит fe0ac2f, коммит 108f530, коммит f64ba53 (16 августа 2018 г.) Кристиана Кудера ( chriscool
)
Помогает: Джефф Кинг ( peff
) и Дуй Нгуен ( pclouds
)
См. Коммит 9eb0986, коммит 16d75fa, коммит 28b8a73, коммит c8d521f (16 августа 2018 г.) Джеффа Кинга ( peff
)
Помогает: Джефф Кинг ( peff
) и Дуй Нгуен ( pclouds
)
(Объединено Юнио С Хамано - gitster
- в комитете f3504ea, 17 сентября 2018 г.)
добавлять
delta-islands.{c,h}
Хостинг-провайдеры, которые позволяют пользователям "разветвлять" существующие репозитории, хотят, чтобы эти вилки занимали как можно больше дискового пространства.
Альтернативы - это существующее решение, позволяющее хранить все объекты всех вилок в едином центральном репо, но это может иметь некоторые недостатки.
Особенно при упаковке центрального репо будут создаваться дельты между объектами из разных вилок.Это может сделать клонирование или выборку разветвления намного медленнее и более интенсивно загружать процессор, поскольку Git, возможно, придется вычислять новые дельты для многих объектов, чтобы избежать отправки объектов с другого разветвления.
Поскольку неэффективность в первую очередь возникает, когда объект делится на другой объект, который не существует в том же ветвлении, мы разделяем объекты на наборы, которые появляются в том же самом разветвлении, и определяем "дельта-острова".
При поиске дельта-базы мы не допускаем, чтобы объект за пределами того же острова считался его базой.Таким образом, "дельта острова" - это способ хранения объектов из разных вилок в одном репо и пакете, без различий между объектами из разных вилок.
Этот патч реализует механизм дельта островов в
delta-islands.{c,h}
", но пока не использует его.Несколько новых полей добавлены в '
struct object_entry
' в "pack-objects.h
" хоть.
Увидеть Documentation/git-pack-objects.txt
Остров Дельта
ДЕЛЬТА ОСТРОВА
Когда возможно,
pack-objects
пытается повторно использовать существующие на диске дельты, чтобы избежать необходимости искать новые на лету. Это важная оптимизация для обслуживания выборок, поскольку это означает, что сервер может вообще не надувать большинство объектов и просто отправлять байты непосредственно с диска.
Эта оптимизация не может работать, когда объект хранится как дельта относительно базы, которой нет у получателя (и которую мы еще не отправляем). В этом случае сервер "ломает" дельту и должен найти новую, которая имеет высокую стоимость процессора. Поэтому для производительности важно, чтобы набор объектов в дельта-отношениях на диске соответствовал тому, что выбрал бы клиент.В обычном хранилище это работает автоматически.
Объекты в основном доступны из веток и тегов, и это то, что выбирают клиенты. Любые ошибки, которые мы обнаруживаем на сервере, могут быть между объектами, которые клиент имеет или будет иметь.Но в некоторых настройках репозитория у вас может быть несколько связанных, но отдельных групп ссылок, когда клиенты стремятся получить эти группы независимо.
Например, представьте, что вы размещаете несколько "вилок" хранилища в одном хранилище общих объектов и позволяете клиентам просматривать их как отдельные хранилища через GIT_NAMESPACE или отдельные хранилища с использованием механизма альтернатив.
Наивный перепак может найти, что оптимальная дельта для объекта против базы, которая найдена только в другом форке.
Но когда клиент выбирает, у него не будет базового объекта, и мы должны найти новую дельту на лету.Подобная ситуация может существовать, если у вас много рефери за пределами
refs/heads/
а такжеrefs/tags/
которые указывают на связанные объекты (например,refs/pull
или жеrefs/changes
используется некоторыми хостинг-провайдерами).
По умолчанию клиенты выбирают только заголовки и теги, и дельты против объектов, найденных только в этих других группах, не могут быть отправлены как есть.Дельта острова решают эту проблему, позволяя вам группировать свои ссылки в отдельные "острова".
Pack-objects вычисляет, какие объекты доступны с каких островов, и отказывается создавать дельту из объектаA
против базы, которой нет во всехA
острова. Это приводит к немного большим пакетам (потому что мы упускаем некоторые возможности дельты), но гарантирует, что выборке одного острова не придется пересчитывать дельты на лету из-за пересечения границ острова.