Git

Материал из Eludia
Перейти к: навигация, поиск


Note.jpg Эта заметка не претендует на энциклопедичность. Она не отличается ни широтой охвата, ни строгостью формулировок. Это просто записочка на память.

Windows-редактор, Linux-сервер (samba)

В этой шпаргалке собраны некоторые сведения, полезные при работе с git в режиме, характерном для многих Eludia-разработчиков, когда:

  • приложение располагается на Linux-сервере;
  • программист работает под Windows;
  • файлы читаются и записываются по протоколу SMB, при помощи Samba.

Разумеется, при таком раскладе теряется время и порождается лишний трафик по ЛВС, однако пока нашим рабочим браузером остаётся MSIE, этими потерями вполне можно пренебречь.

Вот с чем возникают реальные неприятности — так это с частичной несовместимостью атрибутов файловых систем. Конкретно речь идёт о признаке исполнимости файла, который во всех UNIX-совместимых системах столь же важен, как время модификации (и, соответственно, отслеживается git), а в Windows не поддерживается.

Соответственно, samba при создании файла на linux-диске по инициативе windows-программы ставит ему признак исполнимости наобум Лазаря, а портированные под windows изначально linux-программы (такие, как сам git) этого флажка не видят.

В результате получается, что git, запущенный на linux-сервере и git, запущенный на windows-рабочей станции, видят одни и те же файлы в разном состоянии. И если разные git-операции производятся в одном репозитории из-под разных систем, возникают досадные коллизии.

Избежать этого можно так. Во-первых, проставить опцию fileMode = false в раздел core файла .git/config:

git config core.fileMode false

Во-вторых, при переключении с одной ОС на другую отдавать команду

git status

из под той ОС, на которую вы переходите в данный момент. В частности, если вы только что сделали git clone из-под Linux, прописали core.fileMode, поправили несколько файлов и готовы к commit средствами TortoiseGit, то сначала откройте консоль cmd на samba-диск, зайдите в директорию приложения и скажите git status. Тогда в списке на commit покажутся только изменённые файлы, а не все подряд.

Push на сервер

Git — это прежде всего инструмент разработчика. Хотя его довольно удобно использовать как платформу для установки обновлений ПО. Тем не менее, поскольку при этом он используется не совсем по назначению, бывает нужно сделать пару дополнительных шагов.

Рассмотрим следующую ситуацию: вы хотите (одной командой) опубликовать изменения со своей рабочей станции непосредственно на (UNIX) сервер. При этом вы видите сервер, а он вас — нет (например, вы обращаетесь к нему из-за firewall'а).

Для этой цели естественно использовать git push, однако здесь возникает 2 затруднения:

  1. Поскольку серверный репозиторий не bare, а с файлами, push может быть не принят. Ведь если там в это время работает человек, он может не обрадоваться такому сюрпризу, как неожиданная дозапись в историю. Чем выше версия git, тем туже в этом плане гайки.
  2. После того, как вы переслали commit'ы и они прописались в серверном репозитории, файлы сами по себе не изменятся.

Первая проблема решается командой:

git config receive.denyCurrentBranch ignore

После этого репозиторий на сервере будет принимать push безо всяких оговорок. А чтобы он при каждой такой операции доставал файлы на диск, необходимо прописать соответствующий скрипт в качестве .git/hooks/post-receive:

#!/bin/bash
cd ..
env -u GIT_DIR git reset --hard master

Этим скриптом вы расписываетесь за то, что если вы вносите какие-то локальные изменения в файлах на сервере и кто-то в это время делает от себя git push, то ваши неза'commit'енные правки исчезнут бесследно. А за'commit'енные могут быть уничтожены командой git push -f. Что, в общем, вполне справедливо: в идеале файлы там вообще нельзя менять в обход (полу)автоматической системы обновления.

Трюк с env -u необходим из-за несколько неожиданной установки переменной GIT_DIR внутри hooks.

Кроме того, на всякий случай напомним, что скрипт необходимо пометить как исполнимый файл:

chmod a+x .git/hooks/post-receive

Восстановление случайно удалённых веток

Вообще, когда Вы пытаетесь удалить ветвь

git branch my_branch -d

которая содержит уникальные изменения, то git честно вас об этом предупреждает, и опцию '-d' выполнять отказывается. Однако вы можете повысить голос и сказать:

git branch my_branch -D

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

git reflog

В результате вы увидите список последних низкоуровневых действий с метками вида 'HEAD@{...}'. Если вы сделали последний commit в пострадавшую ветвь непосредственно перед её удалением, это действие будет иметь метку HEAD@{1}. Найдя такую метку, достаточно выбрать новое имя для восстановленной ветви (например, 'restored_branch') и сказать

git checkout -b restored_branch HEAD@{1} # ну или не 1, а какой там у вас номер

и всё вернётся.

Персональные инструменты
Пространства имён

Варианты
Действия
Навигация
Разработчику
Администратору
Инструменты