IE 2016

Gitter (Хранилище 1С => Git)

Опубликовал rtnm в раздел Программирование - Инструментарий

Gitter - это конфигурация для автоматизации процесса выгрузки изменений из хранилища 1С в систему версионирования Git.

Введение

Если вы занимаетесь разработкой внутреннего или внешнего продукта, рано или поздно вы начинаете все больше осознавать важность сохранения истории развития вашего продукта. Важно осознавать причинно-следственные связи этого развития. Иногда вам хочется понять, как именно были реализованы требования. Иногда наоборот - глядя на реализацию хочется понять, каковы были требования, кто их сформулировал и почему. Хранилище 1С является одним из связующих элементов хранения истории развития конфигурации. Помещая набор изменений в хранилище, в комментарии указывается связывающая информация, например, номер задачи из системы учета задач.

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

Gitter

Gitter - это конфигурация для автоматизации процесса выгрузки изменений из хранилища 1С в систему версионирования Git. Gitter призван повысить надежность хранения истории ваших изменений.

Gitter Gitter2


Начиная с версии 1С 8.3 появилась возможность выгружать конфигурацию в набор файлов, что позволяет использовать сторонние инструменты по версионированию изменений. Git является одним из таких инструментов.

Не знаете что такое Git? Начните с официального сайта http://git-scm.com, там вы найдете программы-клиенты, книгу на русском языке (http://git-scm.com/book/ru), а так же много другой информации.

В основе Gitter нет чего-то сложного, используется командная строка Git и пакетный режим 1С.

Плюсы

- Повышение надежности.
Помимо локального репозитория Git, в который выгружаются изменения из хранилища, есть возможность выгрузки в удаленные репозитории Git. Например, можно использовать такие ресурсы как github.com или bitbucket.org. Последний имеет возможность бесплатного размещения приватных репозиториев. В свою очередь с удаленных репозиториев можно синхронизировать изменения в любое количество локальных репозиториев. При правильной организации процесса потерять историю изменений просто невозможно.

- Аналитические возможности.
Очень часто для того, чтобы оставить след в истории разработки конфигурации, мы указываем в коде комментарии, содержащие автора, дату, номер задачи. Так или иначе это снижает "чистоту" кода, заставляет вводить регламенты, описывающие то, как следует комментировать код, т.е. в целом усложняет процесс разработки.
Git blame, по моему мнению, позволяет забыть о лишних комментариях. Достаточно оставлять содержательный комментарий при помещении изменений в хранилище. Я создал небольшую демонстрационную конфигурацию, которую выгрузил с помощью Gitter в публичный репозиторий GitterDemo. Здесь видно кто и что добавлял в модуле менеджера справочника "Номенклатура". А здесь видно кто и каким commit-ом добавил в справочник "Номенклатура" реквизит "Цена".

- Простота внедрения.
У вас много разработчиков в команде? Вы используете хранилище для разработки?
Ничего не меняйте, продолжайте использовать хранилище, но дополнительно организуйте выгрузку изменений в репозитории Git.

- Открытость.
Gitter является открытым инструментом. Вы всегда можете реализовать недобходимые для вас доработки.

Особенности текущей реализации

Особенностей сейчас на самом деле много, все и не осознать. Из очевидных мне:
- Проверка работоспособности под linux не производилась
- Не было попыток проверки работоспособности в клиент-серверном варианте с использованием регламентных заданий
- Работает только с версией 1С 8.3

Любые другие особенности, о которых, я надеюсь, вы мне расскажете.

Пошаговая инструкция

Для того чтобы вам было проще ознакомиться с Gitter я написал пошаговую инструкцию. В данной инструкции вы можете ознакомиться с тем, как настроить Gitter и другие вспомогательные компоненты.

Заключение

Надеюсь, Gitter будет вам полезен.

Спасибо за внимание.

Файлы

Наименование Файл Версия Размер Кол. Скачив.
Gitter.cf
.cf 30,99Kb
21.04.14
82
.cf 30,99Kb 82 Скачать

См. также

Лучшие комментарии

