Хак с Git #1: Передача правок через bundle

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

Git скачивает изменения потоком, никакие Download Master’ы тут не помогут. Казалось бы.

Если Вы работаете с людьми, которым с соединением повезло больше чем Вам, то попросите их залить особенно большие правки в bundle и передать его вам любым удобным способом (например, передать через файлобменный сервис, поддерживающий докачку или записать на диск и отправить почтой).

Всё что нужно сделать вашему коллеге, так это выполнить в корне репозитория команду следующего вида:

Где file.bundle — путь к будущему файлу, 5 — колличество правок с конца которые будут записаны в него, а master — имя ветки от которой ведётся отсчёт.

Эта команда создаёт bundle-репозиторий, содержащий 5 последних ревизий ветки master и сохранит его в корне проекта под именем file.bundle.

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

В ОС Windows путь к каталогу с git должен быть добавлен в переменную PATH. Но, если Вас это не устраивает, можно просто указать во всех командах вместо git полный путь к git.exe.

Затем, получив файл, мы можем обновиться с него следующим образом:

Где file.bundle — путь к файлу c bundle-репозиторием, master — имя ветки в bundle, а newBranch — имя ветки в которую будут записаны изменения.

Проверяем, соответствует ли хеш нашего последнего коммита хешу соответствующего коммита на сервере с помощью log

Если всё верно, сдвигаем ветку на нужную правку (где 53c79a876f9f90b8c7b1a6d91bcaede5fc3f07b9 — это хеш-сумма правки. Можно указывать только первые несколько цифр, git найдёт её. Стоит кстати отметить, что действия производятся из целевой ветки (в моём случае master))

Затем удаляем временную ветку

 

«Но ведь правки можно передать заплатками(patch)!» — скажете Вы.
Да, это так, но при применении заплатки меняется время коммита, которое является частью метаданных, от которых высчитывается хеш-сумма коммита.
Другими словами, одни и те же изменения git будет воспринимать как совершенно разные изменения, и вам всё равно придётся выкачивать все новые правки с сервера. Возможно эту проблему можно как-то обойти, но я считаю, что заплатками стоит передавать только те изменения, которые ещё не попали в центральное хранилище.

Примечания

Не обязательно делать всё именно так. Я описал только то, как поступаю я. Мне, например, нравится держать свои изменения в отдельных ветках до самого момента занесения изменений на сервер. И поэтому сдвиг ветки master для меня абсолютно безболезнен.

Вы можете ознакомиться с возможностями, которые предлагает git bundle с помощью следующей команды.

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

Автоматизация

Можно слегка автоматизировать применение коммитов, написав bat-файл следующего содержания

Теперь, перетащив bundle-файл на этот «батник», мы сразу заберём все новые правки к master и поместим их в ветку bundle_branch.

Так же, можно вынести в bat-файл команду создания bundle-репозитория

Остальные действия можно совершать в GUI вроде TortoiseGit.

Поделиться

Оставить ответ