Учебник по git: изучение ветвления git за 5 минут

Проверить ветку и переключить ветку

Удаленный филиал попадает в местный
  • В Remote Branch -> Checkout As… -> укажите название ветки
  • После завершения в местных филиалах
Коммутация местного отделения
  • В Local Branch -> Checkout -> указать ветку
  • Переключение завершено
  • Переключение ветвей — это не операция копирования файла, а операция указателя; это переключатель, на который указывает указатель git HEAD, который указывает на текущую ветвь.
При переключении веток ветви влияют друг на друга
  • Если в локальной рабочей области нет незафиксированных изменений, ветвь будет переключаться плавно; следовательно: при переключении операцийПопробуйте зафиксировать код текущей ветки, Держите рабочую область и область кэша в чистоте

    Версия после фиксации не повлияет на переключаемую ветвь; переключитесь на другую ветку полностью, а при обратном переключении сохранится исходная модификация

  • Если работа не закончена и не может быть отправлена: (например, ветка A -> ветка B); IDEA выдаст подсказку —

    • Как справиться с этой ситуацией:
      • Выберите Force Checkout, некоторые незафиксированные изменения в локальной рабочей области (ветвь A) будут перезаписаны (перезаписаны ветвью B),Высокий шанс потерять код!
      • Выберите Smart Checkout, IDEA сначала выполнит команду stash, сохранит эти незафиксированные изменения, а затем произведет проверку в ветку B. После переключения на ветвь B удалите эти изменения, чтобы эти локальные изменения в ветке A были перенесены в ветвь B. (СвязанныйGIT (08) управление филиалом Примечание для переключения локальных филиалов)
      • Вы также можете использовать Show Diff на приведенном выше рисунке для объединения и вручную скопировать содержимое ветви A в ветку B.(Безопасный способ)

Обработка статистических данных

Еще один важный тип данных — это различного рода журналы, которые необходимо не просто ввести, но еще и анализировать. Изначально для сбора логов использовали привычное для этих целей решение syslog-ng, но оно очень быстро перестало справляться с нагрузкой. Решение нашлось очень просто: программисты Facebook, столкнувшиеся с аналогичной задачей, разработали проект Scribe, который был опубликован в opensource и позже был взят на вооружение в Twitter. По сути это фреймворк для сбора и агрегации логов. Ты пишешь текст для логов и указываешь категорию записи — остальное инструмент берет на себя. Scribe работает локально и надежен даже в случае потери сетевого соединения. Каждый используемый узел знает только, на какой сервер передавать логи, что позволяет создавать масштабируемую иерархическую систему для сбора логов. Поддерживаются различные схемы для записи данных, в том числе обычные файлы и HDFS (к этой файловой системе мы вернемся ниже). Этот продукт полностью решил проблему Twitter со сбором логов, позволив логически разбить поток информации на примерно 30 категорий. В процессе использования программисты активно сотрудничали с командой Facebook, была создана и опубликована масса доработок.

Как опубликовать твит?

Делается это очень просто. Пробуем два варианта.

С компьютера

Заходим в свой аккаунт (как это сделать?). В правом углу экрана нажимаем кнопку «Твитнуть».

Откроется всплывающее окно. Здесь пишем нужный текст. При необходимости вставляем дополнительный контент — фото, видео, опросы и т.д. Для этого используем значки в нижнем меню. Когда форма будет заполнена, жмем «Твитнуть».

После этого новая запись появится в ленте. Это видно в примере выше.

Теперь с телефона

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

Процесс показан ниже.

Как удалить предупреждение из ваших собственных твитов

Чтобы Twitter не отмечал загружаемые вами медиафайлы как деликатные, выберите «Меню» → «Настройки и конфиденциальность» → «Конфиденциальность и безопасность». Убедитесь, что флажок «Пометить медиафайлы, в которых вы публикуете твиты, как материалы, которые могут быть деликатными» не установлен.

Эта опция доступна в Интернете и в приложении для Android, но не в приложении Twitter для iPhone и iPad.

Обратите внимание, что Twitter оставляет за собой право навсегда включить эту опцию для вашей учётной записи, если вы злоупотребляете этой опцией и загружаете деликатные медиафайлы, не помечая их как таковые. Если вы не можете отключить эту опцию до конца, конечное слово за алгоритмами и модераторами