4. pumbaE (файл скачал) 23.04.2014 23:11
(1) nixel, для модулей все без проблем, для всяких внутренних объектов, разработчику в случаи конфликта, необходимо собрать из исходников cf (тот cf который пришел из мастер ветки), объединить его со свое кофнигурацией, при этом объединять подглядывая в diff между ветками, где оставлять свой вариант, где чужой. Конфликты самому решать, для модулей подойдет штатное трехстороннее сравннеи, для форм, ролей как повезет.
После этого разбирает получившийся cf в папку с merge и коммитит.
+ 2 [ Evil Beaver; Redokov; ]
# Ответить
9. mikhailv (файл скачал) 23.10.2014 00:04
Спасибо автору за разработку!
Начали с использования git для внешних обработок + Redmine. Понравилось.
Решили перетащить историю хранилища также в git, ибо скорость сравнения версий в хранилище не сопоставима с таковой в git. Также после выгрузки файлов конфигурации в git сравнение ролей и списков предопределенных доступно "из коробки" (xml). Плюс blame. Плюс авто-подкрепление коммитов к задаче в Redmine.

Ваше решение подошло практически полностью. Что изменили:
  • Убрали папку "Конфигурация", в которую сгружались все файлы. В итоге папки/файлы располагаются сразу в корневой папке репозитория.
  • По мелочи: увеличили размер реквизита "Комментарий"; в коммит вставляется номер версии из хранилища; сделали подмену имени пользователя из хранилища в имя пользователя git.


(3) pumbaE, п.2: решили выделением всего до первой точки в папку (Document, Catalog). Получилась структура, более-менее привычная. И Explorer/GitExtensions перестали тормозить от 10000+ файлов в одном каталоге. Если нужно, python-скрипт могу выслать.

(3) pumbaE, п.3: распаковываем, извлекаем только модуль. Раньше еще "декомпилировали" обычные формы, но поняли, что то, что получается, смотреть тоже не ахти как удобно, да и не все аспекты декомпилируются. Кроме того, на некоторых формах платформа вываливалась в дамп (если интересно, тест для воспроизведения ошибки есть).

Для распаковки большого количества форм написали обработку-обертку для обработки-декомпилятора, чтобы 1С запускалась 1 раз, а не столько, сколько форм/обработок нужно распаковать. Работает на порядок быстрее.

В качестве обработки-декомпилятора и precommit-скриптов используем помеси Ваших (pumbaE, Infostart, GitHub), и этих наработок: PBazelyuk, Infostart BitBucket, за что Вам, Евгений, и Петру также отдельное спасибо.
Ответили: (10) (11) (12) (18)
+ 1 [ Redokov; ]
# Ответить
29. rtnm 21.01.2015 17:51
(28) Elisy, Читал вчера вашу статью, у меня тоже возникало естественное желание раскидать все по папкам, я думаю что разработчики 1С придут к пониманию необходимости этого. В качестве примера можно посмотреть исходники Gitter - https://bitbucket.org/rtnm/gitter/src
Ответили: (30)
+ 1 [ Elisy; ]
# Ответить

Комментарии

1. nixel 23.04.2014 19:29
Уж коли пользуетесь гитом, позволю себе задать вопрос.
Реально ли изменить одну и ту же, например, форму двумя разными разработчиками (без использования хранилища) и, используя только выгрузку в файлы, после обычного текстового мерджа загрузить из файла готовую форму с изменениями?
Поясню - данные об объектах/формах/etc выгружаются в XML. Соответственно, когда два разработчика что-то меняют в форме, их измененные формы тоже выгружаются в XML. После push'а мы либо получим валидную XML, которую можем обратно свернуть в форму, либо полную кашу в случае, если 1с выгружает формы "каждый раз по-разному".
Хочу глобально изучить вопрос перевода контроля версий и групповой разработки на git, но как-то постоянно не нахожу на это времени :)
Ответили: (2) (4)
# Ответить
2. rtnm 23.04.2014 22:26
(1) nixel, Gitter никак не расчитан на использование без хранилища 1С. При использовании Gitter описанной проблемы быть не может.

