На базе Wine-tests не сложно написать скрипт, автоматически обновляющий репозитории eterwine и eterhack. Предполагаемое поведение для eterwine: 1) git pull origin 2) git checkout pure 3) обновить из winehq 4) git checkout master 5) merge pure // вместо 3,4,5 может лучше делать git pull winehq находясь в master. 6)При возникновении ошибки завершится и послать письмо маинтейнеру для ручного обновления 7) запустить сборку 8) Проверить результат сборки и известить майнтейнера 9) Опубликовать репозиторий // публиковать репозиторий или нет, если он смержился, но сборка не прошла? Дальнейшее развитие: Можно попробовать решать простые конфликты. Для этого: 1) При мерже сохраняем список конфликтных файлов 2) пробегаем все конфликтные файлы и смотрим конфликтующие патчи 3) выбираем оттуда только наши (возможно поиск по *.@etersoft.ru) // а если это патч уже принятый в pure? 4) Сортируем конфликтные патчи по дате 5) Откатываем (самые новые вначале) 6) Если все патчи откатились, то можно мержить снова. Конфликтов не должно быть. При этом рассылаем письма авторам патчей с просьбой их переделать. (Баги переоткрывают пусть сами). Если какие-то патчи не откатились, то скрипт уже ничего сделать не может, отправляем письмо майнтейнеру, пускай мержит вручную.
для начала предлагаю разобраться с eterwine. Его мержить проще, т.к можно мержиться с произвольным коммитом из pure.
для начала упростил порядок задания репозиториев. Теперь репозитории описываются не кучей глобальных переменных, а структурами.
Создал скрипт. Добавил разбор параметров командной строки
Столкнулся с небольшой проблемой: у репозиториев eterwine и eterhack разные способы обновления: в eterwine обновляется сначала локальная ветка, а затем уже из неё мержится master. В eterhack мержится сразу из удалённого репозитория. Было принято решение больше не сопровождать ветку pure в репозитории eterwine. Тогда будет единый механизм обновления eterwine и eterhack
Начал реализацию мержа с определённым коммитом
> Начал реализацию мержа с определённым коммитом Закончил реализацию. Работает. Добавил откат на предыдущее состояние, если сборка после мержа не удалась. Проверить работу отката пока не получится: нужен коммит ломающий сборку. Осталось ещё добавить публикацию репозитория, и откат на предыдущее состояние при неудачной публикации
> Осталось ещё добавить публикацию репозитория, и откат на предыдущее состояние > при неудачной публикации Реализовал, осталось проверить
> Реализовал, осталось проверить Проверил. Исправил ошибки. Работает
Появилась проблема: при возникновении конфликтов репозиторий не откатывается к предыдущему состоянию.
(В ответ на comment #9) > Появилась проблема: при возникновении конфликтов репозиторий не откатывается к > предыдущему состоянию. Исправил
Встретил проблему: не мержится при конфликте в configure. Думаю этот случай легко исправить.
Сейчас мерж делается напрямую. При этом сложно получить подробный результат мержа (конфликтующие файлы). Думаю надо попробовать осуществлять мерж с помощью комманд модуля git-python
Встретил новую проблему: не прикладывается лог если сборка не удалась. На почту приходит только сообщение о том, что мерж провалился, но ни слово не сказано про сборку вайн. В логах: [16:40:06]DEBUG wine_merge_task: Running merge task [16:40:06]DEBUG wine_merge_task: Merging with commit 250448d7430c2880a2c399a816df7c1db099a756 [16:40:06]DEBUG wine_repository: Run wine-build script [16:40:21]ERROR wine_repository: Wine build failed. Logfile attached. [16:40:21]ERROR wine_repository: Can't attach the log file. _mail_report variable is unitialized for this class [16:40:21]ERROR wine_repository: Cant't build wine. The current version is broken! [16:40:21]ERROR wine_merge_task: Merge with commit 250448d7430c2880a2c399a816df7c1db099a756 failed
Исправил. Теперь отправляется письмо с логом.
(В ответ на comment #12) > Сейчас мерж делается напрямую. При этом сложно получить подробный результат > мержа (конфликтующие файлы). Думаю надо попробовать осуществлять мерж с помощью > комманд модуля git-python Попытался делать мерж с использованием функций модуля git-python. Пока не получается. при выполнении git pull возникает исключение внутри модуля git-python: Unhandled exception: Traceback (most recent call last): File "./maintain_repo.py", line 70, in <module> result = repo.merge_with_commit(commit_id) File "/srv/vitperov/Projects/tests/git_repository.py", line 185, in merge_with_commit pull_result = remote.pull(rem_branch) File "/usr/lib/python2.6/site-packages/git/remote.py", line 674, in pull return self._get_fetch_info_from_stderr(proc, progress or RemoteProgress()) File "/usr/lib/python2.6/site-packages/git/remote.py", line 610, in _get_fetch_info_from_stderr assert len(fetch_info_lines) == len(fetch_head_info) AssertionError
взял свежий git-python. В нём бага не возникает. Но пока не понятно как парсить результаты git_pull.
После неудачного мержа комманда self.is_dirty() возвращает True. Но пока непонятно как вытащить конфликтные файлы. Пробовал смотреть в self.head.commit.stats.files - список файлов после мержа не изменяется
Возникшие конфликты можно посмотреть при помощи self.git.diff(). Только хорошо бы ещё понять как получить всё это не одним куском текста, а разбить на файлы
Имена файлов можно получить при помощи: stats = Stats._list_from_string(self, diff)
Переделал. Теперь мерж происходит с помощью комманд модуля git-python. Результат доступен как в виде списка конфликтных файлов, так и в виде строки с diff'ом этих файлов. Осталось проверить систему локально, а затем под builder-robot.
Проверил локально при наличии конфликта. Работает.
Попробовал смержить репозиторий вручную - всё работает. Оказывается возвращаемые имена файлов относятся к файлам, которые гит смержил автоматически.
Разобрался. Тут возникает несколько проблем: 1) self.is_dirty() возвращает true при наличии файлов, которые смержились автоматически. Следовательно использовать его нельзя, нужно проверять результат мержа другим способом. Можно пропробовать получать список изменений через self.git.diff без numstat=True. Тогда он должен быть пустой строкой при отсутствии конфликтов. 2) self.git.diff(numstat=True) возвращает даже те файлы, в которых конфликта не было. Возможно придётся использовать его без numstat=True. Но в этом случае не будет информации об изменённых файлах и придётся парсить строку с изменениями вручную. Можно ещё попробовать для каждого файла запускать git annotate, и искать строчки с конфликтом. Если их нет, то считать, что конфликта в файле нет, и он смержился автоматически
> 2) self.git.diff(numstat=True) возвращает даже те файлы, в которых конфликта не > было. Возможно придётся использовать его без numstat=True. Но в этом случае не > будет информации об изменённых файлах и придётся парсить строку с изменениями > вручную. > Можно ещё попробовать для каждого файла запускать git annotate, и искать > строчки с конфликтом. Если их нет, то считать, что конфликта в файле нет, и он > смержился автоматически Проверил. diff показывает конфликты во всех файлах, и автоматически их не исправляет. Возможно есть какой-то атрибут при выполнении git.pull
Есть методы from_tree и merge_tree. Про merge_tree в документации почти ничего не сказано, про from_tree есть упоминание, что этот метод может разрешать конфликты, но пока не совсем понятно как этим пользоваться
Отложил пока автоматическое разрешение конфликтов. Начала реализацию автоматического обновления до апстрима.
Добавил вывод дополнительной информации при мерже с определённым коммитом.
Реализовал мерж при отправке письма. Для этого надо отправить письмо с заголовком [merge_task].... И названием текущего репозитория в первой строке.
Реализовал обновление при помощи отдельного скрипта maintain_repo.py. Обновление работает, только посылка писем майнтейнеру пока не работает
Исправил отправку писем. Обновил конфигурацию для builder-robot@builder Добавил скрипт в автозагрузку в 00:00. Заметил новую проблему: Если репозиторий не требует обновления, то всё-равно мерж считается успешным, и письмо отправляется.
> Заметил новую проблему: Если репозиторий не требует обновления, то всё-равно > мерж считается успешным, и письмо отправляется. Исправил
Исправил работу скрипта ./maintain_repo для мержа с отдельными коммитами. Следующий шаг - добиться, чтобы в этом режиме выводилась информация о конфликтных файлах (сейчас она выводится только при мерже с апстримом.
> Следующий шаг - добиться, чтобы в этом режиме выводилась информация о > конфликтных файлах (сейчас она выводится только при мерже с апстримом. Сделано
начал реализацию разбора полученного git diff.
Достаточно сложно воспроизвести конфликты при мерже. Если откатывать локальный реопозиторий, а потом мержиться с ближайшим коммитом из апстрима, то мерж не проходит, git говорит, что уже всё смержено. Единственный способ воспроизвести конфликты - это откатить локальный репозиторий, и смержиться с верхним коммитом апстрима, ито при условии, что мержа с этим коммитом ещё не было.
(В ответ на comment #35) > Единственный способ воспроизвести конфликты - это откатить локальный > репозиторий, и смержиться с верхним коммитом апстрима, ито при условии, что > мержа с этим коммитом ещё не было. Нет, так тоже не проходит. Спокойно мержит, но не может опубликовать
Создал новую ветку в репозитории. В ней мерж с конфликтным коммитом работает. В итоге результат конфликтного мержа выглядит следующим образом: 0 0 configure 103 94 configure 0 0 configure.ac 63 58 configure.ac
Написал код, получающий список файлов с конфликтами из git-diff
Реализовал автоматическое устранение конфликтов в файле configre. Само устранение конфликтов работает, сборка wine после этого проходит успешно. Но почему-то id верхнего коммита не изменяется, и письмо с результатом не отправляется.
Забыл выполнять git-commit. Исправил. Сейчас возникла проблема с заданием сообщения коммита.
Встретил дополнительную проблему: При мерже с апстримом в дереве не показываются промежуточные коммиты, виден только тот коммит, с которым осуществляется мерж. Нужно попробовать мержиться с апстримом с указанием конкретного id коммита.
(В ответ на comment #41) > Встретил дополнительную проблему: > При мерже с апстримом в дереве не показываются промежуточные коммиты, виден > только тот коммит, с которым осуществляется мерж. > Нужно попробовать мержиться с апстримом с указанием конкретного id коммита. Оказалось, что в исходном репозитории промежуточных коммитов нет. В последний день был только один коммит.
Проверил. Проблемы в configure успешно исправляются. Wine после этого успешно собирается, репозиторий публикуется. Думаю, что багу можно закрывать. Для расширения функциональности (разрешения более сложных конфликтов) создал отдельные баги 7537 и 7538.