Если вы не хотите видеть деликатный контент, не волнуйтесь — в Twitter эта настройка включена по умолчанию. Просто убедитесь, что параметр «Отображать материалы, которые могут содержать деликатный контент» отключён, а параметр «Скрыть деликатный контент» включён для поиска.

Источник

Основные конфликты слияния

Иногда процесс не проходит гладко. Если вы изменили одну и ту же часть одного и того же файла по-разному в двух объединяемых ветках, Git не сможет их чисто объединить. Если ваше исправление ошибки #53 потребовало изменить ту же часть файла что и , вы получите примерно такое сообщение о конфликте слияния:

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

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

Это означает, что версия из (вашей ветки , поскольку именно её вы извлекли перед запуском команды слияния) – это верхняя часть блока (всё, что над =======), а версия из вашей ветки представлена в нижней части. Чтобы разрешить конфликт, придётся выбрать один из вариантов, либо объединить содержимое по-своему. Например, вы можете разрешить конфликт, заменив весь блок следующим:

В этом разрешении есть немного от каждой части, а строки <<<<<<<, ======= и >>>>>>> полностью удалены. Разрешив каждый конфликт во всех файлах, запустите для каждого файла, чтобы отметить конфликт как решённый. Добавление файла в индекс означает для Git, что все конфликты в нём исправлены.

Если вы хотите использовать графический инструмент для разрешения конфликтов, можно запустить , который проведет вас по всем конфликтам:

Если вы хотите использовать инструмент слияния не по умолчанию (в данном случае Git выбрал , поскольку команда запускалась на Mac), список всех поддерживаемых инструментов представлен вверху после фразы «one of the following tools». Просто введите название инструмента, который хотите использовать.

Примечание

Более продвинутые инструменты для разрешения сложных конфликтов слияния мы рассмотрим в разделе «Продвинутое слияние» главы 7.

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

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

Если вы считаете, что коммит слияния требует дополнительных пояснений – опишите, как были разрешены конфликты, и почему были применены именно такие изменения, если это не очевидно.

Другая интересная информация о темах Как работают уведомления и темы, отправленные DM?

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

Давайте посмотрим ниже:

Прямые сообщения

В том случае, если поделиться твит, который является частью потока через сообщения непосредственный, получатель увидит вариант «Показать эту тему» это позволит вам полностью открыть тему и таким образом Смотрите полный контекст части сообщения, которое вы получили.

Уведомления

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

Чтобы вы поняли немного больше здесь, мы научим вас, каковы сроки уведомлений и push-уведомления:

  • Отправить уведомление: Это когда они упоминают вас в ветке, поэтому вы получите уведомление. Кроме того, если вы решили получить push-уведомления, когда аккаунт пишет в Твиттере, вы получите уведомление, когда аккаунт отправил поток.
  • График уведомлений: Каждый раз, когда вы упоминаете в теме, вы сможете увидеть упоминание в ваш график уведомлений, Это позволяет вам указать, что твит Это часть потока, поэтому возможность «Показать тему».

Ретвиты и Ретвиты с комментариями

И, наконец, мы находим этот вариант, который когда вы ретвит или ретвит с комментариями из потока. В таком случае ретвит или ретвит с комментарием собираюсь включить опцию «Показать эту тему» это позволит пользователям получить доступ к полной теме, где они были упомянуты,

Как использовать Tweetstorms для лучшего эффекта

Поскольку каждый пользователь Twitter будет знать эти раздражающие серии от людей, которые думают, что они знают все и нуждаются в том, чтобы вы тоже это знали. Они обычно бессмысленны, скучны и совсем не увлекательны. Хотя они могут использовать букву закона о потоке, они полностью упускают его дух.

Идея хорошего Tweetstorms заключается в том, чтобы предложить ценность. Как и любой твит, будь то для бизнеса или для удовольствия, они должны иметь точку зрения и предлагать ценность или, по крайней мере, понимание темы. Лучшие твиты предлагают уникальные идеи, отвечают на вопросы или решают проблемы. Эффективные также задают вопросы и предлагают мнение, хотя вы должны быть осторожны с ними!

Вот несколько идей для вашего первого Tweetstorm.

Решить проблему

