Выбрать главу

# Машина Джессики $ git clone jessica@githost:simplegit.git Initialized empty Git repository in /home/jessica/simplegit/.git/ ... $ cd simplegit/ $ vim TODO $ git commit -am 'add reset task' [master fbff5bc] add reset task 1 files changed, 1 insertions(+), 0 deletions(-)

Теперь Джессика отправляет свою работу на сервер:

# Машина Джессики $ git push origin master ... To jessica@githost:simplegit.git 1edee6b..fbff5bc master -> master

Джон также пытается выложить свои изменения:

# Машина Джона $ git push origin master To john@githost:simplegit.git ! [rejected] master -> master (non-fast forward) error: failed to push some refs to 'john@githost:simplegit.git'

Джон не может выполнить отправку изменений, так как за это время Джессика уже отправила свои. Это очень важно понять, особенно если вы привыкли к Subversion, так как мы видим, что эти два разработчика не редактировали один и тот же файл. Хотя Subversion и выполняет автоматическое слияние на сервере, если редактировались разные файлы, при использовании Git вы должны слить коммиты локально. Прежде чем Джон сможет отправить свои изменения на сервер, он должен извлечь наработки Джессики и выполнить слияние:

$ git fetch origin ... From john@githost:simplegit + 049d078...fbff5bc master -> origin/master

На этот момент, локальный репозиторий Джона выглядит так, как показано на Рисунке 5-4.

У Джона есть ссылка на изменения, выложенные Джессикой, и он должен слить их со своей работой перед тем, как ему разрешат её отправить:

$ git merge origin/master Merge made by recursive. TODO | 1 + 1 files changed, 1 insertions(+), 0 deletions(-)

Слияние прошло без проблем — история коммитов Джона теперь выглядит как на Рисунке 5-5.

Теперь Джон может протестировать свой код, дабы удостовериться, что он по-прежнему работает нормально, а затем выложить свою работу, уже объединённую с работой Джессики, на сервер:

$ git push origin master ... To john@githost:simplegit.git fbff5bc..72bbc59 master -> master

В результате история коммитов Джона выглядит, как показано на Рисунке 5-6.

Тем временем, Джессика работала над тематической веткой. Она создала тематическую ветку с названием issue54 и сделала три коммита в этой ветке. Она ещё не извлекала изменения Джона, так что её история коммитов выглядит, как показано на Рисунке 5-7.

Джессика хочет синхронизировать свою работу с Джоном, так что она извлекает изменения с сервера:

# Машина Джессики $ git fetch origin ... From jessica@githost:simplegit fbff5bc..72bbc59 master -> origin/master

Эта команда извлекает наработки Джона, которые он успел выложить. История коммитов Джессики теперь выглядит как на Рисунке 5-8.

Джессика полагает, что её тематическая ветка закончена, но она хочет узнать, с чем ей нужно слить свою работу, чтобы она могла выложить её на сервер. Она запускает git log, чтобы выяснить это:

$ git log --no-merges origin/master ^issue54 commit 738ee872852dfaa9d6634e0dea7a324040193016 Author: John Smith <jsmith@example.com> Date: Fri May 29 16:01:27 2009 -0700 removed invalid default value

Теперь Джессика может слить свою тематическую ветку в ветку master, слить работу Джона (origin/master) в свою ветку master и затем отправить изменения на сервер. Сначала она переключается на свою основную ветку, чтобы объединить всю эту работу:

$ git checkout master Switched to branch "master" Your branch is behind 'origin/master' by 2 commits, and can be fast-forwarded.

Она может слить сначала ветку origin/master, а может и issue54 — обе они находятся выше в истории коммитов, так что не важно какой порядок слияния она выберет. Конечное состояние репозитория должно получиться идентичным независимо от того, какой порядок слияния она выберет; только история коммитов будет немного разная. Она решает слить ветку issue54 первой:

$ git merge issue54 Updating fbff5bc..4af4298 Fast forward README | 1 + lib/simplegit.rb | 6 +++++- 2 files changed, 6 insertions(+), 1 deletions(-)

Никаких проблем не возникло; как видите, это был обычная перемотка. Теперь Джессика сливает работу Джона (origin/master):

$ git merge origin/master Auto-merging lib/simplegit.rb Merge made by recursive. lib/simplegit.rb | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)

Слияние проходит нормально, и теперь история коммитов Джессики выглядит так, как показано на Рисунке 5-9.

Теперь указатель origin/master доступен из ветки master Джессики, так что она может спокойно выполнить git push (полагая, что Джон не выкладывал свои изменения за это время):

$ git push origin master ... To jessica@githost:simplegit.git 72bbc59..8059c15 master -> master

Каждый разработчик несколько раз выполнял коммиты и успешно сливал свою работу с работой другого; смотри Рисунок 5-10.

Это один из простейших рабочих процессов. Вы работаете некоторое время, преимущественно в тематической ветке, и, когда приходит время, сливаете её в свою ветку master. Когда вы готовы поделиться этой работой с другими, вы сливаете её в ветку master, извлекаете изменения с сервера и сливаете origin/master (если за это время произошли изменения), и, наконец, отправляете свои изменения в ветку master на сервер. Общая последовательность действий выглядит так, как показано на Рисунке 5-11.