Есть ли какая-либо распределенная система контроля версий, поддерживающая частичное извлечение / клонирование?

Насколько мне известно, все распределенные системы контроля версий требуют, чтобы вы клонировали весь репозиторий. По этой причине нецелесообразно помещать огромное количество контента в один репозиторий (спасибо за этот ответ). Я знаю, что это не ошибка, а особенность, но мне интересно, является ли это требованием для всех распределенных систем контроля версий.

В распределенных rcs история файла (или фрагмента содержимого) представляет собой направленный ациклический граф, так почему вы не можете просто клонировать этот единственный DAG вместо набора всех графов в репозитории? Возможно, я что-то упускаю, но следующие варианты использования сложно выполнить:

  • клонировать только часть репозитория
  • объединить два репозитория (с сохранением их истории!)
  • копировать некоторые файлы с их историей из одного репозитория в другой

Если я повторно использую части кода других людей из нескольких проектов, я не могу сохранить их полную историю. По крайней мере, в git я могу придумать (довольно сложный) обходной путь:

  1. клонировать полный репозиторий
  2. удалить весь контент, который меня не интересует
  3. перепишите историю, чтобы удалить все, чего нет в мастере
  4. объединить оставшийся репозиторий с существующим репозиторием

Я не знаю, возможно ли это также с Mercurial или Bazaar, но, по крайней мере, это совсем непросто. Так есть ли какие-либо распределенные rcs, которые поддерживают частичное извлечение / клонирование по дизайну? Он должен поддерживать одну простую команду для получения одного файла с его историей из одного репозитория и слияния его с другим. Таким образом, вам не нужно будет думать о том, как структурировать ваш контент в репозитории и подмодули, но вы можете с радостью разделить и объединить репозитории по мере необходимости (крайним вариантом будет один репозиторий для каждого отдельного файла).


person Jakob    schedule 22.06.2010    source источник
comment
На самом деле ... 10 лет спустя частичное клонирование может стать возможным с Git в грядущей Git 2.17. См. мой ответ ниже.   -  person VonC    schedule 18.02.2018


Ответы (7)


Начиная с версии 2.0 невозможно создать так называемый "узкий клон" с Mercurial, то есть клон, в котором вы извлекаете данные только для определенного подкаталога. Мы называем это «мелким клоном», когда вы извлекаете только часть истории, скажем, последние 100 ревизий.

Как вы сказали, в общей модели истории на основе DAG нет ничего, что исключает эту функцию, и мы над этим работаем. Питер Арренбрехт, участник Mercurial, реализовал два разных подхода для узких клонов, но ни один из них еще не был объединен.

Кстати, вы, конечно, можете разделить существующий репозиторий Mercurial на части, где каждый меньший репозиторий имеет историю только для определенного подкаталога исходного репозитория. Для этого можно использовать расширение convert. Однако каждый из меньших репозиториев не будет связан с большим репозиторием - сложная часть состоит в том, чтобы сделать разделение бесшовным, чтобы наборы изменений сохранили свою идентичность.

person Martin Geisler    schedule 25.06.2010
comment
(2017) Если вы удовлетворяете требованиям, можно создать репозиторий Mercurial, поддерживающий узкие клоны, используя расширение Google NarrowHG (bitbucket .org / Google / thinhg), но его нет в основной версии Mercurial. - person Anon; 22.02.2017

Начиная с Git 2.17 (второй квартал 2018 г., 10 лет спустя), будет возможно сделать то, что Mercurial планировал реализовать: a узкий клон, то есть клон, в котором вы извлекаете данные только для определенного подкаталога.
Это также называется частичным клоном.

Это отличается от нынешнего

  • мелкий клон
  • копия того, что вам нужно, из клонированного репо в другой рабочей папке.

См. фиксацию 3aa6694, совершить aa57b87, 35a7ae9, совершить 1e1e39b, фиксация acb0c57, совершить bc2d0c3, совершить 640d8b7, совершить 10ac85c (8 декабря 2017 г.), Джефф Хостетлер (_1 _).
См. совершить a1c6d7c, совершить c0c578b, зафиксировать 548719f, зафиксировать a174334, совершить 0b6069f (8 декабря 2017 г.) от Джонатан Тан (jhowtan).
(Объединено с помощью Junio ​​C Hamano - gitster - в commit 6bed209, 13 февраля 2018 г.)

