вторник, 17 февраля 2009 г.

ALT Linux 4.1 Desktop Lite - неофициальная сборка

Время от времени в community@lists.altlinux.ru спрашивают: а где бы раздобыть ALT Linux 4.1 Desktop Lite, который до релиза, как известно, не дожил :(

Поскольку я собирал для себя нечто подобное, но с другим дизайном и с другими дефолтами, и лучше поздно, чем никогда, выкладываю пересобранные на сегодняшнем branch/4.1 cd-образы:
Инсталлятор от официального не отличается ничем, свежеустановленная система выглядит так:


Если кому-то вдруг захочется это собрать, профиль можно взять здесь. Планы по сборке аналогичного дистрибутива на branch/5.0 есть, но если кто-нибудь меня опередит, я буду только рад :)

воскресенье, 15 февраля 2009 г.

Практическое введение в Git

Возможно, я плохо искал, но простого пошагового введения в Git на русском для тех разработчиков и админов, которые кое-как научились использовать CVS или SVN, до сих пор нет. Много полезных материалов и ссылок можно найти на ALT Linux Wiki, однако значительная их часть содержит альтовскую дистрибутивостроительную специфику или, наоборот, несколько далека от практических задач. Я попытаюсь описать один из типичных сценариев использования Git без привязки к каким-либо задачам и без излишних подробностей - за ними лучше сразу идти в Git User's Manual.

Итак, основная идея Git, как и любой распределенной SCM, заключается в том, что мы имеем дело с локальными коммитами в индивидуальных репозитариях разработчиков и с мехнизмами обмена коммитами между репозитариями. Главное преимущество - гибкость (можно вести локальные бранчи с локальными коммитами, не забивая основной репозитарий результатами неудачных или удачных экспериментов), обратная сторона - некоторое увеличение сложности взаимодействия по сравнению с централизованными SCM.

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

Устанавливаем все необходимое и заводим на сервере центральный репозитарий:
# apt-get install git-core
# mkdir /home/repo/alpha.git
# cd /home/repo/alpha.git
# git init --bare --shared=true
Работать с ним будем по ssh, поэтому создаем для разработчиков учетные записи и добавляем их в группу, во владение которой передаем репозитарий:
# useradd -d /var/empty/ -s /usr/bin/git-shell user1
# useradd -d /var/empty/ -s /usr/bin/git-shell user2
# groupadd alpha
# usermod -G alpha user1
# usermod -G alpha user2
# chown -R root:alpha /home/repo/alpha.git
Теперь один из разработчиков может создать локальный репозитарий и сделать в нем несколько коммитов:
[user1@workstation1 ~]$ mkdir alpha
[user1@workstation1 ~]$ cd alpha
[user1@workstation1 alpha]$ git init
[user1@workstation1 alpha]$ git config user.name 'User 1'
[user1@workstation1 alpha]$ git config user.email 'user1@workstation1'
[user1@workstation1 alpha]$ echo 'line 1' > file
[user1@workstation1 alpha]$ git add .
[user1@workstation1 alpha]$ git commit -a -m 'add line 1'
[user1@workstation1 alpha]$ echo 'line 2' >> file
[user1@workstation1 alpha]$ git commit -a -m 'add line 2'
Каждый коммит принадлежит одному или нескольким бранчам. Для первого коммита автоматически создается бранч с именем master, в него же по умолчанию попадают следующие коммиты.

Несколько полезных команд:
  • git branch - показать список бранчей, выделив текущий, создать, удалить или переименовать бранч
  • git status - показать текущее состояние рабочей копии (какие новые файлы появились, а какие были удалены, что закоммитили, а что нет, и т.д.)
  • git log - показать историю коммитов, каждый из которых идентифицируется с помощью хеша sha1
  • git show - показать подробности последнего коммита или любого коммита по его хешу
  • git diff - показать разницу между последним коммитом и рабочей копией или между коммитами
Теперь подготовим наш репозитарий к отгрузке коммитов в центральный репозитарий на сервере:
[user1@workstation1 alpha]$ git remote add origin user1@gitserver:/home/repo/alpha.git
И отправим туда коммиты, принадлежащие локальному бранчу master - они попадут в удаленный бранч с таким же именем:
[user1@workstation1 alpha]$ git push origin master
В дальнейшем можно будет ограничиться git push, т.к. origin - дефолтное имя удаленного репозитария, а бранч master в нем уже существует. С другой стороны, ничто не мешает явно указывать URL удаленного репозитария и имена локального и удаленного бранчей:
[user1@workstation1 alpha]$ git push user1@gitserver:/home/repo/alpha.git master:master
Для получения коммитов из центрального репозитария в локальный бранч master его нужно было бы создать с параметром --track, однако бранч уже существует, поэтому просто укажем соответствующий ему удаленный бранч в настройках:
$ cat >> .git/config << EOF
> [branch "master"]
>       remote = origin
>       merge = refs/heads/master
> EOF
Получить новые коммиты из центрального репозитария можно так:
[user1@workstation1 alpha]$ git fetch
[user1@workstation1 alpha]$ git merge origin/master
или просто:
[user1@workstation1 alpha]$ git pull
В случае конфликтующих изменений операция merge не будет завершена коммитом - в этом случае нужно будет выполнить git commit самостоятельно после разрешения конфликта.

