## Как писать диссертацию на GitHub?

* [Hint](#Hint)
* [Без обновления шаблона](#Без-обновления-шаблона)
* [С обновлением](#С-обновлением)
* [Если что-то пошло не так](#Если-что-то-пошло-не-так)
* [Синхронизация с upstream (для продвинутых пользователей)](#Синхронизация-с-upstream-для-продвинутых-пользователей)

### Hint

При использовании Git может оказаться полезным добавить нужные для пакета
[`gitinfo2`](https://www.ctan.org/pkg/gitinfo2) файлы в локальную копию `.git/hooks`, тогда в режиме черновика на каждой странице диссертации будет указываться используемая ревизия документа (короткий хэш коммита) и дата его внесения.

### Без обновления шаблона

Описанную ниже схему можно использовать для того, чтобы писать свою
диссертацию на GitHub используя шаблон
*Russian-Phd-LaTeX-Dissertation-Template*

0) Создаём учётную запись на GitHub.

1) Логинимся, жмём значок Fork на главной странице шаблона. После
этого шаблон появится в списке репозиториев уже вашей учётной
записи.

2) Открываем свою копию шаблона. Жмём кнопку Branch:master, в поле
«Find or create a branch» пишем имя для ветки репозитория под свой
диссер. У меня ([@kostyfisik](https://github.com/kostyfisik)) это «**disser-Ladutenko**». Если после нажатия на кнопку в
поле ввода вы видите надпись «Filter branches/tags» — вы в чужой копии
репозитория.

3) Дальше можно клонировать шаблон к себе на компьютер. Делать это
надо из **СВОЕЙ** копии шаблона!

4) Пишем диссер в своей ветке, радуемся возможностям системы контроля
версии, например можно утром посмотреть, а что именно ты менял по
тексту вчера в 3 часа ночи…

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

Продвинутый неленивый научник сделает вам pull request с
предлагаемыми изменениями. Хорошей идей может оказаться использовать
инструменты для code review и collaboration, существующие на GitHub. Перед тем как
вносить изменения уже в ветку со своими изменениями — создаёте ещё одну ветку,
а потом из неё делаете pull request в свою основную ветку дисера.
Ссылку на изменения в PR можно послать научнику, а он может прямо на
сайте добавлять комментарии именно по предлагаемым изменениям (т.е. он их сможет
просматривать инкрементально, а не по всему дисеру сразу). Можно заводить
личные issue (или их может добавлять научник), вроде «добавить картинку XXX»,
«изменить описание эффекта YYY» и т.д. Оптимизируйте ваш рабочий процесс,
сделайте его максимально эффективным!

### С обновлением

Остальные инструкции выполняются из командной строки в Linux, а для
Windows\Mac есть программы для работы с git… в которых тоже можно
выполнять указанные ниже команды! Нужны они для того, чтобы улучшения
в основном шаблоне можно было наложить поверх уже начатого дисера.

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

`git remote add upstream https://github.com/AndreyAkinshin/Russian-Phd-LaTeX-Dissertation-Template`

2) Теперь в любой момент можно обновить свою локальную копию и свою
копию на сайте GitHub следующим набором команд.

Переключаемся в master ветку: `git checkout master`

Синхронизируем локальную копию с своей копией на сайте: `git pull`

Получаем актуальные обновления: `git fetch upstream`

Смотрим что поменялось: `git diff upstream/master`

Сливаем изменения в свою локальную копию: `git merge upstream/master`

Отправляем их в свою копию на сайте: `git push`

3) Не сложно подтянуть обновления уже непосредственно в свой диссер. Для этого
(подставлено имя моей ветки диссера):

`git checkout disser-Ladutenko`

по желанию: `git diff master`

`git merge master`

Если изменения были не очень конфликтующие (кто-то подправил файлы
шаблона, которые вы и не трогали, например Readme или какие-то
внутренние опции) всё тоже пройдёт без дополнительных вопросов, а
состояние репозитория сразу перемотается вперёд через все новые коммиты
(fast-forward).

```bash
Updating 22ca047..112b54a
Fast-forward
 Dissertation/disstyles.tex                |  16 +++++++++-
 README.md                                 |   8 +++--
 Bibliography.md => Readme/Bibliography.md |   0
 Installation.md => Readme/Installation.md |   6 ++--
 Links.md => Readme/Links.md               |   0
 Readme/github.md                          | 163 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Synopsis/synstyles.tex                    |  19 ++++++++---
 Synopsis/title.tex                        |  77 ++++++++++++++++++++++-----------------------
 Synopsis/userstyles.tex                   |   1 +
 biblio/biblatex.tex                       |   8 ++---
 common/data.tex                           |  18 ++++++-----
 common/styles.tex                         |   6 ----
 synopsis.tex                              |  33 ++++++++++++++++++--
 13 files changed, 284 insertions(+), 71 deletions(-)
 rename Bibliography.md => Readme/Bibliography.md (100%)
 rename Installation.md => Readme/Installation.md (96%)
 rename Links.md => Readme/Links.md (100%)
 create mode 100644 Readme/github.md
```

4) В противном случае может потребоваться ручное разрешение конфликтов. Например,