Вот тесты для частичного клона:

git clone --no-checkout --filter=blob:none "file://$(pwd)/srv.bare" pc1 

Существуют и другие другие коммиты, участвующие в этой реализации узкой / частичный клон.

В частности, совершить 8b4c010:

sha1_file: поддержка ленивого извлечения недостающих объектов

Научите sha1_file получать объекты с удаленного устройства, настроенного в extensions.partialclone, когда объект запрашивается, но отсутствует.


Предупреждение относительно Git 2.17 / 2.18: недавнее добавление экспериментальной функции частичного клонирования сработало, когда этого не должно быть, а именно, когда не определен фильтр частичного клонирования, даже если установлен extensions.partialclone.

См. commit cac1137 (11 июня 2018 г.) от Джонатан Тан (jhowtan).
(Объединено с помощью Junio ​​C Hamano - gitster - в коммите 92e1bbc, 28 июня 2018 г.)

upload-pack: отключить фильтрацию объектов, если она отключена конфигурацией

Когда upload-pack получил частичную поддержку клонирования (v2.17.0-rc0 ~ 132 ^ 2 ~ 12, 2017-12-08), он был защищен элементом конфигурации uploadpack.allowFilter, чтобы операторы сервера могли контролировать, когда они начинают поддерживать его.

Однако этот элемент конфигурации не зашел достаточно далеко: он контролирует, объявляется ли возможность 'filter', но если (настраиваемый) клиент игнорирует объявление возможности и все равно передает спецификацию фильтра, сервер обработает это, несмотря на то, что allowFilter имеет значение false. .

Это особенно важно, если в этом новом экспериментальном коде частичного клонирования обнаружена ошибка безопасности.
Установки без uploadpack.allowFilter не должны подвергаться влиянию, поскольку они не предназначены для поддержки частичного клонирования, но они могут оказаться уязвимыми .


Это улучшено в Git 2.20 (второй квартал 2018 г.), поскольку git fetch $repo $object в частичном клоне некорректно извлекал запрашиваемый объект, на который ссылается объект в файле пакета promisor, что было исправлено.

См. совершить 35f9e3e, commit 4937291 (21 сентября 2018 г.) Джонатан (jhowtan).
(Объединено Junio ​​C Hamano - gitster - в commit a1e9dff, 19 октября 2018 г.)

fetch: в частичном клоне проверять наличие целей

При извлечении объекта, который известен как объект промисора, в локальный репозиторий, проверка подключения в _ 19_ в builtin/fetch.c завершается успешно, в результате чего передача объекта обходится.
Однако этого не должно происходить, если этот объект просто обещан, а на самом деле отсутствует.

Поскольку это происходит, когда пользователь вызывает git fetch origin <sha-1> в командной строке, объект <sha-1> может не быть получен, даже если команда возвращает код выхода 0. Это проблема, аналогичная той, которая была исправлена ​​(но с другой причиной). автор: a0c9016 (upload-pack: отправлять объекты ссылок, несмотря на фильтр, 2018-07- 09, Git v2.19.0-rc0).

Поэтому обновите quickfetch(), чтобы также напрямую проверить наличие наличие всех извлекаемых объектов.


Вы можете перечислить объекты частичного клона, исключая объекты promisor, с помощью _ 24_

(Только для внутреннего использования.) Предварительный фильтр обхода объекта на границе промисора.
Используется с частичным клонированием.
Это сильнее, чем --missing=allow-promisor, потому что он ограничивает обход, а не просто отключение ошибок об отсутствующих объектах.

Но обязательно используйте Git 2.21 (первый квартал 2019 г.), чтобы избежать ошибки segfault.

См. фиксацию 4cf6786 (5 декабря 2018 г.) по Мэтью Девор (matvore).
(Объединено Junio ​​C Hamano - gitster - в фиксации c333fe7 a>, 14 января 2019 г.)

git rev-list --exclude-promisor-objects пришлось взять объект, который не существует локально (и лениво доступен), из командной строки без прерывания, но код разыменовал NULL.