Отвечая на ваш вопрос могу сказать, что отказ от хранилища в пользу других систем версионирования, таких как git, это достаточно серьезный и сложный шаг. У меня нет такого опыта использования Git. В вашем примере, второй разработчик, который выполняет push, вначале будет обязан выполнить pull, при этом он может получить коллизию при объединении файлов форм, которую сам и должен будет разрешить. При условии что Git ничего не знает о форматах, таких например как xml, то я бы не стал исключать вероятности получения невалидного файла формы после объединения, хотя если посмотреть форматирование xml файла формы, который формирует платформа 1С, то кажется, что эта вероятность сведена к минимуму.
# Ответить
3. pumbaE (файл скачал) 23.04.2014 23:05
1. Скорость получения версии cf из хранилища, только с toolCD удалось ускориться в несколько раз по сравнению со штатной выгрузкой 1С из хранилища по номеру.
2. на маленьких конфигурациях этого не видно, но на больших, такие как упп, УТ11 вся конфигурация в одной папке, очень не удобно. При выгрузке не поддерживается того дерева, которое есть в том же конфигураторе. Очень долго искать простейшее "Документ.Реализация.... "
3. Толстые формы выгружаются в запаковоном формате, что-бы вести историю и для модулей толстых форм, приходиться еще их дополнительно распаковывать.

p.s.: у меня как-то так организован процесс разработки redmine+git+1C , тоже использую синхронизацию хранилища с git.
Ответили: (5) (9)
# Ответить
4. pumbaE (файл скачал) 23.04.2014 23:11
(1) nixel, для модулей все без проблем, для всяких внутренних объектов, разработчику в случаи конфликта, необходимо собрать из исходников cf (тот cf который пришел из мастер ветки), объединить его со свое кофнигурацией, при этом объединять подглядывая в diff между ветками, где оставлять свой вариант, где чужой. Конфликты самому решать, для модулей подойдет штатное трехстороннее сравннеи, для форм, ролей как повезет.
После этого разбирает получившийся cf в папку с merge и коммитит.
+ 2 [ Evil Beaver; Redokov; ]
# Ответить
5. rtnm 24.04.2014 00:11
(3) pumbaE,

1. Скорость действительно не очень высокая. На средней конфигурации выгрузка одного изменения происходит порядка 3 минут. Это является проблемой только в начале, когда нужно всю накопившуюся историю выгрузить в репозиторий.
2. Полностью с вами согласен. Я не понимаю почему 1С реализовала выгрузку именно так, и я надеюсь что они это переделают. В принципе, после выгрузки файлов конфигурации в каталог репозитория их можно "перекидать" по каталогам. Мысль о такой доработке для Gitter у меня имеется.
3. Да, такая особенность имеется. С ней я не собирался бороться. Хочется использовать только штатные средства.
# Ответить
6. russinow 24.04.2014 14:15
век живи, век учись
в упор не видел эту выгрузку в файлики пока не наткнулся на статью )))
конечно такая выгрузка имеет кучу нюансов, но путь 1с-овцами выбран правильный, посмотрим к чему он приведет.

в общем спасибо за наводку )
# Ответить
7. mikhailovaew 15.05.2014 16:58
Начиная с версии 1С 8.3 появилась возможность выгружать конфигурацию в набор файлов

а в 8.2 пункт меню "Конфигурация - Выгрузить файлы конфигурации..." делает не то же самое?
Ответили: (8)
# Ответить
8. rtnm 15.05.2014 20:44
(7) mikhailovaew, нет, в 8.2 имелась возможность выгрузить только программные модули, справочную информацию и макеты, а в 8.3 в файлы выгружается вся конфигурация
# Ответить
9. mikhailv (файл скачал) 23.10.2014 00:04
Спасибо автору за разработку!
Начали с использования git для внешних обработок + Redmine. Понравилось.
Решили перетащить историю хранилища также в git, ибо скорость сравнения версий в хранилище не сопоставима с таковой в git. Также после выгрузки файлов конфигурации в git сравнение ролей и списков предопределенных доступно "из коробки" (xml). Плюс blame. Плюс авто-подкрепление коммитов к задаче в Redmine.

Ваше решение подошло практически полностью. Что изменили:
  • Убрали папку "Конфигурация", в которую сгружались все файлы. В итоге папки/файлы располагаются сразу в корневой папке репозитория.
  • По мелочи: увеличили размер реквизита "Комментарий"; в коммит вставляется номер версии из хранилища; сделали подмену имени пользователя из хранилища в имя пользователя git.


(3) pumbaE, п.2: решили выделением всего до первой точки в папку (Document, Catalog). Получилась структура, более-менее привычная. И Explorer/GitExtensions перестали тормозить от 10000+ файлов в одном каталоге. Если нужно, python-скрипт могу выслать.

