LINUX.ORG.RU

Отправить патч через Git без изменений файлов

 , ,


0

2

Есть проект куда патчи принимаются только через Git, проект на Gerrit. Возможно ли отправить патч не изменяя локальные файлы? Изменение локальных файлов ломает инкрементальную сборку, сборка с нуля занимает примерно 2 часа а инкрементальная сборка 1-2 минуты. Делать копию исходников не вариант, исходники занимают несколько гигабайт и уже используется sparse checkout. Проект использует линейную историю без веток, все патчи rebase’ятся. Отправлять текущую ветку напрямую нельзя, т.к. там есть коммиты, которые не надо отправлять.

Сейчас делается как-то так:

git checkout publish
git reset --hard origin/master
git am <patch list>
git push origin HEAD:refs/for/master
git checkout master

Ответ на: комментарий от trex6

Оно?

Я не вижу как оно позволяет применить патч без изменения файлов (изменяя только содержимое «.git»). Интересно как сам Gerrit умеет это делать, вряд ли там много копий деревьев исходников.

X512 ()
Ответ на: комментарий от X512

применить патч без изменения файлов (изменяя только содержимое «.git»)

Git работает наоборот: index изменяется в соответствии с состоянием файлов. А то что ты хочешь делается через создание нового бранча и коммит в него (принятие патча через мерж).

mord0d ★★★★ ()
Ответ на: комментарий от mord0d

А то что ты хочешь делается через создание нового бранча и коммит в него

Как это сделать без изменения файлов исходников и сброса инкрементальной сборки? Есть набор *.patch файлов и их надо отправить в git push.

X512 ()

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

Нафигачь хардлинков или CoW примени.

t184256 ★★★★★ ()
Ответ на: комментарий от X512

Ты что, хочешь "не заменить но пропатчить" файлы в работающем CI/CD?! о_О Я что-то не понимаю твою ситуацию. Либо ты что-то делаешь не так, либо ты не умеешь объяснять. И лучше (для тебя) бы второе.

mord0d ★★★★ ()
Ответ на: комментарий от grem

Каким образом не изменяя файлы ты планируешь создать патч?

С помощью git format-patch в рабочей ветке. Ветка содержит коммиты, которые не надо отсылать (косметические изменения для личных целей, отладочный вывод, недоделанные и прототипные изменения и т.д.).

Если он уже есть - отправь по почте.

По почте не принимают, принимают только git push.

X512 ()
Последнее исправление: X512 (всего исправлений: 1)
Ответ на: комментарий от X512

У тебя есть доступ в их репу? Если нет, то как ты его будешь push к ним?

Сделай отдельную ветку на основе непропатченных изменений и cherry-pick туда нужного коммита. Оттуда делай push

По почте не принимают

Они тебе явно это сказали?

grem ★★★★★ ()
Последнее исправление: grem (всего исправлений: 1)
Ответ на: комментарий от grem

Если нет, то как ты его будешь push к ним?

Через Gerrit: git push origin HEAD:refs/for/master.

Они тебе явно это сказали?

Все изменения не от владельцев проекта должны проходить через Gerrit code review.

X512 ()
Ответ на: комментарий от grem

Сделай отдельную ветку на основе непропатченных изменений и cherry-pick туда нужного коммита. Оттуда делай push

Это можно сделать без checkout на эту ветку и перезаписи локальных файлов?

X512 ()
Ответ на: комментарий от X512

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

Если так нужно не изменять файлы в локальном дереве в основной ветке, то создаёшь бранч, накладываешь туда патч, и пушишь на удалённую машину с мержем, а потом обратно переключаешь бранч.

mord0d ★★★★ ()
Ответ на: комментарий от X512

Пересобирать придётся заново.

На локальной машине? А CI/CD вам нафига, в который ты запушить хочешь?

И timestamp файлов оказывается перезаписан.

Только тех файлов, на которые будут наложены патчи. Дерево же не полностью пересобирается из индекса, иначе это было бы очень медленно.

mord0d ★★★★ ()
Последнее исправление: mord0d (всего исправлений: 1)

Изменение локальных файлов ломает инкрементальную сборку, сборка с нуля занимает примерно 2 часа а инкрементальная сборка 1-2 минуты.

Пришла пора установить ccache.

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

Если пользуешься btrfs, можно скопировать через cp --reflink=auto. Тогда много места копия не займёт.

Можно ещё попробовать наложить изменяемый слой через overlayfs, и работать с ним. Тогда оригинал останется нетронутым.

i-rinat ★★★★★ ()
Последнее исправление: i-rinat (всего исправлений: 1)
Ответ на: комментарий от mord0d

А CI/CD вам нафига, в который ты запушить хочешь?

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

X512 ()
Последнее исправление: X512 (всего исправлений: 2)
Ответ на: комментарий от X512

С момента создания темы прошло уже больше трёх часов, а значит уже раза два можно было заново собрать. Видимо, это не разовая операция, а регулярное занятие? Тогда инвестируй время в переезд на copy-on-write файловую систему вроде btrfs. Сжатие и дедупликация сэкономят тебе достаточно много места, если уж апгрейд накопителя не обсуждается.

i-rinat ★★★★★ ()
Ответ на: комментарий от X512

3.14-здец…

владельцы проекта не настроили или на него нет денег

И ты занимаешься этим на голом энтузиазме? Раз решили сэкономить (временем или деньгами), то пусть страдают!

mord0d ★★★★ ()

Иными словами стоит задача закомитить в bare репозиторий. Насколько я знаю так нельзя, git не умеет, ему нужен рабочий каталог.

Хотя ятеоретически это более чем возможно, надо просто проделать всё в памяти и обновить объекты. Может быть libgit2 даже такое позволяет, надо смотреть API. Но готовых утилит я не знаю.

Я бы просто сделал копию, .git при локальном клоне будет жёсткими ссылками по большей части, а рабочий каталог можно и скопировать. Работал с объёмными репами, не помню чтобы клонирование было особой проблемой.

xaizek ★★★★★ ()
Ответ на: комментарий от X512

Как ты сделал патч без перезаписи локальных файлов?

Потом сбрось изменения и забей на пересборку до следующего нужного тебе изменения.

grem ★★★★★ ()
Последнее исправление: grem (всего исправлений: 1)
Ответ на: комментарий от X512

И timestamp файлов оказывается перезаписан. Пересобирать придётся заново.

https://github.com/MestreLion/git-tools#git-restore-mtime

git-restore-mtime

Restore original modification time of files based on the date of the most recent commit that modified them

Probably the most popular and useful tool, and the reason this repository was packaged into distros.

gag ★★★★★ ()
Ответ на: комментарий от grem

Как ты сделал патч без перезаписи локальных файлов?

Из рабочей ветки. В рабочей ветке меняется только то что надо и в большинстве случаев инкрементальная сборка не сбрасывается.

X512 ()
Ответ на: комментарий от X512

блин, почитай уже про overlayfs. Смонтируй оверлей над каталогом с проектом, накати туда свои патчи, сделай git push или что там тебе надо, удали оверлей. Файлы в исходном каталоге останутся прежними.

Lrrr ()
Ответ на: комментарий от X512

И timestamp файлов оказывается перезаписан.

Если пересборка случается только из-за изменения timestamp, то сохраняй их вначале и восстанавливай в конце.

Laz ★★★★★ ()