Слишком короткий поисковый запрос.
По вашему запросу ничего не найдено :(
Убедитесь, что запрос написан правильно, или посмотрите другие
наши статьи:

Git – это распределенная система контроля версий с открытым исходным кодом. С ее помощью вы можете легко управлять файлами проекта, локально создавая и обслуживая ветки, подготавливая изменения к фиксации и управляя рабочими процессами.
На сегодняшний день многие разработчики используют Git, и они обычно знакомы с такими базовыми концепциями Git, как:
создание репозитория
создание ветки
подготовка изменения к фиксации или его отмена
фиксация изменения
отправка коммита в удаленный репозиторий
Однако многие разработчики не знают, что такое «слияние» и «разрешение конфликтов слияния». В этой статье мы рассмотрим на практике, как разрешать конфликты слияния. Это значит, что, прочитав эту статью, вы поймете, что означают эти понятия, и сможете применять их на практике.
Что разработчики говорят о «конфликтах слияния»?
Недавно я провел опрос в Twitter, LinkedIn и YouTube. Я хотел узнать, удобно ли разработчикам разрешать конфликты слияния в Git. И угадайте, что я обнаружил?
Примерно 70-80% разработчиков сказали, что им не так-то просто разрешать конфликты слияния в Git. Это значит, что «разрешение конфликтов слияния» является довольно важной темой, которую нужно обсудить.
Результаты опросы – Удобно ли вам разрешать конфликты в Git?
Что такое Git merge и конфликты слияния?
Git – это система контроля версий, которая хранит историю версий всех ваших файлов. Вы можете вернуться к любой из версий в любое время и извлечь, таким образом, более старую версию.
Предположим, вы создали файл abc.txt и поместили его в репозиторий Git. На этом этапе файл имеет свою текущую версию, привязанную к нему. Теперь, если ваш коллега изменит этот файл и отправит его обратно в репозиторий, то к этому файлу будет привязана новая версия.
Git merge – это функция, которая позволяет синхронизировать текущее содержимое файла с предыдущими версиями. Это крайне важная функция, так как любой человек в любой момент времени должен работать с самой последней версией содержимого файла, не переписывая при этом другие изменения из предыдущих версий.
Git merge помогает вам объединить изменения, которые были внесены другими разработчиками, прежде чем вы начнете вносить новые изменения в тот же файл.
Если мы говорим о Git merge, нам следует помнить о двух вещах:
Изменения
: какие действия были выполнены между двумя версиями файла? Добавляется или удаляется новое содержимое, или обновляется текущее содержимое.
Ситуации
: есть два варианта. Изменения могли произойти в одной и той же или разных областях файла. Одна и та же область говорит о том, что разработчики внесли изменения в одном и том же месте (например, в одном абзаце, строке и т.д.) файла.
К счастью, Git позаботился о большинстве таких случаев. Он использует автоматическое слияние. Однако, если изменения произошли в одной и той же области файла, Git не будет его выполнять. Вместо этого вам придется разрешать конфликт слияния.
Конфликты слияния в Git: страшилка
Давайте попробуем разобраться в том, что написано выше, на примере историй двух разработчиков, Алекса и Тины.
В один прекрасный день
Алекс извлек изменения из удаленного репозитория в свой локальный.
Он изменил файл abc.txt, проиндексировал его, зафиксировал изменения, и, наконец, отправил обратно в удаленный репозиторий.
Тем временем Тина, не зная о том, что Алекс внес изменения в файл abc.txt, внесла некоторые свои изменения в ту же область файла и попыталась отправить его в удаленный репозиторий.
Git – это система контроля версий, и она предупредила Тину, что она внесла изменения в версию, более старую, нежели та, что хранилась в удаленном репозитории (так как изменения Алекса уже были там).
Теперь Тина должна сначала извлечь изменения с удаленного репозитория, обновить файл, а затем попытаться снова отправить изменения.
Тина сделала это. Однако, как в ее самом диком кошмаре, она получила предупреждение о том, что автоматическое слияние выполнить не удалось, и ей нужно разрешить конфликт слияния.
Эта ситуация вам что-то напоминает? Сталкивались ли вы с подобными ситуациями? Были ли вы когда-то на месте Тины? Если нет, то рано или поздно это все равно случиться! Итак, давайте разберемся, как Тине справиться с этой ситуацией максимально эффективно.
Как разрешать конфликты слияния в Git
Процесс разрешения конфликтов слияния не так сложен, как может показаться. В 90% случаев он будет еще проще, если вы будете максимально спокойны, и у вас будет четкое понимание того, как происходят изменения.
Решение
Как только Тина получит изменения, в ее локальном файле будут как ее изменения, так и изменения, внесенные Алексом. И теперь Тина может сделать что-то одно из следующего списка:
Она может сохранить изменения Алекса и удалить свои
Она может удалить изменения Алекса и сохранить свои
Она может сохранить как изменения Алекса, так и свои
Она может удалить как изменения Алекса, так и свои
Допустим, но что ей все-таки нужно сделать? Это всецело зависит от потребностей проекта и сценариев использования. Тина должна оценить входящие изменения и сделать все, что необходимо в данной ситуации.
Так, а что такое входящие изменения? Как Тина может их определить? И как Тина будет вносить изменения? Я прекрасно понимаю, что у вас таких вопросов навалом. Давайте попробуем на них ответить, рассмотрев несколько примеров из реальной жизни в следующем разделе.
Процесс разрешения конфликтов слияния в Git
Давайте рассмотрим пару реальных примеров конфликтов слияния и посмотрим, как их можно разрешить.
Пример 1. Изменения в одной области файла
Когда Git не может выполнить автоматическое слияние по причине того, что изменения находятся в одной и той же области, он обозначает «конфликтующие» области специальными символами.
<<<<<<<
=======
>>>>>>>
Все, что находится между <<<<<<< и =======, является вашими локальными изменениями. Этих изменений еще нет в удаленном репозитории. Все строки, которые находятся между ======= и >>>>>>>, - это изменения из удаленного репозитория или какой-то другой ветки. Теперь вам нужно изучить эти два пункта и принять решение.
На изображении ниже продемонстрировано содержимое файла, которое дает нам понять, что автоматического слияния не произошло, и существует конфликт. Конфликт расположен в строке, где мы локально изменили файл, добавив строку - Sleep. Только одновременно с этим кто-то еще внес свои изменения в ту же область файла, добавив строку - Gym.
Выходит, что строка - Sleep помечается как локальное изменение, а - Gym - как входящее изменение из удаленного репозитория или другой ветки.
Конфликт, возникший вследствие внесения изменений в одной и той же области файла
В зависимости от вашего сценария использования и потребностей проекта, вы должны принять соответствующее решение для того, чтобы разрешить конфликт. Если вам нужно сохранить только строку - Sleep, то вы сохраняете ее, а остальные «конфликтующие» строки удаляете. В таком случае содержимое файла станет таким:
- Eat
- Read
- Sleep
Или наоборот, вы можете сохранить строку - Gym и удалить строку - Sleep:
- Eat
- Read
- Gym
Если вам нужно сохранить обе строки, удалите строки, которые вызывают конфликт:
- Eat
- Read
- Sleep
- Gym
Если вы считаете, что ни одно из изменений вам не нужно, удалите их все:
- Eat
- Read
Это только ваше дело, какие изменения оставить, а какие удалить. После того, как вы внесете все изменения, необходимо убедиться, что в файле нет ни одного символа, который указывает на конфликт (<<<<<<<, =======, >>>>>>>). Как только вы определитесь со всеми изменениями, сделайте следующее:
Подготовьте изменения к фиксации:
git add
Зафиксируйте изменения с комментарием «Message»:
git commit -m "Message"
И наконец, отправьте изменения в удаленный репозиторий:
git push
В данной ситуации это все, что вам нужно сделать для того, чтобы разрешить конфликт.
Пример 2. Файл был удален из удаленного репозитория/другой ветки
Конфликт слияния удаленных файлов – это когда разработчик удаляет файл в одной ветке, тогда как другой разработчик редактирует тот же файл в другой ветке. В таком случае вам нужно решить, хотите ли вы сохранить файл или вы вполне можете его удалить.
Для того, чтобы снова добавить удаленный файл в вашу ветку, запустите следующую команду:
git add
А для того, чтобы окончательно его удалить, запустите вот эту команду:
git rm
После чего зафиксируйте изменения с комментарием «Message»:
git commit -m "Message"
И наконец, отправьте изменения:
git push
Что дальше?
Если вы усвоите два приведенных выше примера и попробуете применить их, то сможете справиться с большинством ситуаций и разрешить конфликты слияния. Именно поэтому я рекомендую отработать их пару раз на практике.
Прежде чем мы подведем итоги, хочу дать вам несколько советов:
Во всех примерах, продемонстрированных в этой статье, предполагается, что для разрешения конфликтов вы используете GitBash или любой другой интерфейс командной строки для Git. В целом, вы можете использовать любой другой инструмент с графическим интерфейсом.
Прежде чем приступать к работе над кодом, всегда извлекайте данные из удаленных репозиториев/других веток. Это позволит поддерживать вашу ветку в актуальном состоянии и уменьшит вероятность возникновения конфликтов.
Всегда синхронизируйте данные перед их отправкой, чтобы убедиться, что Git не отклонит ваш запрос.
Если вы не можете решить, какие изменения сохранить, а какие удалить, посоветуйтесь со своими коллегами/соразработчиками. Разбейтесь на пары, чтобы вам было проще разрешать любые сложные конфликты слияния.
Пока что это все. Я надеюсь, что вы узнали из этой статьи много нового, и она оказалась для вас полезной, а также помогла вам справиться с разрешением конфликтов слияния в Git.

Настроим VoIP-шлюз Eltex TAU-16.IP в качестве мини - АТС.Данное устройство нет смысла использовать как полноценную мини - АТС, так как в ней будут отсутствовать многие функции, но в некоторых случаях такой вариант тоже применим.
$dbName_ecom = "to-www_ecom";
$GoodID = "3152129363";
mysql_connect($hostname,$username,$password) OR DIE("Не могу создать соединение ");
mysql_select_db($dbName_ecom) or die(mysql_error());
$query_ecom = "SELECT `model`, `itemimage1`, `price`, `discount`, `url`, `preview115`, `vendor`, `vendorCode` FROM `items` WHERE itemid = '$GoodID';";
$res_ecom=mysql_query($query_ecom) or die(mysql_error());
$row_ecom = mysql_fetch_array($res_ecom);
echo 'Кстати, купить '.$row_ecom['vendor'].' '.$row_ecom['vendorCode'].' можно в нашем магазине Merion Shop по ссылке ниже. С настройкой поможем 🔧
Купить '.$row_ecom['model'].''.number_format(intval($row_ecom['price']) * (1 - (intval($row_ecom['discount'])) / 100), 0, ',', ' ').' ₽';
$dbName_ecom = "to-www_02";
$GoodID = "3152129363";
mysql_connect($hostname,$username,$password) OR DIE("Не могу создать соединение ");
mysql_select_db($dbName_ecom) or die(mysql_error());
Главным достоинством шлюза является поддержка SIP-транков и наличие аналоговых портов FXS одновременно. Обычно Вы можете приобрести более доступную аналоговую мини - АТС с таким же количеством аналоговых портов, но возможность подключения входящих SIP-линий отсутствует или предполагает дополнительные затраты на лицензии или дополнительное оборудования. Или же Вы можете приобрести VoIP АТС с поддержкой SIP-транков и телефонов из коробки, и так же значительно дешевле. Но чтобы подключить к ней аналоговые телефоны необходимо докупить VoIP шлюз(ы) с количеством портов, соответствующим количеству аппаратов.
В первую очередь следует настроить сеть. В самом простом случае, достаточно изменить адрес шлюза, который установлен по-умолчанию. Настройки выполняются в разделе "Сетевые настройки/Сеть":
Если же необходимо разделить сеть для голоса и для управления, следует настроить сети на вкладке "VLAN", указав адреса для каждой сети, а так же указать, по каким сетям будет передаваться голос, сигнальная информация и осуществляться управление (указывается внизу страницы).
Настройки выполняются в разделе "Сетевые настройки/VLAN":
Общий принцип настройки устройства в качестве АТС заключается в следующем: создается два SIP-профиля, один из которых отвечает за связь с внешним миром (с оператором VoIP), а второй за работу аналоговых портов. В первом профиле задаются настройки транка для связи с оператором адрес сервера, порт, данные для регистрации (если требуется), поддерживаемые кодеки и план нумерации, согласно которому устройство будет отправлять вызовы на этот транк. Второй профиль создается без регистрации и дает возможность совершать вызовы по коротким номерам внутри шлюза. План набора этого профиля указывает устройству, какие вызовы выполняются внутри шлюза, а какие следует направлять во внешний мир.
Итак, настройки профиля для связи с провайдером. Выполняются в разделе "PBX / Профили SIP/H323 / Профиль 1". Во вкладке "SIP настройки профиля":
Здесь указываются данные, которые предоставляет оператор связи. Основные данные адрес, куда должен обращаться шлюз для совершения вызовов. Если используется транк с регистрацией, необходимо включить эту функцию в поле 1, и указать данные для регистрации (логин/пароль) в полях 2 и 3. Остальные настройки можно оставить по-умолчанию.
Во вкладке "Кодеки" задаются используемые кодеки, а так же есть возможность задать настройки для передачи модема и факса. Эти данные так же обычно предоставляет оператор. В общем случае, у нас всегда должен работать кодек G.711a. Для успешного прохождения факсов обычно отключаем опцию "Передача модема", а в параметре "Основной кодек передачи факса" выбираем "Т38", резервный G.711a. Так же, с нашим оператором возникают проблемы с опциями "Эхокомпенсатор" и "Комфортный шум", поэтому их так же деактивируем.
Переходим ко вкладке "План набора". Настройки на этой вкладке позволяют совершать вызовы через сеть нашего оператора. Здесь указываем префиксы, набрав которые, абонент должен звонить через внешнюю сеть. В данном случае, удобнее использовать опцию "Табличный план набора":
Нажимаем кнопку "Добавить префикс":
Указываем префикс, минимальное количество цифр в набираемом номере. В поле "Протокол и направление" в нашем случае указываем "SIP-транк" (транк по ip-адресу без регистрации). Тип номера Subscriber (при звонках внутри оператора связи) или National (при звонках на сеть МГ). На самом деле, вероятнее всего, на стороне оператора этот параметр все равно будет корректироваться. В поле "ip-адрес" указывается адрес станции оператора, на который обращается шлюз для выполнения вызовов. Этот же адрес указывался в настройках SIP-профиля. В форме "Абонентские порты" можно указать, какие именно абоненты могут выполнять вызовы по этому правилу.
Переходим к настройке Профиля 2 (для локальных абонентов).
Собственно, вся настройка сводится к настройке Плана набора, в основных настройках все поля оставляем по-умолчанию.
Во вкладке "План набора" выбираем опцию "Строчный план набора" и вписываем следующую строчку:
1xx@192.168.130.58|x.@192.168.130.57
где:
1xx - нумерация, используемая для внутренних абонентов. В нашем случае, внутренние номера телефонов имеют вид 101,102, 103 и т.д.
192.168.130.58 локальный адрес нашего устройства. То есть, если внутренний абонент набирает номер вида 101, 102 и т.д., вызов осуществляется внутри устройства.
x.@192.168.130.57 - данная строчка означает, что все остальные вызовы будут направляться на адрес 192.168.130.57 (адрес оператора), то есть через транк.
Теперь настроим абонентские порты. Переходим на вкладку "PBX/Абонентские порты"
В этой вкладке задаем внутренние номера, а в поле "SIP/H323 профиль" указываем тот профиль, который настраивали для внутренней связи ( в нашем случае, Профиль 2).
После выполнения этих настроек исходящая связь уже должна работать. Остается настроить входящую связь.
Следует помнить, что при настройке параметров на каждой вкладке следует нажимать кнопку "Применить изменения". После выполнения всех настроек необходимо нажать кнопку "Сохранить". В противном случае, после перезагрузки устройства настройки будут утеряны. Эту особенность так же можно использовать в случае, когда что-то пошло не так и необходимо вернуть исходные настройки.
Перейдем к настройке входящих вызовов. Открываем вкладку "PBX/Группы вызова". Здесь нажимаем кнопку "Новая группа":
Имя группы любое, пароль пропускаем, телефонный номер внешний номер, на который совершается вызов и который будет обозначен как B-номер во входящем вызове. Тип группы: групповой звонят все телефоны в группе, серийный после таймаута начинает звонить следующий телефон, при этом предыдущий продолжает звонить, циклический вызов по очереди переходит на следующий в списке порт. "SIP-профиль" - профиль, на котором работают внутренние номера (в нашем случае, Профиль 2). Кнопку "В работе" необходимо включить.
После добавления группы вызова, ее нужно отредактировать:
Для редактирования необходимо нажать иконку в столбце "Изменить".
Здесь появилась новая вкладка "Порты", где можно добавлять или удалять порты, на которые будет поступать вызов и задавать очередность поступления вызова.
На этом настройка шлюза Eltex TAU-16.IP закончена. Настройки применимы на всех устройствах серии ELTEX TAU стоечного исполнения (16,32,36,72 порта). Версия ПО в данном случае - 2.18.0.35

Дружище! В этой статье мы пошагово разберем процесс установки и первичной настройки Kamailio SIP сервера. Установку будем производить на Ubuntu 18.04/16.04. Готов приблизиться к телефонии уровня энтерпрайз, построенной на open – source? :)
А что есть Kamailio?
Kamailio берет начало от SER/Open SER. Откровенно говоря, Kamailio это масштабируемая и гибкая SIP – платформа, созданная как для маленьких инсталляций, так и для больших проектов уровня сервис – провайдеров. Продукт написан на C и работает на Linux/Unix машинах. Kamailio используется в связке с медиа – сервером (RTP потоки и данные, например, Asterisk) и обеспечивает такие фичи как:
До 5000 вызовов в секунду;
Поддержка 300 000 абонентов (WOW!) при условии наличия всего 4ГБ оперативной памяти для сервера Kamailio!
Легкая кластеризация и добавление новых нод в существующих кластер;
Вообще, Kamailio может выполнять такие роли как:
Registrar server - точка для регистрации клиентов (UAC) ;
Location server - сервер определения местоположения. Сервер хранит адрес (сетевой) абонента и отдает его SIP – серверам по запросу;
Proxy server - роль посредника для дальнейшего проксирования этих запросов далее по цепочке SIP - серверов;
SIP Application server - он же SAS. Сервер приложений. Любых. Плечи в БД, API, XML и так далее – все здесь;
Redirect server - информация клиенту (UAC) о его маршруте. Условно говоря, перенаправляет SIP – потоки по нужному пути;
На этом прелести Kamailio не заканчиваются. Вот еще немного фич, на которые стоит обратить внимание:
Поддержка NAT –T (NAT traversal) для SIP и RTP трафика;
Балансировка нагрузки и отказоустойчивость с множеством сценариев/алгоритмов распределения трафика (на случай отказа);
Лёгкий механизм настрйоки правил маршрутизации;
Простота в реализации отказоустойчивой маршрутизации! Отвалился один маршрут – легко перенаправить трафик на другой;
Поддержка IPv4 и IPv6;
SCTP (Stream Control Transmission Protocol) с поддержкой многопоточности и так называемого multi – homing (синхронизация хостов по двум и более физическим каналам);
Коммуникация по протоколам UDP, TCP, TLS и SCTP;
Кодите на Java, Python, Lua, Perl? Ваши навыки точно пригодятся :)
Приступаем
Перед началом работ, у вас должны быть выполнены следующие требования:
У вас есть сервер, с установленной на него Ubuntu 18.04/16.04;
Вы установили MariaDB на этот сервер;
Вы добавили репозитории Kamailio;
Мы предполагаем, что 1 и 2 пункты вы выполнили :) Приступаем к третьему.
Добавляем репозиторий Kamailio
Если у вас установлена Ubuntu версии 16.04 вам нужно добавить репозиторий Kamailio, который будет использован при установке этой SIP – платформы.
Для начала скачиваем и добавляем GPG ключ:
wget -O- http://deb.kamailio.org/kamailiodebkey.gpg | sudo apt-key add -
После этого нужно добавить строки в файл /etc/apt/sources.list. Работать мы будем с версией 5.1 Kamailio:
$ sudo vim /etc/apt/sources.list.d/kamailio.list
Добавляем данные:
deb http://deb.kamailio.org/kamailio51 xenial main
deb-src http://deb.kamailio.org/kamailio51 xenial main
Установка Kamailio
Как только мы сконфигурировали репозитории, приступаем к установке самого продукта. В том числе, мы установим некоторые MySQL модули:
$ sudo apt install kamailio kamailio-mysql-modules
Установим так же модуль для web – сокетов:
$ sudo apt install kamailio-websocket-modules
Ждем. Как только процессы, рождаемые этими командами будут выполнены, мы можем проверить приложение kamailio и увидеть его версию командой kamailio -V:
$ which kamailio
/usr/sbin/kamailio
$ kamailio -V
version: kamailio 5.1.2 (x86_64/linux)
flags: STATS: Off, USE_TCP, USE_TLS, USE_SCTP, TLS_HOOKS, DISABLE_NAGLE, USE_MCAST, DNS_IP_HACK, SHM_MEM, SHM_MMAP, PKG_MALLOC, Q_MALLOC, F_MALLOC, TLSF_MALLOC, DBG_SR_MEMORY, USE_FUTEX, FAST_LOCK-ADAPTIVE_WAIT, USE_DNS_CACHE, USE_DNS_FAILOVER, USE_NAPTR, USE_DST_BLACKLIST, HAVE_RESOLV_RES
ADAPTIVE_WAIT_LOOPS=1024, MAX_RECV_BUFFER_SIZE 262144, MAX_LISTEN 16, MAX_URI_SIZE 1024, BUF_SIZE 65535, DEFAULT PKG_SIZE 8MB
poll method support: poll, epoll_lt, epoll_et, sigio_rt, select.
id: unknown
compiled with gcc 7.3.0
Огонь. После этого, правим файл /etc/kamailio/kamctlrc (откройте так же через vim) и проверяем, что параметр DBENGINE выставлен в значение MySQL.
Раскомментируйте значение DBENGINE=MYSQL, удалив # перед строчкой
Далее, создаем базу данных. Команда, указанная ниже, создаст пользователей и таблицы, необходимые для Kamailio:
$ kamdbctl create
INFO: creating database kamailio ...
INFO: granting privileges to database kamailio ...
INFO: creating standard tables into kamailio ...
INFO: Core Kamailio tables succesfully created.
Install presence related tables? (y/n): y
INFO: creating presence tables into kamailio ...
INFO: Presence tables succesfully created.
Install tables for imc cpl siptrace domainpolicy carrierroute
drouting userblacklist htable purple uac pipelimit mtree sca mohqueue
rtpproxy rtpengine? (y/n): y
INFO: creating extra tables into kamailio ...
INFO: Extra tables succesfully created.
Install tables for uid_auth_db uid_avp_db uid_domain uid_gflags
uid_uri_db? (y/n): y
INFO: creating uid tables into kamailio ...
INFO: UID tables succesfully created.
Во время инсталляции, вам нужно будет указать пароль для MySQL. Инсталлятор сделает следующих юзеров:
kamailio - с паролем kamailiorw. Этот юзер имеет права на чтение и запись в БД;
kamailioro - с паролем kamailioro. Этот юзер имеет права только на чтение;
Почти готово. Теперь слегка поправим конфигурационный файл Kamailio /etc/kamailio/kamailio.cfg. Настроим SIP – домен:
$ sudo vim /etc/kamailio/kamctlrc
## ваш SIP домен
SIP_DOMAIN=wiki.merionet.ru
В том же файле, включим некоторые нужные модули. Расположите следующий код в том же файле, прямо под строкой #!KAMAILIO:
#!define WITH_MYSQL
#!define WITH_AUTH
#!define WITH_USRLOCDB
#!define WITH_ACCDB
Включаем Kamailio!
$ sudo systemctl restart kamailio
Командой systemctl status kamailio можно проверить текущий статус Kamailio. Если что-либо не работает, лог – файл приложения можно найти в /var/log/kamailio.log.