(3) pumbaE, п.3: распаковываем, извлекаем только модуль. Раньше еще "декомпилировали" обычные формы, но поняли, что то, что получается, смотреть тоже не ахти как удобно, да и не все аспекты декомпилируются. Кроме того, на некоторых формах платформа вываливалась в дамп (если интересно, тест для воспроизведения ошибки есть).

Для распаковки большого количества форм написали обработку-обертку для обработки-декомпилятора, чтобы 1С запускалась 1 раз, а не столько, сколько форм/обработок нужно распаковать. Работает на порядок быстрее.

В качестве обработки-декомпилятора и precommit-скриптов используем помеси Ваших (pumbaE, Infostart, GitHub), и этих наработок: PBazelyuk, Infostart BitBucket, за что Вам, Евгений, и Петру также отдельное спасибо.
Ответили: (10) (11) (12) (18)
+ 1 [ Redokov; ]
# Ответить
10. rtnm 23.10.2014 11:40
(9) mikhailv, пожалуйста!
# Ответить
11. pumbaE (файл скачал) 24.10.2014 10:04
(9) mikhailv, я в основном использую вот этот инструментарий https://github.com/xDrivenDevelopment/ .
Для распаковки большого количества форм написали обработку-обертку для обработки-декомпилятора, чтобы 1С запускалась 1 раз, а не столько, сколько форм/обработок нужно распаковать. Работает на порядок быстрее.
если есть возможность, прошу pull-request.
Ответили: (13)
# Ответить
12. bambr1975 (файл скачал) 24.10.2014 10:56
(9) mikhailv,
на некоторых формах платформа вываливалась в дамп (если интересно, тест для воспроизведения ошибки есть).

Вы последнюю версию V8Reader-а используете? Можете ссылку на форму, которая не декомпилируется прислать в личку?
Ответили: (13)
# Ответить
13. artbear 07.11.2014 01:27
Присоединюсь к (11) и (12)
Ждем.
# Ответить
14. Armando 07.11.2014 10:47
В соседней теме я как раз про такую штуку говорил http://infostart.ru/public/310640/
А тут как говорится "Все уже украдено до нас")
Кажется я смогу сэкономить себе времени. Спасибо.
Ответили: (15) (30)
# Ответить
15. artbear 08.11.2014 00:56
(14) Тут мало автоматизации, много кнопок нужно нажимать.
Выгрузка в Гит должна быть автоматической и фоновой.

Подобная фоновая выгрузка реализована в разных проектах.
Например, у нас в https://github.com/xDrivenDevelopment/v83unpack
Ответили: (16)
# Ответить
16. Armando 08.11.2014 01:08
(15)
Выгрузка в Гит должна быть автоматической и фоновой.

Согласен. Мне так и надо.


Спасибо, посмотрю. Не знал, что это тоже синхронизит. Думал, что только распаковывает.
Ответили: (17)
# Ответить
17. pumbaE (файл скачал) 08.11.2014 09:05
(16) все течет, все меняется.
# Ответить
18. ekaruk (файл скачал) 16.11.2014 22:14
Интересная разработка.
Спасибо.
Работает вполне корректно.
Пришлось подправить формат номера при получении версии из хранилища. Номер более 1000 передавался как 1 000. Думаю, не хватает еще регламентного задания. Чтобы настроить и больше не трогать.

(9) mikhailv, Тоже увеличила ширину поля комментария и добавила номер версии.
Структуру не трогали. В ней очень удобно ищутся данные поиском по Ctrl+F в Gif Extensions. С папками, возможно, будет хуже.

При стандартной выгрузке не выгружаются в текст обычные формы. В результате при сравнении
diff --git a/Конфигурация/Catalog.Номенклатура.Form.ФормаЭлемента.Form b/Конфигурация/Catalog.Номенклатура.Form.ФормаЭлемента.Form
index 83c2a4c..962f1a1 100644
Binary files a/Конфигурация/Catalog.Номенклатура.Form.ФормаЭлемента.Form and b/Конфигурация/Catalog.Номенклатура.Form.ФормаЭлемента.Form differ

Подскажите какое-то простое решение. Либо как распаковать перед соммитом, либо может есть какой-то вариант сравнения чем-то другим (использую kdiff3).
Ответили: (19)
# Ответить
19. pumbaE (файл скачал) 17.11.2014 09:41
(18) ekaruk, вопрос в том, какие различия вы хотите получить.
1. Если только модуль, тогда дополнительно используете v8unpack.exe для форм https://github.com/xDrivenDevelopment/v83unpack/blob/develop/src/oscript/un­pack.os#L1759
2. Если хотите посмотреть различия форм, в виде иерархии, тогда вам необходимо для просмотра различий использовать другие инструменты, например v8reader.epf .
Ответили: (20)
# Ответить
20. ekaruk (файл скачал) 17.11.2014 22:56
(19) pumbaE, cпасибо.
Покопалась в Вашем ГитХабе. Остановилась на v8Reader.epr + diff-1c-cf.js.
Правда, не разобралась, как подключить произвольную программу сравнения к GitExtensions.
Пришлось параллельно поставить TortoiseGit.
Обработки, формы, конфигурации сравнивает вполне корректно.

upd. Разобралась с GitExtensions.
По аналогии с http://infostart.ru/public/118207/ подключила DiffMerge
Ответили: (21) (22) (23)
# Ответить
21. artbear 18.11.2014 17:58
(20) Для подобного у нас используется целый проект v8diff https://github.com/xDrivenDevelopment/v8Diff , его базовая версия описана у Жени в http://infostart.ru/public/118207/
Сам постоянно пользуюсь и для Гита, и для Фара, командной строки.
Ответили: (24)
# Ответить
22. artbear 18.11.2014 18:09
(20) Мы сейчас активно юзаем SourceTree (бесплатно, только нужно зарегистрироваться на сайте). Очень удобно.
ЗЫ а у меня и SourceTree установлен, и TortoiseGit :) Но SourceTree намного чаще
# Ответить
23. artbear 18.11.2014 18:15
(20) ИМХО kdiff3 помощнее, чем DiffMerge
Ответили: (24)
+ 1 [ dimk@a; ]
# Ответить
24. ekaruk (файл скачал) 19.11.2014 00:03
(23) artbear, kdiff3 мощнее, но я не нашла, как в нем настроить вызов 1С для просмотра форм из GifExtensions.
TortoiseGit как-то меньше понравился.

(21) artbear, Да, видела v8diff на ГитХабе. Собственно, из него и взяла diff-1c-cf.js
Насколько я понимаю, v8diff это и есть v8reader + diff-1c-cf.js + ИР.
Или он чем-то еще отличается? В чем смысл отдельного проекта, зачем ИР для сравнения?
Ответили: (25)
# Ответить
25. artbear 19.11.2014 00:38
(24) весь смысл v8diff и есть в связке v8reader + diff.js + ИБ_1С

ИМХО ИР в ИБ не нужен, реально нужен простейший код конфигурации

Я не понимаю, зачем ты юзаешь GifExtensions ? в чем прелесть/преимущество?
ИМХО SourceTree и черепаха и Kdiff3 перекрывают практически все сценарии.

У меня анализ/сравнение используется как для бинарника/epf через v8reader, так и напрямую для текстовых представлений модулей и форм, разобранных через проект precommit1C https://github.com/xDrivenDevelopment/precommit1C

Поясни, что подразумевается под "настроить вызов 1С для просмотра форм из GifExtensions." ?

