Git, SourceTree, ветки и несколько пользователей.

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

Я отчетливо понимаю, что "тру-программеры", суровые линуксоиды, а также приверженцы "нормального Git" порвут меня как Тузик грелку... Но тем не менее.

Рассматриваются вопросы и подробности работы с Git на примере SourceTree. Для примера имитируется следующая ситуация:

  1. Над проектом работает 4 человека
  2. 3 человека — разработчики. Могут и постоянно вносят изменения в серверный репозиторий
  3. 1 человек — тестировщик. В серверный репозиторий изменения не вносит, только считывает
  4. Кроме всего прочего, существует еще один репозиторий ("пользовательский"), с которым (впоследствии) будут работать конечные пользователи. Синхронизацию этого репозитория с серверным выполняет любой из разработчиков
  5. Разработчики и тестировщики могут использовать любые ветки. Пользовательский репозиторий использует и синхронизирует только основную ветку — master

Для упрощения работы используется только физический компьютер. Все репозитории располагаются внутри каталога c:\Repositories

Создание серверного репозитория
Создание и настройка репозиториев для клиентов системы
На данный момент у всех "пользователей" системы есть свои собственные репозитории (пускай они сейчас пустые), приступаем к процессу разработки. Чтобы не усложнять ситуацию попусту, будем работать с текстовыми файлами - их и контролировать проще, и менять.
Ветка master
Множество веток, их синхронизация и работа. Начало ветвления и процесс синхронизации
Множество веток, их синхронизация и работа. Завершение ветки, слияние
Несколько советов самому себе
Здесь не были рассмотрены варианты конфликтов и из разрешений - я не поднимал вопрос "а что будет, если два или несколько человек одновременно изменили один и тот же файл". Оставляю "на потом" - все равно придется расписывать ;)

Размещено в CSV, git, Новости, Прочее ПО · Метки: , , ,



Комментарии