```bash
$ git merge master
Auto-merging dissertation.tex
Auto-merging common/styles.tex
CONFLICT (content): Merge conflict in common/styles.tex
Auto-merging common/packages.tex
CONFLICT (content): Merge conflict in common/packages.tex
Auto-merging Dissertation/userstyles.tex
Auto-merging Dissertation/userpackages.tex
Auto-merging Dissertation/part3.tex
CONFLICT (content): Merge conflict in Dissertation/part3.tex
Auto-merging Dissertation/part2.tex
CONFLICT (content): Merge conflict in Dissertation/part2.tex
Auto-merging Dissertation/appendix.tex
CONFLICT (content): Merge conflict in Dissertation/appendix.tex
Automatic merge failed; fix conflicts and then commit the result.
```

Тогда надо каждый файл с конфликтом открыть и исправить конфликт вручную.

Для файлов `partX.tex` это, как правило, означает, что надо удалить строчку

``` tex
<<<<<<< HEAD
```
в начале файла, найти строчку
``` tex
=======
```
и удалить от неё до строчки
``` tex
>>>>>>> master
```

Чаще всего хочется оставить HEAD, но могут быть варианты. Например:

``` tex
<<<<<<< HEAD
%%% Макет страницы %%%
% Выставляем значения полей (ГОСТ 7.0.11-2011, 5.3.7)
\geometry{a4paper,top=2cm,bottom=2cm,left=2.5cm,right=1cm}

=======
>>>>>>> master
```

Описание к геометрии уехало в другой файл, так что его удаляем, а от master останется пустое место.

Ещё пример:

``` tex
<<<<<<< HEAD
%%% Интервалы %%%
\usepackage[onehalfspacing]{setspace} % Опция запуска пакета правит не только интервалы в обычном тексте, но и формульные
\usepackage{needspace}

%%% Разрывы страниц %%%
% \needspace{2\baselineskip} располагает две последующие строчки на
% одной странице. Тут используется, чтобы слово "задачи" и "положения"
% оказались на одной странице со списком из задач и положений
%\usepackage{needspace}
\makeatletter
\newcommand\mynobreakpar{\par\nobreak\@afterheading}
\makeatother

=======
>>>>>>> master
```

Объявления \usepackage переехали в другой файл, их тут удаляем, блок про разрыв страниц оставляем. Служебные

``` tex
<<<<<<< HEAD
=======
>>>>>>> master
```

разумеется, удаляем.

После того как все конфликты разрешены — не забудьте сделать финальный
коммит, который я обычно называю merge.

Собственно всё, ничего другого, чтобы поддерживать уже частично написанный диссер в соответствии с усилиями авторов шаблона достичь идеала не требуется.

### Если что-то пошло не так

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

### Синхронизация с upstream (для продвинутых пользователей)

Шаблон время от времени обновляется, и может возникнуть желание
добавить полезные изменения к себе в работу.
Однако делать это при помощи `merge` может быть проблематично.
Для таких случаев удобно использовать команду  `git rebase`.

Рассмотрим ситуацию -- вы начали писать свою работу после коммита номер 3 в ветке `master`.
После этого шаблон был обновлён в ветке `upstream`.
Эта ситуация проиллюстрирована на рисунке ниже.

```
+--------+     +--------+     +--------+     +--------+     +--------+
|commit 1+----->commit 2+----->commit 3+--+-->commit 4+----->commit 5|   upstream
+--------+     +--------+     +--------+  |  +--------+     +--------+
                                          |
                                          |
                                          |  +--------+     +--------+
                                          +-->commit 6+----->commit 7|   master*
                                             +--------+     +--------+
```

Для `merge` в данном случае наверняка понадобится разрешать множество конфликтов.
`git` предоставляет более лёгкий способ синхронизации изменений -- `rebase`.

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

```bash
git rebase upstream
```

После этого `git` применит Ваши изменения начиная с последнего коммита ветки `upstream`.
Результат этой операции будет выглядеть так:

```
                                                             upstream
+--------+     +--------+     +--------+     +--------+     +--------+     +---------+     +---------+
|commit 1+----->commit 2+----->commit 3+----->commit 4+----->commit 5+----->commit 6*+----->commit 7*|   master
+--------+     +--------+     +--------+     +--------+     +--------+     +---------+     +---------+
```

Такой подход вызовет минимальное количество конфликтов (если у веток только одно пересечение).

Минусом данного подхода является то, что `hash` всех коммитов ветки `master` будет изменён.
Следствием этого будет то, что ссылки на эти коммиты в issue tracker будут сломаны,
так что данный способ лучше **не использовать при наличии ссылок на коммиты в issue tracker**.

Кроме того, при загрузке изменений на сервер потребуется использовать *силу*:

```bash
git push --force origin master
```

А при последующей синхронизации на *другом* компьютере надо будет использовать:

```bash
git fetch origin
git reset --hard origin/master
```