Разумеется новые коммиты могут появиться в центральном репозитарии только после того, как другой разработчик клонирует его, внесет туда какие-либо изменения и отправит их обратно - при этом настраивать свой репозитарий для взаимодействия с удаленным ему уже не потребуется:
[user2@workstation2 ~]$ git clone user2@gitserver:/home/repo/alpha.git
[user2@workstation2 ~]$ cd alpha/
[user2@workstation2 alpha]$ git config user.name 'User 1'
[user2@workstation2 alpha]$ git config user.email 'user2@workstation2'
[user2@workstation2 alpha]$ echo 'line 3' >> file
[user2@workstation2 alpha]$ git commit -a -m 'add line 3'
[user2@workstation2 alpha]$ git push
Теперь чуть подробнее о том, ради чего все эти мучения - ведь для выполнения аналогичных операций средствами CVS или SVN потребовалось бы меньше операций. Дело в том, что до тех пор, пока мы не отгрузили коммиты в удаленный репозитарий, мы вольны распоряжаться ими как нам вздумается. Например, заведем для экспериментов новый локальный бранч и сделаем в нем еще пару коммитов:
[user1@workstation1 alpha]$ git-checkout -b experimental
[user1@workstation1 alpha]$ echo 'line 4' >> file
[user1@workstation1 alpha]$ git commit -a -m 'add line 4'
[user1@workstation1 alpha]$ echo 'line 5' >> file
[user1@workstation1 alpha]$ git commit -a -m 'add line 5'
Если какие-то коммиты лучше было бы не делать, можно откатиться к любому заданному коммиту, указав его:
  • явно в виде sha1 id - их покажет git log
  • по имени тэга - его можно создать для коммита по его sha1 id с помощью git tag
  • относительно другого коммита - например, последнему коммиту, на который указывает HEAD, предшествует HEAD^:
[user1@workstation1 alpha]$ git reset --hard HEAD^
Также бывают полезны параметр --soft (откатиться, но сохранить содержимое измененных файлов для последующего редактирования) и параметр --amend команды git commit (включить содержимое старого коммита в новый).

Вернемся в бранч master, сделаем в нем еще один коммит и втянем туда результаты экспериментов:
[user1@workstation1 alpha]$ git checkout master
[user1@workstation1 alpha]$ subst '/line 1/iline 0' file
[user1@workstation1 alpha]$ git commit -a -m 'add line 0'
[user1@workstation1 alpha]$ git merge experimental
Вместо операции merge, которая создает общий коммит для бранчей, иногда бывает полезно использовать rebase - эта операция переупорядочивает коммиты для того, чтобы сохранить историю линейной. Очень полезно для изучения истории использовать gitk, gitg или qgit - эти инструменты помогут представить описанное более наглядно.

Разумеется, после того, как мы сделали git push, с историей лучше не забавляться - этим мы сильно осложним жизнь тем, кто уже основывает свои новые коммиты на ней. А вот до git push - сколько угодно :)

понедельник, 2 февраля 2009 г.

Redmine quickstart

Похоже, что изначально не приглянувшийся мне Redmine несколько удобнее Trac:
  • есть приличная русификация
  • есть поддержка подпроектов
  • есть web-интерфейс для управления проектами и правами доступа к ним - прям аж обидно, и зачем я тратил время на Trac appliance?
  • и самое главное - дефолтный дизайн отлично гармонирует с дизайном моего блога :)
В качестве ложки дегтя пока заметил лишь то, что принимать информацию об авторизации от Apache он не умеет, правда умеет LDAP, который уже можно прикрутить к Apache. И опакетить его, к сожалению, так просто не выйдет (updated: поэтому вышло непросто).

Мне пришлось поставить из тарболла:
# apt-get install ruby-rake ruby-stdlibs ruby-activerecord-sqlite3-adapter rubygems
# useradd -d /opt/redmine -s /dev/null redmine
# su - redmine -s /bin/bash
$ wget http://rubyforge.org/frs/download.php/49319/redmine-0.8.0.tar.gz
$ tar -zxf redmine-0.8.0.tar.gz 
$ cd redmine-0.8.0
$ cat > config/database.yml << EOF
> production:
>   adapter: sqlite3
>   dbfile: db/production.db
> EOF
$ rake db:migrate RAILS_ENV="production"
$ rake redmine:load_default_data RAILS_ENV="production"
$ ruby script/server -e production
Теперь подключаемся к http://server:3000/ и логинимся под именем admin с таким же точно паролем. Несмотря на грозные предупреждения в руководстве по установке с более новыми, нежели указано, версиями ruby и sqlite вроде бы все работает.