ЗЫ написал в личку, можно ускорить общение :)
# Ответить
26. Redokov (файл скачал) 14.01.2015 22:00
Спасибо за инструмент. А почему Вы его не выложите на тот же самый гитхаб или битбакет? Тогда все те, кто модифицируют его самостоятельно смогут присылать Вам пул реквесты и Вам будет удобнее отслеживать изменения да и в целом, планировать разработку.
Ответили: (27)
# Ответить
27. rtnm 15.01.2015 21:46
(26) Redokov, пожалуйста. Ссылку на репозиторий bitbucket я ненавязчиво указывал в пункте про открытость. По поводу pull request - Gitter так не работает, он выгружает только в одном направлении, из хранилища 1С в git репозиторий
+ 1 [ Redokov; ]
# Ответить
28. Elisy 21.01.2015 06:52
Вы не могли бы дать ссылку на пример выгрузки? Сейчас спрашивают про ваш инструмент в аналогичной статье http://habrahabr.ru/post/248303/
Ответили: (29)
# Ответить
29. rtnm 21.01.2015 17:51
(28) Elisy, Читал вчера вашу статью, у меня тоже возникало естественное желание раскидать все по папкам, я думаю что разработчики 1С придут к пониманию необходимости этого. В качестве примера можно посмотреть исходники Gitter - https://bitbucket.org/rtnm/gitter/src
Ответили: (30)
+ 1 [ Elisy; ]
# Ответить
30. pumbaE (файл скачал) 21.01.2015 18:39
(29) можете встроить обработку из (14) и у вас тоже будет раскидывать по папкам.
Ответили: (31)
# Ответить
31. rtnm 21.01.2015 21:27
(30) pumbaE, спасибо, буду иметь в виду
# Ответить
32. cmd_vasec (файл скачал) 06.05.2015 16:41
Добрый день.
У меня возникла ошибка
{ОбщийМодуль.Git.Модуль(81)}: Неизвестная ошибка при совершении комита(git commit -m "Добавить функционал, как в предварительном контакте" --date 2014-09-24T10:11:03)
ВызватьИсключение ИсключениеОшибкаПриВыполненииКоманды(ОписаниеОшибки, ТекстКоманды);

что не так?
Ответили: (33)
# Ответить
33. rtnm 06.05.2015 22:06
(32) cmd_vasec, проблема в том что ВыполнитьКоманду("Путь/до/репозитория", "git commit -m ""Добавить функционал, как в предварительном контакте"" --date 2014-09-24T10:11:03") возвращает ненулевое значение, а значит есть ошибка. Можно запустить туже самую команду в командной строке (cmd.exe) и всего скорее будет видно более внятное описание проблемы. Так же можно доработать само решение (gitter) - перенаправить вывод программы git из стандартного потока ввода-вывода в файл, тогда можно будет получать более внятное описание проблемы. Еще можно в описании ошибки указывать используемый ПутьДоРепозитория при запуске ВыполнитьКоманду - хуже не будет.
Ответили: (34)
# Ответить
34. cmd_vasec (файл скачал) 07.05.2015 08:56
(33) rtnm,
Получил:
On branch master
nothing to commit (working directory clean)
Команда проверки состояния сообщит, что коммитить нечего. Это означает, что в репозитории хранится текущее состояние рабочего каталога, и нет никаких изменений, ожидающих записи.

У меня первый коммит прошел, а второй нет.

Т.о. получается, что первая версия хранилища равна второй, но это не так.

Что делаю не так?
Ответили: (35)
# Ответить
35. rtnm 07.05.2015 12:03
(34) cmd_vasec, сложно понять где пошел сбой, нужно проанализировать, что именно прошло первым коммитом, посмотреть что именно сейчас находится в рабочем каталоге и какой версии хранилища соответствует, посмотреть на состояние записей справочника ВыгруженаВЛокальныйРепозиторий и в частности на флажок ВыгруженаВЛокальныйРепозиторий, возможно нужно этот флажок сбросить, чтобы еще раз попытаться выгрузить в рабочий каталог проблемную версию хранилища.
Не исключаю, что каким-то образом первым коммитом ушла последняя версия хранилища. Какая версия платформы?
Ответили: (36) (37)
# Ответить
36. cmd_vasec (файл скачал) 07.05.2015 12:30
(35) rtnm,
Почему то выгрузилось последняя версия хранилища. Версия платформы 8.3.5.1482.

Думаю, что не происходит обновление основной конфигурации конфигурацией из хранилища.

Как я правильно понял, в начале мы обновляем основную конфу конфой из хранилища по номеру, а потом выгружает файлы основной конфигурации.
# Ответить
37. cmd_vasec (файл скачал) 07.05.2015 13:25
(35) rtnm,
Разобрался. Надо внимательно читать инструкцию. :-)
Ответили: (38)
# Ответить
38. rtnm 07.05.2015 22:23
(37) cmd_vasec, вот и замечательно :)
# Ответить
Внимание! За постинг в данном форуме $m не начисляются.
Внимание! Для написания сообщения необходимо авторизоваться
Текст сообщения*
Прикрепить файл






IE 2016