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

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

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

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

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

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

Создание серверного репозитория
Этот шаг можно считать предварительным, описывается только для истории. Запустив SourceTree, находим и нажимаем кнопку [Терминал] или нажимаем клавиши Shift+Alt+t.
Вводим команду

1
git init --bare c:/Repositories/Server

Перед bare указывается двойной минус. Путь к “серверному” репозиторию указывается прямыми слешами, а не обратными, как мы привыкли в Windows. В случае использования абсолютного пути закон не меняется.
После выполнения команды вводим команду

1
exit

Окно терминала закроется.

Создание и настройка репозиториев для клиентов системы
Теперь внутри каталога c:\Repositories создаются несколько подкаталогов — Dev1, Dev2, Dev3 (репозитории для разработчиков), Test1 (для тестировщика) и User («пользовательский»). Внутри этих каталогов создаются раздельные репозитории, каждый из которых «привязывается» к серверному как к единственному внешнему. В реальной жизни, естественно, эти локальные репозитории будут находиться где угодно и в любом виде. Ниже приведена последовательность создания репозитория для разработчика (Dev1).

Нажимаем кнопку [Клонировать / Создать]
git_rep_client02 Выбрать [Создать новый репозиторий], установить тип — Git, целевой путь c:\Repositories\Dev1, указать имя Dev1, [Создавать закладку] — да.
После создания выполнить щелчок правой кнопкой мыши на столбце с “Состояния файлов” и выбрать “Добавить новое внешнее хранилище”
git_rep_client04 В диалоге нажать кнопку [Добавить]
git_rep_client05 В диалоге установить галочку [Внешний по умолчанию]; ввести (вручную) URL c:\Repositories\Dev1 и нажать ОК. Остальные поля оставить пустыми — никакой интеграции с интернет-репозиториями не планируется и не выполняется.

Аналогичным образом создаются репозитории для Dev2, Dev3, Test и User:
git_rep_client06

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

git_master01 Допустим, разработчик Dev1 создает текстовый файл Dev1master.txt с содержимым

1
Dev1 | master
git_master02 …и выполняет фиксацию внесенных изменений в своем репозитории
git_master03 При выполнении фиксации изменений (коммите) обязательно пишется комментарий и устанавливается галочка [Сразу отправить изменения в ...]

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

Теперь вид SourceTree для Dev1 выглядит таким образом:
git_master04
Обратите внимание, установлена галочка Показать внешние ветки, и в перечне изменений показывается origin/master и master. Первое – это название той ветки, с которой синхронизируется текущее состояние дел. Второе – имя ветки, с которой работает пользователь.

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

git_master05 Пользователь активирует свой SourceTree со своим репозиторием (например, это будет пользователь Test1) и нажимает кнопку [Получить]
git_master06 В диалоговом окне выбирается синхронизируемая ветка (в данном случае – master) и указывается, что после слияния выполнить фиксацию изменений

Теперь у пользователя Test1 вид окна SourceTree полностью аналогичен окну Dev1:
git_master07
Аналогичные действия выполняют все разработчики, синхронизируя свои репозитории с серверным. И у всех пользователей в каталоге репозитория появляется файл Dev1master.txt с содержимым

1
Dev1 | master

:
git_master08

Множество веток, их синхронизация и работа. Начало ветвления и процесс синхронизации
Теперь начинается то, с чем мы и столкнулись: ветвление процесса разработки.
Dev1 создает отдельную ветку Dev1Br#1 и в этой ветке создает отдельный файл Dev1br1.txt, а Dev3 – свою ветку Dev3Br#1 с файлом Dev3br1.txt. Создание ветки автоматически переводит соответствующего клиента на эту ветку. При фиксации изменений галочка “Сразу отправить изменения в…” установлена. В результате состояние дел у пользователей будет таким:

Имя пользователя Вид окна SourceTree
Dev1 br001
Dev3 br002
Остальные пользователи br003

Обращаем внимание на то, что установлена галочка “Показать внешние ветки”. Если она не будет установлена, вид немного упростится: будут показываться только те ветки и коммиты, которые существуют в текущем репозитории.

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

Подчеркну: и Dev1, и Dev3 успешно создали собственные ветки и “залили” их в серверный репозиторий. Теперь Dev1 решает, что пора бы и протестировать внесенные изменения. Он отправляет пользователю Test1 сообщение с указанием названия ветки, которую надо получить: Dev1Br#1. Каковы будут действия пользователя Test1?

br005 Пользователь Test1 активирует SourceTree и нажимает кнопку [Получить]
br006 В выпадающем списке выбрать нужную ветку – Dev1Br#1
br007 Результирующий вид окна SourceTree для пользователя Test1

Обратите особое внимание на несколько моментов:

  1. У пользователя Test1 до сих пор только одна его ветка – master:
    br008
    Импорт ветки Dev1Br#1 не изменил название локальной ветки, не создал новую ветку – ни-че-го! Изменения из внешней ветки origin\Dev1Br#1 просто были помещены поверх старого состояния репозитория
  2. Состояние репозитория в результате получения изменений из Dev1Br#1 стало таким:
    br009
  3. SourceTree (точнее, Git) считает, что ему есть что отправить в серверный репозиторий:
    br010
    Хотя, конечно, это не так. Просто обновилась локальная ветка master, и Git предполагает, что ее надо срочно синхронизировать с серверной. Ни в коем случае этого делать нельзя! Ветку master в серверном (общем) репозитории обновляют только разработчики (ну или специально обученные люди, обладающие достаточной квалификацией и правами).

