Вопрос или проблема
Проблема, которую я пытаюсь решить:
- Необходимо сбрасывать (тестовую) ветку на главную ветку раз в день.
- Это нужно, чтобы, когда люди выполняют pull, они оказывались в одном и том же состоянии.
Что я пробовал:
git reset --hard master
git push --force
Проблема с тем, что я пробовал:
- Когда люди выполняют pull ветки, git, как бы помогая, объединяет любые коммиты, которые у них есть в рабочей области, с входящей веткой, что обычно включает в себя всё, что было в ветке до принудительного пуша. Это нужно сбрасывать при выполнении pull.
Фон:
Ветка используется для тестирования в среде, где git flow, к сожалению, не вариант. Поэтому мы каждый день объединяем изменения без предварительного просмотра в тестовую ветку, запускаем тесты (что занимает 12 часов) на ночь и сбрасываем её на главную ветку на следующий день, чтобы повторить процесс с новыми изменениями/отзывами из тестов и т.д.
Вопрос:
Как мы можем сделать это таким образом, чтобы это было надежно и требовало минимального количества работы со стороны разработчиков? (обратите внимание, процесс фиксированный. Это явно не идеально, но это лучший вариант, поэтому я не ищу комментариев по этому поводу в этом посте).
Стандартные рабочие процессы Git не предназначены для переписывания истории. Обычно вы не должны переписывать историю для веток, которые были опубликованы в удаленном репозитории, над которыми могут работать другие коллеги. (А git reset переписывает историю)
Если вы хотите сделать это, вместо использования одной ветки, которая сбрасывается каждую неделю, рассмотрите возможность использования другого имени ветки для тестовой ветки каждую неделю. Например, testbranch_2024.40
для ветки 2024 года, недели 40, а затем создайте новую ветку на следующей неделе testbranch_2024.41
.
Это более ясно указывает на то, что это независимые ветки с разными историями коммитов. Это тот подход, который мы используем для создания веток релизов (которые, в некотором смысле, являются тестовыми ветками, где проводится дополнительное тестирование перед выпуском).
Если вы хотите обязательно сохранить ветку, вы просто не должны использовать git pull для получения изменений. git pull
означает “получить последние обновления из удаленного репозитория и объединить их с моей локальной веткой”. Если вы хотите отказаться от вашей локальной истории и принудительно обновить вашу локальную ветку, вам следует делать что-то вроде:
git fetch +testbranch:testbranch
testbranch:testbranch
называется refspec (см. страницы man git fetch). Это в основном означает “получить testbranch
из удаленного репозитория и использовать его для обновления моей локальной testbranch
. Знак +
означает разрешить принудительное обновление (т.е. обновление, не являющееся fast-forward (необходимо, поскольку вы оставляете коммиты из состояния прошлой недели позади)).
Ответ или решение
Как сбросить ветку и ее удаленную копию до состояния ветки master
Введение
Ваша задача заключается в том, чтобы ежедневно сбрасывать тестовую ветку в голову ветки master, чтобы гарантировать, что все разработчики имеют одинаковое состояние при выполнении pull. Важно понимать, что стандартные методы работы с Git не предназначены для переписывания истории, особенно на ветках, с которыми работают несколько участников. Однако есть пути решения вашей проблемы с минимальными неудобствами для команды.
Решение
Избегание использования git pull
Первое и самое важное, что следует помнить: команда git pull
автоматически выполняет fetch
и merge
, что приведет к слиянию локальных изменений с новыми изменениями из удаленной ветки. Это может привести к конфликтам и нежелательным результатам.
Вместо этого, для обновления вашей локальной ветки до состояния удаленной, воспользуйтесь следующими командами:
-
Сброс ветки на удаленный
master
:git checkout testing-branch git fetch origin git reset --hard origin/master
В этом случае вы перемещаете
HEAD
вашей локальной веткиtesting-branch
к последнему коммиту веткиmaster
на удаленном репозитории. -
Принудительно обновите удаленную ветку:
После того как вы сбросили локальную ветку, необходимо обновить удаленную. Для этого используйте команду:
git push --force
Это перезапишет удаленную ветку
testing-branch
, и все другие разработчики получат состояние веткиmaster
.
Альтернатива – Использование временных веток
Если ваша команда активно работает с веткой, и вы не хотите затруднять других разработчиков, то имеет смысл рассмотреть возможность создания новой временной ветки каждый день с новым именем. Например:
git checkout -b testing-branch-2024.40
git push origin testing-branch-2024.40
Таким образом, у вас будет отдельная ветка для каждого цикла тестирования, и разработчики смогут просто переключиться на нужную ветку, не опасаясь конфликтов.
Что делать разработчикам?
Для разработки и тестирования, после ежедневного сброса, разработчики должны использовать команду fetch
с обновлением локальной ветки:
git fetch origin
git checkout testing-branch
git reset --hard origin/testing-branch
Эта последовательность команд обеспечит, что локальная версия ветки testing-branch
будет синхронизирована с последней версией на удаленном репозитории.
Заключение
Хотя такая практика сброса ветки и перезаписи её истории может вызвать споры среди сторонников лучших практик Git, может оказаться, что это наилучший способ удовлетворить ваши требования с минимальными усилиями со стороны команды. Рассмотрение использования временных веток может также упростить работу и улучшить видимость текущих тестов. Не забывайте, что важно поддерживать.communication внутри команды, чтобы все были в курсе изменений.