list-objects.c: не использовать segfault для отсутствующих объектов cmdline

Когда команда вызывается как с --exclude-promisor-objects, --objects-edge-aggressive, так и с отсутствующим объектом в командной строке, массив rev_info.cmdline может получить указатель NULL для значения поля 'item'.
Предотвратить разыменование указателя NULL в этом ситуация.


Обратите внимание, что в Git 2.21 (первый квартал 2019 г.) исправлена ​​ошибка:

См. фиксацию bbcde41 (3 декабря 2018 г.) на Мэтью Девор (matvore).
(Объединено Джунио C Хамано - gitster - в фиксации 6 a>, 14 января 2019 г.)

exclude-promisor-objects: объявить, когда опция разрешена

Параметр --exclude-promisor-objects вызывает странное поведение по крайней мере в двух командах: log и blame.
Это вызывает сбой ОШИБКИ:

$ git log --exclude-promisor-objects
BUG: revision.c:2143: exclude_promisor_objects can only be used
when fetch_if_missing is 0
Aborted
[134]

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

pack-objects
prune
rev-list

Команды были найдены путем поиска логики, которая анализирует --exclude-promisor-objects за пределами revision.c.
Требуется дополнительная логика за пределами revision.c, потому что fetch_if_missing необходимо включить до того, как revision.c увидит эту опцию, иначе произойдет ошибка ошибки. Приведенный выше список подтверждается тем фактом, что никакая другая команда не вызывается интроспективно другой командой, передающей --exclude-promisor-object.


Git 2.22 (второй квартал 2019 г.) оптимизирует узкий клон:
При запуске git diff в ленивом клоне мы можем заранее узнать, какие недостающие капли нам понадобятся, вместо того, чтобы ждать, пока механизм по запросу обнаружит их один за другим. < br /> Стремитесь к повышению производительности за счет пакетной обработки запросов на эти обещанные BLOB-объекты.

См. фиксацию 7fbbcb2 (5 апреля 2019 г.) и совершить 0f4a4fb (29 марта 2019 г.) от Джонатан Тан (jhowtan).
(Объединено Junio ​​C Hamano - - gitster - в commit 32dc15d, 25 апреля 2019 г.)

diff: пакетная загрузка отсутствующих BLOB-объектов

При выполнении такой команды, как git show или git diff в частичном клоне, пакетируйте все отсутствующие большие двоичные объекты, которые будут извлечены как один запрос.

Это похоже на c0c578b (unpack-trees: пакетная выборка отсутствующих больших двоичных объектов, 2017-12- 08, Git v2.17.0-rc0), но для другой команды.


Git 2.23 (третий квартал 2019 г.) обеспечит будущее, когда в пакете отсутствует часть большого двоичного объекта.

См. фиксацию 31f5256 (28 мая 2019 г.) по Деррик Столи (derrickstolee).
(Объединено Джунио C Хамано - gitster - в совершить 5d5 a>, 17 июня 2019 г.)

sha1-file: сплит OBJECT_INFO_FOR_PREFETCH

Битовый флаг OBJECT_INFO_FOR_PREFETCH был добавлен к sha1-file.c в 0f4a4fb, 2019sha1-file: support -29, Git v2.22.0-rc0) и используется для предотвращения использования метода fetch_objects(), когда он включен.

Однако есть проблема с текущим использованием.
Определение OBJECT_INFO_FOR_PREFETCH дается добавлением 32 к OBJECT_INFO_QUICK.
Это ясно указано выше определения (в комментарии), что это так OBJECT_INFO_FOR_PREFETCH подразумевает OBJECT_INFO_QUICK .
Проблема в том, что использование flag & OBJECT_INFO_FOR_PREFETCH означает, что OBJECT_INFO_QUICK также подразумевает OBJECT_INFO_FOR_PREFETCH.

Разделите единственный бит из OBJECT_INFO_FOR_PREFETCH на новый OBJECT_INFO_SKIP_FETCH_OBJECT как отдельный бит и оставьте OBJECT_INFO_FOR_PREFETCH как объединение двух флагов.