Теперь Dev3 сообщает пользователю Test1, что у него тоже есть что “обновить”. Действия пользователя Test1 ничем не отличаются от уже описанных, только выбираемая ветка будет Dev3Br#1. Правда, результат будет совсем другим:
br011
А вот что будет твориться в репозитории с точки зрения файловой системы:
br012
Таким образом, получается, что Test1 “подхватил” новые файлы и из ветки Dev1Br#1, и из ветки Dev3Br#1. При этом сам пользователь Test1 находится на своей собственной ветке master. Фактически произошло слияние (merge) веток Dev1Br#1 и Dev3Br#1 в локальной ветке master пользователя Test1.

А теперь в игру вступает Dev2, про которого мы почти забыли – и вносит изменения в начальный файл Dev1master.txt, добавляя строку

1
Dev2 | master

и выполняет коммит без создания новой ветки: изменения настолько критичны, что касаются всех и сразу.
br013
Естественно, что Dev2 сообщает об изменениях всем причастным (каким образом – неважно) и в обязательном порядке называет имя ветки, которую надо обновлять. Каковы будут действия пользователей системы и как это отразится на состоянии из репозиториев?

Пойдем, пожалуй, по алфавиту: Dev1, Dev3, Test1, User. Пользовательский репозиторий затрагивается обязательно: изменения касаются все, еще раз повторюсь.

Рассмотрим последовательность действий пользователя Dev1:

br014 Пользователю не надо ничего отправлять в серверный репозиторий, поэтому он нажимает кнопку [Получить]
br015 Поскольку известно, что надо обновлять ветку master, в выпадающем списке выбираем именно ее. Для гарантии безошибочности работы настоятельно рекомендуется нажать кнопку [Обновить] Галочка “Выполнять фиксацию сразу после слияния” устанавливаем включенной
br016 Обратите внимание: обновление осуществляется в локальную ветку Dev1Br#1, как нам и требуется. Если в процессе работы пользователь “перескакивал” между ветками, то синхронизация будет выполняться с текущей.
br017 Таким образом будет выглядеть окно SourceTree. Обратите внимание: активирована ветка Dev1Br#1

А что же будет твориться в каталоге репозитория Dev1?
Во-первых, оба файла на месте:
br018
Во-вторых, проверим измененявшийся файл Dev1master.txt:

1
2
Dev1 | master
Dev2 | master

Отлично, сработало! Теперь такие же действия выполняет Dev3, Test1 и User, расписывать уже не буду – картина в результате будет полностью аналогична.

Множество веток, их синхронизация и работа. Завершение ветки, слияние
В общем и целом, сейчас ситуация, кажется, нормализовалась: у всех пользователей именно то, что необходимо, все синхронизировано и все работает. Проходит какое-то время, и выясняется, что ветка Dev1Br#1 (которую, если помните, создавал Dev1) стала не нужна. Ее надо удалить – так, чтобы она не мозолила глаза никому и нигде. Какие действия будет выполнять Dev1?

br019 В контекстном меню выбирается “Перейти на master”, либо двойной клик на имени локальной ветки, на которую планируется перейти
br020 Вызвать контекстное меню для ветки Dev1Br#1 и выбрать [Удалить Dev1Br#1]
br021 В диалоговом окне нажать ОК

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

Чтобы ветка во внешнем хранилище не мешалась, не помешает удалить и ее:
br022

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

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

Теперь возьмем пользователя Dev3: его ветка оказалась настолько удачной и нужной, что ее следует “внедрить” в рабочую (master). На данный момент SourceTree для Dev3 выглядит так:
br024

Предлагаю не усложнять (по крайней мере пока) задачу: считаем, что Dev3 вел всего одну ветку.

Dev3, во-первых, отправляет свои изменения ветки на внешнее хранилище (если этого еще не было сделано). Описывать уж не стану – выше это было рассмотрено достаточно подробно.
Далее – он получает ветку master с внешнего хранилища и активирует ее:
br102
Выполняет слияние своей ветки с master:
br103
И удаляет свою ветку.

Несколько советов самому себе
Советы пишу именно для себя, исходя из сегодняшнего понимания ситуации.

  1. Отработанные ветки крайне желательно удалять. Лишняя информация
  2. Имена веткам стоит задавать более-менее осмысленные: через полгода вспомнить, о чем была ветка “Ветка1634″ – нереально
  3. Из отслеживания крайне желательно убирать backup- и debug-файлы и каталоги (это отдельная песня, в качестве подсказки – гугл, gitignore)
  4. Использовать кнопку [Слияние] я бы не стал (по крайней мере пока): неочевидно, что с чем сливается и что станет в результате
Здесь не были рассмотрены варианты конфликтов и из разрешений - я не поднимал вопрос "а что будет, если два или несколько человек одновременно изменили один и тот же файл". Оставляю "на потом" - все равно придется расписывать ;)

Размещено в 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. Андрей пишет:

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

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


Я не робот.