# Конфликты

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

Предположим, вы и другой пользователь одновременно изменили файл `main.cpp` в 45 строчке. В истории это будет выглядеть так:

```bash

*(c)  * (mybranch:HEAD)
|     |
*     *
|     |
* - - *
|
* (trunk)

```

Здесь: 
**(c)** – изменения другого пользователя в файл `main.cpp`
**(mybranch:HEAD)** – ваши изменения в файл `main.cpp` в локальной ветке

Конфликт может обнаружиться двумя способами:

**Способ 1. При создании пулл-реквеста локальной ветки через `arc pr`.**

```bash

    о  <– о Каждый PR создается поверх изменений самого свежего trunk,
    -     | А только после этого заливается в Арканум. На этом этапе мы получаем конфликт, т.к. наши коммиты (с) конфликтуют.
(c) *     * (mybranch:HEAD) –> Создаем из этой позиции PR
    |     |
    *     *
    |     |
    * - - *
    |
    * (trunk)

```

В этом случае нужно обновить состояние локальной ветки из trunk.

**Способ 2. При обновлении состояния локальной ветки из trunk.**

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

```bash
(mybranch) $ arc pull trunk # Скачиваем свежие изменения в ветке trunk
(mybranch) $ arc rebase trunk # Пытаемся применить их в ветку mybranch
```

{% note tip "Important" %}

В Arc на текущий момент доступна только команда `rebase`. Это сделано для того, чтобы история в репозитории была максимально линейна, а разработка делалась поверх самых свежих изменений других команд в едином репозитории. Более подробно, о том, чем различаются модели разработки можно почитать по [ссылке](https://stxnext.com/blog/2018/02/28/escape-merge-hell-why-i-prefer-trunk-based-development-over-feature-branching-and-gitflow/)

```bash

    о
    |\
    о \
    |\ \
    о \ \ <––– (новая база локальной ветки mybranch ставится поверх свежего trunk)
    |\ \ \     каждый коммит делает rebase поверх свежего состояния trunk
    | \ \ \
    |  \ \ \
(с) *   \ \  * (mybranch:HEAD) –> Create PR
    |    \ \ |
    *     \  *
    |      \ |
    *  x-x-x  <––– * (старая база ветки удаляется)
    |
    * (trunk)

```

{% endnote %}

При обнаружении конфликта команда `rebase` сообщит, что обнаружен конфликт. Чтобы разрешить конфликт:

1. Откройте файл `main.cpp` в редакторе и отредактируйте его таким образом, чтобы файл содержал в себе изменения в trunk и в вашей локальной ветке. Конфликтующие строчки в файле всегда окружены маркерами конфликта (отдельная строка, содержащая символы `>>>>`). По окончании редактирования в коде не должно остаться таких маркеров.

2. Добавьте измененные вручную файлы в индекс:

    ```bash
    (rebase) $ arc add main.cpp
    ```

3. Продолжите выполнение `rebase`:

    ```bash
    (rebase) $ arc rebase --continue # Может опять произойти конфликт, который нужно разрешить
    ```

4. Команда `rebase` не изменяет исходные коммиты, а создает новые. Поэтому после успешного выполнения `rebase` нужно перезаписать историю в вашей ветке на сервере:

    ```bash
    (mybranch) $ arc push -f # Флаг -f (--force) перезаписывает изменения в удаленной ветке
    ```

{% note tip "Important" %}

Если вы в процессе разрешения конфликтов передумали делать `rebase` и хотите вернуться к состоянию до `rebase`, то выполните команду:

    (rebase) $ arc rebase --abort
    
{% endnote %}
