
Существует прекрасная общепринятая схема работы с контролем версий — у каждого разработчика своя копия проекта, коммиты в ветки, мерж, test‑сервер, pre‑prod, CI/CD.
Для больших проектов все отлично и автоматизировано. Нет никаких сомнений что так и должно быть, НО...
Есть мелкие проекты — какой‑нибудь сайт, где раз в пару месяцев надо внести небольшие правки и заказчик при этом каждый раз нанимает разных фрилансеров.
Естественно невозможно заставить фрилансера ради задачи на 2 часа поднимать у себя копию проекта и настраивать окружение (особенно если сайт не простой, например идет с коробочной CRM, гигантской БД и еще пачкой инфраструктурных решений в придачу).
И даже сделать фрилансеру отдельную копию проекта на сервере, а потом чистить ее, или следить за актуальностью ради мелкой задачи не имеет смысла.
Единственный вариант — это дать фрилансеру доступ к общей тестовой копии проекта на которой уже параллельно может работать другой фрилансер над другой 2х часовой задачей.
Организовать работу так чтобы они не пересекались в коде и не правили файлы друг друга — это можно сделать плюс‑минус вручную. Но дальше встает вопрос — как работать с контролем версий?
Поясню — фрилансер работает в IDE, но заливает измененные файлы сразу на тестовый сервер потому что ему нужно видеть прогресс в реальном времени «внес правку — посмотрел что вышло, внес дальше».
И вот он закончил задачу. Пришло время сделать коммит. Есть 2 пути:
1. Он может зайти на тестовый сервер по ssh и сделать коммит из консоли добавив только те файлы которые он менял (потому что с сервером работают параллельно другие и общее кол‑во незакомиченных измененных файлов больше).
Но если файлов много, то это довольно неудобно — надо вспоминать что именно ты менял и еще не ошибиться чтобы не закоммитить чужой скрипт.
2. Поэтому удобно сделать коммит с локалки из IDE. Там уже автоматом собираются только те файлы которые менял ты. Возникает вопрос что делать с тестовым сервером?
Можно было бы оставить его вообще без гита, но тут есть неудобства
— хотелось бы видеть в каких файлах продолжается работа и самое главное в чем именно тестовый отличается от гита (боевого)
— встречаются еще более странные случаи когда правку в какие‑нибудь «параметры компонента» или конфиг может внести вообще даже не программист а кто‑то типа админа сразу на сервере без IDE и тогда ему хорошо бы сделать коммит сразу из консоли сервера (хоть так).
И тут мы приходим к ситуации при которой у нас есть
— гит на тестовом сервере
— коммит в гите в удаленном репозитории (сделанный с локалки)
— измененные скрипты залитые напрямую на сервер (которые соответствуют коммиту)
— измененные скрипты по другим задачам в работе которые пока не надо коммитить
И очень хочется сделать git pull, но git, зараза, ругается что файлы на сервере изменены. Git сравнивает содержимое файла с тем, что записано в индексе и не понимает что измененные на сервере файлы на самом деле идентичны коммиту из удаленного репозитория.

Приходится откатывать все файлы которые есть в коммите и потом делать git pull. Это требует пачки ручных манипуляций (собрать список файлов для отката и так далее) и осложняется дополнительными кейсами когда например файла вообще не было ранее и в последнем коммите в гите он только добавился. Тогда откат (git checkout) не сработает и надо такие файлы удалять перед коммитом.
А еще хорошо бы сразу увидеть нет ли случайно локальных коммитов на сервере не выгруженных в удаленный репозиторий или еще подобной ерунды.
В итоге мы придумали решение — сделать bash скрипт «gitPullForce.sh» который собственно
— определяет какие файлы в невыгруженных коммитах удаленного репозитория отличаются от файлов на сервере.
— сделает checkout тем которым нужен checkout, удалит те которые нужно удалить, заодно проверит нет ли прочих расхождений между сервером и удаленным репозиторием (кол‑во невыгруженных коммитов их даты и все что может вызвать подозрение на дополнительные сложности)
— и в конце собственно сделает git pull чтобы все файлы из последних коммитов удаленного репозитория привелись в соответствие с ним но ПРИ ЭТОМ чтобы другие измененные файлы на сервере которые пока что незакомиченны остались нетронутыми.
Схема работы получается простой — закончил задачу на сервере, сделал коммит с локалки, вызывал одну команду на сервере и у тебя прошел корректный git pull именно по твоей задаче.

🔗 Скрипт
После загрузки на сервер выставляем ему права на выполнение:
chmod +x gitForcePull.sh
Вызываем скрипт из категории где у вас инициализирован git (сам скрипт может располагаться в другом месте).
Можно сначала вызвать его с параметром -check чтобы он просто сообщил что собирается делать.

Вопрос: сталкиваетесь ли вы с такой проблемой? (счастливчиков которые стабильно работают на одном проекте без постоянного жонглирования случайными фрилансерами прошу не кидать помидоры. Просто радуйтесь что у все хорошо :))
