У всех есть проблемы, но не пишите 99 твитов с описанием каждого. Начните с одной проблемы, а затем предложите несколько решений. Опубликуйте вопрос или проблему в своем первом твите, а затем — в каждом последующем твите

Важно, чтобы в каждом твите была полезная вещь, чтобы ваши читатели хотели большего

Расскажи историю

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

Сломать некоторые новости

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

Разглагольствование

Хотя разглагольствование является жизнеспособным методом привлечения внимания, вы должны делать это осторожно, чтобы он работал правильно. Мы склонны отключаться, когда кто-то нападает на что-то или другое, и вы должны избегать этого

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

Основы ветвления

Предположим, вы работаете над проектом и уже имеете несколько коммитов.

Рисунок 18 – Простая история коммитов

Вы решаете, что теперь вы будете заниматься проблемой #53 из вашей системы отслеживания ошибок. Чтобы создать ветку и сразу переключиться на нее, можно выполнить команду с параметром :

Это то же самое что и:

Рисунок 19 – Создание нового указателя ветки

Вы работаете над своим сайтом и делаете коммиты. Это приводит к тому, что ветка движется вперед, так как вы переключились на нее ранее ( указывает на нее).

Рисунок 20 – Ветка двигается вперед

Тут вы получаете сообщение об обнаружении уязвимости на вашем сайте, которую нужно немедленно устранить. Благодаря Git, не требуется размещать это исправление вместе с тем, что вы сделали в . Вам даже не придется прилагать усилий, чтобы откатить все эти изменения для начала работы над исправлением. Всё, что вам нужно – переключиться на ветку .

Но перед тем как сделать это – имейте в виду, что если рабочий каталог или индекс содержат незафиксированные изменения, конфликтующие с веткой, на которую вы хотите переключиться, то Git не позволит переключить ветки. Лучше всего переключаться из чистого рабочего состояния проекта. Есть способы обойти это (припрятать изменения (stash) или добавить их в последний коммит (amend)), но об этом мы поговорим позже в разделе «Припрятывание и очистка» главы 7. Теперь предположим, что вы зафиксировали все свои изменения и можете переключиться на ветку :

С этого момента ваш рабочий каталог имеет точно такой же вид, какой был перед началом работы над проблемой #53, и вы можете сосредоточиться на работе над исправлением

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

Теперь вы можете перейти к написанию исправления. Давайте создадим новую ветку для исправления, в которой будем работать, пока не закончим.

Рисунок 21 – Ветка основана на ветке

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

Заметили фразу «fast-forward» в этом слиянии? Git просто переместил указатель ветки вперед, потому что коммит C4, на который указывает слитая ветка , был прямым потомком коммита C2, на котором вы находились до этого. Другими словами, если коммит сливается с тем, до которого можно добраться двигаясь по истории прямо, Git упрощает слияние просто перенося указатель ветки вперед, поскольку расхождений в изменениях нет. Это называется «fast-forward».

Теперь ваши изменения включены в коммит, на который указывает ветка , и исправление можно внедрять.

Рисунок 22 – перемотан до

После внедрения вашего суперважного исправления, вы готовы вернуться к работе над тем, что были вынуждены отложить. Но сначала нужно удалить ветку , потому что она больше не нужна – ветка указывает на то же самое место

Для удаления ветки выполните команду с параметром :

Теперь вы можете переключиться обратно на ветку и продолжить работу над проблемой #53:

Рисунок 23 – Продолжение работы над iss53

Стоит обратить внимание на то, что все изменения из ветки не включены в вашу ветку. Если их нужно включить, вы можете влить ветку в вашу ветку командой , или же вы можете отложить слияние этих изменений до завершения работы, и затем влить ветку в

Старые твиты и поиск по дате

Недавно был добавлен интересный инструмент — расширенный поиск. С его помощью мы можем искать старые твиты — которые публиковали наши друзья, и мы сами.

Перед вами будем поисковая форма. Заполняйте нужные поля, и осуществляйте поиск.

Нас больше всего интересуют следующие поля:

  • Слова. Если нужно найти определенный текст или слово, эти поля придут на помощь.
  • От этих пользователей. Здесь можно указать ник, чтобы найти твиты нужного человека.
  • С указанной даты. Укажите нужное число, или временной диапазон. С помощью этого блока, можно посмотреть самые старые твиты.