И git fetch в ленивом клоне забыл получить базовые объекты, необходимые для завершения дельты в тонком пак-файле, что было исправлено.

См. фиксацию 810e193, зафиксировать 5718c53 (11 июня 2019 г.) и совершить 8a30a1e, совершить 385d1bf (14 мая 2019 г.) ) от Джонатана Тана (jhowtan).
(объединено с помощью Junio ​​C Hamano - gitster - в commit 8867aa8, 21 июня 2019 г.)

index-pack: в предварительной выборке отсутствуют REF_DELTA баз

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

Если сервер пропускает такой объект, это нормально: клиент может лениво получить этот объект до этой выборки, и он все еще может сделать это после.

Проблема заключается в том, что сервер отправляет тонкий пакет, содержащий объект, который является REF_DELTA, против такого отсутствующего объекта: index-pack не может исправить тонкий пакет.
Когда поддержка ленивого извлечения отсутствующих объектов была добавлена ​​в 8b4c010 (sha1_file: поддержка ленивого извлечения недостающих объектов, 08.12.2017, Git v2.17.0-rc) , поддержка в index-pack была отключена, поскольку он считал, что он обращается к репо только для проверки хеш-коллизий.
Однако это неверно: ему также нужен доступ к репо для разрешения REF_DELTA базы.

Поддержка ленивой выборки по-прежнему должна быть отключена в index-pack, поскольку она используется как часть самого процесса ленивой выборки (в противном случае могут возникнуть бесконечные циклы), но нам действительно нужно извлекать REF_DELTA баз.
(При получении REF_DELTA баз маловероятно, что они сами REF_DELTA, потому что мы не отправляем have при выполнении таких выборок.)

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


Git 2.24 (4 квартал 2019 г.) исправляет выборку объектов по запросу в ленивом клоне, который неправильно пытался получить коммиты из проектов подмодулей, все еще работая в суперпроекте.

См. commit a63694f (20 августа 2019 г.) по Джонатан Тан (jhowtan).
(Объединено с помощью Junio ​​C Hamano - gitster - в фиксации d8b1ce7 a>, 09 сен 2019)

diff: пропускать GITLINK при ленивом извлечении отсутствующих объектов

В 7fbbcb2 (diff: пакетная загрузка отсутствующих BLOB-объектов, 2019-04-08, Git v2.22.0-rc0) diff был обучен пакетной выборке отсутствующих объектов при работе с частичным клоном, но не был обучен воздерживаться от выборки GITLINK.
Научите diff проверять, является ли объект GITLINK перед включением это в наборе для извлечения.


Git 2.24 (4 квартал 2019 г.) также вводит понятие удаленного репозитория promisor.

См. совершить 4ca9474, совершить 60b7a92, commit db27dca, совершить 75de085, совершить 7e154ba, совершить 9a4c507, зафиксировать 5e46139, совершить fa3d1b6, Christian Couder (chriscool).
(Объединено Junio ​​C Hamano - gitster - в совершить b9, 18 сен 2019 г.)

зафиксировать 842b005, совершить 7a7 , совершить 9430147 (27 июня 2019 г.) от Мэтью Девор (matvore).
(Объединено Junio ​​C Hamano - gitster - в совершить 627b826 a>, 18 сен 2019)

Это позволяет:

  • комбинирование фильтров таким образом, что отображаются только объекты, принятые всеми фильтрами.
    Мотивация для этого состоит в том, чтобы разрешить получение списков каталогов без извлечения больших двоичных объектов. Это можно сделать, объединив blob:none с tree:<depth>.
    Существуют огромные репозитории, деревья которых больше, чем ожидалось, даже если вы включаете только одну фиксацию.

Комбинированный фильтр поддерживает любое количество подфильтров и записывается в следующей форме:

combine:<filter 1>+<filter 2>+<filter 3>
  • объединение нескольких фильтров путем простого повторения флага --filter.
    Раньше пользователю приходилось несколько неудобно комбинировать их в один флаг (например, --filter=combine:FOO+BAR), включая URL-кодирование отдельных фильтров.

В Git 2.27 (второй квартал 2020 г.) git diff в частичном клоне научились избегать отложенной загрузки объектов blob в большем количестве случаев, когда они не нужны.