Есть 7 коммент. к “Git, SourceTree, ветки и несколько пользователей.”
  1. Кулик Алексей aka kpblc пишет:

    Исправил несколько опечаток.

  2. Андрей пишет:

    >Ветка master существует в любом репозитории и считается “главной”. Ее нельзя уничтожить, ее нельзя переименовывать.

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

    Переименование ветки:
    git branch -m

    Удаление ветки:
    git branch -d

    >…и выполняет фиксацию внесенных изменений в своем репозитории. При выполнении фиксации изменений (коммите) обязательно пишется комментарий и устанавливается галочка

    Я не понимаю тебя: ты дважды употребляешь слово "фиксация" но применительно к двум совершенно разным операциям: к добавлению изменений в staged area, а так же к последующему выполнению commit. Это "четыре совершенно разных человека".... Кстати, я вообще не вижу упоминания о staged area, которая является одним из ключевых понятий git. Вот хорошая картинка по теме: https://git-scm.com/book/en/v2/book/02-git-basics/images/lifecycle.png

    >Любой другой пользователь получает сообщение (как – неважно: по телефону, через почту и т.д.) о том, что в серверный репозиторий были внесены изменения.

    Имхо - лучше обезопасить себя от получения подобных SMS в 2 часа ночи. Гораздо целесообразней было бы выполнять git fetch --all тогда, когда разработчик сам захочет проверить состояние оригинального репозитория. Решать о том, когда именно выполнять git pull - ему так же виднее, чем повесить это на автоматизацию.

    >Просто обновилась локальная ветка master, и Git предполагает, что ее надо срочно синхронизировать с серверной. Ни в коем случае этого делать нельзя!

    Раз в год и палка стреляет. Т.о. у тестеровщика не должно быть прав для записи к обозначенному "серверному" репозиторию. имхо.

    >Имена веткам стоит задавать более-менее осмысленные: через полгода вспомнить, о чем была ветка “Ветка1634″ – нереально

    По хорошему ветка должна быть одна. Дополнительные ветки являются временными и в конце концов сливаются с основной, после чего удаляются. Имя ветки вроде "issue #123" вполно информативное - это ветка, исправляющая баг, зарегистрированная в багтрекере под указанным номером. Вряд ли дополнительные ветки будут жить долго, но информативные имена важны и для того, чтобы если ты вдруг выиграешь миллион евро и положишь болт на работу, то подхвативший упавшее знамя программист смог бы разобраться что к чему. Кстати, ключевые этапы разработки принято помечать тэгами через git tag. Затем тэги легко просматривать, фильтровать и т.п.

  3. Кулик Алексей aka kpblc пишет:

    Андрей, у меня стояла задача использовать консольный вариант в минимальном объеме. Поэтому, к сожалению, команды приходится отодвигать в сторону.
    В остальном спорить не стану - у тебя больше опыта по использованию систем контроля версий :) хотя master я бы не трогал в смысле переименования ;)

  4. Андрей пишет:

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

    >хотя master я бы не трогал в смысле переименования
    Согласен. Я показывал не то, как надо поступать с master, а то, что она не отличается от др. веток и переименовать/удалить её так же возможно.

    >у тебя больше опыта по использованию систем контроля версий
    Я этого не говорил. На данный момент я сам только изучаю Git по книжке и документации.

  5. Андрей пишет:

    > 3 человека — разработчики. Могут и постоянно вносят изменения в серверный репозиторий
    Фатальная ошибка: центральный репозиторий, доступный для редактирования всем разработчикам - это отстой. Хаос гарантирован. Лёша, если тебя реально интересует процесс организации взаимодействия и предоставлении различных уровней доступа (при использовании Git), то рекомендую прочесть эту главу: http://git-scm.com/book/en/v2/Distributed-Git-Distributed-Workflows

    > Разработчики и тестировщики могут использовать любые ветки. Пользовательский репозиторий использует и синхронизирует только основную ветку — master

    Этих фраз я вообще не понял... Тем более, что далее по тексту заметки ты используешь не только master, но и ветки Dev1Br#1, Dev3Br#1.

    > Ниже приведена последовательность создания репозитория для разработчика (Dev1).

    Ну, если уж ты зашёл в консоль для создания пустого серверного репозитория, то и свои Dev1..3, а так же test1 мог бы сразу там же создать (обрати внимение на то, как указаны пути):

    git init --bare /c/Repositories/Server
    git clone /c/Repositories/Server /c/Repositories/Dev1
    git clone /c/Repositories/Server /c/Repositories/Dev2
    git clone /c/Repositories/Server /c/Repositories/Dev3
    git clone /c/Repositories/Server /c/Repositories/Test1

    ну и затем открывать их в SourceTree. В итоге: меньше кликов мышки и получение результата быстрее.

    > Чтобы не усложнять ситуацию попусту, будем работать с текстовыми файлами – их и контролировать проще, и менять.

    Это не "чтобы не усложнять ситуацию", а единственный тип файлов, для которого может выполняться СЛИЯНИЕ. Для НЕ текстовых файлов выполняется ЗАМЕНА. Т.о. работать СОВМЕСТНО над НЕ текстовыми файлами не получится.

    > Ветка master существует в любом репозитории и считается “главной”. Ее нельзя уничтожить, ее нельзя переименовывать.

    Как я уже писал в предыдущем комменте - это не так. На всякий случай показываю пример того, как master можно переименовать или удалить:

    ================================================================================

    bushm@DESKTOP-ISD2NUH MINGW64 /d/sandbox/sample (master)
    $ git branch
    * master

    bushm@DESKTOP-ISD2NUH MINGW64 /d/sandbox/sample (master)
    $ git branch -m master basic

    bushm@DESKTOP-ISD2NUH MINGW64 /d/sandbox/sample (basic)
    $ git branch
    * basic

    bushm@DESKTOP-ISD2NUH MINGW64 /d/sandbox/sample (basic)
    $ git branch -m basic master

    bushm@DESKTOP-ISD2NUH MINGW64 /d/sandbox/sample (master)
    $ git branch
    * master

    bushm@DESKTOP-ISD2NUH MINGW64 /d/sandbox/sample (master)
    $ git checkout -b main
    Switched to a new branch 'main'

    bushm@DESKTOP-ISD2NUH MINGW64 /d/sandbox/sample (main)
    $ git branch
    * main
    master

    bushm@DESKTOP-ISD2NUH MINGW64 /d/sandbox/sample (main)
    $ git branch -d master
    Deleted branch master (was 4b74f49).

    bushm@DESKTOP-ISD2NUH MINGW64 /d/sandbox/sample (main)
    $ git branch
    * main

    bushm@DESKTOP-ISD2NUH MINGW64 /d/sandbox/sample (main)

    ================================================================================

    > При выполнении фиксации изменений (коммите) обязательно пишется комментарий и устанавливается галочка [Сразу отправить изменения в ...]

    "Сразу отправить изменения в ..." - плохой подход. Вспоминаем всё ту же ссылку которую я показал в начале этого коммента.

    > Если файл появился, был изменен или удален – система контроля версий в лучшем случае скажет автору, что “файл изменен”. Об этих изменениях ни один другой пользователь системы не узнает. Чтобы сообщить об этом, а заодно и предоставить обновленную версию файла (файлов), и надо выполнять фиксацию изменений (коммит).

    Нет, ты лепишь вместе два понятия: git commit и git push... Первая команда фиксирует изменения в твоём локальном репозитории, а вторая отправляет изменения на сервер. Лёша, выполнение первой операции без второй не достаточно для того, чтобы твои сокамерники увидели изменения (если они не подключены к твоему локальному репозиторию через git remote). Любой человек, имеющий доступ к репозиторию, может легко получить информацию обо всех изменениях как на уровне файловой системы, с пояснением о том, какой файл добавлен/изменён/удалён, так и полную информацию о том, что именно было изменено в каждом (или интересующем тебя) файле, т.е. просмотреть патч файла.

    > Другие пользователи выполняют операцию получения (push) – и у них появляется свежая версия файла.

    Неверно. Команда git push заливает изменения, а не скачивает их. "Другим пользователям" нужно либо выполнить git fetch дабы закачать себе обновления и иметь возможность потестить их, после чего могут принять решения о том, стоит ли выполнять слияние; либо сразу выполнить команду git pull, которая закачает изменения и тут же автоматом попытается выполнить слияние.

    > Любой другой пользователь получает сообщение (как – неважно: по телефону, через почту и т.д.) о том, что в серверный репозиторий были внесены изменения.

    Пользователь и сам может проверить состояние серверного репозитория (поскольку ты в него лепишь всё без разбору) и увидеть все изменения, выполненные с момента его последнего получения оттуда данных (при условии, что серверный репозиторий подключен к локальному посредством git remote, обычно по умолчанию ему назначается имя origin; посмотреть подключенные репозитории можно с помощью команды git remote -v):

    git remote show origin

    > В диалоговом окне выбирается синхронизируемая ветка (в данном случае – master) и указывается, что после слияния выполнить фиксацию изменений

    А если закачиваемый контент содержит чепуху? Лучше сначала потестить то, что скачал с удалённого репозитория и только убедившись, что изменённая версия работает корректно, заливать себе в локальный репозиторий и затем, при желании, выполнять слияние. Результатом слияния будет новый коммит.

    > Dev1 создает отдельную ветку Dev1Br#1

    Не самое информативное имя. Имхо - имя ветки должно отображать смысл того, ради чего она создана.

    > При фиксации изменений галочка “Сразу отправить изменения в…” установлена.

    Как я уже писал выше, сразу всё отправлять в центральный репозиторий - очень плохое решение.

    > Он отправляет пользователю Test1 сообщение с указанием названия ветки, которую надо получить: Dev1Br#1.

    Насколько я знаю, "получает" Test1 по любому полную версию сетевого репозитория а не только ветку Dev1Br#1, т.к. git fetch качает не какую-то отдельную ветку, но весь репозиторий в целом.

    > У пользователя Test1 до сих пор только одна его ветка – master:

    Всё правильно. А ты ожидал другого? :)

    > Импорт ветки Dev1Br#1 не изменил название локальной ветки, не создал новую ветку – ни-че-го!

    Ты так удивляешься... :))))) С какого перепугу ты ожидал получить изменения в локальной? На скрине у тебя показано, что локальная ветка master отстаёт от ветки origin\Dev1Br#1 на один коммит. Решение о переименовании или слиянии принимает юзер. Ты пока не давал ни одной из этих команд.

    > Импорт ветки Dev1Br#1 не изменил название локальной ветки, не создал новую
    > ветку – ни-че-го! Изменения из внешней ветки origin\Dev1Br#1 просто были
    > помещены поверх старого состояния репозитория
    > Состояние репозитория в результате получения изменений из Dev1Br#1 стало таким:

    Маленький ликбез: у тебя произошло переключение на на ветку origin\Dev1Br#1 - это НЕ ЛОКАЛЬНАЯ ветка. Переключение на ветку автоматом заменяет содержимое рабочего дерева (working tree), т.е. содержимое каталога, который ты смотришь на скрине. В этот момент у тебя HEAD указывает на последний коммит ветки origin\Dev1Br#1. Так что ничего удивительного не произошло.

    > SourceTree (точнее, Git) считает, что ему есть что отправить в серверный репозиторий:

    Я не знаю, чего там "считает" SourceTree, но возможно ты не верно интерпретируешь то, что видишь на показанном скрине.

    > Хотя, конечно, это не так. Просто обновилась ЛОКАЛЬНАЯ ветка master, и Git предполагает, что ее надо срочно синхронизировать с серверной.

    Нет, ЛОКАЛЬНАЯ ветка master не обновилась. Как я уже писал выше, произошло ПЕРЕКЛЮЧЕНИЕ на ветку origin\Dev1Br#1 (т.е. HEAD указывает теперь на origin\Dev1Br#1).

    > Ни в коем случае этого делать нельзя! Ветку master в серверном (общем) репозитории обновляют только разработчики

    А нефиг кому попало раздавать права для записи в центральный репозиторий! Настрой ACL для каталога так, чтобы тестер имел права только на чтение. Конкретно В ДАННОМ случае ничего не случится страшного даже если юзер нажмёт кнопку записи на сервер - он просто не сможет залить что-либо на сервер до тех пор, пока предварительно не синхронизируется с текущим состоянием сервера. На данный момент его локальный репозиторий отличается от серверного.

    > Таким образом, получается, что Test1 “подхватил” новые файлы и из ветки Dev1Br#1, и из ветки Dev3Br#1. При этом сам пользователь Test1 находится на своей собственной ветке master. Фактически произошло слияние (merge) веток Dev1Br#1 и Dev3Br#1 в локальной ветке master пользователя Test1.

    Маленькая поправочка: не "Test1 "подхватил"", а ты своими шаловливыми пальчиками натворил чего не следовало... :) Согласно содержимому каталога, которое ты показываеш на скрине, очень пхоже на то, что ты действительно выполнил слияние. Вот только вопрос: ЗАЧЕМ??? Я очень сомневаюсь что Test1 хотел именно этого...

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

    Ничего не нормализовалось: у test1 в ветке каша,как мы помним и проскакивать этот момент не следует... Все дальнейшие перечисленные шаги повествуют о том, как делать НЕ НАДО. Вспоминаем всю ту же ссылку, приведённую мною в начале комментария.

    Давай вернёмся к тому моменту, когда test1 получил кашу: слияние трёх веток вместо того, чтобы иметь возможность протестировать каждую в отдельности. Рассмотрим это более подробно, дабы показать что ты по факту сделал и что же нужно было сделать на самом деле... Сделаем так: я оформлю это в виде подробно комментированного sh-скрипта, который следует запускать в Git Bash. Скрипт выложил у себя в блоге, т.к. в комментах данной заметки это будет нечитабельно. Ссылка на скрипт: http://bushman-andrey.blogspot.ru/2015/09/blog-post.html#more

  6. Андрей пишет:

    > Разработчики и тестировщики могут использовать любые ветки. Пользовательский репозиторий использует и синхронизирует только основную ветку — master

    Всё, до меня дошла эта фраза. :)

  7. Андрей пишет:

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

Поделитесь своим мнением


Я не робот.