Чтобы понять, как работает расширенный поиск, давайте попробуем найти мои твиты, опубликованные 19 июня 2019 года. Напоминаю, мой ник в Твиттер — Techprofi2. Пробуем.

Merge

Наличие нескольких веток чрезвычайно удобно для того, чтобы новые изменения были отделены друг от друга, а также чтобы вы случайно не запушили несанкционированные или поврежденные изменения в продакшин. Как только изменения будут одобрены, мы хотим получить эти изменения в нашей прод ветке!

Один из способов получить изменения из одной ветки в другую — выполнить ! Есть два типа менж команд, которые может выполнять Git: fast-forward или no-fast-forward 

Fast-forward ()

Fast-forward merge когда текущая ветка не имеет дополнительных коммитов по сравнению с веткой, которую мы мержим. Git у нас ленив и сначала попытается выполнить самый простой вариант: Fast-forward! Этот тип менжа не создает новый коммит, а скорее объединяет коммит(ы) в ветку, которую мы объединяем прямо в текущей ветке

Отлично! Теперь у нас есть все изменения, которые были сделаны в ветке , в ветке . Итак, что же такое  no-fast-forward?

No-fast-foward ()

Хорошо, если ваша текущая ветка не имеет каких-либо дополнительных коммитов по сравнению с веткой, которую вы хотите смержить, но, к сожалению, это случается редко! Если мы зафиксировали изменения в текущей ветке, которых нет в ветке, которую мы хотим объединить, git выполнит объединение без fast-forward merge. При слиянии без fast-forward Git создает новый коммит мержа в активную ветку. Родительский коммит указывает на активную ветку и ветку, которую мы хотим объединить!

Merge конфликты

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

В этом случае Git попросит вас помочь решить, какой из двух вариантов мы хотим сохранить. Допустим, что в обеих ветках мы отредактировали первую строку в файле README.md.

Если мы хотим смержить  в , это приведет к конфликту: хотите, чтобы заголовок был Hello! или hey!?

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

Что такое коммит (git commit)

Программировать только в облаке неудобно — проще скачать себе на компьютер весь проект и писать код на своей машине. Но чтобы правки увидели остальные, их нужно отправить обратно в репозиторий. Это и есть коммит.

Коммитить можно и один файл, и сразу несколько. Система сама найдёт, что изменилось в каждом файле, и добавит эти изменения в проект. Но все эти правки внесутся в репозиторий за один раз, потому что при коммите обрабатываются сразу все добавленные в список файлы. 

Например, вы изменили файл главной страницы index.html и добавили его в список файлов текущего коммита. Теперь его можно отправить на сервер, а можно ещё поправить сразу style.css и внести в этот же коммит. Системе всё равно, сколько файлов обрабатывать, поэтому как и что коммитить — решает программист.

Единственное требование к коммитам — указывать, что именно вы поменяли в проекте, человеческим языком. Хорошим тоном и правильным подходом считается писать, что именно вы изменили: «Добавил цвет и стили основной кнопки», «Убрали метод вызова старого API», «Сделали рефакторинг функции SetOutOfDate()». Это описание будут читать другие разработчики. 

Коммитить можно хоть после правки каждой строчки — весь вопрос в том, насколько нужна такая детализация в проекте

Но иногда и изменения из одной строчки можно закоммитить, если оно действительно важное

Слияние ветки через pull request

Теперь объединим ветку development с master, используя процесс pull request. Мы притворимся, что клонировали репозиторий разработчика, и хотим, чтобы разработчик влил наше изменение в ветку development. (Другими словами, у нас может нет прав на слияние веток в мастер.) Для этого мы создадим запрос на извлечение (pull request).

  1. Как выше, переключаемся на ветку development, вносим изменения в содержимое файла, сохраняем и подтверждаем изменения. После внесения изменений нажимаем Push origin, чтобы отправить наши изменения в удаленную версию ветки разработки на GitHub.
  2. В GitHub Desktop, с выбранной веткой development, переходим в Branch > Create Pull Request.

На сайте GiHub pull request выглядит так:

Стрелка влево (указывающая из ветви development в направлении master) указывает, что запрос на извлечение («PR») хочет объединить ветку development с основной веткой.

  1. Напишем причину запроса на извлечение и нажмем Create pull request.

  2. На этом этапе разработчики получат запрос по электронной почте с просьбой объединить их изменения. Попробуем себя в роли разработчика, перейдя на вкладку Pull requests (на GitHub), чтобы проверить и подтвердить запрос. Пока запрос на слияние не вызывает конфликтов, видна кнопка Merge pull request.

  1. Чтобы увидеть, какие изменения объединяются с мастером, можете щелкнуть вкладку Files changed (которая появляется на дополнительной навигационной панели вверху). Затем кликаем Merge pull request для объединения в ветке и Confirm merge, чтобы завершить объединение.

  2. Теперь получим обновления, которые мы слили в ветку, в свою локальную копию. В GitHub Desktop выбираем ветку и кликаем кнопку Fetch origin. Fetch получает последние обновления из источника, но не обновляет локальную рабочую копию с изменениями.

После нажатия кнопка Fetch origin изменится на Pull Origin.

  1. Нажимаем на Pull Origin чтобы обновить локальную копию с полученными изменениями.

Проверим файлы и обратим внимание, что обновления, которые изначально были в ветке development, теперь отображаются и в master

Что такое разветвление?

Представьте, что вы работаете над проектом со своей командой и создаете новую функцию, которая требует внесения большого количества изменений в кодовую базу. В процессе вы обнаружите ошибку, которую необходимо исправить. Эта ошибка связана с вашей новой функцией, и вы не хотите влиять на свой код. Эта ситуация могла усложниться. Где вы будете хранить код, над которым работали?

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

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

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

Обработка запросов пользователей

Активная аудитория Twitter генерирует неимоверное количество запросов через веб-страницы и программный интерфейс, который используют для своей работы все приложения-клиенты (как для десктопных, так и для мобильных ОС). Любопытно, что лишь 25% трафика приходится на веб-сайт, остальное идет через API. Это легко объяснить: только за последний год рост числа мобильных пользователей, которые активно твиттерят, составил 182%. Статистика впечатляет: 6 000 000 000 запросов к API в день, около 70 000 в секунду! Так как оба способа взаимодействия с сервисом основаны на HTTP, методы их обработки практически идентичны. Для генерации страниц используется в основном известный фреймворк Ruby on Rails, притом практически вся работа «за сценой» реализована на чистом Ruby или Scala. Многие говорят, что Ruby on Rails — далеко не самый производительный фреймворк, на что представители Twitter отвечают, что использование более быстрого решения позволило бы выиграть 10-20% в производительности, но благодаря RoR на ранних стадиях проекта был быстро реализован механизм горизонтального масштабирования. Последний позволил легко подключать новые сервера к системе без изменения кода и, как следствие, достичь роста производительности системы на несколько порядков. Сейчас проект использует более тысячи серверов, которые расположены в NTT America, однако планируется переезд в собственный датацентр. От «облаков» и виртуализации разработчики отказались с самого начала: существующие решения страдают слишком высокими задержками, особенно при доступе к дисковой подсистеме.

В роли балансировщика нагрузки используется привычный Apache httpd, но с учетом основного инструмента разработки, для обработки самих запросов необходим сервер приложений для Ruby. Для этого используется Unicorn, который имеет массу положительных сторон — например, развертывание новых версий кода без простоя, более низкое (до 30% меньше) потребление вычислительных ресурсов и оперативной памяти по сравнению с другими решениями. Связка «Apache + Unicorn» хорошо работала в начале. Но по мере развития проекта начали всплывать и серьезные недостатки решения: в подсистеме кэширования стали наблюдаться проблемы с инвалидацией (удалением устаревших данных), а ActiveRecord, автоматический генератор SQL-запросов в Ruby, как оказалось, использует не самые удачные варианты, что непременно замедляет время отклика и приводит к высоким задержкам в очереди и при репликации. Эти проблемы пришлось решать.

Архитектура средств для обработки запросов

Рейтинг
( Пока оценок нет )
Editor
Editor/ автор статьи

Давно интересуюсь темой. Мне нравится писать о том, в чём разбираюсь.

Понравилась статья? Поделиться с друзьями:
Zoom-Obi
Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: