Обилие ссылок на github.com репозитории в повествовании о JRuby on Rails в AppEngine натолкнуло меня на мысль о том, что неплохо бы рассказать как пользоваться этим самым git. Я не буду вас мучить примерами с пустыми репозиториями. Давайте попробуем решить сугубо практическую задачу – внести небольшое изменение в библиотеку Bumble. Она и будет нашим учебным репозиторием. Скопировать удаленный репозиторий git можно с помощью команды clone:
~$ git clone git://github.com/olabini/bumble.git
Initialized empty Git repository in /home/engineer/bumble/.git/
remote: Counting objects: 5, done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 5 (delta 0), reused 0 (delta 0)
Receiving objects: 100% (5/5), done.
Git обладает очень простым и понятным интерфейсом работы с ветками. Плодить ветки в git репозитории под любые свои нужды – практика совершенно нормальная. Основная ветка репозитория называется master, получить список всех доступных вам веток можно командой branch:
~/bumble$ git branch
* master
Пока вам доступна одна ветка, master. Обратите внимание на “*” справа – так обозначена текущая ветка. Давайте сделаем свою ветку, перейдем в нее и приступим к изменениям кода:
~/bumble$ git branch filters
~/bumble$ git branch
filters
* master
~/bumble$ git checkout filters
Switched to branch "filters"
Добавим в Bumble::DS::Query обертку для методов add_filter в DataStore. В исходной версии Bumble есть возможно выбирать данные только с одним фильтром – EQUAL. Кроме него, есть еще четыре фильтра, работу с которыми мы добавим в Bumble, на примере метода all:
class Query
[:equal, :greater_than, :greater_than_or_equal, :less_than, :less_than_or_equal].each do |filter|
filter = filter.to_s
class_eval <<-END_EVAL
def add_filter_#{filter.sub('_than', '')}(name, value)
add_filter(name, DS::Query::FilterOperator::#{filter.upcase}, value)
end
END_EVAL
end
end
Теперь немного поправим метод all. Тут мы поменяем только разрабор параметра conditions, так что полный код метода я приводить не буду:
def all(conditions = {}, options = {})
q = DS::Query.new(self.name)
conditions.each do |k, v|
property_name = k.to_s
if v.is_a? Hash
v.each do |filter_op, value|
q = q.send "add_filter_#{filter_op}", property_name, value
end
else
q = q.add_filter(property_name, DS::Query::FilterOperator::EQUAL, v)
end
end
# some code below
Результаты своего труда можно увидеть с помощью команды diff. Попробуйте сами, заодно посмотрите man. Теперь нам нужно каким-то образом изменения в своей ветке зафиксировать, перенести в основную и пользоваться в своих проектах. Конечно, в git есть commit, но сам процесс несколько отличается от обычных систем контроля версий (я имею ввиду CVS, Subversion).
Сперва, вы должны добавить нужные файлы для commit командой add. Узнать имена этих файлов можно не только из diff, но командой status:
~/bumble$ git status
# On branch filters
# Changed but not updated:
# (use "git add ..." to update what will be committed)
# (use "git checkout -- ..." to discard changes in working directory)
#
# modified: bumble/bumble.rb
#
no changes added to commit (use "git add" and/or "git commit -a")
~/bumble$ git add bumble/bumble.rb
~/bumble$ git commit -m 'new filters and all() refactored'
[filters]: created 300e887: "new filters and all() refactored"
1 files changed, 39 insertions(+), 21 deletions(-)
Номер ревизии, как впрочем и количество измененных строк у вас могут быть совсем другими. Теперь перенесем наши изменения в основную ветку:
~bumble/$ git checkout master
Switched to branch "master"
~bumble/$ git merge filters
Updating 96bdfc0..300e887
Fast forward
bumble/bumble.rb | 60 +++++++++++++++++++++++++++++++++++------------------
1 files changed, 39 insertions(+), 21 deletions(-)
~bumble/$ git status
# On branch master
# Your branch is ahead of 'origin/master' by 1 commit.
#
nothing to commit (working directory clean)
Ну вот, надеюсь вы догадались, что переходить между ветками можно командой checkout, а перенести изменения – merge. В status вы видете, что ваш локальный репозиторий “опережает” основную ветку на удаленном сервере на один commit.
Конечно, рассмотренные выше примеры работы с git довольно примитивны. К сложным вопросам мы еще вернемся, а ответы к несложным я надеюсь читатель найдет в документации. Мне лишь хотелось вас заинтересовать.