См. фиксацию 95acf11, совершить c14b6f8, совершить 1c37e86 (7 апреля 2020 г.) и совершить db7ed74 (2 апреля 2020 г.) ) от Джонатана Тана (jhowtan).
(объединено с помощью Junio ​​C Hamano - gitster - в commit 8f5dc5a, 28 апреля 2020 г.)

diff: ограничить при предварительной выборке

Помощник: Джефф Кинг
Подписал: Джонатан Тан

Фиксация 7fbbcb21b1 (diff: пакетная выборка отсутствующих, BLOB-объектов, 2019-04-08 v2.22.0-rc0 - слияние, перечисленное в пакет № 7) оптимизирован diff путем предварительной выборки больших двоичных объектов в частичном клоне, но в некоторых случаях это не требуется. prefetched.
В этих случаях любая команда, использующая механизм сравнения, будет без необходимости извлекать капли.

diffcore_std() может читать капли при вызове следующих функций:

  1. diffcore_skip_stat_unmatch() (управляется конфигурационной переменной diff.autorefreshindex)
  2. diffcore_break() и diffcore_merge_broken() (для обнаружения прерывания-перезаписи)
  3. diffcore_rename() (для обнаружения переименования)
  4. diffcore_pickaxe() (для обнаружения добавления / удаления указанной строки)

Вместо того, чтобы всегда выполнять предварительную выборку больших двоичных объектов, научите diffcore_skip_stat_unmatch(), diffcore_break() и diffcore_rename() выполнять предварительную выборку больших двоичных объектов при первом чтении отсутствующего объекта.
Это охватывает пункты (1), (2) и (3): чтобы охватить все остальное, научите diffcore_std() для предварительной выборки, если тип вывода включает данные большого двоичного объекта (и, следовательно, данные большого двоичного объекта все равно потребуются позже), или если он знает, что (4) будет запущен.


Обратите внимание, что ленивая выборка, выполняемая внутри, чтобы сделать недостающие объекты доступными в частичном клоне, неправильно нанесла необратимый ущерб фильтру частичного клонирования в репозитории, что было исправлено с помощью Git 2.29 (4 квартал 2020 г.).

См. фиксацию 23547c4 (28 сентября 2020 г.) и совершить 625e7f1 (21 сентября 2020 г.) от Джонатан Тан (jhowtan).
(Объединено Junio ​​C Hamano - - gitster - в фиксации e68f0a4, 5 октября 2020 г.)

fetch: не отменять частичный фильтр клонирования

Подписано: Джонатан Тан

Когда выполняется выборка с аргументом --filter, устанавливается настроенный фильтр по умолчанию, даже если он уже существует. Это изменение было внесено в 5e46139376 (builtin/fetch: удалить уникальное ограничение удаленного доступа 2019-06 -25, Git v2.24.0-rc0 - объединить, перечисленные в пакет № 3) - в частности, изменение с:

  • Если это ПЕРВЫЙ запрос частичной выборки, мы включаем частичное
  • в этом репо и запомните данную спецификацию фильтра как значение по умолчанию
  • для последующих загрузок на этот пульт.

to:

  • Если это запрос частичной выборки, мы включаем частичную выборку
  • это репо, если оно еще не включено, и запомните данный
  • filter-spec по умолчанию для последующих выборок к этому
  • дистанционный пульт.

(Данная спецификация фильтра запоминается, даже если она уже существует.)

Это проблематично, когда выполняется ленивая выборка, поскольку ленивая выборка выполняется с использованием git fetch --filter=blob:none (мужчина), но это также произойдет, если пользователь вызовет git fetch --filter=<filter> (man) вручную. Поэтому восстановите поведение до 5e46139376, которое записывает спецификацию фильтра, только если текущий запрос выборки является первым запросом частичной выборки (для этого пульта).

person VonC    schedule 18.02.2018
comment
Примечание. filter=blob:none исправлен в последний момент: stackoverflow.com/a/52916879/6309 - person VonC; 04.11.2019

Для git есть модуль поддерева, позволяющий выделить часть репозитория в новое репо, а затем объединить изменения в / из оригинала и поддерева. Вот его файл readme на github: http://github.com/apenwarr/git-subtree/blob/master/git-subtree.txt

