git.alt/Справочник
Эта страница документирует команды git.alt, но не является кратким руководством или учебником по нему.
Как воспользоваться git.alt?
git.alt предоставляет несколько видов доступа:
- ssh-доступ. Предоставляет несколько команд: для поиска репозиториев, их клонирования, создания, удаления, а также служебных.
- ssh-, git-, rsync-, http-доступ для непосредственной работы с репозиториями.
- git-, rsync- и http-адреса предоставляют r/o доступ, ssh — r/w.
- Web-интерфейс. Находится по адресу git.altlinux.org, предоставляет навигацию по списку репозиториев и gitweb для индивидуальных репозиториев.
ssh-доступ к git.alt выдаётся после принятия в ALT Linux Team.
SSH-доступ
git.alt доступен по SSH по адресу git.altlinux.org:222. Аккаунт для доступа — git_$USERNAME, где USERNAME — имя, присвоенное в процессе принятия в Team, с символами «-» заменёнными на «_».
Пример ~/.ssh/config:
Host git.alt HostName git.altlinux.org Port 222 User git_USERNAME # if stored separately #IdentityFile ~/.ssh/id_dsa-git.alt
Для работы через прокси и в других сложных условиях SSH также доступен по адресу git.altlinux.org:443.
Для работы с git.alt необходимо настроить свой git — параметры user.name, user.email, user.signingkey:
$ git config --global user.signingkey "<ID ключа GPG для подписи тэгов>" $ git config --global user.email "<ваш email, как мантейнера>" $ git config --global user.name "FirstName LastName"
Например,
$ git config --global user.signingkey 0xA26F54C8 $ git config --global user.email dottedmag@altlinux.org $ git config --global user.name "Mikhail Gusarov"
Чтобы узнать свой user.signingkey, выполните команду
$ gpg --list-secret-keys
Искомое значение находится в секции sec выхлопа команды. Его-то и следует прописать в переменную user.signingkey, предварительно снабдив символами 0x
Список команд выдаётся при ssh-логине с командой help:
$ ssh git.alt help Available commands: help charset <path to git repository> [<charset>] clone <path to git repository> [<path to directory>] default-branch <path to git repository> [<branch>] find-package <pattern> init-db <path to directory> ls [<path to directory>] mv-db <path to source directory> <path to destination directory> quota repack <path to git repository> [<value>] rm-db <path to git repository> task {--help|ls|show|new|add|delsub|run|share|approve|rm} ... build [-b <binary_repository_name>] <gear_repo_1> <gear_tag_1> ... acl {--help|<binary_repository_name> ...}
Во всех командах суффикс директорий репозиториев .git опционален и может быть опущен. В выводе команд .git присутствует всегда.
Управление git-репозиториями
ls
$ ssh git.alt ls [<directory>]
Эта команда позволяет посмотреть содержимое различных директорий на git.alt:
$ ssh git.alt ls /people/dottedmag/public total 24 drwxr-sr-x 5 4096 Jun 13 10:22 bugzilla-repo-sync.git ... drwxr-sr-x 5 4096 Jul 7 18:03 wackoconvert.git $
Без параметров — показывает содержимое /people/$USERNAME:
$ ssh git.alt ls total 16 drwxr-s--- 5 4096 May 30 21:27 etc drwxr-sr-x 14 4096 Aug 13 23:53 packages drwxr-s--x 2 4096 Feb 13 2007 private drwxr-sr-x 8 4096 Aug 13 23:57 public $
От этой же директории отсчитываются относительные пути:
$ ssh git.alt ls public total 24 drwxr-sr-x 5 4096 Jun 13 10:22 bugzilla-repo-sync.git ... drwxr-sr-x 5 4096 Jul 7 18:03 wackoconvert.git $
find-package
$ ssh git.alt find-package <pattern>
Эта команда позволяет искать репозитории по переданному шаблону. Единственный метасимвол, допустимый в шаблоне — *. Репозитории ищутся в директории packages каждого пользователя, поскольку предполагается, что gear-репозитории располагаются именно там.
$ ssh git.alt find-package glibc* /people/avm/packages/glibc.git 1216320095 ... /people/peet/packages/glibc-kernheaders.git 1177084354 /people/mike/packages/glibc-kvercheck.git 1160664813 $ ssh git.alt find-package glibc /people/avm/packages/glibc.git 1216320095 ... /people/peet/packages/glibc.git 1177084600 $
Вторая колонка в выводе find-package — unixtime времени последнего обновления репозитория. Получить время в привычном представлении можно с помощью команды date -d @unixtime.
База данных для find-package обновляется в начале каждого часа. В неё попадают только те репозитории, в которые был сделан хотя бы один git push. Репозитории, не изменившиеся после первичного создания/клонирования, в эту базу не попадают.
clone
$ ssh git.alt clone <path to git repository> [<destination directory>]
Эта команда позволяет «склонировать», то есть создать в своей директории копию репозитория для начала работы над ним. При этом локальные клоны (из /people) задействуют хардлинки, экономя дисковое пространство, а также ваши квоту на git.alt и трафик до него.
Без второго аргумента — клонирует в директорию packages:
$ ssh git.alt clone /people/ldv/packages/glibc girar-clone: /people/dottedmag/packages/glibc.git $
Вторым аргументом можно указать как директорию, в которую нужно поместить клон репозитория, так и название репозитория:
$ ssh git.alt clone /people/ldv/packages/glibc public/test girar-clone: /people/dottedmag/public/test.git $
Можно также склонировать репозиторий, находящийся вне git.alt:
$ ssh git.alt clone git://git.fedorahosted.org/chkconfig.git girar-clone: /people/dottedmag/packages/chkconfig.git $
init-db
$ ssh git.alt init-db <path to directory>
Позволяет создать новый git-репозиторий. По умолчанию репозиторий создаётся в директории packages:
$ ssh git.alt init-db test girar-init-db: /people/dottedmag/packages/test.git
При указании пути создаёт репозиторий по указанному пути:
$ ssh git.alt init-db public/test girar-init-db: /people/dottedmag/public/test.git
mv-db
$ ssh git.alt mv-db <path to source directory> <path to destination directory>
Позволяет перемещать и переименовывать свои репозитории. При указании только имени репозитория подразумевается директория packages.
Перемещение packages/test.git в public/newname.git:
$ ssh git.alt mv-db test public/newname $
Перемещение public/newname.git в packages/test.git:
$ ssh git.alt mv-db public/newname test $
Переименовывание packages/test.git в packages/megatest.git:
$ ssh git.alt mv-db test megatest $
rm-db
$ ssh git.alt rm-db <path to git repository>
Позволяет удалять свои репозитории. При указании только имени репозитория подразумевается директория packages:
$ ssh git.alt rm-db megatest # удаляет packages/megatest.git $ ssh git.alt rm-db public/test
Управление ACL пакетов
Смотри ACL для общей информации об ACL пакетов в Sisyphus.
Команда acl требует указания репозитория, над которым производится работа. Список доступных репозиториев можно узнать у gitalt:
$ ssh git.alt acl --help Usage: girar-acl --list or: girar-acl <repository> [{<package>|@<group>} {check|show}] or: girar-acl <repository> [{<package>|@<group>} {add|del|leader|replace} {<login>|@<group>}...] or: girar-acl <repository> Valid repositories are: sisyphus t6 p6 c6 p5 5.1 5.0 4.1 4.0 If no package is given, read commands from stdin, one command per line. See http://www.altlinux.org/Incoming/acl for details. $
Если в командной строке указан только репозиторий, но не указана подкоманда, то список команд читается со стандартного ввода, по одной команде на строку, и выполняется тразакционно: ошибка в выполнении хотя бы одной команды отменяет действие всего набора команд:
$ ssh git.alt acl sisyphus keyjnote girar-acl: Go ahead and type your commands keyjnote add peet < keyjnote add peet > OK: keyjnote: dottedmag peet keyjnote add raorn < keyjnote add raorn > OK: keyjnote: dottedmag peet raorn ^D girar-acl: 2 command(s) queued $
Все команды, меняющие состав группы или ACL пакета, могут производиться только лидером — первым в списке ACL пакета или в составе группы. Набор из нескольких команд выполняется транзакционно. Результат выполнения acl-команд сообщается по email всем, кого они затрагивают.
acl show
$ ssh git.alt acl <binary repository> <package> show
Показывает ACL указанного пакета
$ ssh git.alt acl sisyphus bugzilla show bugzilla @nobody
$ ssh git.alt acl <binary repository> @<group> show
Показывает состав указанной группы майнтайнеров.
$ ssh git.alt acl sisyhpus @python show @python ns ldv george akhavr bga lav swi at hiddenman sin mithraen kas
acl check
$ ssh git.alt acl <binary repository> <package> check
Проверяет ACL указанного пакета
$ ssh git.alt acl sisyphus bugzilla check girar-check-perms: access to bugzilla ALLOWED for ldv: project is orphaned
acl add/del
$ ssh git.alt acl <binary repository> <package> add|del <login>|@<group> ...
Добавляет/удаляет указанных пользователей и группы в/из ACL указанного пакета.
$ ssh git.alt acl sisyphus keyjnote add damir < keyjnote add damir > OK: keyjnote: dottedmag damir girar-acl: 1 command(s) queued $ ssh git.alt acl sisyphus keyjnote del damir < keyjnote del damir > OK: keyjnote: dottedmag girar-acl: 1 command(s) queued
$ ssh git.alt acl <binary repository> @<group> add|del <login>|@<group> ...
Добавляет/удаляет указанных пользователей и группы в/из указанной группы.
$ ssh git.alt acl sisyphus @python add ns < @python add ns > OK: @python: real ldv george lav swi at hiddenman sin mithraen enp vvk viy vitty ns girar-acl: 1 command(s) queued $ ssh git.alt acl sisyphus @python del ns < @python del ns > OK: @python: real ldv george lav swi at hiddenman sin mithraen enp vvk viy vitty girar-acl: 1 command(s) queued
acl replace
$ ssh git.alt acl <binary repository> <package>|@<group> replace <login>|@<group> <login>|@<group>
Заменяет указанную запись в ACL пакета или составе группы на вторую указанную.
$ ssh git.alt acl sisyphus keyjnote replace dottedmag @python
Заменяет в ACL пакета keyjnote запись dottedmag на @python.
acl leader
$ ssh git.alt acl <binary repository> <package> leader <login>|@<group>
Устанавливает лидера пакета — указанного пользователя, или лидера указанной группы. Пользователь или группа, устанавливаемые лидерами, не обязаны присутствовать в списке ACL пакета до выполнения этой команды.
$ ssh git.alt acl sisyphus keyjnote leader @python
$ ssh git.alt acl <binary repository> @<group> leader <login>|@<group>
Устанавливает лидера группы — указанного пользователя, или лидера указанной группы. Пользователь или группа, устанавливаемые лидерами, не обязаны присутствовать в списке членов группы до выполнения этой команды.
$ ssh git.alt acl sisyphus @python leader ns
Сборка пакетов
Для сборки пакетов используется механизм заданий — пользователь указывает, какие gear-репозитории необходимо собрать одной транзакцией, создавая задание, после чего запускает его на выполнение. Задание выполняются асинхронно. После завершения задания пользователю приходит отчёт по e-mail (плюс, отчёты о сборке доступны на git.alt, см. ниже). Каждое задание предназначено для изменения только одного репозитория пакетов.
task
$ ssh git.alt task ls [--all]
Показывает текущий список всех заданий пользователя с указанием их статуса и краткого содержания.
С указанием параметра --all показывает список заданий всех пользователей.
$ ssh git.alt task show [<task_id>]
Показывает содержимое указанного (по умолчанию последнего созданного) задания.
$ ssh git.alt task new [<binary_repository_name>]
Создаёт новое задание для сборки пакетов в указанный репозиторий пакетов (по умолчанию — Sisyphus).
Список репозиториев можно узнать с помощью task new --help.
Данная команда выводит идентификатор задания на stdout.
$ ssh git.alt task add [<task_id> [<before_subtask_id>]] repo <gear_repo> <gear_tag>
Добавляет в задание пакет, который необходимо собрать.
Пакет определяется двумя обязательными характеристиками: путём к gear-репозиторию и именем git-тэга.
По умолчанию новые подзадания добавляются в конец списка подзаданий, с шагом 0100 (восьмеричное 100). Новое подзадание, добавляемое перед подзаданием номер N, получает восьмеричный номер (K+N)/2, где K — это номер подзадания, идущего непосредственно перед подзаданием номер N[1].
$ ssh git.alt task add [<task_id> [<before_subtask_id>]] srpm <srpm file>
Добавляет в задание пакет, который необходимо собрать.
Пакет определяется именем предварительно отправленного на сервер путём rsync git.alt: srpm-файла (Пример: rsync grace-5.1.22-alt6.src.rpm git.alt:).
$ ssh git.alt task add [<task_id> [<before_subtask_id>]] copy <package> [<binary_repository_name>]
Добавляет в задание имя пакета, который необходимо скопировать из другого репозитория пакетов (по умолчанию — Sisyphus).
Параметры:
- package — имя пакета (без версии, релиза и расширения).
$ ssh git.alt task add [<task_id> [<before_subtask_id>]] del <package>
Добавляет в задание имя пакета, который необходимо удалить из репозитория.
$ ssh git.alt task delsub <task_id> <subtask_id>
Удаляет из указанного задания подзадание с указанным номером.
$ ssh git.alt task run [--test-only] [<task_id>]
Отправляет на выполнение указанное (по умолчанию последнее созданное) задание.
Если задан опциональный параметр --test-only, то финальное выкладывание собранного в репозиторий не производится (т.н. тестовая сборка).
Не забудьте указать --test-only при необходимости повторного теста.
Задания, успешно собравшиеся в репозиторий (со статусом обработки DONE), архивируются сразу по окончании обработки.
Остальные задания автоматически архивируются через 5 суток после завершения обработки.
$ ssh git.alt task share [<task_id>] <status|enabled|disabled>
Показывает или изменяет режим доступа к указанному (по умолчанию последнему созданному) заданию.
Задание с режимом доступа share enabled может быть дополнено другими пользователями с помощью команды task add.
По умолчанию задания создаются в режиме доступа share disabled.
$ ssh git.alt task approve <task_id> <subtask_id>
Подтверждает сборку подзадания с указанным номером, входящего в состав указанного чужого задания.
Используется для разрешения сборки автором, не имеющим полномочий для обновления собираемого пакета (NMU).
$ ssh git.alt task check-git-inheritance <task_id> <subtask_number> disable <commit_sha_id>
Для подзадания с номером <subtask_number>, входящего в состав задания <task_id>,
выключается обязательность проверки наследования от git-коммита <commit_sha_id>.
Используется при необходимости осознанного обхода проверки наследования.
$ ssh git.alt task rm [<task_id>]
Удаляет указанное (по умолчанию последнее созданное) задание.
$ ssh git.alt task abort <task_id>
Досрочно прерывает обработку указанного задания.
Если задание еще не находится на обработке, то оно снимается с очереди на обработку сразу.
В противном случае оно помечается как задание, обработку которого следует прервать при первой возможности.
Пример:
$ ssh git.alt task ls girar-task ls: no tasks for ldv $ ssh git.alt task new 1234 new task #1234: owner=ldv repo=sisyphus $ ssh git.alt task ls #1234 NEW sisyphus $ ssh git.alt task show id=1234 locked=no shared=no repo=sisyphus owner=ldv seq= rc= $ ssh git.alt task add repo vitmp 1.0-alt4 task #1234: added #1 build tag 1.0-alt4 from /people/ldv/packages/vitmp.git $ ssh git.alt task show id=1234 locked=no shared=no repo=sisyphus owner=ldv seq= rc= 1:dir=/people/ldv/packages/vitmp.git 1:tag_name=1.0-alt4 1:tag_id=11c24aa6683506efd89b174de8dbea2af1cebf84 1:tag_author=Dmitry V. Levin (for packages) <ldv@altlinux.org> 1:userid=ldv $ ssh git.alt task run task #1234: queued, result will be emailed to ldv@altlinux.org $ ssh git.alt task ls #1234 AWAITING sisyphus vitmp.git=1.0-alt4
через некоторое время вывод последней команды изменится на
#1234 BUILDING [locked] sisyphus vitmp.git=1.0-alt4
а ещё через некоторое время — на
#1234 DONE sisyphus vitmp.git=1.0-alt4
(или TESTED, если сборка тестовая)
build
$ ssh git.alt build [--test-only] [-b <binary_repository_name>] <gear_repo_path 1> <gear_tag_name 1> ...
Эта команда создаёт задание по сборке указанных пакетов и отправляет его на выполнение,
последовательно запуская task new, task add и task run.
Параметр binary repository name имеет тот же смысл, что и в команде task new.
Параметры gear repo path и gear tag name имеют тот же смысл, что и в команде task add. Параметр --test-only имеет тот же смысл что и в команде task run.
$ ssh git.alt build [-b <binary_repository_name>] srpm <srpm file> ...
Эта команда создаёт задание по сборке указанных пакетов и отправляет его на выполнение,
последовательно запуская task new, task add и task run.
Параметр binary repository name имеет тот же смысл, что и в команде task new.
Параметр srpm file имеет тот же смысл, что и в команде task add.
Отчёты о сборке
Информация о сборках публикуется по адресу http://git.altlinux.org/tasks/
Каждая поддиректория /tasks/ содержит информацию об одной сборочной задаче. Идентификатор задачи выдаётся при её создании и указывается в почтовых оповещениях.
Задача может состоять из нескольких подзадач. Информация о каждой подзадаче публиуется в директориях /tasks/<id>/build/<sid> и /tasks/<id>/gears/<sid>.
Наиболее интересные файлы:
- <id>/task/log
- краткий лог сборки
- <id>/build/<sid>/<arch>/srpm.log
- лог сборки подзадачи для архитектуры <arch>, если сборка производилась через incoming
- <id>/build/<sid>/<arch>/log
- лог сборки подзадачи для архитектуры <arch>, если сборка производилась через git.alt
- <id>/gears/<sid>
- информация о подзадаче <sid>, если сборка производилась через git.alt
- <id>/gears/<sid>/git
- частичный git-репозиторий, на основании которго собиралась подзадача <sid>
Более подробное описание структуры задания можно найти в документации на girar-builder.
Всё, что находится по адресу http://git.altlinux.org/tasks/, в равной степени доступно и по rsync.
Вспомогательные команды
charset
$ ssh git.alt charset <path to git repository> [<charset>]
Позволяет узнать или установить кодировку, используемую почтовым клиентом при отправке уведомлений, содержащих цитаты изменений файлов указанного git-репозитория:
$ ssh git.alt charset packages/glibc utf-8 $ ssh git.alt charset packages/glibc cp1252 $ ssh git.alt charset packages/glibc cp1252 $
quota
$ ssh git.alt quota
Позволяет узнать квоту и занимаемое пользователем дисковое пространство.
$ ssh git.alt quota Filesystem blocks quota limit grace files quota limit grace /dev/simfs 16932 977M 1465M 555 100k 150k $
git-receive-pack, git-upload-pack
Эти команды используются утилитами git push, git pull и подобными, и не предназначены для вызова пользователем.
Клонирование и работа с репозиториями
Работа с git-репозиториями, расположенными на git.alt, ничем не отличается от работы с другими git-репозиториями.
URL-ы репозиториев на git.alt:
- git (r/o)
- git://git.altlinux.org/people/$USER/(packages%7Cpublic)/$PACKAGE.git
- rsync (r/o)
- git.altlinux.org::people/$USER/(packages|public)/$PACKAGE.git
- http (r/o)
- http://git.altlinux.org/people/$USER/(packages|public)/$PACKAGE.git
- ssh (r/w)
- ssh://git.altlinux.org/people/$USER/(etc%7Cpackages%7Cpublic%7Cprivate)/$PACKAGE.git
HTTP- и git-URL-ы репозиториев можно в любой момент узнать в web-интерфейсе git.alt.
Web-интерфейс
Располагается по адресу http://git.altlinux.org/
Предоставляет навигацию по
- публичным репозиториям пользователей (по каталогам вида /people/$USERNAME/{packages,public})
- кэширующим репозиториям /gears и /srpms
- базе данных ACL
- файлу people-packages-list, содержащий все репозитории из каталогов /people/$USERNAME/packages и даты их последнего изменения (в unixtime)
- сборочным заданиям
- логам тестовых пересборок Сизифа и бранчей
- статистике непересобираемости пакетов в Сизифе и бранчах
Структура репозиториев
git.alt содержит три дерева репозиториев:
- репозитории /people/$USERNAME для каждого зарегистрированного пользователя
- репозитории /gears с исходным кодом для пакетов, собранных из gear-репозиториев.
- репозитории /srpms с исходным кодом для пакетов, собранных из SRPM-пакетов.
/people
Каждому зарегистрированному на git.alt разработчику предоставляется место для git-репозиториев, начинающееся с /people/$USERNAME. Доступ на запись в эти директории даётся только владельцу. Структура для хранения репозиториев жёстко определена:
/people/$USERNAME/etc
Содержит репозитории packages.git, private.git, public.git, с помощью которых можно управлять подпиской на почтовые оповещения. Эти репозитории доступны на чтение только владельцу.
/people/$USERNAME/packages
Директория предназначена для хранения gear-репозиториев для пакетов Сизифа. Публично доступна.
git-репозитории в этой директории будут искаться при выполнении команды find-package, и эта директория будет использоваться по умолчанию в командах init-db, clone, build и task add repo
/people/$USERNAME/private
Директория предназначена для хранения приватных репозиториев, о существовании и содержании которых должно быть известно только самому разработчику.
Для удобства работают прямые http-ссылки на файлы репозиториев, размещённых в этой директории.
/people/$USERNAME/public
Директория предназначена для хранения публичных git-репозиториев, не являющихся gear-репозиториями для пакетов Сизифа.
/gears
В эту директорию помещаются gear-репозитории с исходным кодом пакетов Sisyphus и других стабильных веток. Добавление исходного кода в репозиторий /gears происходит после успешной сборки пакета с помощью команд git.alt task или build.
Каждый git-репозиторий в /gears назван по имени пакета с исходным кодом. Бранчи в нём называются по имени ветки, в которую собрался пакет (sisyphus, t6 и т.д). Тэги в репозитории соответствуют собранным версиям пакетов (1.0-alt1, 1.0-alt0.M50.1 и т.д.).
/srpms
В этой директории размещаются git-репозитории с исходным кодом пакетов Sisyphus и других стабильных веток, собранных из SRPMS-пакетов.
После первой сборки пакета из gear, git.alt репозиторий в /srpms замораживается.
Почтовая подписка
На git.alt реализовано два вида почтовой подписки на события:
- Пользователь подписывается на события, происходящие в репозиториях packages и public.
- Пользователь подписывает кого-то на события, происходящие в его репозиториях packages, public и private.
Для подписки используются репозитории из каталога etc: packages.git, public.git, private.git в каталоге пользователя. Схема работы с подписками напоминает работу с CVSROOT из CVS: пользователь клонирует нужный репозиторий, коммитит изменения в него и push-ит обратно на сервер, после чего изменения вступают в силу.
В каждом из трёх репозиториев находится два файла: email-subscription и email-distribution (точнее, в private.git — только email-distribution). git.alt использует бранч master и не обращает внимания на остальные бранчи в этих репозиториях.
email-subscription
Этот файл позволяет подписаться на события в публичных репозиториях git.alt. Формат файла — последовательность строк следующего вида:
$USER $PACKAGE $REFTYPE $REFNAME
где
- $USER — имя пользователя git.alt,
- $PACKAGE — имя пакета,
- $REFTYPE — вид изменения: head — новые/удалённые коммиты, tag — новые/удалённые тэги (техническая подробность: второй компонент из изменяемой ссылки refs/*/*)
- $REFNAME — имя изменения: имя бранча для коммитов, имя тэга для тэгов (техническая подробность: третий и последующие компоненты из изменяемой ссылки refs/*/*).
Каждое из полей может быть полным именем или вайлдкардом *. Для имён пакетов также разрешён вайлдкард в конце имени (например, docs-*).
Примеры
Подписка на все события во всех репозиториях:
* * * *
Подписка на новые/удалённые тэги в репозитории /people/ldv/packages/glibc.git:
ldv glibc tag *
Действия для осуществления подписки:
git clone git.alt:etc/packages.git cd packages echo 'ldv glibc tag *' >> email-subscription git commit -m "Subscribe to new tags in ldv's glibc repository" email-subscription git push
email-distribution
Этот файл позволяет подписать других пользователей git.alt на события в ваших репозиториях. Формат файла — последовательность строк вида:
$PACKAGE $REFTYPE $REFNAME $MAILTO
где
- $PACKAGE, $REFTYPE, $REFNAME аналогичны параметрам из файла email-subscription
- $MAILTO — разделённый запятыми список имён пользователей git.alt — получателей оповещения.
Вайлдкарды в первых трёх полях допустимы так же, как и в email-subscription. Вайлдкарды в $MAILTO не допускаются.