person kwatford    schedule 23.06.2010
comment
Большое спасибо. Даже через 3 года это полезно - хотя я полагаю, что вполне вероятно, что git-subtrees не поддерживается. - person Krazy Glew; 23.05.2013
comment
Нет коммитов с 2012-07, но все еще кажется интересным. - person Zaz; 20.05.2015

В распределенных rcs история файла (или фрагмента содержимого) представляет собой направленный ациклический граф, так почему вы не можете просто клонировать этот единственный DAG вместо набора всех графов в репозитории?

По крайней мере, в Git группа DAG, представляющая историю репозитория, применяется ко всему репозиторию целиком, а не только к отдельному файлу. Каждый объект фиксации указывает на объект «дерево», который представляет все состояние репозитория на тот момент.

Git 1.7 поддерживает «разреженные проверки», которые позволяют ограничивать размер вашей рабочей копии. Однако все данные репозитория по-прежнему клонируются.

person Greg Hewgill    schedule 23.06.2010
comment
Хорошо, это отвечает на мой вопрос, по крайней мере, для git. Интересно, спроектированы ли все распределенные rcs таким образом или у вас может быть дизайн, позволяющий разделять и объединять репозитории. - person Jakob; 23.06.2010
comment
@Jakob: Я думаю, это так, потому что это дает вам атомарные коммиты. Вам нужно вернуться в темные дни CVS, чтобы получить систему контроля версий, которая хранит исправления в файлах отдельно. Вы не хотите этого делать. - person Paul S; 20.01.2012

В базаре вы можете разделять и объединять части репозитория.

Команда split позволяет разделить репозиторий на несколько репозиториев. Команда join позволяет объединять репозитории. Оба хранят историю.

Однако это не так удобно, как SVN-модель, где вы можете проверить / зафиксировать поддерево.

Есть запланированная функция под названием Nested-Trees для базара, которая, возможно, позволит частичную проверку.

person Gamlor    schedule 23.06.2010
comment
Хм, я пробовал разделить и присоединиться, но они хранят всю историю, а не только историю подмножества репозитория. Плагин быстрого импорта (launchpad.net/bzr-fastimport), похоже, выполняет свою работу, но потом я не может объединять обновления из исходного репозитория, из которого я отделился. Я надеюсь, что вложенные деревья не бесполезны. - person Jakob; 23.06.2010
comment
Я не на 100%, но у базара есть только глобальные версии и история. Каждый набор изменений применяется ко всему репозиторию. Таким образом, когда вы разделяете, вся история относится также и к подкаталогу. Поэтому после раскола вся история не исчезла. За исключением того, что некоторые записи не имеют никакого эффекта. Вложенные деревья: не знаю. Будем надеяться, что это не паразит. - person Gamlor; 24.06.2010

Я надеюсь, что один из этих RCS добавит возможность узкого клонирования. Насколько я понимаю, архитектура GIT (изменения / перемещения отслеживаются по всему репо) очень затрудняет это.

Bazaar гордится тем, что поддерживает множество различных типов рабочих процессов. Отсутствие возможности узкого клонирования запрещает рабочий процесс, подобный SVN / CVS, в bzr / hg / git, поэтому я надеюсь, что у них будет мотивация найти способ сделать это.

Новые функции не должны происходить за счет базовой функциональности, такой как возможность получить один файл / каталог из репозитория. «Распределенная» функция современных rcs - это «круто», но, на мой взгляд, препятствует хорошей практике разработки (частые слияния / непрерывная интеграция). Кажется, что всем этим новым RCS не хватает самой базовой функциональности. Даже SVN без реальной поддержки ветвления / тегирования казался шагом назад по сравнению с CVS imo.

person nairbv    schedule 01.08.2010

От 1_ :

--depth <depth> Create a shallow clone with a history truncated to the specified number of revisions. A shallow repository has a number of limitations (you cannot clone or fetch from it, nor push from nor into it), but is adequate if you are only interested in the recent history of a large project with a long history, and would want to send in fixes as patches.

Это дает что-то похожее на то, что вы ищете?

person kristianlm    schedule 03.11.2012