From cc3f1da2a246326f3c500ee8d1d971b489afbcc0 Mon Sep 17 00:00:00 2001 From: Dexter Morganov Date: Thu, 2 Jan 2020 14:33:59 +0300 Subject: [PATCH] =?UTF-8?q?=D0=98=D1=81=D0=BF=D1=80=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=20=D0=B7=D0=BD=D0=B0=D0=BA=20=D1=82=D0=B8=D1=80?= =?UTF-8?q?=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- B-embedding-git.asc | 2 +- C-git-commands.asc | 24 ++++---- README.asc | 4 +- .../sections/about-version-control.asc | 12 ++-- book/01-introduction/sections/basics.asc | 12 ++-- .../01-introduction/sections/command-line.asc | 4 +- .../sections/first-time-setup.asc | 6 +- book/01-introduction/sections/history.asc | 4 +- book/01-introduction/sections/installing.asc | 4 +- .../sections/basic-branching-and-merging.asc | 8 +-- book/03-git-branching/sections/nutshell.asc | 6 +- book/03-git-branching/sections/rebasing.asc | 16 +++--- .../sections/remote-branches.asc | 2 +- book/03-git-branching/sections/workflows.asc | 2 +- book/04-git-server/sections/git-daemon.asc | 2 +- book/04-git-server/sections/gitlab.asc | 18 +++--- book/04-git-server/sections/protocols.asc | 2 +- .../sections/contributing.asc | 56 +++++++++---------- .../sections/distributed-workflows.asc | 10 ++-- .../sections/maintaining.asc | 2 +- .../sections/1-setting-up-account.asc | 4 +- .../sections/advanced-merging.asc | 18 +++--- book/07-git-tools/sections/bundling.asc | 2 +- book/07-git-tools/sections/credentials.asc | 4 +- book/07-git-tools/sections/debugging.asc | 10 ++-- .../sections/interactive-staging.asc | 8 +-- book/07-git-tools/sections/replace.asc | 10 ++-- book/07-git-tools/sections/rerere.asc | 8 +-- book/07-git-tools/sections/reset.asc | 24 ++++---- .../sections/revision-selection.asc | 30 +++++----- .../sections/rewriting-history.asc | 14 ++--- book/07-git-tools/sections/searching.asc | 6 +- .../sections/stashing-cleaning.asc | 10 ++-- book/07-git-tools/sections/submodules.asc | 22 ++++---- book/07-git-tools/sections/subtree-merges.asc | 10 ++-- .../sections/attributes.asc | 18 +++--- book/08-customizing-git/sections/config.asc | 34 +++++------ book/08-customizing-git/sections/hooks.asc | 8 +-- book/08-customizing-git/sections/policy.asc | 10 ++-- .../sections/client-bzr.asc | 4 +- .../sections/client-hg.asc | 16 +++--- .../sections/client-p4.asc | 28 +++++----- .../sections/client-svn.asc | 32 +++++------ .../sections/client-tfs.asc | 14 ++--- .../sections/import-bzr.asc | 6 +- .../sections/import-custom.asc | 12 ++-- .../sections/import-hg.asc | 2 +- .../sections/import-p4.asc | 2 +- .../sections/import-svn.asc | 8 +-- .../sections/import-tfs.asc | 4 +- .../10-git-internals/sections/environment.asc | 22 ++++---- .../10-git-internals/sections/maintenance.asc | 28 +++++----- book/10-git-internals/sections/objects.asc | 38 ++++++------- book/10-git-internals/sections/packfiles.asc | 18 +++--- .../sections/plumbing-porcelain.asc | 8 +-- book/10-git-internals/sections/refs.asc | 10 ++-- book/10-git-internals/sections/refspec.asc | 4 +- .../sections/transfer-protocols.asc | 16 +++--- .../sections/bash.asc | 4 +- .../sections/guis.asc | 38 ++++++------- .../B-embedding-git/sections/command-line.asc | 6 +- book/B-embedding-git/sections/dulwich.asc | 2 +- book/B-embedding-git/sections/go-git.asc | 8 +-- book/B-embedding-git/sections/jgit.asc | 12 ++-- book/B-embedding-git/sections/libgit2.asc | 26 ++++----- book/dedication.asc | 4 +- book/introduction.asc | 2 +- book/preface_scott.asc | 2 +- 68 files changed, 411 insertions(+), 411 deletions(-) diff --git a/B-embedding-git.asc b/B-embedding-git.asc index 8c52ba5c..5bdf8ca2 100644 --- a/B-embedding-git.asc +++ b/B-embedding-git.asc @@ -3,7 +3,7 @@ == Встраивание Git в ваши приложения Если вы пишете приложение для разработчиков, с высокой вероятностью оно выиграет от интеграции с системой управления версиями. -Даже приложения для обычных пользователей — например, текстовые редакторы — могут извлечь пользу из систем управления версиями. Git хорошо работает во многих сценариях. +Даже приложения для обычных пользователей -- например, текстовые редакторы -- могут извлечь пользу из систем управления версиями. Git хорошо работает во многих сценариях. Если вам нужно интегрировать Git в ваше приложение, то у вас есть два основных варианта: запустить шелл и выполнять Git команды в нем или добавить библиотеку Git и использовать её. Ниже мы рассмотрим интеграцию командной строки и несколько найболее популярных встраиваемых библиотек Git. diff --git a/C-git-commands.asc b/C-git-commands.asc index d9985998..4a31218f 100644 --- a/C-git-commands.asc +++ b/C-git-commands.asc @@ -16,7 +16,7 @@ === Настройка и конфигурация -Две довольно распространённые команды, используемые как сразу после установки Git, так и в повседневной практике для настройки и получения помощи — это `config` и `help`. +Две довольно распространённые команды, используемые как сразу после установки Git, так и в повседневной практике для настройки и получения помощи -- это `config` и `help`. ==== git config @@ -80,7 +80,7 @@ === Клонирование и создание репозиториев -Существует два способа создать Git репозиторий. Первый — клонировать его из существующего репозитория (например, по сети); второй — создать репозиторий в существующей директории. +Существует два способа создать Git репозиторий. Первый -- клонировать его из существующего репозитория (например, по сети); второй -- создать репозиторий в существующей директории. ==== git init @@ -139,7 +139,7 @@ Команда `git diff` используется для вычисления разницы между любыми двумя Git деревьями. Это может быть разница между вашей рабочей директорией и индексом (собственно `git diff`), разница между индексом и последним коммитом (`git diff --staged`), или между любыми двумя коммитами (`git diff master branchB`). -Мы познакомили вас с основами этой команды в главе <>, где показали как посмотреть какие изменения уже добавлены в индекс, а какие — ещё нет. +Мы познакомили вас с основами этой команды в главе <>, где показали как посмотреть какие изменения уже добавлены в индекс, а какие -- ещё нет. О том как использовать эту команду для проверки на проблемы с пробелами с помощью аргумента `--check` можно почитать в главе <>. @@ -189,7 +189,7 @@ ==== git mv -Команда `git mv` — это всего лишь удобный способ переместить файл, а затем выполнить `git add` для нового файла и `git rm` для старого. +Команда `git mv` -- это всего лишь удобный способ переместить файл, а затем выполнить `git add` для нового файла и `git rm` для старого. Мы лишь вкратце упомянули это команду в главе <>. @@ -205,7 +205,7 @@ ==== git branch -Команда `git branch` — это своего рода "менеджер веток". Она умеет перечислять ваши ветки, создавать новые, удалять и переименовывать их. +Команда `git branch` -- это своего рода "менеджер веток". Она умеет перечислять ваши ветки, создавать новые, удалять и переименовывать их. Большая часть главы <> посвящена этой команде, она используется повсеместно в этой главе. Впервые команда `branch` была представлена в разделе <>, а большинство таких её фич как перечисление и удаление веток были разобраны в разделе <>. @@ -253,7 +253,7 @@ Практически во всех главах книги эта команда используется для демонстрации истории проекта. -Мы познакомились c `git log` и некоторыми её деталями в главе <>. Там мы видели использование опций `-p` и `--stat` для получения представления об изменениях в каждом коммите, а также `--pretty` and `--oneline` для настройки формата вывода этой команды — более полным и подробным или кратким. +Мы познакомились c `git log` и некоторыми её деталями в главе <>. Там мы видели использование опций `-p` и `--stat` для получения представления об изменениях в каждом коммите, а также `--pretty` and `--oneline` для настройки формата вывода этой команды -- более полным и подробным или кратким. В главе <> мы использовали опцию `--decorate` чтобы отобразить указатели веток на истории коммитов, а также `--graph` чтобы просматривать историю в виде дерева. @@ -340,7 +340,7 @@ ==== git submodule -Команда `git submodule` используется для управления вложенными репозиториями. Например, это могут быть библиотеки или другие, используемые не только в этом проекте ресурсы. У команды `submodule` есть несколько под-команд — `add`, `update`, `sync` и др. — для управления такими репозиториями. +Команда `git submodule` используется для управления вложенными репозиториями. Например, это могут быть библиотеки или другие, используемые не только в этом проекте ресурсы. У команды `submodule` есть несколько под-команд -- `add`, `update`, `sync` и др. -- для управления такими репозиториями. Эта команда упомянута и полностью раскрыта в главе <>. @@ -354,7 +354,7 @@ В главе <> мы использовали её для показа коммитов, подпадающих под различные селекторы диапазонов. -Ещё одна интересная вещь, которую мы проделывали с помощью `git show` в главе <> — это извлечение содержимого файлов на различных стадиях во время конфликта слияния. +Ещё одна интересная вещь, которую мы проделывали с помощью `git show` в главе <> -- это извлечение содержимого файлов на различных стадиях во время конфликта слияния. ==== git shortlog @@ -375,7 +375,7 @@ ==== git bisect -Команда `git bisect` — это чрезвычайно полезная утилита для поиска коммита в котором впервые проявился баг или проблема с помощью автоматического бинарного поиска. +Команда `git bisect` -- это чрезвычайно полезная утилита для поиска коммита в котором впервые проявился баг или проблема с помощью автоматического бинарного поиска. О ней упоминается только в главе <>, где она полностью и раскрыта. @@ -403,7 +403,7 @@ ==== git rebase -`git rebase` — это "автоматизированный" `cherry-pick`. Он выполняет ту же работу, но для цепочки коммитов, тем самым как бы перенося ветку на новое место. +`git rebase` -- это "автоматизированный" `cherry-pick`. Он выполняет ту же работу, но для цепочки коммитов, тем самым как бы перенося ветку на новое место. Мы в деталях разобрались с механизмом переноса веток в главе <>, включая рассмотрение потенциальных проблем переноса опубликованных веток при совместной работе. @@ -415,7 +415,7 @@ ==== git revert -Команда `git revert` — полная противоположность `git cherry-pick`. Она создаёт "антикоммит" для указанного коммита, таким образом отменяя изменения, внесённые в нём.. +Команда `git revert` -- полная противоположность `git cherry-pick`. Она создаёт "антикоммит" для указанного коммита, таким образом отменяя изменения, внесённые в нём.. Мы использовали её в главе <> чтобы отменить коммит слияния (merge commit). @@ -510,7 +510,7 @@ Также в этой книге встречались некоторые низкоуровневые ("сантехнические") команды. -Первая из них — это `ls-remote`, с которой мы столкнулись в главе <> и использовали для просмотра ссылок на сервере. +Первая из них -- это `ls-remote`, с которой мы столкнулись в главе <> и использовали для просмотра ссылок на сервере. В главах <>, <> и <> мы использовали команду `ls-files` чтобы просмотреть "сырые" данные в индексе. diff --git a/README.asc b/README.asc index a82127f9..e53cf2c3 100644 --- a/README.asc +++ b/README.asc @@ -22,11 +22,11 @@ image:https://travis-ci.org/progit/progit2-ru.svg?branch=master["Build Status", Есть два способа собрать файл для электронной книги из этого кода. -Самый простой — поручить это нам. Робот реагирует на изменения в главной ветви репозитория и собирает книгу автоматически. +Самый простой -- поручить это нам. Робот реагирует на изменения в главной ветви репозитория и собирает книгу автоматически. Текущую сборку можно найти на http://git-scm.com/book/ru/v2. -Другой способ получить файл — собрать его самостоятельно с помощью Asciidoctor. Если вы используете команды ниже, то сможете получить HTML, Epub, Mobi и PDF файлы: +Другой способ получить файл -- собрать его самостоятельно с помощью Asciidoctor. Если вы используете команды ниже, то сможете получить HTML, Epub, Mobi и PDF файлы: ---- $ bundle install diff --git a/book/01-introduction/sections/about-version-control.asc b/book/01-introduction/sections/about-version-control.asc index 4b78cb6e..3236a871 100644 --- a/book/01-introduction/sections/about-version-control.asc +++ b/book/01-introduction/sections/about-version-control.asc @@ -2,10 +2,10 @@ (((version control))) Что такое «система контроля версий» и почему это важно? -Система контроля версий — это система, записывающая изменения в файл или набор файлов в течение времени и позволяющая вернуться позже к определённой версии. +Система контроля версий -- это система, записывающая изменения в файл или набор файлов в течение времени и позволяющая вернуться позже к определённой версии. Для контроля версий файлов в этой книге в качестве примера будет использоваться исходный код программного обеспечения, хотя на самом деле вы можете использовать контроль версий практически для любых типов файлов. -Если вы графический или web-дизайнер и хотите сохранить каждую версию изображения или макета (скорее всего, захотите), система контроля версий (далее СКВ) — как раз то, что нужно. +Если вы графический или web-дизайнер и хотите сохранить каждую версию изображения или макета (скорее всего, захотите), система контроля версий (далее СКВ) -- как раз то, что нужно. Она позволяет вернуть файлы к состоянию, в котором они были до изменений, вернуть проект к исходному состоянию, увидеть изменения, увидеть, кто последний менял что-то и вызвал проблему, кто поставил задачу и когда и многое другое. Использование СКВ также значит в целом, что, если вы сломали что-то или потеряли файлы, вы спокойно можете всё исправить. В дополнение ко всему вы получите всё это без каких-либо дополнительных усилий. @@ -28,7 +28,7 @@ RCS хранит на диске наборы патчей (различий м ==== Централизованные системы контроля версий (((version control,centralized))) -Следующая серьёзная проблема, с которой сталкиваются люди, — это необходимость взаимодействовать с другими разработчиками. +Следующая серьёзная проблема, с которой сталкиваются люди, -- это необходимость взаимодействовать с другими разработчиками. Для того, чтобы разобраться с ней, были разработаны централизованные системы контроля версий (ЦСКВ). Такие системы, как CVS, Subversion и Perforce, используют единственный сервер, содержащий все версии файлов, и некоторое количество клиентов, которые получают файлы из этого централизованного хранилища. (((CVS)))(((Subversion)))(((Perforce))) Применение ЦСКВ являлось стандартом на протяжении многих лет. @@ -41,16 +41,16 @@ image::images/centralized.png[Диаграмма централизованно Администраторы имеют полный контроль над тем, кто и что может делать, и гораздо проще администрировать ЦСКВ, чем оперировать локальными базами данных на каждом клиенте. Несмотря на это, данный подход тоже имеет серьёзные минусы. -Самый очевидный минус — это единая точка отказа, представленная централизованным сервером. +Самый очевидный минус -- это единая точка отказа, представленная централизованным сервером. Если этот сервер выйдет из строя на час, то в течение этого времени никто не сможет использовать контроль версий для сохранения изменений, над которыми работает, а также никто не сможет обмениваться этими изменениями с другими разработчиками. -Если жёсткий диск, на котором хранится центральная БД, повреждён, а своевременные бэкапы отсутствуют, вы потеряете всё — всю историю проекта, не считая единичных снимков репозитория, которые сохранились на локальных машинах разработчиков. +Если жёсткий диск, на котором хранится центральная БД, повреждён, а своевременные бэкапы отсутствуют, вы потеряете всё -- всю историю проекта, не считая единичных снимков репозитория, которые сохранились на локальных машинах разработчиков. Локальные СКВ страдают от той же самой проблемы: когда вся история проекта хранится в одном месте, вы рискуете потерять всё. ==== Распределённые системы контроля версий (((version control,distributed))) Здесь в игру вступают распределённые системы контроля версий (РСКВ). -В РСКВ (таких как Git, Mercurial, Bazaar или Darcs) клиенты не просто скачивают снимок всех файлов (состояние файлов на определённый момент времени) — они полностью копируют репозиторий. +В РСКВ (таких как Git, Mercurial, Bazaar или Darcs) клиенты не просто скачивают снимок всех файлов (состояние файлов на определённый момент времени) -- они полностью копируют репозиторий. В этом случае, если один из серверов, через который разработчики обменивались данными, умрёт, любой клиентский репозиторий может быть скопирован на другой сервер для продолжения работы. Каждая копия репозитория является полным бэкапом всех данных. diff --git a/book/01-introduction/sections/basics.asc b/book/01-introduction/sections/basics.asc index 5a6c73f0..be8980ab 100644 --- a/book/01-introduction/sections/basics.asc +++ b/book/01-introduction/sections/basics.asc @@ -7,7 +7,7 @@ Git хранит и использует информацию совсем ин ==== Снимки, а не различия -Основное отличие Git’а от любой другой СКВ (включая Subversion и её собратьев) — это подход Git’а к работе со своими данными. +Основное отличие Git от любой другой СКВ (включая Subversion и её собратьев) -- это подход к работе со своими данными. Концептуально, большинство других систем хранят информацию в виде списка изменений в файлах. Эти системы (CVS, Subversion, Perforce, Bazaar и т.д.) представляют хранимую информацию в виде набора файлов и изменений, сделанных в каждом файле, по времени (обычно это называют контролем версий, _основанным на различиях_). @@ -30,11 +30,11 @@ Git переосмысливает практически все аспекты ==== Почти все операции выполняются локально -Для работы большинства операций в Git достаточно локальных файлов и ресурсов — в основном, системе не нужна никакая информация с других компьютеров в вашей сети. +Для работы большинства операций в Git достаточно локальных файлов и ресурсов -- в основном, системе не нужна никакая информация с других компьютеров в вашей сети. Если вы привыкли к ЦСКВ, где большинство операций страдают от задержек из-за работы с сетью, то этот аспект Git’а заставит вас думать, что боги скорости наделили Git несказанной мощью. Так как вся история проекта хранится прямо на вашем локальном диске, большинство операций кажутся чуть ли не мгновенными. -Для примера, чтобы посмотреть историю проекта, Git’у не нужно соединяться с сервером для её получения и отображения — система просто считывает данные напрямую из локальной базы данных. +Для примера, чтобы посмотреть историю проекта, Git’у не нужно соединяться с сервером для её получения и отображения -- система просто считывает данные напрямую из локальной базы данных. Это означает, что вы увидите историю проекта практически моментально. Если вам необходимо посмотреть изменения, сделанные между текущей версией файла и версией, созданной месяц назад, Git может найти файл месячной давности и локально вычислить изменения, вместо того, чтобы запрашивать удалённый сервер выполнить эту операцию, либо вместо получения старой версии файла с сервера и выполнения операции локально. @@ -81,20 +81,20 @@ SHA-1 хеш выглядит примерно так: * Зафиксированный значит, что файл уже сохранён в вашей локальной базе. * К изменённым относятся файлы, которые поменялись, но ещё не были зафиксированы. -* Подготовленные файлы — это изменённые файлы, отмеченные для включения в следующий коммит. +* Подготовленные файлы -- это изменённые файлы, отмеченные для включения в следующий коммит. Мы подошли к трём основным секциям проекта Git: Git-директория (Git directory), рабочая директория (working directory) и область подготовленных файлов (staging area). .Рабочая директория, область подготовленных файлов и директория Git. image::images/areas.png["Рабочая директория, область подготовленных файлов и директория Git."] -Git-директория — это то место, где Git хранит метаданные и базу объектов вашего проекта. +Git-директория -- это то место, где Git хранит метаданные и базу объектов вашего проекта. Это самая важная часть Git, и это та часть, которая копируется при клонировании репозитория с другого компьютера. Рабочая директория является снимком версии проекта. Файлы распаковываются из сжатой базы данных в Git-директории и располагаются на диске, для того чтобы их можно было изменять и использовать. -Область подготовленных файлов — это файл, обычно располагающийся в вашей Git-директории, в нём содержится информация о том, какие изменения попадут в следующий коммит. +Область подготовленных файлов -- это файл, обычно располагающийся в вашей Git-директории, в нём содержится информация о том, какие изменения попадут в следующий коммит. Эту область ещё называют ``индекс'', однако называть её stage-область также общепринято. Базовый подход в работе с Git выглядит так: diff --git a/book/01-introduction/sections/command-line.asc b/book/01-introduction/sections/command-line.asc index 9dc672fa..5214c11c 100644 --- a/book/01-introduction/sections/command-line.asc +++ b/book/01-introduction/sections/command-line.asc @@ -3,9 +3,9 @@ Есть много различных способов использования Git. Помимо оригинального клиента, имеющего интерфейс командной строки, существует множество клиентов с графическим пользовательским интерфейсом, в той или иной степени реализующих функциональность Git. В рамках данной книги мы будем использовать Git в командной строке. -С одной стороны, командная строка — это единственное место, где вы можете запустить *все* команды Git, так как большинство клиентов с графическим интерфейсом реализуют для простоты только некоторую часть функциональности Git. +С одной стороны, командная строка -- это единственное место, где вы можете запустить *все* команды Git, так как большинство клиентов с графическим интерфейсом реализуют для простоты только некоторую часть функциональности Git. Если вы знаете, как выполнить какое-либо действие в командной строке, вы, вероятно, сможете выяснить, как то же самое сделать и в GUI-версии, а вот обратное не всегда верно. -Кроме того, в то время, как выбор графического клиента — это дело личного вкуса, инструменты командной строки доступны _всем_ пользователям сразу после установки Git. +Кроме того, в то время, как выбор графического клиента -- это дело личного вкуса, инструменты командной строки доступны _всем_ пользователям сразу после установки Git. Поэтому мы предполагаем, что вы знаете, как открыть терминал в Mac или командную строку, или Powershell в Windows. Если вам не понятно, о чем мы здесь говорим, то вам, возможно, придётся ненадолго прерваться и изучить эти вопросы, чтобы вы могли понимать примеры и пояснения из этой книги. diff --git a/book/01-introduction/sections/first-time-setup.asc b/book/01-introduction/sections/first-time-setup.asc index 020b2568..a416de23 100644 --- a/book/01-introduction/sections/first-time-setup.asc +++ b/book/01-introduction/sections/first-time-setup.asc @@ -2,7 +2,7 @@ === Первоначальная настройка Git Теперь, когда Git установлен в вашей системе, самое время настроить среду для работы с Git под себя. -Это нужно сделать только один раз — при обновлении версии Git настройки сохранятся. +Это нужно сделать только один раз -- при обновлении версии Git настройки сохранятся. Но, при необходимости, вы можете поменять их в любой момент, выполнив те же команды снова. В состав Git входит утилита `git config`, которая позволяет просматривать и настраивать параметры, контролирующие все аспекты работы Git, а также его внешний вид. @@ -35,7 +35,7 @@ $ git config --list --show-origin ==== Имя пользователя -Первое, что вам следует сделать после установки Git — указать ваше имя и адрес электронной почты. +Первое, что вам следует сделать после установки Git -- указать ваше имя и адрес электронной почты. Это важно, потому что каждый коммит в Git содержит эту информацию, и она включена в коммиты, передаваемые вами, и не может быть далее изменена: [source,console] @@ -74,7 +74,7 @@ $ git config --global core.editor "'C:/Program Files/Notepad++/notepad++.exe' -m [NOTE] ==== -Vim, Emacs и Notepad++ — популярные текстовые редакторы, которые часто используются разработчиками как в Unix-подобных системах, таких как Linux и Mac, так и в Windows. +Vim, Emacs и Notepad++ -- популярные текстовые редакторы, которые часто используются разработчиками как в Unix-подобных системах, таких как Linux и Mac, так и в Windows. Если вы используете другой редактор или его 32-битную версию, то обратитесь к разделу <> за дополнительными инструкциями как использовать его совместно с Git. ==== diff --git a/book/01-introduction/sections/history.asc b/book/01-introduction/sections/history.asc index 38baf9eb..860b5bc1 100644 --- a/book/01-introduction/sections/history.asc +++ b/book/01-introduction/sections/history.asc @@ -2,12 +2,12 @@ Как и многие вещи в жизни, Git начинался с капелькой творческого хаоса и бурных споров. -Ядро Linux — это достаточно большой проект с открытым исходным кодом.(((Linux))) +Ядро Linux -- это достаточно большой проект с открытым исходным кодом.(((Linux))) Большую часть времени разработки ядра Linux (1991-2002 гг.) изменения передавались между разработчиками в виде патчей и архивов. В 2002 году проект ядра Linux начал использовать проприетарную децентрализованную СКВ BitKeeper. В 2005 году отношения между сообществом разработчиков ядра Linux и коммерческой компанией, которая разрабатывала BitKeeper, прекратились, и бесплатное использование утилиты стало невозможным. -Это сподвигло сообщество разработчиков ядра Linux (а в частности Линуса Торвальдса — создателя Linux) разработать свою собственную утилиту, учитывая уроки, полученные при работе с BitKeeper.(((Linus Torvalds))) +Это сподвигло сообщество разработчиков ядра Linux (а в частности Линуса Торвальдса -- создателя Linux) разработать свою собственную утилиту, учитывая уроки, полученные при работе с BitKeeper.(((Linus Torvalds))) Некоторыми целями, которые преследовала новая система, были: * Скорость diff --git a/book/01-introduction/sections/installing.asc b/book/01-introduction/sections/installing.asc index 6bfcc7e4..6a20ac85 100644 --- a/book/01-introduction/sections/installing.asc +++ b/book/01-introduction/sections/installing.asc @@ -34,7 +34,7 @@ $ sudo apt install git (((Mac, installing))) Существует несколько способов установки Git на Mac. -Самый простой — установить Xcode Command Line Tools.(((Xcode))) +Самый простой -- установить Xcode Command Line Tools.(((Xcode))) В версии Mavericks (10.9) и выше вы можете добиться этого просто первый раз выполнив 'git' в терминале. [source,console] @@ -64,7 +64,7 @@ image::images/git-osx-installer.png[OS X инсталлятор Git.] Для автоматической установки вы можете использовать https://chocolatey.org/packages/git[пакет Git Chocolatey]. Обратите внимание, что пакет Chocolatey поддерживается сообществом. -Другой простой способ установки Git — установить GitHub для Windows. +Другой простой способ установки Git -- установить GitHub для Windows. Его установщик включает в себя утилиты командной строки и GUI Git. Он также корректно работает с Powershell, обеспечивает чёткое сохранение учётных данных и правильные настройки CRLF.(((Powershell)))(((CRLF)))(((credential caching))) Вы познакомитесь с этими вещами подробнее несколько позже, здесь же отметим, что они будут вам необходимы. diff --git a/book/03-git-branching/sections/basic-branching-and-merging.asc b/book/03-git-branching/sections/basic-branching-and-merging.asc index 0d6f4b4c..40640030 100644 --- a/book/03-git-branching/sections/basic-branching-and-merging.asc +++ b/book/03-git-branching/sections/basic-branching-and-merging.asc @@ -59,9 +59,9 @@ image::images/basic-branching-3.png[Ветка iss53 двигается впер Тут вы получаете сообщение об обнаружении уязвимости на вашем сайте, которую нужно немедленно устранить. Благодаря Git, не требуется размещать это исправление вместе с тем, что вы сделали в `iss53`. Вам даже не придется прилагать усилий, чтобы откатить все эти изменения для начала работы над исправлением. -Все, что вам нужно — переключиться на ветку `master`. +Все, что вам нужно -- переключиться на ветку `master`. -Но перед тем как сделать это — имейте в виду, что если ваш рабочий каталог либо область подготовленных файлов содержат изменения, не попавшие в коммит и конфликтующие с веткой, на которую вы хотите переключиться, то Git не позволит вам переключить ветки. +Но перед тем как сделать это -- имейте в виду, что если ваш рабочий каталог либо область подготовленных файлов содержат изменения, не попавшие в коммит и конфликтующие с веткой, на которую вы хотите переключиться, то Git не позволит вам переключить ветки. Лучше всего переключаться из чистого рабочего состояния проекта. Есть способы обойти это (спрятать (stash) или исправить (amend) коммиты), но об этом мы поговорим позже в главе <>. Теперь предположим, что вы зафиксировали все свои изменения и можете переключиться на ветку `master`: @@ -92,7 +92,7 @@ $ git commit -a -m 'fixed the broken email address' .Ветка hotfix основана на ветке `master` image::images/basic-branching-4.png[Ветка hotfix основана на ветке `master`.] -Вы можете прогнать тесты, чтобы убедиться, что ваше исправление делает именно то, что нужно. И если это так — выполнить слияние ветки `hotfix` с веткой `master` для включения изменений в продукт. +Вы можете прогнать тесты, чтобы убедиться, что ваше исправление делает именно то, что нужно. И если это так -- выполнить слияние ветки `hotfix` с веткой `master` для включения изменений в продукт. Это делается командой `git merge`:(((git commands, merge))) [source,console] @@ -316,4 +316,4 @@ Conflicts: # ---- -Если вы считаете, что коммит слияния требует дополнительных пояснений - опишите как были разрешены конфликты и почему были применены именно такие изменения, если это не очевидно. +Если вы считаете, что коммит слияния требует дополнительных пояснений -- опишите как были разрешены конфликты и почему были применены именно такие изменения, если это не очевидно. diff --git a/book/03-git-branching/sections/nutshell.asc b/book/03-git-branching/sections/nutshell.asc index a2a18497..702b4c3e 100644 --- a/book/03-git-branching/sections/nutshell.asc +++ b/book/03-git-branching/sections/nutshell.asc @@ -30,14 +30,14 @@ image::images/commit-and-tree.png[Коммит и его дерево.] .Коммит и его родители image::images/commits-and-parents.png[Коммит и его родители.] -Ветка в Git — это простой перемещаемый указатель на один из таких коммитов. +Ветка в Git -- это простой перемещаемый указатель на один из таких коммитов. По умолчанию, имя основной ветки в Git -- `master`. Как только вы начнёте создавать коммиты, ветка `master` будет всегда указывать на последний коммит. Каждый раз при создании коммита указатель ветки `master` будет передвигаться на следующий коммит автоматически. [NOTE] ==== -Ветка ``master'' в Git — это не какая-то особенная ветка.(((master))) +Ветка ``master'' в Git -- это не какая-то особенная ветка.(((master))) Она точно такая же, как и все остальные ветки. Она существует почти во всех репозиториях только лишь потому, что ее создает команда `git init`, а большинство людей не меняют ее название. ==== @@ -137,7 +137,7 @@ image::images/checkout-master.png[HEAD перемещается, когда вы ==== Важно запомнить, что при переключении веток в Git происходит изменение файлов в рабочей директории. Если вы переключаетесь на старую ветку, то рабочий каталог будет выглядеть так же, как выглядел на момент последнего коммита в ту ветку. -Если Git по каким-то причинам не может этого сделать — он не позволит вам переключиться вообще. +Если Git по каким-то причинам не может этого сделать -- он не позволит вам переключиться вообще. ==== Давайте сделаем еще несколько изменений и создадим очередной коммит: diff --git a/book/03-git-branching/sections/rebasing.asc b/book/03-git-branching/sections/rebasing.asc index d74aee90..12f7fb21 100644 --- a/book/03-git-branching/sections/rebasing.asc +++ b/book/03-git-branching/sections/rebasing.asc @@ -57,7 +57,7 @@ image::images/basic-rebase-4.png[Перемотка ветки master.] В этом случае вам следует работать в своей ветке и затем перебазировать вашу работу поверх `origin/master`, когда вы будете готовы отправить свои изменения в основной проект. Тогда владельцу проекта не придется делать никакой лишней работы -- все решится простой перемоткой или бесконфликтным слиянием. -Учтите, что снимок, на который ссылается ваш последний коммит — является ли он последним коммитом после перебазирования или коммитом слияния после слияния — в обоих случаях это один и тот же снимок, отличаются только истории коммитов. +Учтите, что снимок, на который ссылается ваш последний коммит -- является ли он последним коммитом после перебазирования или коммитом слияния после слияния -- в обоих случаях это один и тот же снимок, отличаются только истории коммитов. Перебазирование повторяет изменения из одной ветки поверх другой в том порядке, в котором эти изменения были сделаны, в то время как слияние берет две конечные точки и сливает их вместе. ==== Более интересные перемещения @@ -193,7 +193,7 @@ image::images/perils-of-rebasing-4.png[Вы снова выполняете сл * Определять, какая работа уникальна для вашей ветки (C2, C3, C4, C6, C7) * Определять, какие коммиты не были коммитами слияния (C2, C3, C4) -* Определять, что не было перезаписано в основной ветке (только C2 и C3, поскольку C4 - это тот же патч, что и C4') +* Определять, что не было перезаписано в основной ветке (только C2 и C3, поскольку C4 -- это тот же патч, что и C4') * Применять эти коммиты к ветке `teamone/master` Таким образом, вместо результата, который мы можем наблюдать на <>, у нас получилось бы что-то вроде <>. @@ -221,18 +221,18 @@ image::images/perils-of-rebasing-5.png[Перемещение в начало fo Теперь, когда вы увидели перемещение и слияние в действии, вы можете задаться вопросом, что из них лучше. Прежде чем ответить на этот вопрос, давайте вернёмся немного назад и поговорим о том, что означает история. -Одна из точек зрения заключается в том, что история коммитов в вашем репозиториии - это *запись того, что на самом деле произошло*. +Одна из точек зрения заключается в том, что история коммитов в вашем репозиториии -- это *запись того, что на самом деле произошло*. Это исторический документ, ценный сам по себе, и его нельзя подделывать. С этой точки зрения изменение истории коммитов практически кощунственно; вы _лжете_ о том, что на самом деле произошло. Но что, если произошла путаница в коммитах слияния? Если это случается, репозиторий должен сохранить это для потомков. -Противоположная точка зрения заключается в том, что история коммитов - это *история того, как был сделан ваш проект*. +Противоположная точка зрения заключается в том, что история коммитов -- это *история того, как был сделан ваш проект*. Вы не публикуете первый черновик книги или инструкции по поддержке вашего программного обеспечения, так как это нуждается в тщательном редактировании. Сторонники этого лагеря считают использование инструментов `rebase` и `filter-branch` способом рассказать историю проекта наилучшим образом для будущих читателей. -Теперь к вопросу о том, что лучше - слияние или перебазирование: надеюсь, вы видите, что это не так просто. -Git - мощный инструмент, позволяющий вам делать многое с вашей историей, однако каждая команда и каждый проект индивидуален. -Теперь, когда вы знаете, как работают оба эти приёма, выбор - какой из них будет лучше в вашей ситуации - решать вам. +Теперь к вопросу о том, что лучше -- слияние или перебазирование: надеюсь, вы видите, что это не так просто. +Git -- мощный инструмент, позволяющий вам делать многое с вашей историей, однако каждая команда и каждый проект индивидуален. +Теперь, когда вы знаете, как работают оба эти приёма, выбор -- какой из них будет лучше в вашей ситуации -- решать вам. -В основном, стоит взять лучшее от обоих миров - использовать перебазирование для наведения порядка в истории ваших локальных изменений, ещё не отправленных на удаленный сервер, но никогда не применять перебазирование для уже отправленных куда-нибудь изменений. +В основном, стоит взять лучшее от обоих миров -- использовать перебазирование для наведения порядка в истории ваших локальных изменений, ещё не отправленных на удаленный сервер, но никогда не применять перебазирование для уже отправленных куда-нибудь изменений. diff --git a/book/03-git-branching/sections/remote-branches.asc b/book/03-git-branching/sections/remote-branches.asc index a2284467..f49612ff 100644 --- a/book/03-git-branching/sections/remote-branches.asc +++ b/book/03-git-branching/sections/remote-branches.asc @@ -20,7 +20,7 @@ Git также создаст вам локальную ветку `master`, которая будет начинаться там же, где и ветка `master` в `origin`, так что вам будет с чего начать. [NOTE] -.``origin'' — это не специальное название +.``origin'' -- это не специальное название ==== Подобно названию ветки ``master'', ``origin'' не имеет какого-либо специального значения в Git. В то время как ``master'' -- это название по умолчанию для ветки при выполнении `git init` только потому что часто используется, ``origin'' -- это название по умолчанию для удаленного сервера когда вы запускаете `git clone`. diff --git a/book/03-git-branching/sections/workflows.asc b/book/03-git-branching/sections/workflows.asc index 7975e85d..f44f26ff 100644 --- a/book/03-git-branching/sections/workflows.asc +++ b/book/03-git-branching/sections/workflows.asc @@ -36,7 +36,7 @@ image::images/lr-branches-2.png[Представление диаграммы с (((branches, topic))) А вот такая вещь, как тематические ветки, полезна вне зависимости от величины проекта. Тематической веткой называется временная ветка, создаваемая и используемая для работы над конкретной функциональной возможностью или решения сопутствующих задач. -Скорее всего, при работе с другими СКВ вы никогда ничего подобного не делали, так как там создание и слияние веток — затратные операции. +Скорее всего, при работе с другими СКВ вы никогда ничего подобного не делали, так как там создание и слияние веток -- затратные операции. Но в Git это обычное дело -- много раз в день создавать ветки, работать с ними, сливать их и удалять. Пример тематических веток вы видели в предыдущем разделе, когда мы создавали ветки `iss53` и `hotfix`. diff --git a/book/04-git-server/sections/git-daemon.asc b/book/04-git-server/sections/git-daemon.asc index 05ad1aaa..796156c2 100644 --- a/book/04-git-server/sections/git-daemon.asc +++ b/book/04-git-server/sections/git-daemon.asc @@ -3,7 +3,7 @@ (((serving repositories, git protocol))) Далее мы установим демон, обслуживающий репозитории по протоколу ``Git''. Это широко распространённый вариант для быстрого доступа без аутентификации. -Помните, что раз сервис — без аутентификации, всё, что обслуживается по этому протоколу — публично доступно в сети. +Помните, что раз сервис -- без аутентификации, всё, что обслуживается по этому протоколу -- публично доступно в сети. Если вы запускаете демон на сервере не за сетевым экраном, он должен использоваться только для проектов, которые публично видны внешнему миру. Если сервер находится за вашим сетевым экраном, вы можете использовать его для проектов, к которым большое число людей или компьютеров (серверов непрерывной интеграции или сборки) должно иметь доступ только на чтение, и если вы не хотите для каждого из них заводить SSH-ключ. diff --git a/book/04-git-server/sections/gitlab.asc b/book/04-git-server/sections/gitlab.asc index b52302cc..576b31df 100644 --- a/book/04-git-server/sections/gitlab.asc +++ b/book/04-git-server/sections/gitlab.asc @@ -8,19 +8,19 @@ GitWeb довольно-таки прост. ==== Установка -GitLab — это веб-приложение на основе базы данных, так что его установка немного сложней, чем у некоторых других серверов git. +GitLab -- это веб-приложение на основе базы данных, так что его установка немного сложней, чем у некоторых других серверов git. К счастью, этот процесс хорошо задокументирован и поддерживается. Есть несколько подходов к установке GitLab. -Для экономии времени, вы можете загрузить образ виртуальной машины или инсталлятор из https://bitnami.com/stack/gitlab[], и поправить конфигурацию под своё окружение.(((bitnami))) -Приятная возможность, включенная Bitnami, это экран входа (доступен по нажатию alt-→); он указывает IP-адрес и логин с паролем по умолчанию для установленного GitLab. +Для экономии времени, вы можете загрузить образ виртуальной машины или инсталлятор с https://bitnami.com/stack/gitlab[] и поправить конфигурацию под своё окружение.(((bitnami))) +Приятная возможность, включенная Bitnami, это экран входа (доступен по нажатию alt+→); он указывает IP-адрес и логин с паролем по умолчанию для установленного GitLab. [[rbitnami]] .Экран входа виртуальной машины Bitnami GitLab. image::images/bitnami.png[Экран входа виртуальной машины Bitnami GitLab.] Для всего остального, следуйте инструкциям GitLab Community Edition, которые можно найти на https://gitlab.com/gitlab-org/gitlab-ce/tree/master[]. -Там вы найдёте помощь по установке GitLab посредством рецептов Chef, на виртуальную машину Digital Ocean, или из RPM или DEB пакетов (которые на момент написания всё ещё находились в бета-версии). +Там вы найдёте помощь по установке GitLab посредством рецептов Chef, виртуальную машину для Digital Ocean, или из RPM или DEB пакетов (которые на момент написания всё ещё находились в бета-версии). Есть также ``неофициальная'' инструкция по запуску GitLab на нестандартных операционных системах и базах данных, полностью ручной сценарий установки и множество других тем. ==== Администрирование @@ -36,7 +36,7 @@ image::images/gitlab-menu.png[Пункт ``Административная зо ===== Пользователи -Пользователи в GitLab — это учётные записи, соответствующие людям. +Пользователи в GitLab -- это учётные записи, соответствующие людям. Пользовательские учётные записи не очень сложны; в основном это набор персональной информации, прикреплённый к имени. У каждого пользователя есть *пространство имён*, логически группирующее проекты данного пользователя. Если у пользователя +jane+ есть проект +project+, адрес этого проекта будет http://server/jane/project[]. @@ -55,7 +55,7 @@ image::images/gitlab-users.png[Экран управления пользова [[r_gitlab_groups_section]] ===== Группы -Группы GitLab — это коллекция проектов с указанием того, как пользователи получают к ним доступ. +Группы GitLab -- это коллекция проектов с указанием того, как пользователи получают к ним доступ. Каждая группа имеет пространство имён проектов (так же как и пользователи), так что если в группе +training+ есть проект +materials+, его адрес будет http://server/training/materials[]. [[rgitlab_groups]] @@ -113,11 +113,11 @@ $ git clone https://server/namespace/project.git ==== Совместная работа -Самый простой метод совместной работы над проектом GitLab — это выдача другому пользователю прямого доступа на запись (push) в git-репозитории. +Самый простой метод совместной работы над проектом GitLab -- это выдача другому пользователю прямого доступа на запись (push) в git-репозитории. Вы можете добавить пользователя в проект в разделе ``Участники'' (``Members'') настроек проекта, указав уровень доступа (уровни доступа кратко обсуждались в <>). Получая уровень доступа ``Разработчик'' (``Developer'') или выше, пользователь может невозбранно отсылать свои коммиты и ветки непосредственно в репозиторий. -Другой, более разобщённый способ совместной работы — использование запросов на слияние (merge requests). +Другой, более разобщённый способ совместной работы -- использование запросов на слияние (merge requests). Эта возможность позволяет любому пользователю, который видит проект, вносить свой вклад подконтрольным способом. Пользователи с прямым доступом могут просто создать ветку, отослать в неё коммиты и открыть запрос на слияние из их ветки обратно в `master` или любую другую ветку. Пользователи без доступа на запись могут ``форкнуть'' репозиторий (``fork'', создать собственную копию), отправить коммиты в _эту_ копию и открыть запрос на слияние из их форка обратно в основной проект. @@ -127,5 +127,5 @@ $ git clone https://server/namespace/project.git Каждый запрос на слияние допускает построчное обсуждение предлагаемого изменения (поддерживая облегчённое рецензирование кода), равно как и общее обсуждение. И те и другие могут присваиваться пользователям или организовываться в вехи (milestones). -Мы в основном сосредоточились на частях GitLab, связанных с git, но это — довольно зрелая система, и она предоставляет много других возможностей, помогающих вашей команде работать совместно, например вики-страницы для проектов и инструменты поддержки системы. +Мы в основном сосредоточились на частях GitLab, связанных с git, но это -- довольно зрелая система, и она предоставляет много других возможностей, помогающих вашей команде работать совместно, например вики-страницы для проектов и инструменты поддержки системы. Одно из преимуществ GitLab в том, что, однажды запустив и настроив сервер, вам редко придётся изменять конфигурацию или заходить на него по SSH; большинство административных и пользовательских действий можно выполнять через веб-браузер. diff --git a/book/04-git-server/sections/protocols.asc b/book/04-git-server/sections/protocols.asc index 5f8013f6..92f597bd 100644 --- a/book/04-git-server/sections/protocols.asc +++ b/book/04-git-server/sections/protocols.asc @@ -145,7 +145,7 @@ $ git clone https://example.com/gitproject.git (((protocols, SSH))) Часто используемый транспортный протокол для самостоятельного хостинга Git -- это SSH. Причина этого в том, что доступ по SSH уже есть на многих серверах, а если его нет, то его очень легко настроить. -К тому же, SSH — протокол с аутентификацией, и его благодаря распространенности обычно легко настроить и использовать. +К тому же, SSH -- протокол с аутентификацией, и его благодаря распространенности обычно легко настроить и использовать. Чтобы клонировать Git-репозиторий по SSH, вы можете указать префикс `ssh://`` в URL, например: diff --git a/book/05-distributed-git/sections/contributing.asc b/book/05-distributed-git/sections/contributing.asc index 2a243c71..6814a741 100644 --- a/book/05-distributed-git/sections/contributing.asc +++ b/book/05-distributed-git/sections/contributing.asc @@ -2,25 +2,25 @@ === Участие в проекте (((contributing))) -Как именно участвовать в проекте - описать сложно, так как существует очень много различных вариаций как это делать. -Так как Git очень гибок, люди могут и работают вместе по разному. Отсюда и проблема описания участия в проекте - все проекты разные. +Как именно участвовать в проекте -- описать сложно, так как существует очень много различных вариаций как это делать. +Так как Git очень гибок, люди могут и работают вместе по разному. Отсюда и проблема описания участия в проекте -- все проекты разные. Переменными здесь являются: количество активных участников, выбранный рабочий процесс, права доступа и, возможно, метод организации внесения вклада в проект из вне. -Первая переменная - количество активных участников - подразумевает количество пользователей, котороые активно отправляют свой код в проект и как часто они это делают. +Первая переменная -- количество активных участников -- подразумевает количество пользователей, котороые активно отправляют свой код в проект и как часто они это делают. В большинстве случаев у вас два или три разработчика, которые делают по несколько коммитов в день или меньше, если речь идёт о вялотекущих проектах. В больших компаниях или проектах количество разработчиков может исчисляться тысячами с сотнями тысяч коммитов в день. Это очень важно, так как при увеличении количества разработчиков вы сталкиваетесь со всё большим количеством проблем, связанных со встраиванием или слиянием нового кода. Изменения, которые вы отправляете, могут быть признаны устаревшимим или быть серьёзно затронутыми уже примененными изменениями, пока ваши ожидали одобрения. Как в таком случае можно быть уверенным, что ваш код консистентен и актуален, а ваши коммиты валидны? -Следующая переменная - это используемый рабочий процесс. +Следующая переменная -- это используемый рабочий процесс. Централизован ли рабочий процесс и обладают ли все разработчики одинаковыми правами на запись в основную ветку разработки? Существует ли менеджер по интеграции или сопровождающий, кто проверяет все патчи? Все ли патчи проверяются другими разработчиками и проходят одобрение? Вы вовлечены в этот процесс? Существует ли лейтенант, которому следует отправить изменения прежде, чем в основной репозиторий? -Следующая проблема - это уровень доступа. +Следующая проблема -- это уровень доступа. Рабочий процесс, используемый для участия в проекте, может сильно отличаться в зависимости от того, есть ли у вас доступ на запись или нет. Если у вас нет доступа на запись, то как проект принимает изменения? Существует ли вообще политика принятия изменений? @@ -35,11 +35,11 @@ Прежде чем мы начнём рассматривать конкретные варианты использования, давайте вспомним о сообщениях к коммитам. Наличие четких рекомендаций по созданию коммитов и их соблюдение делают работу с Git и взаимодействие с другими гораздо проще. -Проект Git предоставляет документ, в котором содержится ряд полезных советов по созданию коммитов для отправки патчей - вы можете ознакомиться с ними, прочитав файл `Documentation/SubmittingPatches`, находящийся в исходных кодах Git. +Проект Git предоставляет документ, в котором содержится ряд полезных советов по созданию коммитов для отправки патчей -- вы можете ознакомиться с ними, прочитав файл `Documentation/SubmittingPatches`, находящийся в исходных кодах Git. (((git commands, diff, check))) Для начала, вам не следует отправлять ненужные пробелы. -Git предоставляет простой способ проверки - перед коммитом выполните команду `git diff --check`, которая выведет список ненужных пробелов. +Git предоставляет простой способ проверки -- перед коммитом выполните команду `git diff --check`, которая выведет список ненужных пробелов. .Вывод команды `git diff --check`. image::images/git-diff-check.png[Вывод команды `git diff --check`.] @@ -47,19 +47,19 @@ image::images/git-diff-check.png[Вывод команды `git diff --check`.] выполняя эту команду перед коммитом вы сможете избежать отправки ненужных пробелов, которые могут раздражать других разработчиков. Далее, постарайтесь делать коммит логически разделенного набора изменений. -Если возможно, попытайтесь делать ваши изменения легко понятными - не нужно писать код все выходные, работая над пятью разными задачами, а в понедельник отправлять результат как один большой коммит. +Если возможно, попытайтесь делать ваши изменения легко понятными -- не нужно писать код все выходные, работая над пятью разными задачами, а в понедельник отправлять результат как один большой коммит. Даже если вы не делали коммиты на выходных, то в понедельник используйте область подготовленных файлов для того, чтобы разделить проделанную работу по принципу минимум один коммит на задачу, давая полезные комментарии к каждому из них. Если несколько изменений касаются одного файла, используйте `git add --patch` для частичного добавления файлов в индекс (детально описано в <>). Состояние проекта в конце ветки не зависит от количества сделанных вами коммитов, так как все изменения добавятся в один момент, поэтому постарайтесь облегчить задачу вашим коллегам, когда они будут просматривать ваши изменения. Такой подход так же облегчает ивлечение или отмену отдельных изменений, если это вдруг потребуется в будущем. -<> описывает ряд полезных трюков Git для переписывания истории изменений и интерактивного инексирования - используйте эти инструменты для создания чистой и понятной истории перед отправкой проделанной работы кому-то ещё. +<> описывает ряд полезных трюков Git для переписывания истории изменений и интерактивного инексирования -- используйте эти инструменты для создания чистой и понятной истории перед отправкой проделанной работы кому-то ещё. -Последнее, что нужно иметь ввиду - это сообщение коммита. +Последнее, что нужно иметь ввиду -- это сообщение коммита. Привычка создавать качественные сообщения к коммитам позволяет упростить использование и взаимодействие посредством Git. Как правило, ваши сообщения должны начинаться кратким однострочным описанием не более 50 символов, затем должна идти пустая строка, после которой следует более детальное описание. -Проект Git требует, чтобы детальное описание включало вашу мотивацию при внесении изменения и сравнение с текущей реализацией - это хороший пример для подражания. +Проект Git требует, чтобы детальное описание включало вашу мотивацию при внесении изменения и сравнение с текущей реализацией -- это хороший пример для подражания. Так же хорошей идеей будет использование фраз в повелительном наклонении настоящего времени. -Другими словами - используйте команды. +Другими словами -- используйте команды. Вместо ``Я добавил тесты для'' или ``Добавление тестов для'', используйте ``Добавить тесты для''. Ниже представлен шаблон, написанный Tim Pope: @@ -69,7 +69,7 @@ image::images/git-diff-check.png[Вывод команды `git diff --check`.] Текст более детального описания, если необходим. Старайтесь не первышать длинну строки в 72 символа. В некоторых случаях -первая строка подразумевается как тема письма, а всё остальное - +первая строка подразумевается как тема письма, а всё остальное -- тело письма. Пустая строка, разделяющая сообщение, критически важна (если существует детальное описание); такие утилиты как rebase могут запутаться, если вы запустите сразу две. @@ -84,7 +84,7 @@ image::images/git-diff-check.png[Вывод команды `git diff --check`.] ----- Вам и вашим разработчикам будет гораздо проще, если все сообщения ваших коммитов будут так выглядеть. -В проекте Git все сообщения хорошо отформатированы - выполните команду `git log --no-merges`, чтобы увидеть как выглядит хорошо отформатированная история коммитов. +В проекте Git все сообщения хорошо отформатированы -- выполните команду `git log --no-merges`, чтобы увидеть как выглядит хорошо отформатированная история коммитов. В последующих примерах, как и практически везде в этой книге, для краткости не используется расширенное форматирование; вместо этого используется опция `-m` команды `git commit`. Делайте как мы говорим, а не так как делаем мы. @@ -95,7 +95,7 @@ image::images/git-diff-check.png[Вывод команды `git diff --check`.] (((contributing, private small team))) Самая простая ситуация, с которой вы можете столкнуться, это приватный проект с одинм или двумя другими разработчиками. -``Частная'' - в данном контесте понимается как проект с закрытым исходным кодом, недоступный для внешнего мира. Вы и другие разработчики имеете права записи в репозиторий. +``Частная'' -- в данном контесте понимается как проект с закрытым исходным кодом, недоступный для внешнего мира. Вы и другие разработчики имеете права записи в репозиторий. В такой среде вы можете использовать рабочий процесс, при котором выполняемые действия анологичны использованию Subversion или другой централизованной системе. Вы всё ещё можете использовать преимущества создания коммитов оффлайн, значительно более простое ветвление и слияние, но процесс будет очень похожим; основное отличие в том, что слияние происходит на стороне клиента, а не на сервере во время коммита. @@ -116,7 +116,7 @@ $ git commit -am 'removed invalid default value' 1 files changed, 1 insertions(+), 1 deletions(-) ----- -Второй разработчик Джессика делает тоже самое - клонирует репозиторий и делает коммит: +Второй разработчик Джессика делает тоже самое -- клонирует репозиторий и делает коммит: [source,console] ----- @@ -181,7 +181,7 @@ Merge made by recursive. 1 files changed, 1 insertions(+), 0 deletions(-) ----- -Процесс слияния проходит гладко - история коммитов у Джона выглядит примерно так: +Процесс слияния проходит гладко -- история коммитов у Джона выглядит примерно так: .Репозиторий Джона после слияния с `origin/master`. image::images/small-team-2.png[Репозиторий Джона после слияния с `origin/master`.] @@ -237,7 +237,7 @@ Date: Fri May 29 16:01:27 2009 -0700 removed invalid default value ----- -`issue54..origin/master` - это синтаксис фильтра, который указывает Git отображать только список коммитов, которые существуют в последней ветке (в данном случае `origin/master`), но отсутствуют в первой (в данном случае `issue54`). Более детально этот синтаксис рассматривается в главе <>. +`issue54..origin/master` -- это синтаксис фильтра, который указывает Git отображать только список коммитов, которые существуют в последней ветке (в данном случае `origin/master`), но отсутствуют в первой (в данном случае `issue54`). Более детально этот синтаксис рассматривается в главе <>. В данном случае, в выводе команды мы видим только один коммит, сделанный Джоном и ещё не слитый Джессикой. Если она сольёт `origin/master`, то это будет единственный коммит, который изменит локальное состояние. @@ -395,7 +395,7 @@ Merge made by recursive. 1 files changed, 4 insertions(+), 0 deletions(-) ----- -Одна небольшая проблема - ей нужно отправить слитые изменения из локальной ветки `featureB` в ветку `featureBee` на сервере. +Одна небольшая проблема -- ей нужно отправить слитые изменения из локальной ветки `featureB` в ветку `featureBee` на сервере. Для этого в комаде `git push` Джессика указывает названия локальной и удаленной веток, разделенных двоеточием: [source,console] @@ -471,7 +471,7 @@ image::images/managed-team-2.png[История коммитов Джессик image::images/managed-team-3.png[История коммитов Джессики после слияния тематических веток.] Многие переходят на Git именно из-за возможности параллельной работы нескольких команд в различных направлениях с последующим слиянием проделанной работы. -Возможность совместной работы небольших подгрупп команды в удаленных ветках без необходимости вовлекать или мешать всей команде - огромное преимущество Git. +Возможность совместной работы небольших подгрупп команды в удаленных ветках без необходимости вовлекать или мешать всей команде -- огромное преимущество Git. Последовательность действий в описанном рабочем процессе выглядит следующим образом: .Основная последовательность описанного рабочего процесса управляемой команды. @@ -526,7 +526,7 @@ $ git push -u myfork featureA (((git commands, request-pull))) Когда ваши изменения отправлены в ваш форк, следует уведомить об этом сопровождающего проекта. -Обычно, это называется запросом слияния, который вы можете создать используя веб сайт - GitHub использует собственный механизм запросов слияния, который будет рассмотрен в разделе <> - или используя команду `git request-pull` отправить её вывод по почте. +Обычно, это называется запросом слияния, который вы можете создать используя веб сайт -- GitHub использует собственный механизм запросов слияния, который будет рассмотрен в разделе <> -- или используя команду `git request-pull` отправить её вывод по почте. Команда `request-pull` принимает в качестве аргументов название базовой ветки, в которую следует влить изменения из вашей тематической ветки, и ссылку на Git репозиторий, из которого следут получать изменения, а результатом будет список всех изменений, которые вы предлагаете внести. Например, если Джессика хочет отправить Джону запрос слияния и она отправила два коммита в тематическую ветку, то ей следует выполнить команду: @@ -550,11 +550,11 @@ Jessica Smith (2): 1 files changed, 9 insertions(+), 1 deletions(-) ----- -Вывод команды можно отправить сопровождающему проекта - в нём говорится с какого момента велась работа, приводится сводка коммитов и указывается откуда можно получить эти изменения. +Вывод команды можно отправить сопровождающему проекта -- в нём говорится с какого момента велась работа, приводится сводка коммитов и указывается откуда можно получить эти изменения. В проектах, где вы не являеетесь сопровождающим, проще держать ветку `master` в соответствии с `origin/master`, а работать в тематических ветках, так вам будет проще отменить изменения, если они будут отклонены. Разделение направлений разработки по изолированным веткам облегчит их перебазирование, когда состояние основного репозитория изменится, а ваши коммиты уже не смогут быть чисто применены. -Например, если вы собираетесь отправить исправления на другую тему, не продолжайте работать в той же тематической ветке - создайте новую, базируясь на ветке `master` основного репозитория: +Например, если вы собираетесь отправить исправления на другую тему, не продолжайте работать в той же тематической ветке -- создайте новую, базируясь на ветке `master` основного репозитория: [source,console] ----- @@ -566,7 +566,7 @@ $ git push myfork featureB $ git fetch origin ----- -Теперь, каждая из ваших тематик разработки изолирована - аналогично очереди патчей - каждую из которых можно переписать, перебазировать или исправить без влияния на другие ветки: +Теперь, каждая из ваших тематик разработки изолирована -- аналогично очереди патчей -- каждую из которых можно переписать, перебазировать или исправить без влияния на другие ветки: .История коммитов в начале работы над `featureB`. image::images/public-small-1.png[История коммитов в начале работы над `featureB`.] @@ -617,11 +617,11 @@ image::images/public-small-3.png[История коммитов после ра ==== Публичный проект посредством E-Mail (((contributing, public large project))) -Много проектов имеют устоявшиеся процедуры по принятию патчей - вам следует знакомиться с правилами для каждого проекта, так как они могут отличаться. +Много проектов имеют устоявшиеся процедуры по принятию патчей -- вам следует знакомиться с правилами для каждого проекта, так как они могут отличаться. Так как существует несколько больших старых проектов, которые принимают патчи посредством почтовых рассылок, мы рассмотрим такой пример. -Рабочий процесс схожий - вы создаёте тематическую ветку для каждого набора патчей, над которыми собираетесь работать. -Основное отличие - это способ их передачи проекту. +Рабочий процесс схожий -- вы создаёте тематическую ветку для каждого набора патчей, над которыми собираетесь работать. +Основное отличие -- это способ их передачи проекту. Вместо того, чтобы создать форк и отправить в него свои изменения, вы генерируете e-mail версию для каждого набора коммитов и отправляете её в почтовую рассылку разработчиков: [source,console] @@ -635,7 +635,7 @@ $ git commit (((git commands, format-patch))) Сейчас у вас два коммита, которые вы хотите отправить в почтовую рассылку. -Используйте команду `git format-patch` для генерации файлов в формате mbox, которые можно отправить по почте - это обернет каждый коммит в e-mail сообщение, где первая строка из сообщение коммита будет темой письма, а остальные строки плюс сам патч будут телом письма. +Используйте команду `git format-patch` для генерации файлов в формате mbox, которые можно отправить по почте -- это обернет каждый коммит в e-mail сообщение, где первая строка из сообщение коммита будет темой письма, а остальные строки плюс сам патч будут телом письма. Применение патча в формате e-mail, сгенерированного с помощью команды `format-patch`, сохраняет всю информацию о коммите должным образом. [source,console] diff --git a/book/05-distributed-git/sections/distributed-workflows.asc b/book/05-distributed-git/sections/distributed-workflows.asc index 4deb0ebd..8b6aa229 100644 --- a/book/05-distributed-git/sections/distributed-workflows.asc +++ b/book/05-distributed-git/sections/distributed-workflows.asc @@ -10,7 +10,7 @@ ==== Централизованный рабочий процесс (((workflows, centralized))) -В централизованных системах как правило присутствует только одна модель взаимодействия - централизованный рабочий процесс. +В централизованных системах как правило присутствует только одна модель взаимодействия -- централизованный рабочий процесс. Центральный хаб или репозиторий может принимать код, а все остальные синхронизируют свою работу с ним. Все разработчики являются узлами (пользователями хаба) и синхронизируются только с ним. @@ -54,20 +54,20 @@ image::images/integration-manager.png[Рабочий процесс с мене (((forking))) Это достаточно распространенный вид организации рабочего процесса, в котором используются хабы, такие как GitHub или GitLab, где легко создать свой репозиторий как ответвление проекта (форк) и отправить туда свои изменения. Одним из основных преимуществ этого подхода является то, что вы можете продолжать работать, а сопровождающий основного репозитория может слить ваши изменения в любое время. -Участники не должны ждать пока основной проект примет их изменения - каждый может работать в своём темпе. +Участники не должны ждать пока основной проект примет их изменения -- каждый может работать в своём темпе. ==== Рабочий процесс с Диктатором и Лейтенантами (((workflows, dictator and lieutenants))) Это вариант организации рабочего процесса с использованием нескольких репозиториев. -В основном такой подход используеся на огромных проектах, насчитывающих сотни участников; самый известный пример - ядро Linux. -Лейтенанты - это интеграционные менеджеры, которые отвечают за отдельные части репозитория. +В основном такой подход используеся на огромных проектах, насчитывающих сотни участников; самый известный пример -- ядро Linux. +Лейтенанты -- это интеграционные менеджеры, которые отвечают за отдельные части репозитория. У всех лейтенантов есть свой интеграционный менеджер, который называется доброжелательным диктатором. Репозиторий доброжелательного диктатора выступает как эталонный, откуда все участники процесса должны получать изменения. Процесс работает следующим образом (смотри <>): 1. Обычные разработчики работают в своих тематических ветках и перебазируют свою работу относительно `master` ветки. - Ветка `master` - это ветка диктатора. + Ветка `master` -- это ветка диктатора. 2. Лейтенанты сливают изменения из тематических веток разработчиков в свои ветки `master`. 3. Диктатор сливает изменения из `master` веток лейтенантов в свою ветку `master`. 4. Диктатор отправляет свою `master` ветку в эталонный репозиторий, чтобы все остальные могли перебазировать свою работу на основании неё. diff --git a/book/05-distributed-git/sections/maintaining.asc b/book/05-distributed-git/sections/maintaining.asc index 14bc8ccf..ed481c5f 100644 --- a/book/05-distributed-git/sections/maintaining.asc +++ b/book/05-distributed-git/sections/maintaining.asc @@ -11,7 +11,7 @@ Перед интеграцией новых изменений желательно проверить их в тематической ветке -- временной ветке, специально созданной для проверки работоспособности новых изменений. Таким образом, можно применять патчи по одному и пропускать неработающие, пока не найдётся время к ним вернуться. Если вы создадите ветку с коротким и понятным названием, основанным на тематике изменений, например, `ruby_client` или что-то похожее, то без труда можно будет вернуться к ней, если пришлось на какое-то время отказаться от работы с ней. -Сопровождающему Git проекта свойственно использовать пространство имен для веток, например, `sc/ruby_client`, где `sc` - это сокращение от имени того, кто проделал работу. +Сопровождающему Git проекта свойственно использовать пространство имен для веток, например, `sc/ruby_client`, где `sc` -- это сокращение от имени того, кто проделал работу. Как известно, ветки можно создавать на основании базовой ветки, например: [source,console] diff --git a/book/06-github/sections/1-setting-up-account.asc b/book/06-github/sections/1-setting-up-account.asc index 439643fa..77e1bc6e 100644 --- a/book/06-github/sections/1-setting-up-account.asc +++ b/book/06-github/sections/1-setting-up-account.asc @@ -48,7 +48,7 @@ image::images/ssh-keys.png[Ссылка (``SSH keys'')] [[r_personal_avatar]] ==== Ваш аватар -Следующий шаг, если хотите – замена аватара, который был сгенерирован для вас, на вами выбранный аватар. Пожалуйста зайдите во вкладку ``Профиль''(``Profile''), она расположена над вкладкой "Ключи SSH" и нажмите ``Загрузить новую картинку''(``Upload new picture''). +Следующий шаг, если хотите -- замена аватара, который был сгенерирован для вас, на вами выбранный аватар. Пожалуйста зайдите во вкладку ``Профиль''(``Profile''), она расположена над вкладкой "Ключи SSH" и нажмите ``Загрузить новую картинку''(``Upload new picture''). .Ссылка ``Профиль''(``Profile''). image::images/your-profile.png[Ссылка ``Профиль''(``Profile'').] @@ -74,7 +74,7 @@ image::images/email-settings.png[Добавьте все ваши почтовы ==== Двухфакторная аутентификация -В качестве дополнительной меры безопасности, вы можете настроить "Двухфакторную аутентификацию" (``Two-factor Authentication'' или ``2FA''). Двухфакторная аутентификация — механизм, который становится все более и более популярным методом по снижению риска скомпрометировать вашу учетную запись в ситуации, когда пароль от вашей учетной записи, по тем или иным причинам, стал известен злоумышленникам. Активация этого механизма заставит GitHub запрашивать у вас оба пароля при авторизации, поэтому даже в ситуациях, когда ваш основной пароль скомпрометирован, злоумышленник все равно не получит доступ к вашей учетной записи. +В качестве дополнительной меры безопасности, вы можете настроить "Двухфакторную аутентификацию" (``Two-factor Authentication'' или ``2FA''). Двухфакторная аутентификация -- механизм, который становится все более и более популярным методом по снижению риска скомпрометировать вашу учетную запись в ситуации, когда пароль от вашей учетной записи, по тем или иным причинам, стал известен злоумышленникам. Активация этого механизма заставит GitHub запрашивать у вас оба пароля при авторизации, поэтому даже в ситуациях, когда ваш основной пароль скомпрометирован, злоумышленник все равно не получит доступ к вашей учетной записи. Вы сможете найти настройку "Двухфакторной аутентификации" (``Two-factor Authentication'') в секции "Безопасность" ("Security") вкладки ``Настройка учетной записи''(``Account settings''). diff --git a/book/07-git-tools/sections/advanced-merging.asc b/book/07-git-tools/sections/advanced-merging.asc index 2729c83d..cf7a6361 100644 --- a/book/07-git-tools/sections/advanced-merging.asc +++ b/book/07-git-tools/sections/advanced-merging.asc @@ -141,11 +141,11 @@ Merge made by the 'recursive' strategy. Хотя Git довольно хорошо обрабатывает пробельные символы, с другими типами изменений он не может справиться автоматически, но существуют другие варианты исправления. Например, представим, что Git не умеет обрабатывать изменения пробельных символов и нам нужно сделать это вручную. -То что нам действительно нужно – это перед выполнением самого слияния прогнать сливаемый файл через программу `dos2unix`. Как мы будем делать это? +То что нам действительно нужно -- это перед выполнением самого слияния прогнать сливаемый файл через программу `dos2unix`. Как мы будем делать это? Во-первых, мы перейдем в состояние конфликта слияния. Затем нам необходимо получить копии _нашей_ версии файла, _их_ версии файла (из ветки, которую мы сливаем) и _общей_ версии (от которой ответвились первые две). Затем мы исправим либо их версию, либо нашу и повторим слияние только для этого файла. -Получить эти три версии файла, на самом деле, довольно легко. Git хранит все эти версии в индексе в разных ``состояниях'', каждое из которых имеет ассоциированный с ним номер. Состояние 1 – это общий предок, состояние 2 – ваша версия и состояния 3 взято из `MERGE_HEAD` – версия, которую вы сливаете (``их'' версия). +Получить эти три версии файла, на самом деле, довольно легко. Git хранит все эти версии в индексе в разных ``состояниях'', каждое из которых имеет ассоциированный с ним номер. Состояние 1 -- это общий предок, состояние 2 -- ваша версия и состояния 3 взято из `MERGE_HEAD` -- версия, которую вы сливаете (``их'' версия). Вы можете извлечь копию каждой из этих версий конфликтующего файла с помощью команды `git show` и специального синтаксиса. @@ -220,7 +220,7 @@ index 36c06c8..44d0a25 100755 hello() ---- -Итак, здесь мы можем легко увидеть что же произошло с нашей веткой, какие изменения в действительности внесло слияние в данный файл – изменение только одной строки. +Итак, здесь мы можем легко увидеть что же произошло с нашей веткой, какие изменения в действительности внесло слияние в данный файл -- изменение только одной строки. Если вы хотите узнать чем результат слияния отличается от сливаемой ветки, то можете выполнить команду `git diff --theirs`. В этом и следующем примере мы используем опцию `-w` для того, чтобы не учитывать изменения в пробельных символах, так как мы сравниваем результат с тем, что есть в Git, а не с нашим исправленным файлом `hello.theirs.rb`. @@ -326,7 +326,7 @@ hello() Полезным в данном случае инструментом является команда `git checkout` с опцией `--conflict'. Она заново выкачает файл и заменит маркеры конфликта. Это может быть полезно, если вы хотите восстановить маркеры конфликта и попробовать разрешить его снова. -В качестве значения опции `--conflict` вы можете указывать `diff3` или `merge` (последнее значение используется по умолчанию). Если вы укажете `diff3`, Git будет использовать немного другую версию маркеров конфликта – помимо ``нашей'' и ``их'' версий файлов будет также отображена ``базовая'' версия, и таким образом вы получите больше информации. +В качестве значения опции `--conflict` вы можете указывать `diff3` или `merge` (последнее значение используется по умолчанию). Если вы укажете `diff3`, Git будет использовать немного другую версию маркеров конфликта -- помимо ``нашей'' и ``их'' версий файлов будет также отображена ``базовая'' версия, и таким образом вы получите больше информации. [source,console] ---- @@ -366,7 +366,7 @@ $ git config --global merge.conflictstyle diff3 [[r_merge_log]] ===== История при слиянии -Другой полезный инструмент при разрешении конфликтов слияния – это команда `git log`. Она поможет вам получить информацию о том, что могло привести к возникновению конфликтов. Временами может быть очень полезным просмотреть историю, чтобы понять почему в двух ветках разработки изменялась одна и та же область кода. +Другой полезный инструмент при разрешении конфликтов слияния -- это команда `git log`. Она поможет вам получить информацию о том, что могло привести к возникновению конфликтов. Временами может быть очень полезным просмотреть историю, чтобы понять почему в двух ветках разработки изменялась одна и та же область кода. Для получения полного списка всех уникальных коммитов, которые были сделаны в любой из сливаемых веток, мы можем использовать синтаксис ``трех точек'', который мы изучили в <>. @@ -484,7 +484,7 @@ index 0399cd5,59727f0..e1d0799 ==== Отмена слияний Теперь когда вы знаете как создать коммит слияния, вы можете сделать ее по ошибке. -Одна из замечательных вещей в работе с Git – это то, что ошибки совершать не страшно, так как есть возможность исправить их (и в большинстве случаев сделать это просто). +Одна из замечательных вещей в работе с Git -- это то, что ошибки совершать не страшно, так как есть возможность исправить их (и в большинстве случаев сделать это просто). Коммит слияния не исключение. Допустим, вы начали работать в тематической ветке, случайно слили ее в `master`, и теперь ваша история коммитов выглядит следующим образом: @@ -527,7 +527,7 @@ $ git revert -m 1 HEAD ---- Опция `-m 1` указывает какой родитель является ``основной веткой'' и должен быть сохранен. -Когда вы выполняете слияние в `HEAD` (`git merge topic`), новый коммит будет иметь двух родителей: первый из них `HEAD` (`C6`), а второй – вершина ветки, которую сливают с текущей (`C4`). +Когда вы выполняете слияние в `HEAD` (`git merge topic`), новый коммит будет иметь двух родителей: первый из них `HEAD` (`C6`), а второй -- вершина ветки, которую сливают с текущей (`C4`). В данном случае, мы хотим отменить все изменения, внесенные слиянием родителя #2 (`C4`), и сохранить при этом всё содержимое из родителя #1 (`C6`). История с коммитом восстановления (отменой коммита слияния) выглядит следующим образом: @@ -563,7 +563,7 @@ $ git merge topic image::images/undomerge-revert3.png[History after re-merging a reverted merge.] В этом примере, `M` и `^M` отменены. -В коммите `^^M`, фактически, сливаются изменения из `C3` и `C4`, а в `C8` – изменения из `C7`, таким образом, ветка `topic` полностью слита. +В коммите `^^M`, фактически, сливаются изменения из `C3` и `C4`, а в `C8` -- изменения из `C7`, таким образом, ветка `topic` полностью слита. ==== Другие типы слияний @@ -605,7 +605,7 @@ Merge made by the 'recursive' strategy. Такая же опция может быть передана команде `git merge-file`, которую мы обсуждали ранее, то есть для слияния отдельных файлов можно использовать команду `git merge-file --ours`. -На случай если вам нужно нечто подобное, но вы хотите, чтобы Git даже не пытался сливать изменения из другой версии, существует более суровый вариант – _стратегия_ слияния ``ours''. Важно отметить, что это не тоже самое что _опция_ ``ours'' рекурсивной стратегии слияния. +На случай если вам нужно нечто подобное, но вы хотите, чтобы Git даже не пытался сливать изменения из другой версии, существует более суровый вариант -- _стратегия_ слияния ``ours''. Важно отметить, что это не тоже самое что _опция_ ``ours'' рекурсивной стратегии слияния. Фактически, эта стратегия выполнит ненастоящее слияние. Она создаст новый коммит слияния, у которой родителями будут обе ветки, но при этом данная стратегия даже не взглянет на ветку, которую вы сливаете. В качестве результата слияния она просто оставляет тот код, который находится в вашей текущей ветке. diff --git a/book/07-git-tools/sections/bundling.asc b/book/07-git-tools/sections/bundling.asc index d2b81f3b..b2cc358b 100644 --- a/book/07-git-tools/sections/bundling.asc +++ b/book/07-git-tools/sections/bundling.asc @@ -67,7 +67,7 @@ c99cf5b fourth commit - second repo b1ec324 first commit ---- -Во-первых, нам нужно определить диапазон коммитов, которые мы хотим включить в пакет. В отличие от сетевых протоколов, которые сами выясняют минимальный набор данных, который нужно передать по сети, в данном случае мы должны сделать это сами вручную. В данном примере вы можете сделать, как раньше и упаковать полностью весь репозиторий, но будет лучше упаковать только изменения – три коммита, сделанные локально. +Во-первых, нам нужно определить диапазон коммитов, которые мы хотим включить в пакет. В отличие от сетевых протоколов, которые сами выясняют минимальный набор данных, который нужно передать по сети, в данном случае мы должны сделать это сами вручную. В данном примере вы можете сделать, как раньше и упаковать полностью весь репозиторий, но будет лучше упаковать только изменения -- три коммита, сделанные локально. Для того, чтобы сделать это, вы должны вычислить различия. Как мы рассказывали в <>, вы можете указать диапазон коммитов несколькими способами. Для того, чтобы получить три коммита из нашей основной ветки, которые отсутствовали в изначально склонированной ветке, мы можем использовать запись вида `origin/master..master` или `master ^origin/master`. Вы можете проверить ее с помощью команды `log`. diff --git a/book/07-git-tools/sections/credentials.asc b/book/07-git-tools/sections/credentials.asc index ece6551a..d7699f90 100644 --- a/book/07-git-tools/sections/credentials.asc +++ b/book/07-git-tools/sections/credentials.asc @@ -4,7 +4,7 @@ (((credentials))) (((git commands, credential))) Если для подключения к удаленным серверам вы используете SSH-транспорт, то вы можете использовать ключ без пароля, что позволит вам безопасно передавать данные без ввода логина и пароля. -Однако, это невозможно при использовании HTTP-протоколов – каждое подключение требует пары логин, пароль. +Однако, это невозможно при использовании HTTP-протоколов -- каждое подключение требует пары логин, пароль. Все ещё сложнее для систем с двухфакторной аутентификацией, когда выражение, которое вы используете в качестве пароля, генерируется случайно и его сложно воспроизвести. К счастью, в Git есть система управления учетными данными, которая может помочь в этом. @@ -112,7 +112,7 @@ password=s3cre7 Для операций `store` и `erase` не требуется ответа (в любом случае Git его игнорирует). Однако, для Git очень важно, что помощник ответит на операцию `get`. -Если помощник не знает что-либо полезного, он может просто завершить работу не выводя ничего, но если знает – он должен добавить к введенной информации имеющуюся у него информацию. +Если помощник не знает что-либо полезного, он может просто завершить работу не выводя ничего, но если знает -- он должен добавить к введенной информации имеющуюся у него информацию. Вывод обрабатывается как набор операций присваивания; выведенные значения заменят те, что Git знал до этого. Ниже приведет пример, используемый ранее, но вместо git-credential напрямую вызывается git-credential-store: diff --git a/book/07-git-tools/sections/debugging.asc b/book/07-git-tools/sections/debugging.asc index 700c0574..59a8c09b 100644 --- a/book/07-git-tools/sections/debugging.asc +++ b/book/07-git-tools/sections/debugging.asc @@ -27,16 +27,16 @@ $ git blame -L 12,22 simplegit.rb 42cf2861 (Magnus Chacon 2008-04-13 10:45:01 -0700 22) end ---- -Обратите внимание, что первое поле – это неполная SHA-1 сумма последнего коммита, который изменял соответствующую строку. -Следующими двумя полями являются значения, извлеченные из этого коммита – имя автора и время создания коммита – таким образом, вы можете легко увидеть кто изменял строку и когда. +Обратите внимание, что первое поле -- это неполная SHA-1 сумма последнего коммита, который изменял соответствующую строку. +Следующими двумя полями являются значения, извлеченные из этого коммита -- имя автора и время создания коммита -- таким образом, вы можете легко увидеть кто изменял строку и когда. После этого следуют номер строки и содержимое файла. Обратите внимание на строки со значением `^4832fe2` в поле коммита, так обозначаются те строки, которые были в первом коммите этого файла. Этот коммит был сделан, когда данный файл был впервые добавлен в проект и с тех пор эти строки не были изменены. Немного сбивает с толку то, что вы уже видели в Git, по крайней мере, три различных варианта использования символа `^` для изменения SHA-1 коммита, в данном случае этот символ имеет такое значение. -Другая отличная вещь в Git – это то, что он не отслеживает явно переименования файлов (пользователю не нужно _явно_ указывать какой файл в какой был переименован). +Другая отличная вещь в Git -- это то, что он не отслеживает явно переименования файлов (пользователю не нужно _явно_ указывать какой файл в какой был переименован). Он сохраняет снимки и уже после выполнения самого переименования неявно попытается выяснить, что было переименовано. -Одна из интересных возможностей, вытекающих из этого – это то, что вы также можете попросить Git выявить перемещения кода всех других видов. +Одна из интересных возможностей, вытекающих из этого -- это то, что вы также можете попросить Git выявить перемещения кода всех других видов. Если передать опцию `-C` команде `git blame`, Git проанализирует аннотируемый файл и пытается выяснить откуда изначально появились фрагменты кода, если они, конечно же, были откуда-то скопированы. Например, предположим при реорганизации кода в файле `GITServerHandler.m` вы разнесли его по нескольким файлам, один из которых `GITPackUpload.m`. Вызывая `git blame` с опцией `-C` для файла `GITPackUpload.m`, вы можете увидеть откуда изначально появились разные фрагменты этого файла. @@ -134,7 +134,7 @@ $ git bisect reset Это мощный инструмент, который помогает вам за считанные минуты проверить сотни коммитов на возможность внесения ошибки. В действительности, если у вас есть скрипт, который будет возвращать 0 если проект находится в рабочем состоянии и любое другое число в обратном случае, то вы можете полностью автоматизировать `git bisect`. Сперва, вы снова сообщаете границы бинарного поиска, указывая известные плохие и хорошие коммиты. -Вы можете сделать это, передавая их команде `bisect start` – первым аргументом известный плохой коммит, а вторым известный хороший коммит: +Вы можете сделать это, передавая их команде `bisect start` -- первым аргументом известный плохой коммит, а вторым известный хороший коммит: [source,console] ---- diff --git a/book/07-git-tools/sections/interactive-staging.asc b/book/07-git-tools/sections/interactive-staging.asc index 7a4012cc..b751cd2f 100644 --- a/book/07-git-tools/sections/interactive-staging.asc +++ b/book/07-git-tools/sections/interactive-staging.asc @@ -21,11 +21,11 @@ $ git add -i What now> ---- -Вы можете видеть, что эта команда показывает вашу область подготовленных изменений в уникальном представлении – вообще говоря, ту же информацию вы получите с помощью команды `git status`, но несколько более сжато и информативно. -Эта команда показывает проиндексированные изменения слева, а непроиндексированные – справа. +Вы можете видеть, что эта команда показывает вашу область подготовленных изменений в уникальном представлении -- вообще говоря, ту же информацию вы получите с помощью команды `git status`, но несколько более сжато и информативно. +Эта команда показывает проиндексированные изменения слева, а непроиндексированные -- справа. Затем следует раздел со списком команд. -С их помощью вы можете выполнить множество вещей – добавить или исключить файлы из индекса, добавить в индекс части файлов, добавить в индекс неотслеживаемые файлы и просмотреть проиндексированные изменения. +С их помощью вы можете выполнить множество вещей -- добавить или исключить файлы из индекса, добавить в индекс части файлов, добавить в индекс неотслеживаемые файлы и просмотреть проиндексированные изменения. ==== Добавление и удаление файлов из индекса @@ -199,6 +199,6 @@ What now> 1 Таким образом, вы частично проиндексировали этот файл. В данный момент вы можете выйти из интерактивного режима команды `git add` и выполнить `git commit`, чтобы зафиксировать частично проиндексированные файлы. -Также вам не обязательно находиться в интерактивном режиме индексирования файлов для выполнения частичной индексации файлов – вы также можете запустить ее, используя команды `git add -p` или `git add --patch`. +Также вам не обязательно находиться в интерактивном режиме индексирования файлов для выполнения частичной индексации файлов -- вы также можете запустить ее, используя команды `git add -p` или `git add --patch`. Более того, вы можете использовать работу с отдельными частями файлов для частичного восстановления файлов с помощью команды `reset --patch`, для переключения частей файлов с помощью команды `checkout --patch` и для прибережения частей файлов с помощью `stash save --patch`. Мы рассмотрим каждую из этих команд более подробно, когда будем изучать более продвинутые варианты их использования. diff --git a/book/07-git-tools/sections/replace.asc b/book/07-git-tools/sections/replace.asc index 12e3fce2..f99c811d 100644 --- a/book/07-git-tools/sections/replace.asc +++ b/book/07-git-tools/sections/replace.asc @@ -5,9 +5,9 @@ Команда `replace` позволяет вам указать объект Git и сказать "каждый раз, когда встречается этот объект, заменяй его другим". В основном, это бывает полезно для замены одного коммита в вашей истории другим. -Например, допустим в вашем проекте огромная история изменений и вы хотите разбить ваш репозиторий на два – один с короткой историей для новых разработчиков, а другой с более длинной историей для людей, интересующихся анализом истории. Вы можете пересадить одну историю на другую, 'заменяя' самый первый коммит в короткой истории последним коммитом в длинной истории. Это удобно, так как вам не придется по-настоящему изменять каждый коммит в новой истории, как это вам бы потребовалось делать в случае обычного объединения историй (так как родословная коммитов влияет на SHA-1). +Например, допустим в вашем проекте огромная история изменений и вы хотите разбить ваш репозиторий на два -- один с короткой историей для новых разработчиков, а другой с более длинной историей для людей, интересующихся анализом истории. Вы можете пересадить одну историю на другую, 'заменяя' самый первый коммит в короткой истории последним коммитом в длинной истории. Это удобно, так как вам не придется по-настоящему изменять каждый коммит в новой истории, как это вам бы потребовалось делать в случае обычного объединения историй (так как родословная коммитов влияет на SHA-1). -Давайте испробуем как это работает, возьмем существующий репозиторий и разобьем его на два – один со свежими правками, а другой с историческими, и затем посмотрим как мы можем воссоединить их с помощью операции `replace`, не изменяя при этом значений SHA-1 в свежем репозитории. +Давайте испробуем как это работает, возьмем существующий репозиторий и разобьем его на два -- один со свежими правками, а другой с историческими, и затем посмотрим как мы можем воссоединить их с помощью операции `replace`, не изменяя при этом значений SHA-1 в свежем репозитории. Мы будем использовать простой репозиторий с пятью коммитами: @@ -21,7 +21,7 @@ c6e1e95 fourth commit c1822cf first commit ---- -Мы хотим разбить его на два семейства историй. Одно семейство, которое начинается от первого коммита и заканчивается четвертым, будет историческим. Второе, состоящее пока только из четвертого и пятого коммитов – будет семейством со свежей историей. +Мы хотим разбить его на два семейства историй. Одно семейство, которое начинается от первого коммита и заканчивается четвертым, будет историческим. Второе, состоящее пока только из четвертого и пятого коммитов -- будет семейством со свежей историей. image::images/replace1.png[] @@ -56,7 +56,7 @@ To git@github.com:schacon/project-history.git * [new branch] history -> master ---- -Таким образом, наша история опубликована, а мы теперь займемся более сложной частью – усечем свежую историю. Нам необходимо перекрытие, так чтобы мы смогли заменить коммит из одной части коммитом из другой, то есть мы будем обрезать историю, оставив четвертый и пятый коммиты (таким образом четвертый коммит будет входить в пересечение). +Таким образом, наша история опубликована, а мы теперь займемся более сложной частью -- усечем свежую историю. Нам необходимо перекрытие, так чтобы мы смогли заменить коммит из одной части коммитом из другой, то есть мы будем обрезать историю, оставив четвертый и пятый коммиты (таким образом четвертый коммит будет входить в пересечение). [source,console] ---- @@ -184,4 +184,4 @@ e146b5f14e79d4935160c0e83fb9ebe526b8da0d commit refs/remotes/origin/master c6e1e95051d41771a649f3145423f8809d1a74d4 commit refs/replace/81a708dd0e167a3f691541c7a6463343bc457040 ---- -Следовательно можно легко поделиться заменами – для этого мы можем отправить их на наш сервер, а другие люди могут легко скачать их оттуда. Это не будет полезным в случае если вы используете `replace` для пересадки истории (так как в этом случае все люди будут скачивать обе истории, тогда зачем мы разделяли их?), но это может быть полезным в других ситуациях. +Следовательно можно легко поделиться заменами -- для этого мы можем отправить их на наш сервер, а другие люди могут легко скачать их оттуда. Это не будет полезным в случае если вы используете `replace` для пересадки истории (так как в этом случае все люди будут скачивать обе истории, тогда зачем мы разделяли их?), но это может быть полезным в других ситуациях. diff --git a/book/07-git-tools/sections/rerere.asc b/book/07-git-tools/sections/rerere.asc index 0f383429..4e229960 100644 --- a/book/07-git-tools/sections/rerere.asc +++ b/book/07-git-tools/sections/rerere.asc @@ -1,11 +1,11 @@ [[r_rerere]] === Rerere -Функциональность `git rerere` – частично скрытый компонент Git. Ее имя является сокращением для ``reuse recorded resolution'' (``повторное использование сохраненных разрешений конфликтов''). Как следует из имени, эта функциональность позволяет попросить Git запомнить то, как вы разрешили некоторую часть конфликта, так что в случае возникновения такого же конфликта, Git сможет его разрешить автоматически. +Функциональность `git rerere` -- частично скрытый компонент Git. Ее имя является сокращением для ``reuse recorded resolution'' (``повторное использование сохраненных разрешений конфликтов''). Как следует из имени, эта функциональность позволяет попросить Git запомнить то, как вы разрешили некоторую часть конфликта, так что в случае возникновения такого же конфликта, Git сможет его разрешить автоматически. Существует несколько ситуаций, в которых данная функциональность может быть действительно удобна. Один из примеров, упомянутый в документации, состоит в том, чтобы обеспечить в будущем простоту слияния некоторой долгоживущей ветки, не создавая при этом набор промежуточных коммитов слияния. При использовании `rerere` вы можете время от времени выполнять слияния, разрешать конфликты, а затем откатывать слияния. Если делать это постоянно, то итоговое слияние должно пройти легко, так как `rerere` сможет разрешить все конфликты автоматически. -Такая же тактика может быть использована, если вы хотите сохранить ветку легко перебазируемой, то есть вы не хотите сталкиваться с одними и теми же конфликтами каждый раз при перебазировании. Или, например, вы решили ветку, которую уже сливали и разрешали при этом некоторые конфликты, вместо слияния перебазировать – наврядли вы захотите разрешать те же конфликты еще раз. +Такая же тактика может быть использована, если вы хотите сохранить ветку легко перебазируемой, то есть вы не хотите сталкиваться с одними и теми же конфликтами каждый раз при перебазировании. Или, например, вы решили ветку, которую уже сливали и разрешали при этом некоторые конфликты, вместо слияния перебазировать -- наврядли вы захотите разрешать те же конфликты еще раз. Другая ситуация возникает, когда вы изредка сливаете несколько веток, относящихся к еще разрабатываемым задачам, в одну тестовую ветку, как это часто делается в проекте самого Git. Если тесты завершатся неудачей, вы можете откатить все слияния и повторить их, исключив из них ветку, которая поломала тесты, при этом не разрешая конфликты снова. @@ -29,7 +29,7 @@ def hello end ---- -Как и ранее, в одной ветке мы изменили слово ``hello'' на ``hola'', а в другой – слово ``world'' на ``mundo''. +Как и ранее, в одной ветке мы изменили слово ``hello'' на ``hola'', а в другой -- слово ``world'' на ``mundo''. image::images/rerere1.png[] @@ -66,7 +66,7 @@ $ git rerere status hello.rb ---- -А команда `git rerere diff` показывает текущее состояние разрешения конфликта – то, с чего вы начали разрешать конфликт, и то, как вы его разрешили (фактически, патч, который в дальнейшем можно использовать для разрешения такого же конфликта). +А команда `git rerere diff` показывает текущее состояние разрешения конфликта -- то, с чего вы начали разрешать конфликт, и то, как вы его разрешили (фактически, патч, который в дальнейшем можно использовать для разрешения такого же конфликта). [source,console] ---- diff --git a/book/07-git-tools/sections/reset.asc b/book/07-git-tools/sections/reset.asc index f33449c8..c0a84827 100644 --- a/book/07-git-tools/sections/reset.asc +++ b/book/07-git-tools/sections/reset.asc @@ -24,7 +24,7 @@ ===== HEAD -HEAD – это указатель на текущую ветку, которая, в свою очередь, является указателем на последний коммит, сделанный в этой ветке. +HEAD -- это указатель на текущую ветку, которая, в свою очередь, является указателем на последний коммит, сделанный в этой ветке. Это значит, что HEAD будет родителем следующего созданного коммита. Как правило, самое простое считать HEAD снимком *вашего последнего коммита*. @@ -51,7 +51,7 @@ $ git ls-tree -r HEAD [[r_the_index]] ===== Индекс -Индекс – это ваш *следующий намеченный коммит*. Мы также упоминали это понятие как ``область подготовленных изменений'' Git – то, что Git просматривает, когда вы выполняете `git commit`. +Индекс -- это ваш *следующий намеченный коммит*. Мы также упоминали это понятие как ``область подготовленных изменений'' Git -- то, что Git просматривает, когда вы выполняете `git commit`. Git заполняет индекс списком изначального содержимого всех файлов, выгруженных в последний раз в ваш рабочий каталог. Затем вы заменяете некоторые из таких файлов их новыми версиями и команда `git commit' преобразует изменения в дерево для нового коммита. @@ -66,7 +66,7 @@ $ git ls-files -s Повторим, здесь мы используем служебную команду `ls-files`, которая показывает вам, как выглядит сейчас ваш индекс. -Технически, индекс не является древовидной структурой, на самом деле, он реализован как сжатый список (_flattened manifest_) – но для наших целей такого представления будет достаточно. +Технически, индекс не является древовидной структурой, на самом деле, он реализован как сжатый список (_flattened manifest_) -- но для наших целей такого представления будет достаточно. ===== Рабочий Каталог @@ -89,7 +89,7 @@ $ tree ==== Технологический процесс -Основное предназначение Git – это сохранение снимков последовательно улучшающихся состояний вашего проекта, путем управления этими тремя деревьями. +Основное предназначение Git -- это сохранение снимков последовательно улучшающихся состояний вашего проекта, путем управления этими тремя деревьями. image::images/reset-workflow.png[] @@ -122,7 +122,7 @@ image::images/reset-ex4.png[] image::images/reset-ex5.png[] -Если сейчас мы выполним `git status`, то увидим, что этот файл выделен зеленым цветом в разделе ``Изменения, которые будут закоммичены'', так как Индекс и HEAD различны – то есть, наш следующий намеченный коммит сейчас отличается от нашего последнего коммита. +Если сейчас мы выполним `git status`, то увидим, что этот файл выделен зеленым цветом в разделе ``Изменения, которые будут закоммичены'', так как Индекс и HEAD различны -- то есть, наш следующий намеченный коммит сейчас отличается от нашего последнего коммита. Наконец, мы выполним `git commit`, чтобы окончательно совершить коммит. image::images/reset-ex6.png[] @@ -145,7 +145,7 @@ image::images/reset-start.png[] ===== Шаг 1: Перемещение HEAD -Первое, что сделает `reset` – переместит то, на что указывает HEAD. +Первое, что сделает `reset` -- переместит то, на что указывает HEAD. Обратите внимание, изменяется не сам HEAD (что происходит при выполнении команды `checkout`); `reset` перемещает ветку, на которую указывает HEAD. Таким образом, если HEAD указывает на ветку `master` (то есть вы сейчас работаете с веткой `master`), выполнение команды `git reset 9e5e6a4` сделает так, что `master` будет указывать на `9e5e6a4`. @@ -175,7 +175,7 @@ image::images/reset-mixed.png[] ===== Шаг 3: Обновление Рабочего Каталога (--hard) -Третье, что сделает `reset` – это приведение вашего Рабочего Каталога к тому же виду, что и Индекс. +Третье, что сделает `reset` -- это приведение вашего Рабочего Каталога к тому же виду, что и Индекс. Если вы используете опцию `--hard`, то выполнение команды будет продолжено до этого шага. image::images/reset-hard.png[] @@ -233,7 +233,7 @@ image::images/reset-path3.png[] ==== Слияние коммитов -Давайте посмотрим, как, используя вышеизложенное, сделать кое-что интересное – слияние коммитов. +Давайте посмотрим, как, используя вышеизложенное, сделать кое-что интересное -- слияние коммитов. Допустим, у вас есть последовательность коммитов с сообщениями вида ``упс.'', ``В работе'' и ``позабыл этот файл''. Вы можете использовать `reset` для того, чтобы просто и быстро слить их в один. @@ -252,7 +252,7 @@ image::images/reset-squash-r2.png[] image::images/reset-squash-r3.png[] -Теперь вы можете видеть, что ваша ``достижимая'' история (история, которую вы впоследствии отправите на сервер), сейчас выглядит так – у вас есть первый коммит с файлом `file-a.txt` версии *v1*, и второй, который изменяет файл `file-a.txt` до версии *v3* и добавляет `file-b.txt`. Коммита, который содержал файл версии *v2* не осталось в истории. +Теперь вы можете видеть, что ваша ``достижимая'' история (история, которую вы впоследствии отправите на сервер), сейчас выглядит так -- у вас есть первый коммит с файлом `file-a.txt` версии *v1*, и второй, который изменяет файл `file-a.txt` до версии *v3* и добавляет `file-b.txt`. Коммита, который содержал файл версии *v2* не осталось в истории. ==== Сравнение с `checkout` @@ -265,7 +265,7 @@ image::images/reset-squash-r3.png[] Команда `git checkout [branch]` очень похожа на `git reset --hard [branch]`, в процессе их выполнения все три дерева изменяются так, чтобы выглядеть как `[branch]`. Но между этими командами есть два важных отличия. Во-первых, в отличие от `reset --hard`, команда `checkout` бережно относится к рабочему каталогу, и проверяет, что она не трогает файлы, в которых есть изменения. -В действительности, эта команда поступает немного умнее – она пытается выполнить в Рабочем Каталоге простые слияния так, чтобы все файлы, которые вы _не_ изменяли, были обновлены. +В действительности, эта команда поступает немного умнее -- она пытается выполнить в Рабочем Каталоге простые слияния так, чтобы все файлы, которые вы _не_ изменяли, были обновлены. С другой стороны, команда `reset --hard` просто заменяет всё целиком, не выполняя проверок. Второе важное отличие заключается в том, как эти команды обновляют HEAD. @@ -285,7 +285,7 @@ image::images/reset-checkout.png[] Другой способ выполнить `checkout` состоит в том, чтобы указать путь до файла. В этом случае, как и для команды `reset`, HEAD не перемещается. Эта команда как и `git reset [branch] file` обновляет файл в индексе версией из коммита, но дополнительно она обновляет и файл в рабочем каталоге. -То же самое сделала бы команда `git reset --hard [branch] file` (если бы `reset` можно было бы так запускать) – это небезопасно для рабочего каталога и не перемещает HEAD. +То же самое сделала бы команда `git reset --hard [branch] file` (если бы `reset` можно было бы так запускать) -- это небезопасно для рабочего каталога и не перемещает HEAD. Также как `git reset` и `git add`, команда `checkout` принимает опцию `--patch` для того, чтобы позволить вам избирательно откатить измения содержимого файла по частям. @@ -295,7 +295,7 @@ image::images/reset-checkout.png[] Ниже приведена памятка того, как эти команды воздействуют на каждое из деревьев. В столбце ``HEAD'' указывается ``REF'' если эта команда перемещает ссылку (ветку), на которую HEAD указывает, и ``HEAD'' если перемещается только сам HEAD. -Обратите особое внимание на столбец ``Сохранность РК?'' – если в нем указано *NO*, то хорошенько подумайте прежде чем выполнить эту команду. +Обратите особое внимание на столбец ``Сохранность РК?'' -- если в нем указано *NO*, то хорошенько подумайте прежде чем выполнить эту команду. [options="header", cols="3,1,1,1,1"] |================================ diff --git a/book/07-git-tools/sections/revision-selection.asc b/book/07-git-tools/sections/revision-selection.asc index a48c471a..db2b0202 100644 --- a/book/07-git-tools/sections/revision-selection.asc +++ b/book/07-git-tools/sections/revision-selection.asc @@ -11,7 +11,7 @@ Git позволяет различными способами указать к ==== Сокращенный SHA-1 -Git достаточно умен, чтобы понять какой коммит имеется ввиду по нескольким первым символам ее хеша, если указанная часть SHA-1 имеет в длину по крайней мере четыре символа и однозначна – то есть в текущем репозитории существует только один объект с таким частичным SHA-1. +Git достаточно умен, чтобы понять какой коммит имеется ввиду по нескольким первым символам ее хеша, если указанная часть SHA-1 имеет в длину по крайней мере четыре символа и однозначна -- то есть в текущем репозитории существует только один объект с таким частичным SHA-1. Например, предположим, чтобы найти некоторый коммит, вы выполнили команду `git log` и нашли коммит, в которой добавили определенную функциональность: @@ -76,7 +76,7 @@ a11bef0 first commit Длина SHA-1 составляет 20 байт или 160 бит. Количество случайно хешированных объектов, необходимых для достижения 50% вероятности возникновения коллизии, равно примерно 2^80^. (формула для определения вероятности возникновения коллизии `p = (n(n-1)/2) * (1/2^160))`. -2^80^ — это 1.2 × 10^24^, или 1 миллион миллиардов миллиардов, что в 1200 раз больше количества песчинок на земле. +2^80^ -- это 1.2 × 10^24^, или 1 миллион миллиардов миллиардов, что в 1200 раз больше количества песчинок на земле. Приведем пример, чтобы дать вам представление, чего будет стоить получение коллизии SHA-1. Если бы все 6.5 миллиардов человек на Земле были программистами, и ежесекундно каждый из них производил количество кода, эквивалентное всей истории ядра Linux (3.6 миллиона Git-объектов), и отправлял его в один огромный Git репозитории, то потребовалось бы около 2 лет, пока этот репозиторий накопил бы количество объектов, достаточное для 50% вероятности возникновения SHA-1 коллизии. @@ -110,7 +110,7 @@ ca82a6dff817ec66f44342007202690a93763949 [[r_git_reflog]] ==== RefLog-сокращения -Одна из вещей, которую Git выполняет в фоновом режиме, пока вы работаете – это ведение ``журнала ссылок'' – журнала, в котором за последние несколько месяцев сохраняется то, куда указывали HEAD и ветки. +Одна из вещей, которую Git выполняет в фоновом режиме, пока вы работаете -- это ведение ``журнала ссылок'' -- журнала, в котором за последние несколько месяцев сохраняется то, куда указывали HEAD и ветки. Вы можете просмотреть свой журнал ссылок, используя команду `git reflog`: @@ -168,13 +168,13 @@ Date: Thu Dec 11 15:08:43 2008 -0800 Merge commit 'phedders/rdocs' ---- -Важно отметить, что информация в журнале ссылок строго локальная – это лог того, что вы делали в вашем репозитории. +Важно отметить, что информация в журнале ссылок строго локальная -- это лог того, что вы делали в вашем репозитории. Ссылки не будут такими же в других копиях репозитория; а сразу после первоначального клонирования репозитория, у вас будет пустой журнал ссылок, так как никаких действий в вашем репозитории пока не производилось. -Команда `git show HEAD@{2.months.ago}` будет работать только если вы клонировали проект по крайней мере два месяца назад – если вы клонировали его пять минут назад, то не получите никаких результатов. +Команда `git show HEAD@{2.months.ago}` будет работать только если вы клонировали проект по крайней мере два месяца назад -- если вы клонировали его пять минут назад, то не получите никаких результатов. ==== Ссылки на предков -Еще один популярный способ указать коммит – это использовать ее родословную. +Еще один популярный способ указать коммит -- это использовать ее родословную. Если вы поместите `^` в конце ссылки, Git поймет, что нужно использовать родителя этого коммита. Предположим, история вашего проекта выглядит следующим образом: @@ -204,9 +204,9 @@ Date: Thu Dec 11 15:08:43 2008 -0800 Merge commit 'phedders/rdocs' ---- -Также вы можете указать число после `^` – например, `d921970^2` означает ``второй родитель коммита d921970''. +Также вы можете указать число после `^` -- например, `d921970^2` означает ``второй родитель коммита d921970''. Такой синтаксис полезен только для коммитов слияния, которые имеют больше одного родителя. -Первым родителем является ветка, в которую вы выполняли слияние, а вторым – коммит в ветке, которую вы сливали: +Первым родителем является ветка, в которую вы выполняли слияние, а вторым -- коммит в ветке, которую вы сливали: [source,console] ---- @@ -228,7 +228,7 @@ Date: Wed Dec 10 22:22:03 2008 +0000 Второе важное обозначение для указания предков это `~`. Оно также ссылается на первого родителя, поэтому `HEAD~` и `HEAD^` эквивалентны. Различия становятся заметными, когда вы указываете число. -`HEAD~2` означает ``первый родитель первого родителя'' или ``прадедушка'' – переход к первому родителю осуществляется столько раз, сколько вы указали. +`HEAD~2` означает ``первый родитель первого родителя'' или ``прадедушка'' -- переход к первому родителю осуществляется столько раз, сколько вы указали. Например, для показанной ранее истории, коммитом `HEAD~3` будет [source,console] @@ -253,13 +253,13 @@ Date: Fri Nov 7 13:47:59 2008 -0500 ignore *.gem ---- -Вы также можете совмещать эти обозначения – можно получить второго родителя предыдущей ссылки (предполагается, что это коммит слияния) используя запись `HEAD~3^2`, и так далее. +Вы также можете совмещать эти обозначения -- можно получить второго родителя предыдущей ссылки (предполагается, что это коммит слияния) используя запись `HEAD~3^2`, и так далее. [[r_commit_ranges]] ==== Диапазоны коммитов Теперь вы умеете указывать отдельные коммиты, давайте посмотрим как указывать диапазоны коммитов. -Это в частности полезно для управления вашими ветками – если у вас есть множество веток, вы можете использовать указание диапазонов коммитов для ответа на вопрос ``Что было сделано в этой ветке, что я еще не слил в основную ветку?'' +Это в частности полезно для управления вашими ветками -- если у вас есть множество веток, вы можете использовать указание диапазонов коммитов для ответа на вопрос ``Что было сделано в этой ветке, что я еще не слил в основную ветку?'' ===== Две точки @@ -272,7 +272,7 @@ Date: Fri Nov 7 13:47:59 2008 -0500 image::images/double-dot.png[Example history for range selection.] Вы хотите посмотреть что находится в вашей экспериментальной ветке, которая еще не была слита в основную. -Вы можете попросить Git отобразить в логе только такие коммиты, используя запись `master..experiment` – она означает ``все коммиты, которые доступны из ветки `experiment`, но не доступны из ветки `master`''. +Вы можете попросить Git отобразить в логе только такие коммиты, используя запись `master..experiment` -- она означает ``все коммиты, которые доступны из ветки `experiment`, но не доступны из ветки `master`''. Для краткости и наглядности в этих примерах вместо настоящего вывода лога мы будем использовать для коммитов их буквенные обозначения из диаграммы, располагая их в должном порядке: [source,console] @@ -293,7 +293,7 @@ E ---- Это полезно если вы хотите сохранить ветку `experiment` в актуальном состоянии и просмотреть, какие изменения нужно в нее слить. -Другое частое использование такого синтаксиса – просмотр того, что будет отправлено в удаленный репозиторий. +Другое частое использование такого синтаксиса -- просмотр того, что будет отправлено в удаленный репозиторий. [source,console] ---- @@ -303,7 +303,7 @@ $ git log origin/master..HEAD Такая команда покажет вам все коммиты вашей текущей ветки, которые отсутствуют в ветке `master` удаленного репозитория `origin`. Если вы выполните `git push`, находясь на ветке, отслеживающей `origin/master`, то коммиты, отображенные командой `git log origin/master..HEAD`, будут теми коммитами, которые отправятся на сервер. Вы также можете опустить одну из частей в такой записи, Git будет считать ее равной HEAD. -Например, вы можете получить такой же результат как в предыдущем примере, выполнив `git log origin/master..` – Git подставит HEAD, если одна часть отсутствует. +Например, вы можете получить такой же результат как в предыдущем примере, выполнив `git log origin/master..` -- Git подставит HEAD, если одна часть отсутствует. ===== Множество точек @@ -332,7 +332,7 @@ $ git log refA refB --not refC [[r_triple_dot]] ===== Три точки -Последний основной способ выбора ревизий – это синтаксис с тремя точками, который обозначает все коммиты, доступные хотя бы из одной ссылки, но не из обеих сразу. +Последний основной способ выбора ревизий -- это синтаксис с тремя точками, который обозначает все коммиты, доступные хотя бы из одной ссылки, но не из обеих сразу. Вспомните пример истории коммитов в <>. Если вы хотите узнать какие коммиты есть либо в ветке `master`, либо в `experiment`, но не в обеих сразу, вы можете выполнить: diff --git a/book/07-git-tools/sections/rewriting-history.asc b/book/07-git-tools/sections/rewriting-history.asc index 429e979e..80263348 100644 --- a/book/07-git-tools/sections/rewriting-history.asc +++ b/book/07-git-tools/sections/rewriting-history.asc @@ -4,7 +4,7 @@ Неоднократно при работе с Git, вам может потребоваться по какой-то причине исправить вашу историю коммитов. Одно из преимуществ Git заключается в том, что он позволяет вам отложить принятие решений на самый последний момент. Область подготовленных изменений позволяет вам решить, какие файлы попадут в коммит непосредственно перед ее выполнением; благодаря команде `stash` вы можете решить, что не хотите продолжать работу над какими-то изменениями; также вы можете изменить уже совершенные коммиты так, чтобы они выглядели совершенно другим образом. -В частности, можно изменить порядок коммитов, сообщения или измененные в коммитах файлы, объединить вместе или разбить на части, полностью удалить коммит – но только до того, как вы поделитесь своими наработками с другими. +В частности, можно изменить порядок коммитов, сообщения или измененные в коммитах файлы, объединить вместе или разбить на части, полностью удалить коммит -- но только до того, как вы поделитесь своими наработками с другими. В данном разделе вы узнаете, как выполнять эти очень полезные задачи. Таким образом, перед тем, как поделиться вашими наработками с другими, вы сможете привести вашу историю коммитов к нужному виду. @@ -28,7 +28,7 @@ $ git commit --amend Вы добавляете в индекс необходимые изменения, редактируя файл и выполняя для него `git add` или `git rm` для отслеживаемого файла, а последующая команда `git commit --amend` берет вашу текущую область подготовленных изменений и делает ее снимок для нового коммита. Вы должны быть осторожными, используя этот прием, так как при этом изменяется SHA-1 коммита. -Поэтому как и с операцией `rebase` – не изменяйте ваш последний коммит, если вы уже отправили ее в общий репозиторий. +Поэтому как и с операцией `rebase` -- не изменяйте ваш последний коммит, если вы уже отправили ее в общий репозиторий. [[r_changing_multiple]] ==== Изменение сообщений нескольких коммитов @@ -39,15 +39,15 @@ $ git commit --amend Вы можете запустить `rebase` в интерактивном режиме, добавив опцию `-i` к `git rebase`. Вы должны указать, какие коммиты вы хотите изменить, передав команде коммит, на который нужно выполнить перебазирование. -Например, если вы хотите изменить сообщения последних трех коммитов, или сообщение какой-то одному коммиту этой группы, то передайте как аргумент команде `git rebase -i` родителя последнего коммита, который вы хотите изменить – `HEAD~2^` или `HEAD~3`. -Может быть, проще будет запомнить `~3`, так как вы хотите изменить последние три коммита; но не забывайте, что вы, в действительности, указываете четвертый коммит с конца – родителя последнего коммита, который вы хотите изменить: +Например, если вы хотите изменить сообщения последних трех коммитов, или сообщение какой-то одному коммиту этой группы, то передайте как аргумент команде `git rebase -i` родителя последнего коммита, который вы хотите изменить -- `HEAD~2^` или `HEAD~3`. +Может быть, проще будет запомнить `~3`, так как вы хотите изменить последние три коммита; но не забывайте, что вы, в действительности, указываете четвертый коммит с конца -- родителя последнего коммита, который вы хотите изменить: [source,console] ---- $ git rebase -i HEAD~3 ---- -Напомним, что это команда перебазирования – каждый коммит, входящий в диапазон `HEAD~3..HEAD`, будет изменен вне зависимости от того, изменили вы сообщение или нет. +Напомним, что это команда перебазирования -- каждый коммит, входящий в диапазон `HEAD~3..HEAD`, будет изменен вне зависимости от того, изменили вы сообщение или нет. Не включайте в такой диапазон коммит, который уже был отправлен на центральный сервер: сделав это, вы можете запутать других разработчиков, предоставив вторую версию одних и тех же изменений. Выполнение этой команды отобразит в вашем текстовом редакторе список коммитов, в нашем случае, например, следующее: @@ -222,7 +222,7 @@ added cat-file Разбиение коммита отменяет его и позволяет затем по частям индексировать и фиксировать изменения, создавая таким образом столько коммитов, сколько вам нужно. Например, предположим, что вы хотите разбить средний коммит на три. -Вместо одного коммита ``updated README formatting and added blame'' вы хотите получить два разных: первый – ``updated README formatting'', и второй – ``added blame''. +Вместо одного коммита ``updated README formatting and added blame'' вы хотите получить два разных: первый -- ``updated README formatting'', и второй -- ``added blame''. Вы можете добиться этого, изменив в скрипте `rebase -i` инструкцию для разбиваемой коммита на ``edit'': [source,console] @@ -262,7 +262,7 @@ f3cc40e changed my name a bit ==== Продвинутый инструмент: filter-branch -Существует еще один способ изменения истории, который вы можете использовать при необходимости изменить большое количество коммитов каким-то программируемым способом – например, изменить глобально ваш адрес электронной почты или удалить файл из всех коммитов. +Существует еще один способ изменения истории, который вы можете использовать при необходимости изменить большое количество коммитов каким-то программируемым способом -- например, изменить глобально ваш адрес электронной почты или удалить файл из всех коммитов. Для этого существует команда `filter-branch`, и она может изменять большие периоды вашей истории, поэтому вы, возможно, не должны ее использовать кроме тех случаев, когда ваш проект еще не стал публичным и другие люди еще не имеют наработок, основанных на коммитах, которые вы собираетесь изменить. Однако, эта команда может быть очень полезной. Далее вы ознакомитесь с несколькими обычными вариантами использованиями этой команды, таким образом, вы сможете получить представление о том, на что она способна. diff --git a/book/07-git-tools/sections/searching.asc b/book/07-git-tools/sections/searching.asc index 58dac537..a4beb954 100644 --- a/book/07-git-tools/sections/searching.asc +++ b/book/07-git-tools/sections/searching.asc @@ -81,7 +81,7 @@ v1.8.0:zlib.c 31:#define ZLIB_BUF_MAX ((uInt) 1024 * 1024 * 1024) /* 1GB */ ---- -Команда `git grep` имеет несколько преимуществ перед поиском с помощью таких команд, как `grep` и `ack`. Во-первых, она действительно быстрая, во-вторых – `git grep` позволяет искать не только в рабочем каталоге, но и в любом другом дереве Git. Как вы видели, в прошлом примере мы искали в старой версии исходных кодов Git, а не в текущем снимке файлов. +Команда `git grep` имеет несколько преимуществ перед поиском с помощью таких команд, как `grep` и `ack`. Во-первых, она действительно быстрая, во-вторых -- `git grep` позволяет искать не только в рабочем каталоге, но и в любом другом дереве Git. Как вы видели, в прошлом примере мы искали в старой версии исходных кодов Git, а не в текущем снимке файлов. ==== Поиск в журнале изменений Git @@ -96,13 +96,13 @@ e01503b zlib: allow feeding more than 4GB in one go ef49a7a zlib: zlib can only process 4GB at a time ---- -Если мы посмотрим на изменения, сделанные в этих коммитах, то увидим, что в `ef49a7a` константа была добавлена, а в `e01503b` – изменена. +Если мы посмотрим на изменения, сделанные в этих коммитах, то увидим, что в `ef49a7a` константа была добавлена, а в `e01503b` -- изменена. Если вам нужно найти что-то более сложное, вы можете с помощью опции `-G` передать регулярное выражение. ===== Поиск по журналу изменений строки -Другой, довольно продвинутый, поиск по истории, который бывает черезвычайно полезным – поиск по истории изменений строки. Эта возможность была добавлена совсем недавно и пока не получила известности. Для того, чтобы ей воспользоваться нужно команде `git log` передать опцию `-L`, в результате вам будет показана история изменения функции или строки кода в вашей кодовой базе. +Другой, довольно продвинутый, поиск по истории, который бывает черезвычайно полезным -- поиск по истории изменений строки. Эта возможность была добавлена совсем недавно и пока не получила известности. Для того, чтобы ей воспользоваться нужно команде `git log` передать опцию `-L`, в результате вам будет показана история изменения функции или строки кода в вашей кодовой базе. Например, если мы хотим увидеть все изменения, произошедшие с функцией `git_deflate_bound` в файле `zlib.c`, мы можем выполнить `git log -L :git_deflate_bound:zlib.c`. Эта команда постарается определить границы функции, выполнит поиск по истории и покажет все изменения, которые были сделаны с функцией, в виде набора патчей в обратном порядке до момента создания функции. diff --git a/book/07-git-tools/sections/stashing-cleaning.asc b/book/07-git-tools/sections/stashing-cleaning.asc index 804e2776..0934c3ad 100644 --- a/book/07-git-tools/sections/stashing-cleaning.asc +++ b/book/07-git-tools/sections/stashing-cleaning.asc @@ -79,7 +79,7 @@ $ git stash apply Как видите, Git восстановил в файлах изменения, которые вы отменили ранее, когда прятали свои наработки. В данном случае при применении отложенных наработок ваша рабочая директория была без изменений, а вы пытались применить их в той же ветке, в которой вы их и сохранили; но отсутствие изменений в рабочей директории и применение их в той же ветке не являются необходимыми условиями для успешного восстановления спрятанных наработок. Вы можете спрятать изменения, находясь в одной ветке, а затем переключиться на другую и попробовать восстановить эти изменения. -Также при восстановлении спрятанных наработок в вашей рабочей директории могут присутствовать измененные и незафиксированные файлы – Git выдаст конфликты слияния, если не сможет восстановить какие-то наработки. +Также при восстановлении спрятанных наработок в вашей рабочей директории могут присутствовать измененные и незафиксированные файлы -- Git выдаст конфликты слияния, если не сможет восстановить какие-то наработки. Спрятанные изменения будут применены к вашим файлам, но файлы, которые вы ранее добавляли в индекс, не будут добавлены туда снова. Для того, чтобы это было сделано, вы должны запустить `git stash apply` с опцией `--index`, при которой команда попытается восстановить изменения в индексе. @@ -101,7 +101,7 @@ $ git stash apply --index # ---- -Команда `apply` только пытается восстановить спрятанные наработки – при этом они останутся в хранилище. +Команда `apply` только пытается восстановить спрятанные наработки -- при этом они останутся в хранилище. Для того, чтобы удалить их, вы можете выполнить `git stash drop`, указав имя удаляемых изменений: [source,console] @@ -118,7 +118,7 @@ Dropped stash@{0} (364e91f3f268f0900bc3ee613f9f733e82aaed43) ==== Продуктивное прибережение -У откладываемых изменений есть несколько дополнительных вариантов использования, которые также могут быть полезны. Первый – это использование довольно популярной опции `--keep-index` с командой `stash save`. Она просит Git не прятать то, что вы уже добавили в индекс командой `git add`. +У откладываемых изменений есть несколько дополнительных вариантов использования, которые также могут быть полезны. Первый -- это использование довольно популярной опции `--keep-index` с командой `stash save`. Она просит Git не прятать то, что вы уже добавили в индекс командой `git add`. Это может быть полезно в случае, когда вы сделали какие-то изменения, но хотите зафиксировать только часть из них, а к оставшимся вернуться через некоторое время. @@ -136,7 +136,7 @@ $ git status -s M index.html ---- -Другой распространенный вариант, который вы, возможно, захотите использовать – это спрятать помимо отслеживаемых файлов также и неотслеживаемые. По умолчанию `git stash` будет сохранять только файлы, которые уже добавлены в индекс. Если вы укажете `--include-untracked` или `-u`, Git также спрячет все неотслеживаемые файлы, которые вы создали. +Другой распространенный вариант, который вы, возможно, захотите использовать -- это спрятать помимо отслеживаемых файлов также и неотслеживаемые. По умолчанию `git stash` будет сохранять только файлы, которые уже добавлены в индекс. Если вы укажете `--include-untracked` или `-u`, Git также спрячет все неотслеживаемые файлы, которые вы создали. [source,console] ---- @@ -243,7 +243,7 @@ Would remove test.o Would remove tmp/ ---- -Если вы не знаете, что сделает при запуске команда `git clean`, всегда сначала выполняйте ее с опцией `-n`, чтобы проверить дважды, перед заменой `-n` на `-f` и выполнением настоящей очистки. Другой способ, который позволяет вам более тщательно контролировать сам процесс – это выполнение команды с опцией `-i` (в ``интерактивном'' режиме). +Если вы не знаете, что сделает при запуске команда `git clean`, всегда сначала выполняйте ее с опцией `-n`, чтобы проверить дважды, перед заменой `-n` на `-f` и выполнением настоящей очистки. Другой способ, который позволяет вам более тщательно контролировать сам процесс -- это выполнение команды с опцией `-i` (в ``интерактивном'' режиме). Ниже выполнена команда очистки в интерактивном режиме. diff --git a/book/07-git-tools/sections/submodules.asc b/book/07-git-tools/sections/submodules.asc index 85e7edf8..fe909a3a 100644 --- a/book/07-git-tools/sections/submodules.asc +++ b/book/07-git-tools/sections/submodules.asc @@ -3,7 +3,7 @@ Часто при работе над одним проектом, возникает необходимость использовать в нем другой проект. Возможно, это библиотека, разрабатываемая сторонними разработчиками или вами, но в рамках отдельного проекта, и используемая в нескольких других проектах. -Типичная проблема, возникающая при этом – вы хотите продолжать работать с двумя проектами по отдельности, но при этом использовать один из них в другом. +Типичная проблема, возникающая при этом -- вы хотите продолжать работать с двумя проектами по отдельности, но при этом использовать один из них в другом. Приведем пример. Предположим, вы разрабатываете веб-сайт и создаете ленту в формате Atom. @@ -34,7 +34,7 @@ Unpacking objects: 100% (11/11), done. Checking connectivity... done. ---- -По умолчанию подмодули добавляют подпроекты в директории, называемые так же, как и соответствующие репозитории, в нашем примере – ``DbConnector''. +По умолчанию подмодули добавляют подпроекты в директории, называемые так же, как и соответствующие репозитории, в нашем примере -- ``DbConnector''. Если в данный момент вы выполните `git status`, то заметите несколько моментов. @@ -154,7 +154,7 @@ $ ---- Директория `DbConnector` присутствует, но она пустая. -Вы должны выполнить две команды: `git submodule init` – для инициализации локального конфигурационного файла, и `git submodule update` – для извлечения всех данных этого проекта и переключения на соответствующий коммит, указанный в вашем основном проекте. +Вы должны выполнить две команды: `git submodule init` -- для инициализации локального конфигурационного файла, и `git submodule update` -- для извлечения всех данных этого проекта и переключения на соответствующий коммит, указанный в вашем основном проекте. [source,console] ---- @@ -360,7 +360,7 @@ Submodule DbConnector c3f01dc..c87d55d: До сих пор, когда мы выполняли команду `git submodule update` для извлечения изменений из репозитория подмодуля, Git получал изменения и обновлял файлы в поддиректории, но оставлял подрепозиторий в состоянии, называемом ``отделенный HEAD'' (``detached HEAD''). Это значит, что локальная рабочая ветка (такая, например, как ``master''), отслеживающая изменения, отсутствует. Таким образом, любые вносимые вами изменения не будут нормально отслеживаться. -Для упрощения работы с подмодулями вам необходимо сделать две вещи. Вам нужно перейти в каждый подмодуль и переключиться на ветку, в которой будете в дальнейшем работать. Затем вам необходимо сообщить Git, что ему делать если вы внесли изменения, а затем командой `git submodule update --remote` получаете новые изменения из репозитория. Возможны два варианта – вы можете слить их в вашу локальную версию или попробовать перебазировать ваши локальные наработки поверх новых изменений. +Для упрощения работы с подмодулями вам необходимо сделать две вещи. Вам нужно перейти в каждый подмодуль и переключиться на ветку, в которой будете в дальнейшем работать. Затем вам необходимо сообщить Git, что ему делать если вы внесли изменения, а затем командой `git submodule update --remote` получаете новые изменения из репозитория. Возможны два варианта -- вы можете слить их в вашу локальную версию или попробовать перебазировать ваши локальные наработки поверх новых изменений. Первым делом, давайте перейдем в директорию нашего подмодуля и переключимся на нужную ветку. @@ -419,7 +419,7 @@ Submodule path 'DbConnector': checked out '5d60ef9bbebf5a0c1c1050f242ceeb54ad58d Не беспокойтесь, если такое случится, вы можете просто вернуться в директорию, переключиться обратно на вашу ветку (которая все еще будет содержать ваши наработки) и слить или перебазировать ветку `origin/stable` (или другую нужную вам удаленную ветку) вручную. -Если вы не зафиксировали ваши изменения в подмодуле и выполнили его обновление, то это приведет к проблемам – Git извлечет изменения из вышестоящего репозитория, но не затрет несохраненные наработки в директории вашего подмодуля. +Если вы не зафиксировали ваши изменения в подмодуле и выполнили его обновление, то это приведет к проблемам -- Git извлечет изменения из вышестоящего репозитория, но не затрет несохраненные наработки в директории вашего подмодуля. [source,console] ---- @@ -489,9 +489,9 @@ or cd to the path and use to push them to a remote. ---- -Как видите, эта команда также дает нам некоторые полезные советы о том, что мы могли бы делать дальше. Самый простой вариант – это пройти по всем подмодулям и вручную отправить изменения на серверы, чтобы гарантировать доступность изменений другим людям, а затем повторить первоначальную команду `push`. +Как видите, эта команда также дает нам некоторые полезные советы о том, что мы могли бы делать дальше. Самый простой вариант -- это пройти по всем подмодулям и вручную отправить изменения на серверы, чтобы гарантировать доступность изменений другим людям, а затем повторить первоначальную команду `push`. -Другой вариант – это использовать значение ``on-demand'', которое попытается сделать это все за вас. +Другой вариант -- это использовать значение ``on-demand'', которое попытается сделать это все за вас. [source,console] ---- @@ -552,7 +552,7 @@ index eb41d76,c771610..0000000 +++ b/DbConnector ---- -Так, в данном примере `eb41d76` является *нашим* коммитом в подмодуле, а `c771610` – коммитом из вышестоящего репозитория. Если мы перейдем в директорию нашего подмодуля, то он должен быть на коммит `eb41d76`, так как операция слияния его не изменяла. Если по каким-то причинам это не так, то вы можете просто переключиться на ветку (создав ее при необходимости), указывающую на этот коммит. +Так, в данном примере `eb41d76` является *нашим* коммитом в подмодуле, а `c771610` -- коммитом из вышестоящего репозитория. Если мы перейдем в директорию нашего подмодуля, то он должен быть на коммит `eb41d76`, так как операция слияния его не изменяла. Если по каким-то причинам это не так, то вы можете просто переключиться на ветку (создав ее при необходимости), указывающую на этот коммит. Куда более важным является SHA-1 хеш коммита другой стороны, который мы должны будем слить. Вы можете либо просто выполнить слияние, указав непосредственно этот SHA-1 хеш, либо вы можете создать с ним отдельную ветку и затем уже сливать эту ветку. Мы предлагаем использовать последний вариант, хотя бы только из-за того, что сообщение коммита слияния получается более читаемым. @@ -610,7 +610,7 @@ $ git commit -m "Merge Tom's Changes" <5> Интересно, что существует еще один случай, который Git обрабатывает. Если существует какой-то коммит слияния подмодуля, который содержит в своей истории **оба** первоначальных коммита, то Git предложит его вам как возможное решение. Он видит, что в какой-то момент в подмодуле, кто-то уже слил ветки, содержащие эти два коммита, поэтому, может быть, это то, что вы хотите. -Именно поэтому выше сообщение об ошибке содержало ``merge following commits not found'' – Git не смог сделать *это* (найти такой коммит). Оно обескураживает – кто мог ожидать, что Git **пытается** сделать это? +Именно поэтому выше сообщение об ошибке содержало ``merge following commits not found'' -- Git не смог сделать *это* (найти такой коммит). Оно обескураживает -- кто мог ожидать, что Git **пытается** сделать это? Если удастся найти единственный приемлемый коммит, то вы увидите нечто подобное: @@ -679,7 +679,7 @@ Entering 'DbConnector' Switched to a new branch 'featureA' ---- -Подкинем вам еще одну идею. Действительно, полезная вещь, которую вы можете сделать с помощью этой команды – это создать комплексную дельту того, что изменилось в вашем основном проекте, а также и во всех подпроектах. +Подкинем вам еще одну идею. Действительно, полезная вещь, которую вы можете сделать с помощью этой команды -- это создать комплексную дельту того, что изменилось в вашем основном проекте, а также и во всех подпроектах. [source,console] ---- @@ -730,7 +730,7 @@ $ git config alias.spush 'push --recurse-submodules=on-demand' $ git config alias.supdate 'submodule update --remote --merge' ---- -Таким образом при необходимости обновить ваши подмодули вы можете просто выполнить команду `git supdate`, а для отправки изменений с проверкой зависимостей подмодулей – команду `git spush`. +Таким образом при необходимости обновить ваши подмодули вы можете просто выполнить команду `git supdate`, а для отправки изменений с проверкой зависимостей подмодулей -- команду `git spush`. ==== Проблемы с подмодулями diff --git a/book/07-git-tools/sections/subtree-merges.asc b/book/07-git-tools/sections/subtree-merges.asc index 334acb1b..8e3e8c2b 100644 --- a/book/07-git-tools/sections/subtree-merges.asc +++ b/book/07-git-tools/sections/subtree-merges.asc @@ -29,7 +29,7 @@ Branch rack_branch set up to track remote branch refs/remotes/rack_remote/master Switched to a new branch "rack_branch" ---- -Таким образом, теперь у нас в ветке `rack_branch` находится основная ветка проекта Rack, а в ветке `master` – наш собственный проект. +Таким образом, теперь у нас в ветке `rack_branch` находится основная ветка проекта Rack, а в ветке `master` -- наш собственный проект. Если вы переключитесь сначала на одну ветку, а затем на другую, то увидите, что они имеют абсолютно разное содержимое: [source,console] @@ -55,7 +55,7 @@ README $ git read-tree --prefix=rack/ -u rack_branch ---- -Когда мы будем выполнять коммит, он будет выглядеть так, как будто все файлы проекта Rack были добавлены в эту субдиректорию – например, мы скопировали их из архива. +Когда мы будем выполнять коммит, он будет выглядеть так, как будто все файлы проекта Rack были добавлены в эту субдиректорию -- например, мы скопировали их из архива. Важно отметить, что слить изменения одной из веток в другую довольно легко. Таким образом, если проект Rack обновился, мы можем получить изменения из его репозитория просто переключившись на соответствующую ветку и выполнив операцию `git pull`: @@ -79,11 +79,11 @@ Automatic merge went well; stopped before committing as requested ---- Все изменения из проекта Rack слиты и подготовлены для локального выполнения коммита. -Вы также можете поступить наоборот – сделать изменения в субдиректории `rack` вашей основной ветки и затем слить их в вашу ветку `rack_branch`, чтобы позже передать их ответственным за проекты или отправить их в вышестоящий репозиторий проекта Rack. +Вы также можете поступить наоборот -- сделать изменения в субдиректории `rack` вашей основной ветки и затем слить их в вашу ветку `rack_branch`, чтобы позже передать их ответственным за проекты или отправить их в вышестоящий репозиторий проекта Rack. -Таким образом, слияние субдеревьев дает нам возможность использовать рабочий процесс в некоторой степени похожий на рабочий процесс с субмодулями, но при этом без использования субмодулей (которые мы рассмотрим в <>). Мы можем держать ветки с другими связанными проектами в нашем репозитории и периодически сливать их как субдеревья в наш проект. С одной стороны это удобно, например, тем, что весь код хранится в одном месте. Однако, при этом есть и некоторые недостатки – субдеревья немного сложнее, проще допустить ошибки при повторной интеграции изменений или случайно отправить ветку не в тот репозиторий. +Таким образом, слияние субдеревьев дает нам возможность использовать рабочий процесс в некоторой степени похожий на рабочий процесс с субмодулями, но при этом без использования субмодулей (которые мы рассмотрим в <>). Мы можем держать ветки с другими связанными проектами в нашем репозитории и периодически сливать их как субдеревья в наш проект. С одной стороны это удобно, например, тем, что весь код хранится в одном месте. Однако, при этом есть и некоторые недостатки -- субдеревья немного сложнее, проще допустить ошибки при повторной интеграции изменений или случайно отправить ветку не в тот репозиторий. -Другая небольшая странность состоит в том, что для получения различий между содержимым вашей субдиректории `rack` и содержимого ветки `rack_branch` – для того, чтобы увидеть необходимо ли выполнять слияния между ними – вы не можете использовать обычную команду `diff`. +Другая небольшая странность состоит в том, что для получения различий между содержимым вашей субдиректории `rack` и содержимого ветки `rack_branch` -- для того, чтобы увидеть необходимо ли выполнять слияния между ними -- вы не можете использовать обычную команду `diff`. Вместо этого вы должны выполнить команду `git diff-tree`, указав ветку, с которой вы хотите выполнить сравнение: [source,console] diff --git a/book/08-customizing-git/sections/attributes.asc b/book/08-customizing-git/sections/attributes.asc index 774a33ed..a460dbe3 100644 --- a/book/08-customizing-git/sections/attributes.asc +++ b/book/08-customizing-git/sections/attributes.asc @@ -18,7 +18,7 @@ Некоторые файлы выглядят как текстовые, но работать с ними нужно как с бинарными данными. Например, на Mac в Xcode проекте содержится файл с расширением `.pbxproj`, который генерируется IDE, содержит различные настройки проекта и сохраняется в формате JSON (текстовое представление Javascript данных). -Технически - это текстовый файл (потому как все данные в UTF-8), фактически - легковесная база данных; отслеживание изменений в нём бесполезно, а слияние изменений - сделанных двумя людьми - невозможно, поэтому вы вряд ли захотите обрабатывать его как текстовый файл. +Технически -- это текстовый файл (потому как все данные в UTF-8), фактически -- легковесная база данных; отслеживание изменений в нём бесполезно, а слияние изменений -- сделанных двумя людьми -- невозможно, поэтому вы вряд ли захотите обрабатывать его как текстовый файл. Файл предназначен для чтения машиной, а не человеком. Вот почему его следует рассматривать как бинарный. @@ -37,7 +37,7 @@ Сделать это можно указав Git каким образом конвертировать бинарные данные в текстовый формат, чтобы затем сравнить их обычным способом. Этот подход решает одну из самых досадных проблем, известных человечеству: контроль версий документов Microsoft Word. -Все уже знают, что Word - самый ужасный редактор из всех, но, как ни странно, продолжают его использовать. +Все уже знают, что Word -- самый ужасный редактор из всех, но, как ни странно, продолжают его использовать. Если вы хотите контролировать версии документов Word, то поместите их в Git репозиторий и периодически делайте коммиты; но как это решает проблему? Если вы просто выполните команду `git diff`, то увидите следующее: @@ -106,10 +106,10 @@ index 0b013ca..ba25db5 100644 ---- Git сообщает нам, что была добавлена строка ``Testing: 1, 2, 3.''. -Решение не идеальное - изменения форматирования не отображаются - но работает. +Решение не идеальное -- изменения форматирования не отображаются -- но работает. Проблему сравнения файлов изображений можно решить аналогичным образом. -Один из способов реализации заключается в передаче изображения на фильтр для извлечения EXIF информации - метаданных, которые сохраняются для большинства форматов изображений. +Один из способов реализации заключается в передаче изображения на фильтр для извлечения EXIF информации -- метаданных, которые сохраняются для большинства форматов изображений. Скачав и установив программу `exiftool`, вы сможете использовать её для сравнения изменений метаданных изображения: [source,console] @@ -149,7 +149,7 @@ index 88839c4..4afcb7c 100644 (((keyword expansion))) Разработчики часто хотят использовать расширение ключевых слов в стиле SVN или CVS. -Основная проблема в Git - это невозможность изменять файлы с информацией о коммите после его совершения, так как Git сначала вычисляет контрольную сумму. +Основная проблема в Git -- это невозможность изменять файлы с информацией о коммите после его совершения, так как Git сначала вычисляет контрольную сумму. Однако, вы можете добавить текст в файл после извлечения и убрать его перед добавлением файла в коммит. Атрибуты Git позволяют это сделать двумя способами. @@ -209,7 +209,7 @@ $ git config --global filter.indent.smudge cat По сути, программа `cat` ничего не делает: она возвращает те же данные, что и получает на вход. Указанная комбинация позволяет эффективно обрабатывать файлы с исходным кодом на С программой `indent` перед коммитом. -Другой интересный пример - это подстановка ключевого слова `$Date$` в стиле системы контроля ревизий. +Другой интересный пример -- это подстановка ключевого слова `$Date$` в стиле системы контроля ревизий. Чтобы правильно это реализовать, вам нужен простой скрипт, который получает имя файла, определяет дату последнего коммита и вставляет её в файл. Ниже приведен небольшой пример такого скрипта на Ruby: @@ -221,7 +221,7 @@ last_date = `git log --pretty=format:"%ad" -1` puts data.gsub('$Date$', '$Date: ' + last_date.to_s + '$') ---- -Всё, что делает скрипт - это получает дату последнего коммита с помощью команды `git log`, заменяет результатом все подстроки `$Date$` и возвращает результат. Вы можете написать аналогичный скрипт на любом языке. +Всё, что делает скрипт -- это получает дату последнего коммита с помощью команды `git log`, заменяет результатом все подстроки `$Date$` и возвращает результат. Вы можете написать аналогичный скрипт на любом языке. Назовите файл со скриптом, например, `expand_date` и сохраните в директории с программами. Теперь, нужно настроить Git фильтр (назовите его `dater`) и укажите ему использовать ваш скрипт `expand_date` при извлечении файлов. Всместе с этим, мы будем использовать регулярное выражение Perl для очистки перед коммитом: @@ -255,7 +255,7 @@ $ cat date_test.txt Как вы могли заметить, описанный подход предоставляет большие возможности. Однако, вам стоит быть осторожным, так как файл `.gitattributes` включается в коммит и распространяется вместе с проектом, а драйвер (в данном случае `dater`) нет, поэтому он не будет работать везде. -Учитывайте это при разработке фильтров оставляя возможность работы без них - так вы сохраните проект в рабочем состоянии. +Учитывайте это при разработке фильтров оставляя возможность работы без них -- так вы сохраните проект в рабочем состоянии. ==== Экспорт репозитория @@ -303,7 +303,7 @@ Last commit date: $Format:Tue Apr 21 08:38:48 2009 -0700$ (((merging, strategies))) Используя атрибуты Git можно применять разные стратегии слияния для разных типов файлов вашего проекта. -Одна из полезных опций - это указать Git не сливать изменения в определенных файлах в случае конфликта, при этом использовать вашу версию файла. +Одна из полезных опций -- это указать Git не сливать изменения в определенных файлах в случае конфликта, при этом использовать вашу версию файла. Это полезно в случае, когда ветка разошлась или у вас специализированная ветка, при этом вы хотите иметь возможность сливать изменения, но игнорировать определенные файлы. Предположим, что у вас есть файл с настройками базы данных `database.xml`, содержимое которого в разных ветках отличается, при этом вы хотите сливать изменения из другой ветки не меняя этот файл. diff --git a/book/08-customizing-git/sections/config.asc b/book/08-customizing-git/sections/config.asc index fc80cfdd..799c6f9e 100644 --- a/book/08-customizing-git/sections/config.asc +++ b/book/08-customizing-git/sections/config.asc @@ -17,7 +17,7 @@ $ git config --global user.email johndoe@example.com Вначале, Git ищет настройки в файле `/etc/gitconfig`, который содержит настройки для всех пользователей в системе и всех репозиториев. Если передать опцию `--system` команде `git config`, то операции чтения и записи будут производиться именно с этим файлом. -Следующее место, куда смотрит Git - это файл `~/.gitconfig` (или `~/.config/git/config`), который хранит настройки конкретного пользователя. +Следующее место, куда смотрит Git -- это файл `~/.gitconfig` (или `~/.config/git/config`), который хранит настройки конкретного пользователя. Вы можете указать Git читать и писать в него, используя опцию `--global`. Наконец, Git ищет параметры конфигурации в файле настроек в директории Git (`.git/config`) используемого в данный момент репозитория. @@ -34,7 +34,7 @@ $ git config --global user.email johndoe@example.com ==== Базовая конфигурация клиента Конфигурационные параметры Git разделяются на две категории: настройки клиента и настройки сервера. -Большая часть - клиентские, для настройки ваших личных предпочтений в работе. +Большая часть -- клиентские, для настройки ваших личных предпочтений в работе. Существует много, _очень много_ настроек, но подавляющее большинство из них применимо только в конкретных случаях. Мы рассмотрим только самые основные и самые полезные из них. Для просмотра полного списка настроек, поддерживаемых вашей версией Git, выполните команду: @@ -50,7 +50,7 @@ $ man git-config ===== `core.editor` ((($EDITOR)))((($VISUAL, see $EDITOR))) -По умолчанию, Git использует ваш редактор по умолчанию (`$VISUAL` или `$EDITOR`), если значение не задано - переходит к использованию редактора `vi` при создании и редактировании сообщений коммитов или тэгов. +По умолчанию, Git использует ваш редактор по умолчанию (`$VISUAL` или `$EDITOR`), если значение не задано -- переходит к использованию редактора `vi` при создании и редактировании сообщений коммитов или тэгов. Чтобы изменить редактор по умолчанию, воспользуйтесь настройкой `core.editor`: [source,console] @@ -183,7 +183,7 @@ Continuing under the assumption that you meant 'checkout' in 0.1 seconds automatically... ---- -Обратите внимание, что команда выполнилась через ``0.1'' секунды. `help.autocorrect` - это число, указываемое в десятых долях секунды. +Обратите внимание, что команда выполнилась через ``0.1'' секунды. `help.autocorrect` -- это число, указываемое в десятых долях секунды. Поэтому, если вы установите значение 50, то Git даст вам 5 секунд изменить своё решение перед тем, как выполнить скорректированную команду. ==== Цвета в Git @@ -202,7 +202,7 @@ Git автоматически подсвечивает большую част $ git config --global color.ui false ---- -Значение по умолчанию - `auto`, при котором цвета используются при непосредственном выводе в терминал, но исключаются при перенаправлении вывода в именованный канал или файл. +Значение по умолчанию -- `auto`, при котором цвета используются при непосредственном выводе в терминал, но исключаются при перенаправлении вывода в именованный канал или файл. Вы так же можете установить значение `always`, что делает вывод одинаковым как в терминал, так и в именованный канал. Скорее всего, вам это не понадобится; в большинстве случаев, при желании использовать цвета в перенаправленном выводе, указывется флаг `--color` команде Git для принудительного использования цветовых кодов. @@ -239,7 +239,7 @@ $ git config --global color.ui false Сначала, скачайте P4Merge отсюда http://www.perforce.com/downloads/Perforce/[]. Затем, создайте скрипты обёртки для вызова внешних программ. -Мы будем использовать путь к исполняемому файлу в системе Mac; в других системах - это путь к файлу `p4merge`. +Мы будем использовать путь к исполняемому файлу в системе Mac; в других системах -- это путь к файлу `p4merge`. Создайте скрипт с названием `extMerge` для вызова программы слияния и передачи ей заданных параметров: [source,console] @@ -275,7 +275,7 @@ $ sudo chmod +x /usr/local/bin/extDiff ---- Теперь можно изменить файл конфигурации для использования ваших инструментов слияния и сравнения. -Для этого необходимо изменить ряд настроек: `merge.tool` - чтобы сказать Git какую стратегию использовать, `mergetool..cmd` - чтобы сказать Git как запускать команду, `mergetool..trustExitCode` - чтобы сказать Git как интерпретировать код выхода из программы, `diff.external` - чтобы сказать Git какую команду использовать для сравнения. +Для этого необходимо изменить ряд настроек: `merge.tool` -- чтобы сказать Git какую стратегию использовать, `mergetool..cmd` -- чтобы сказать Git как запускать команду, `mergetool..trustExitCode` -- чтобы сказать Git как интерпретировать код выхода из программы, `diff.external` -- чтобы сказать Git какую команду использовать для сравнения. Таким образом, команду конфигурации нужно запустить четыре раза: [source,console] @@ -365,7 +365,7 @@ environment. If run in a terminal-only session, they will fail. $ git config --global merge.tool kdiff3 ---- -Если выполнить эту команду вместо настройки использования файлов `extMerge` и `extDiff`, то Git будет использовать KDiff3 для разрешения конфликтов слияния, а для сравнения - стандартную программу diff. +Если выполнить эту команду вместо настройки использования файлов `extMerge` и `extDiff`, то Git будет использовать KDiff3 для разрешения конфликтов слияния, а для сравнения -- стандартную программу diff. ==== Форматирование и пробелы @@ -378,12 +378,12 @@ $ git config --global merge.tool kdiff3 (((crlf)))(((line endings))) Если вы программируете в Windows и работаете с людьми, что не использует её (или наоборот), рано или поздно, вы столкнетесь с проблемами переноса строк. -Это происходит потому, что Windows при создании файлов использует для обозначения переноса строки два символа "возврат каретки" и "перевод строки", в то время как Mac и Linux используют только один - "перевод строки". +Это происходит потому, что Windows при создании файлов использует для обозначения переноса строки два символа "возврат каретки" и "перевод строки", в то время как Mac и Linux используют только один -- "перевод строки". Это незначительный, но невероятно раздражающий факт кроссплатформенной работы; большинство редакторов в Windows молча заменяют переносы строк вида LF на CRLF или вставляют оба символа, когда пользователь нажимает клавишу ввод. -Git может автоматически конвертировать переносы строк CRLF в LF при добавлении файла в индекс и наоборот - при извлечении кода. +Git может автоматически конвертировать переносы строк CRLF в LF при добавлении файла в индекс и наоборот -- при извлечении кода. Такое поведение можно включить используя настройку `core.autocrlf`. -Если у вас Windows, то установите значение `true` - при извлечении кода LF окончания строк будут преобразовываться в CRLF: +Если у вас Windows, то установите значение `true` -- при извлечении кода LF окончания строк будут преобразовываться в CRLF: [source,console] ---- @@ -410,11 +410,11 @@ $ git config --global core.autocrlf false ===== `core.whitespace` Git поставляется настроенным на обнаружение и исправление некоторых проблем с пробелами. -Он в состоянии найти шесть основных проблем, обнаружение трёх из них включено по умолчанию, а трёх других - выключено. +Он в состоянии найти шесть основных проблем, обнаружение трёх из них включено по умолчанию, а трёх других -- выключено. -Те, что включены по умолчанию - это `blank-at-eol`, что ищет пробелы в конце строки; `blank-at-eof`, что ищет пробелы в конце файла; и `space-before-tab`, что ищет пробелы перед символом табуляции в начале строки. +Те, что включены по умолчанию -- это `blank-at-eol`, что ищет пробелы в конце строки; `blank-at-eof`, что ищет пробелы в конце файла; и `space-before-tab`, что ищет пробелы перед символом табуляции в начале строки. -Те, что выключены по умолчанию - это `indent-with-non-tab`, что ищет строки с пробелами вначале вместо символа табуляции (и контролируется настройкой `tabwidth`); `tab-in-indent`, что ищет символы табуляции в отступах в начале строки; и `cr-at-eol`, которая указывает Git на валидность наличия CR в конце строки. +Те, что выключены по умолчанию -- это `indent-with-non-tab`, что ищет строки с пробелами вначале вместо символа табуляции (и контролируется настройкой `tabwidth`); `tab-in-indent`, что ищет символы табуляции в отступах в начале строки; и `cr-at-eol`, которая указывает Git на валидность наличия CR в конце строки. Указав через запятую значения для настройки `core.whitespace`, можно сказать Git какие из этих опций должны быть включены. Чтобы отключить ненужные проверки, достаточно удалить их из строки значений или поставить знак `-` перед каждой из них. @@ -465,7 +465,7 @@ $ git config --system receive.fsckObjects true ===== `receive.denyNonFastForwards` Если вы перебазируете коммиты, которые уже отправлены, и попытаетесь отправить их снова или попытаетесь отправить коммит в удаленную ветку, в которой не содержится коммит, на который она указывает, то данные приняты не будут. -В принципе, это правильная политика; но в случае перебазирования - вы знаете, что делеаете и можете принудительно обновить удаленную ветку используя флаг `-f` для команды `push`. +В принципе, это правильная политика; но в случае перебазирования -- вы знаете, что делеаете и можете принудительно обновить удаленную ветку используя флаг `-f` для команды `push`. Для запрета перезаписи истории установите `receive.denyNonFastForwards`: @@ -474,7 +474,7 @@ $ git config --system receive.fsckObjects true $ git config --system receive.denyNonFastForwards true ---- -Сделать тоже самое можно другим способом - используя хук на стороне сервера, мы рассмотрим его немного позже. +Сделать тоже самое можно другим способом -- используя хук на стороне сервера, мы рассмотрим его немного позже. Этот подход позволяет более гибко настроить ограничения, например, запретить перезапись истории определенной группе пользователей. ===== `receive.denyDeletes` @@ -489,4 +489,4 @@ $ git config --system receive.denyDeletes true Эта команда запретит удаление веток и тэгов всем пользователям. Чтобы удалить ветку, придётся удалить все соответствующие ей файлы на сервере вручную. -Куда более интересный способ - это настроить права пользователей, с ним вы познакомитесь в разделе <>. +Куда более интересный способ -- это настроить права пользователей, с ним вы познакомитесь в разделе <>. diff --git a/book/08-customizing-git/sections/hooks.asc b/book/08-customizing-git/sections/hooks.asc index aa143b5e..fbb5b4a7 100644 --- a/book/08-customizing-git/sections/hooks.asc +++ b/book/08-customizing-git/sections/hooks.asc @@ -12,7 +12,7 @@ Хуки хранятся в поддиректории `hooks` относительно основной директории Git. Для большинства проектов это `.git/hooks`. Когда вы инициализируете новый репозиторий командой `git init`, Git наполняет директорию `hooks` примерами скриптов, большинство из которых готовы к использованию, при этом каждый из них содержит документацию по используемым входным данным. -Все примеры представлены в виде шелл скриптов, содержащими код на Perl, но вы можете использовать любой язык для написания скриптов - главное правильно именовать исполняемые файлы. +Все примеры представлены в виде шелл скриптов, содержащими код на Perl, но вы можете использовать любой язык для написания скриптов -- главное правильно именовать исполняемые файлы. Если вы решите использовать какой-либо из предустановленных скриптов, то достаточно его просто переименовать, убрав суффикс `.sample`. Для подключения собственного скрипта достаточно задать ему соответствующее имя, поместить в поддиректорию `hooks` основной директории Git и сделать его исполняемым. @@ -44,7 +44,7 @@ Для обычных коммитов этот хук бесполезен, однако находит своё применение для коммитов, где сообщние генерируется автоматически, например, для сообщений на основе шаблонов, коммитов слияния, сжимаемых и исправляемых коммитов. Его можно использовать для програмного заполнения шаблона коммита необходимой информацией. -Хук `commit-msg` принимает один параметр - путь к временному файлу, содержащему указанное разработчиком сообщение коммита. +Хук `commit-msg` принимает один параметр -- путь к временному файлу, содержащему указанное разработчиком сообщение коммита. Если скрипт завершается с ненулевым кодом, то Git отменяет создание коммита, поэтому вы можете использовать этот хук для валидации состояния проекта или сообщения коммита до того как он будет создан. В последнем разделе этой главы мы покажем как использовать этот хук для проверки сообщения коммита на соответствие заданному шаблону. Хук `post-commit` запускается после того, как коммит создан. @@ -80,7 +80,7 @@ Git отменит патч если этот скрипт завершится Git устанавливается с примером такого скрипта, однако он делает некоторые допущения, которые могут не соответствовать вашему рабочему процессу. Хук `post-rewrite` запускается командами, которые заменяют коммиты: `git commit --amend` и `git rebase` (но не `git filter-branch`). -Его единственный аргумент - команда, которая инициировала перезапись, а список перезаписанных изменений передаётся через `stdin`. +Его единственный аргумент -- команда, которая инициировала перезапись, а список перезаписанных изменений передаётся через `stdin`. Его применение практически аналогично хукам `post-checkout` и `post-merge`. После успешного выполнения `git checkout` запускается хук `post-checkout`; его можно использовать для настройки рабочей директории в соответствии с требованиями проекта. @@ -119,5 +119,5 @@ Pre-хуки могут возвращать ненулевой код в люб Хук `post-receive` вызывается после окончания всего процесса и может быть использован для обновления других сервисов или уведомления пользователей. Он принимает на `stdin` те же данные, что и хук `pre-receive`. -Использовать его можно, например, для e-mail рассылки, для уведомления сервера непрерывной интеграции или обновления системы управления задачами - разобрав сообщение коммита, можно определить необходимость создания, изменения или закрытия каких либо задач. +Использовать его можно, например, для e-mail рассылки, для уведомления сервера непрерывной интеграции или обновления системы управления задачами -- разобрав сообщение коммита, можно определить необходимость создания, изменения или закрытия каких либо задач. Этот хук не может прервать процесс, но клиент остаётся подключенным пока он не завершится, поэтому избегайте выполнения длительных операций. diff --git a/book/08-customizing-git/sections/policy.asc b/book/08-customizing-git/sections/policy.asc index e7ff685f..07593d5d 100644 --- a/book/08-customizing-git/sections/policy.asc +++ b/book/08-customizing-git/sections/policy.asc @@ -6,7 +6,7 @@ In this section, you'll use what you've learned to establish a Git workflow that You'll build client scripts that help the developer know if their push will be rejected and server scripts that actually enforce the policies. The scripts we'll show are written in Ruby; partly because of our intellectual inertia, but also because Ruby is easy to read, even if you can't necessarily write it. -However, any language will work – all the sample hook scripts distributed with Git are in either Perl or Bash, so you can also see plenty of examples of hooks in those languages by looking at the samples. +However, any language will work -- all the sample hook scripts distributed with Git are in either Perl or Bash, so you can also see plenty of examples of hooks in those languages by looking at the samples. ==== Server-Side Hook @@ -35,7 +35,7 @@ puts "(#{$refname}) (#{$oldrev[0,6]}) (#{$newrev[0,6]})" ---- Yes, those are global variables. -Don't judge – it's easier to demonstrate this way. +Don't judge -- it's easier to demonstrate this way. [[r_enforcing_commit_message_format]] ===== Enforcing a Specific Commit-Message Format @@ -390,7 +390,7 @@ you have to use files_modified = `git diff-index --cached --name-only HEAD` ---- -But those are the only two differences – otherwise, the script works the same way. +But those are the only two differences -- otherwise, the script works the same way. One caveat is that it expects you to be running locally as the same user you push as to the remote machine. If that is different, you must set the `$user` variable manually. @@ -435,7 +435,7 @@ This script uses a syntax that wasn't covered in the Revision Selection section ---- The `SHA^@` syntax resolves to all the parents of that commit. -You're looking for any commit that is reachable from the last commit on the remote and that isn't reachable from any parent of any of the SHA-1s you're trying to push up – meaning it's a fast-forward. +You're looking for any commit that is reachable from the last commit on the remote and that isn't reachable from any parent of any of the SHA-1s you're trying to push up -- meaning it's a fast-forward. -The main drawback to this approach is that it can be very slow and is often unnecessary – if you don't try to force the push with `-f`, the server will warn you and not accept the push. +The main drawback to this approach is that it can be very slow and is often unnecessary -- if you don't try to force the push with `-f`, the server will warn you and not accept the push. However, it's an interesting exercise and can in theory help you avoid a rebase that you might later have to go back and fix. diff --git a/book/09-git-and-other-scms/sections/client-bzr.asc b/book/09-git-and-other-scms/sections/client-bzr.asc index 10496682..08683139 100644 --- a/book/09-git-and-other-scms/sections/client-bzr.asc +++ b/book/09-git-and-other-scms/sections/client-bzr.asc @@ -1,7 +1,7 @@ ==== Git и Bazaar Ещё одна известная ДСКВ http://bazaar.canonical.com[Bazaar]. -Bazaar - это бесплатная система с открытым исходным кодом, являющаяся частью проекта https://www.gnu.org[GNU Project]. +Bazaar -- это бесплатная система с открытым исходным кодом, являющаяся частью проекта https://www.gnu.org[GNU Project]. Её поведение сильно отличается от Git. Иногда, чтобы сделать тоже самое, что и в Git, следует использовать другое ключевое слово, а некоторые такие же ключевые слова имеют другое значение. В частности, управления ветками сильно отличается и может вызвать путаницу, особенно для кого-нибудь из вселенной Git. @@ -24,7 +24,7 @@ $ chmod +x ~/bin/git-remote-bzr Им просто пользоваться. Чтобы склонировать Bazaar репозиторий достаточно добавить префикс `bzr::`. Так как Git и Bazaar полностью клонируют репозиторий на ваш компьютер, то можно добавить клон Git к локальному клону Bazaar, но так делать не рекомендуется. -Гораздо проще связать клон Git с центральным хранилищем - тем же местом, с которым связан клон Bazaar. +Гораздо проще связать клон Git с центральным хранилищем -- тем же местом, с которым связан клон Bazaar. Предположим, что вы работали с удаленным репозиторием, находящимся по адресу `bzr+ssh://developer@mybazaarserver:myproject`. Чтобы его склонировать, нужно выполнить следующие команды: diff --git a/book/09-git-and-other-scms/sections/client-hg.asc b/book/09-git-and-other-scms/sections/client-hg.asc index 3788113a..08265df0 100644 --- a/book/09-git-and-other-scms/sections/client-hg.asc +++ b/book/09-git-and-other-scms/sections/client-hg.asc @@ -13,7 +13,7 @@ ===== git-remote-hg Для начала необходимо установить `git-remote-hg`. -Ничего особенного — просто поместите файл в место, откуда он будет виден другим программам, типа: +Ничего особенного -- просто поместите файл в место, откуда он будет виден другим программам, типа: [source,console] ---- @@ -34,10 +34,10 @@ $ pip install mercurial (Если же у вас ещё нет Python, пора исправить это: скачайте установщик с https://www.python.org/[].) Ну и наконец понадобится сам клиент Mercurial. -Если он ещё не установлен — скачайте и установите с http://mercurial.selenic.com/[]. +Если он ещё не установлен -- скачайте и установите с http://mercurial.selenic.com/[]. Теперь можно отжигать! -Всё что потребуется — репозиторий Mercurial с которым вы можете работать. +Всё что потребуется -- репозиторий Mercurial с которым вы можете работать. К счастью, подойдёт любой, так что мы воспользуемся репозиторием "привет, мир", используемом для обучения Mercurial'у. [source,console] @@ -94,10 +94,10 @@ $ tree .git/refs `git-remote-hg` пытается нивелировать различия между Git и Mercurial, преобразовывая форматы за кулисами. Ссылки на объекты в удалённом репозитории хранятся в директории `refs/hg`. -Например, `refs/hg/origin/branches/default` — это Git-ссылка, содержащая SHA-1 "ac7955c" — коммит на который ссылается ветка `master`. -Таким образом, директория `refs/hg` — это что-то типа `refs/remotes/origin`, с той разницей что здесь же отдельно хранятся Mercurial-закладки и ветки. +Например, `refs/hg/origin/branches/default` -- это Git-ссылка, содержащая SHA-1 "ac7955c" -- коммит на который ссылается ветка `master`. +Таким образом, директория `refs/hg` -- это что-то типа `refs/remotes/origin`, с той разницей что здесь же отдельно хранятся Mercurial-закладки и ветки. -Файл `notes/hg` — отправная точка для выяснения соответствия между хешами коммитов в Git и идентификаторами ревизий в Mercurial. +Файл `notes/hg` -- отправная точка для выяснения соответствия между хешами коммитов в Git и идентификаторами ревизий в Mercurial. Давайте посмотрим что там: [source,console] @@ -128,7 +128,7 @@ $ git cat-file -p ac9117f В целом, работа с Mercurial сервером не сильно отличается от работы с Git сервером. Ещё одна вещь, которую следует учитывать: список игнорируемых файлов. -Mercurial и Git используют очень похожие механизмы для таких списков, но всё же хранить `.gitignore` в Mercurial репозитории — не самая удачная идея. +Mercurial и Git используют очень похожие механизмы для таких списков, но всё же хранить `.gitignore` в Mercurial репозитории -- не самая удачная идея. К счастью, в Git есть механизм игнорирования специфичных для локальной копии репозитория файлов, а формат списка исключений в Mercurial совместим с Git, так что можно просто скопировать `.hgignore` кое-куда: [source,console] @@ -299,7 +299,7 @@ o 0 0a04b987be5a 2005-08-26 01:20 -0700 mpm Обратите внимание на метку `[featureA]` на пятой ревизии. Таким образом, со стороны Git "закладки" выглядят как обычные ветки с одним лишь исключением: нельзя удалить закладку через Git (это одно из ограничений обёрток для взаимодействия с другими СКВ). -Можно работать и с полноценными ветками Mercurial — просто поместите Git ветку в пространство имён `branches`: +Можно работать и с полноценными ветками Mercurial -- просто поместите Git ветку в пространство имён `branches`: [source,console] ---- diff --git a/book/09-git-and-other-scms/sections/client-p4.asc b/book/09-git-and-other-scms/sections/client-p4.asc index f63dd890..7bf28471 100644 --- a/book/09-git-and-other-scms/sections/client-p4.asc +++ b/book/09-git-and-other-scms/sections/client-p4.asc @@ -2,14 +2,14 @@ (((Interoperation with other VCSs, Perforce))) (((Perforce))) -Perforce — очень распространённая система контроля версий в корпоративной среде. +Perforce -- очень распространённая система контроля версий в корпоративной среде. Она появилась в 1995 году, что делает её самой старой СКВ, рассматриваемой в этой главе. Perforce разработан в духе тех времён; он предполагает постоянное подключение к центральному серверу, а локально хранится одна-единственная версия файлов. На самом деле, его возможности, как и ограничения, разрабатывались для решения вполне конкретных проблем; хотя многие проекты, использующие Perforce сегодня, выиграли бы от перехода на Git. Существует два варианта совместного использования Git и Perforce. -Первый — Git Fusion от разработчиков Perforce — позволяет выставлять субдеревья Perforce-депо в качестве удалённых Git репозиториев. -Второй — `git-p4` — клиентская обёртка над Perforce для Git; она не требует дополнительной настройки Perforce сервера. +Первый -- Git Fusion от разработчиков Perforce -- позволяет выставлять субдеревья Perforce-депо в качестве удалённых Git репозиториев. +Второй -- `git-p4` -- клиентская обёртка над Perforce для Git; она не требует дополнительной настройки Perforce сервера. [[r_p4_git_fusion]] ===== Git Fusion @@ -19,7 +19,7 @@ Perforce разработан в духе тех времён; он предпо ====== Установка -Для примера мы воспользуемся простейшим способом настройки Git Fusion — подготовленным образом для виртуальной машины с предустановленным Perforce демоном и собственно Git Fusion'ом. +Для примера мы воспользуемся простейшим способом настройки Git Fusion -- подготовленным образом для виртуальной машины с предустановленным Perforce демоном и собственно Git Fusion'ом. Вы можете скачать образ на http://www.perforce.com/downloads/Perforce/20-User[], а затем импортировать его в ваше любимое средство виртуализации (мы будем использовать VirtualBox). Во время первого запуска вам потребуется сконфигурировать пароли трёх Linux пользователей (`root`, `perforce` и `git`) и имя хоста, которое будет идентифицировать компьютер в сети. @@ -99,7 +99,7 @@ $ tree ---- Директория `objects` используется Git Fusion для отображения объектов Perforce в Git и наоборот, вам не следует ничего здесь трогать. -Внутри расположен глобальный конфигурационный файл `p4gf_config`, а также по одному такому же файлу для каждого репозитория — эти файлы и определяют поведение Git Fusion. +Внутри расположен глобальный конфигурационный файл `p4gf_config`, а также по одному такому же файлу для каждого репозитория -- эти файлы и определяют поведение Git Fusion. Заглянем в тот, что в корне: [source,ini] @@ -187,7 +187,7 @@ joe employeeY@example.com "Anon Y. Mouse" ====== Рабочий процесс -Perforce Git Fusion — это двунаправленный "мост" между Perforce и Git. +Perforce Git Fusion -- это двунаправленный "мост" между Perforce и Git. Давайте посмотрим, как выглядит работа со стороны Git. Предполагается, что мы настроили отображение проекта "Jam", используя приведённую выше конфигурацию. Тогда мы можем клонировать его: @@ -304,11 +304,11 @@ image::images/git-fusion-perforce-graph.png[Граф ревизий Perforce п У Perforce не было именованной ветки для сохранения коммитов `1` и `2`, так что он создал "анонимную" ветку в директории `.git-fusion`. Git Fusion поступит так же для именованных Git веток не соответствующих веткам в Perforce, но вы можете задать соответствие в конфигурационном файле. -Большинство происходящей магии скрыто от посторонних глаз, а в результате кто-то в команде может использовать Git, кто-то — Perforce и никто не будет подозревать о выборе других. +Большинство происходящей магии скрыто от посторонних глаз, а в результате кто-то в команде может использовать Git, кто-то -- Perforce и никто не будет подозревать о выборе других. ====== Заключение по Git-Fusion -Если у вас есть (или вы можете получить) доступ к Perforce серверу, Git Fusion — это прекрасный способ подружить Git и Perforce. +Если у вас есть (или вы можете получить) доступ к Perforce серверу, Git Fusion -- это прекрасный способ подружить Git и Perforce. Конечно, требуется небольшая работа напильником, но в целом всё довольно интуитивно и просто. Это один из немногих разделов в этой главе, где мы не будем предупреждать вас об опасности использования всей функциональности Git. Но Perforce не всеяден: если вы попытаетесь переписать опубликованную историю, Git Fusion отклонит изменения. @@ -320,7 +320,7 @@ Git Fusion поступит так же для именованных Git вет ===== Git-p4 (((git commands, p4))) -Git-p4 — это двусторонний мост между Git и Perforce. +Git-p4 -- это двусторонний мост между Git и Perforce. Он работает на стороне клиента, так что вам не нужен будет доступ к Perforce серверу (разумеется, вам по-прежнему понадобятся логин и пароль). Git-p4 не так гибок и полнофункционален, как Git Fusion, но он позволяет совершать большинство необходимых действий. @@ -344,7 +344,7 @@ $ export P4USER=john ====== Начало работы -Как обычно при работе с Git, первая команда — это клонирование: +Как обычно при работе с Git, первая команда -- это клонирование: [source,console] ---- @@ -488,7 +488,7 @@ Files: `git-p4` старается учитывать Git и Perforce настройки когда нужно предоставить имя для коммита, но в некоторых случаях вы захотите изменить его. Например, если коммит в Git был создан человеком, у которого нет Perforce аккаунта, вы всё равно захотите сделать автором коммита его, а не себя. -`git-p4` вставил сообщение из коммита Git в содержимое набора изменений Perforce, так что всё что нам остаётся сделать — это дважды сохранить и закрыть редактор (по одному разу на каждый коммит). +`git-p4` вставил сообщение из коммита Git в содержимое набора изменений Perforce, так что всё что нам остаётся сделать -- это дважды сохранить и закрыть редактор (по одному разу на каждый коммит). В результате мы получим такой вывод: [source,console] @@ -578,7 +578,7 @@ Would apply 3be6fd8 Correct email address ---- -Флаг `-n` — это сокращение для `--dry-run`, который, в свою очередь, пытается вывести результат выполнения отправки, как если бы отправка на самом деле произошла. +Флаг `-n` -- это сокращение для `--dry-run`, который, в свою очередь, пытается вывести результат выполнения отправки, как если бы отправка на самом деле произошла. В этом случае, похоже мы создадим три ревизии в Perforce, по одной для каждой не являющейся слиянием коммита в Git. Звучит логично, давайте посмотрим что произойдёт на самом деле: @@ -658,7 +658,7 @@ $ git config git-p4.branchList main:dev $ git clone --detect-branches //depot/project@all . ---- -Задав конфигурационный параметр `git-p4.branchList` равным `main:dev` мы указали `git-p4`, что "main" и "dev" — это ветки, и что вторая является потомком первой. +Задав конфигурационный параметр `git-p4.branchList` равным `main:dev` мы указали `git-p4`, что "main" и "dev" -- это ветки, и что вторая является потомком первой. Если мы теперь выполним `git checkout -b dev p4/project/dev` и зафиксируем в ветке `dev` некоторые изменения, `git-p4` будет достаточно смышлёным, чтобы догадаться, в какую ветку отправлять изменения при выполнении `git p4 submit`. К сожалению, `git-p4` не позволяет использовать несколько веток в поверхностных копиях репозиториев; если у вас есть большой проект и вы хотите работать более чем в одной ветке, вам придётся выполнять `git p4 clone` для каждой ветки, в которую вы хотите отправлять изменения. @@ -673,4 +673,4 @@ $ git clone --detect-branches //depot/project@all . Тем не менее, не стоит забывать, что источником данных по-прежнему остаётся Perforce, а Git используется лишь для локальной работы. Будьте осторожны с публикацией Git коммитов: если у вас есть удалённый репозиторий, который используют другие люди, не публикуйте в нём коммиты, не отправленные на Perforce сервер. -Если вы хотите свободно смешивать Git и Perforce для контроля версий, уговорите администратора установить Git Fusion — он позволяет использовать Git в качестве полноценного клиента для Perforce сервера. +Если вы хотите свободно смешивать Git и Perforce для контроля версий, уговорите администратора установить Git Fusion -- он позволяет использовать Git в качестве полноценного клиента для Perforce сервера. diff --git a/book/09-git-and-other-scms/sections/client-svn.asc b/book/09-git-and-other-scms/sections/client-svn.asc index 905b46a7..ca804b3f 100644 --- a/book/09-git-and-other-scms/sections/client-svn.asc +++ b/book/09-git-and-other-scms/sections/client-svn.asc @@ -4,18 +4,18 @@ (((Subversion)))(((Interoperation with other VCSs, Subversion))) Весомая часть проектов с исходным кодом, равно как и огромное количество корпоративных проектов, до сих пор используют Subversion для версионирования исходного кода. SVN'у больше десяти лет и большую часть этого срока он оставался _единственным_ вариантом СКВ для проектов с открытым исходным кодом. -SVN очень похож на CVS, своего предка — "крёстного отца" всех современных СКВ. +SVN очень похож на CVS, своего предка -- "крёстного отца" всех современных СКВ. (((git commands, svn)))(((git-svn))) -Одна из многих замечательных вещей в Git — это поддержка двусторонней интеграции с SVN через `git svn`. +Одна из многих замечательных вещей в Git -- это поддержка двусторонней интеграции с SVN через `git svn`. Этот инструмент позволяет использовать Git в качестве полноценного SVN клиента; вы можете использовать всю функциональность Git для работы с локальным репозиторием, скомпоновать ревизии и отправить их на сервер, словно вы использовали обычный SVN. Да, вы не ослышались: можно создавать локальные ветки, производить слияния, использовать индекс для неполного применения изменений, перемещать коммиты и повторно применять их (cherry-pick) и т.д., в то время как ваши коллеги, использующие SVN, застряли в палеолите. Это отличный способ по-партизански внедрить Git в процесс разработки и помочь соратниками стать более продуктивными, а затем потребовать от инфраструктуры полной поддержки Git. -`git svn` — это первый укол наркотика "РСКВ", вызывающего сильнейшее привыкание. +`git svn` -- это первый укол наркотика "РСКВ", вызывающего сильнейшее привыкание. ===== `git svn` -Основная команда для работы с Subversion — это `git svn`. +Основная команда для работы с Subversion -- это `git svn`. Она принимает несколько дополнительных команд, которые мы рассмотрим далее. Важно понимать, что каждый раз, когда вы используете `git svn`, вы взаимодействуете с Subversion, который работает совсем не как Git. @@ -24,7 +24,7 @@ SVN очень похож на CVS, своего предка — "крёстн Не изменяйте уже опубликованную историю, и не зеркалируйте изменения в Git репозитории, с которым работают люди, использующие Git (они могут изменить историю). В Subversion может быть только одна линейная история коммитов. -Если в вашей команде часть людей использует SVN, а часть — Git, убедитесь, что все используют SVN сервер для сотрудничества. +Если в вашей команде часть людей использует SVN, а часть -- Git, убедитесь, что все используют SVN сервер для сотрудничества. Это сделает вашу жизнь проще. ===== Установка @@ -32,7 +32,7 @@ SVN очень похож на CVS, своего предка — "крёстн Чтобы попробовать `git svn` в деле вам понадобится обычный SVN репозиторий с правом на запись. Если вы хотите попробовать примеры ниже, вам понадобится копия нашего тестового репозитория. К счастью, в Subversion есть инструмент `svnsync`, который упростит перенос. -Для тестов мы создали новый Subversion репозиторий на Google Code, являющийся частичной копией проекта `protobuf` — библиотеки для сериализации структурированных данных для передачи по сети. +Для тестов мы создали новый Subversion репозиторий на Google Code, являющийся частичной копией проекта `protobuf` -- библиотеки для сериализации структурированных данных для передачи по сети. Если вы с нами, создайте локальный Subversion репозиторий: @@ -42,7 +42,7 @@ $ mkdir /tmp/test-svn $ svnadmin create /tmp/test-svn ---- -Затем, позвольте всем пользователям изменять т.н. `revprops`; самый простой способ сделать это — добавить скрипт `pre-revprop-change`, всегда возвращающий 0: +Затем, позвольте всем пользователям изменять т.н. `revprops`; самый простой способ сделать это -- добавить скрипт `pre-revprop-change`, всегда возвращающий 0: [source,console] ---- @@ -75,7 +75,7 @@ Copied properties for revision 2. ---- На всё про всё у вас уйдёт несколько минут, но на самом деле вам ещё повезло: если бы вы копировали данные не на свой компьютер, а в другой удалённый репозиторий, понадобился бы почти час, несмотря на то, что в тестовом проекте меньше сотни ревизий. -Subversion копирует данные последовательно, скачивая по одной ревизии и отправляя в другой репозиторий — это поразительно неэффективно, но как есть, так есть. +Subversion копирует данные последовательно, скачивая по одной ревизии и отправляя в другой репозиторий -- это поразительно неэффективно, но как есть, так есть. ===== Начало работы @@ -103,9 +103,9 @@ Checked out HEAD: file:///tmp/test-svn/trunk r75 ---- -Приведённая выше команда является композицией двух других — `git svn init` и `git svn fetch` для указанного URL. +Приведённая выше команда является композицией двух других -- `git svn init` и `git svn fetch` для указанного URL. Процесс копирования займёт некоторое время. -Тестовый проект невелик — всего 75 коммитов — но Git вынужден последовательно скачивать SVN ревизии и превращать их в Git коммиты по одной за раз. +Тестовый проект невелик -- всего 75 коммитов -- но Git вынужден последовательно скачивать SVN ревизии и превращать их в Git коммиты по одной за раз. Для проекта с сотней или тысячей ревизий это может занять часы или даже дни! Параметры `-T trunk -b branches -t tags` говорят Git о том, что клонируемый репозиторий следует стандартному, принятому в Subversion, расположению директорий с транком, ветками и метками. @@ -311,7 +311,7 @@ Fast-forwarded master to refs/remotes/origin/trunk. После того как вы привыкните к Git, вам понравится создавать тематические ветки, работать в них и сливать их основную ветку разработки. Если работаете с Subversion сервером через `git svn`, вам придётся перемещать изменения, а не проводить слияния. -Причина кроется в линейности истории в Subversion — в нём принята несколько иная концепция ветвления и слияния — так что `git svn` учитывает лишь первого родителя любого коммита при преобразовании её в SVN формат. +Причина кроется в линейности истории в Subversion -- в нём принята несколько иная концепция ветвления и слияния -- так что `git svn` учитывает лишь первого родителя любого коммита при преобразовании её в SVN формат. [source,console] ---- @@ -333,7 +333,7 @@ Resetting to the latest refs/remotes/origin/trunk Выполнение команды `dcommit` на ветке с уже слитой историй пройдёт успешно, за исключением того момента, что при просмотре истории вы заметите, что коммита из ветки `experiment` не были переписаны один за другим; вместо этого они схлопнулись в один коммит-слияние. -Когда кто-нибудь склонирует этот репозиторий, всё что он увидит — единственное слияние, в котором собраны все изменения, словно вы выполнили `git merge --squash`; они не увидят кто и когда производил коммиты. +Когда кто-нибудь склонирует этот репозиторий, всё что он увидит -- единственное слияние, в котором собраны все изменения, словно вы выполнили `git merge --squash`; они не увидят кто и когда производил коммиты. ===== Subversion-ветвление @@ -360,7 +360,7 @@ r91 = f1b64a3855d3c8dd84ee0ef10fa89d27f1584302 (refs/remotes/origin/opera) ===== Переключение активных веток -Git определяет ветку, в которую он отправит ваши коммиты при выполнении `dcommit`, ища верхушку Subversion-ветки в вашей истории — она должна быть одна и она должна быть последней в текущей истории веток, имеющей метку `git-svn-id`. +Git определяет ветку, в которую он отправит ваши коммиты при выполнении `dcommit`, ища верхушку Subversion-ветки в вашей истории -- она должна быть одна и она должна быть последней в текущей истории веток, имеющей метку `git-svn-id`. Если вы хотите работать одновременно с несколькими ветками, вы можете настроить локальные ветки на внесение изменений через `dcommit` в конкретные ветки Subversion, отпочковывая их из импортированных SVN-ревизий нужных веток. Если вам нужна ветка `opera`, в которой вы можете поработать отдельно, можете выполнить: @@ -376,7 +376,7 @@ $ git branch opera remotes/origin/opera Помните, что хотя вы и используете `git merge` для этой операции, и слияние, скорее всего, произойдёт намного проще, чем в Subversion (потому что Git автоматически определяет подходящую основу для слияния), оно не является обычным слиянием в Git. Вы должны передать данные обратно на сервер в Subversion, который не способен справиться с коммитом, имеющим более одного родителя; так что после передачи она будет выглядеть как единое целое, куда будут затолканы все изменения из другой ветки. После того как вы сольёте одну ветку в другую, вы не сможете просто так вернуться к работе над ней, как могли бы в Git. -Команда `dcommit` удаляет всю информацию о том, какая ветка была влита, так что последующие вычисления базы слияния будут неверными — команда `dcommit` сделает результаты выполнения `git merge` такими же, какими они были бы после выполнения `git merge --squash`. +Команда `dcommit` удаляет всю информацию о том, какая ветка была влита, так что последующие вычисления базы слияния будут неверными -- команда `dcommit` сделает результаты выполнения `git merge` такими же, какими они были бы после выполнения `git merge --squash`. К сожалению, избежать подобной ситуации вряд ли удастся: Subversion не способен сохранять подобную информацию, так что вы всегда будете связаны этими ограничениями. Во избежание проблем вы должны удалить локальную ветку (в нашем случае `opera`) после того, как вы вольёте её в trunk. @@ -463,9 +463,9 @@ Last Changed Date: 2009-05-02 16:07:37 -0700 (Sat, 02 May 2009) Если вы клонируете Subversion-репозиторий с установленными `svn:ignore` свойствами, скорее всего, вы захотите создать соответствующие им файлы `.gitignore`, чтобы ненароком не зафиксировать лишнего. Для решения этой проблемы в `git svn` имеется две команды. -Первая — `git svn create-ignore` — автоматически создаст соответствующие файлы `.gitignore`, которые вы затем можете зафиксировать. +Первая -- `git svn create-ignore` -- автоматически создаст соответствующие файлы `.gitignore`, которые вы затем можете зафиксировать. -Вторая команда — `git svn show-ignore` — выводит на стандартный вывод строки, которые следует включить в файл `.gitignore`; вы можете попросту перенаправить вывод этой команды в файл исключений: +Вторая команда -- `git svn show-ignore` -- выводит на стандартный вывод строки, которые следует включить в файл `.gitignore`; вы можете попросту перенаправить вывод этой команды в файл исключений: [source,console] ---- diff --git a/book/09-git-and-other-scms/sections/client-tfs.asc b/book/09-git-and-other-scms/sections/client-tfs.asc index d4b7a065..658470a6 100644 --- a/book/09-git-and-other-scms/sections/client-tfs.asc +++ b/book/09-git-and-other-scms/sections/client-tfs.asc @@ -3,8 +3,8 @@ (((Interoperation with other VCSs, TFS))) (((TFS)))((("TFVC", see="TFS"))) Git набирает популярность среди Windows-разработчиков и если вы один из них, то велика вероятность что вы пользовались Microsoft Team Foundation Server (TFS). -TFS — это комплексное решение, включающее в себя систему отслеживание ошибок, систему учёта рабочего времени, решения для поддержки Scrum методологии, инструменты для проведения инспекции кода и собственно систему контроля версий. -Здесь есть небольшая путаница: *TFS* — это сервер, поддерживающий управление версиями как с помощью Git, так и с помощью собственной СКВ — *TFVC* (Team Foundation Version Control). +TFS -- это комплексное решение, включающее в себя систему отслеживание ошибок, систему учёта рабочего времени, решения для поддержки Scrum методологии, инструменты для проведения инспекции кода и собственно систему контроля версий. +Здесь есть небольшая путаница: *TFS* -- это сервер, поддерживающий управление версиями как с помощью Git, так и с помощью собственной СКВ -- *TFVC* (Team Foundation Version Control). Поддержка Git появилась в TFS относительно недавно (начиная с 2013-й версии), так что когда идёт речь об управлении версиями в более ранних версиях TFS, имеется в виду именно TFVC. Если вы оказались в команде, работающей с TFVC, но хотите использовать Git для управления версиями, есть проект, способный вам помочь. @@ -51,7 +51,7 @@ Git-tf больше не поддерживается компанией Microso $ git tf clone https://tfs.codeplex.com:443/tfs/TFS13 $/myproject/Main project_git ---- -Первый аргумент — это URL TFVC коллекции, второй представляет собой строку вида `$/project/branch`, и третий — это путь к локальному Git репозиторию, который будет создан (третий параметр опционален). +Первый аргумент -- это URL TFVC коллекции, второй представляет собой строку вида `$/project/branch`, и третий -- это путь к локальному Git репозиторию, который будет создан (третий параметр опционален). `git-tf` поддерживает одновременную работу только с одной веткой; если вы хотите работать с разными TFVC ветками, вам потребуется несколько копий репозитория. Приведённая выше команда создаёт обыкновенный Git репозиторий: @@ -88,7 +88,7 @@ d44b17a (HEAD, tag: TFS_C35190, origin_tfs/tfs, master) Goodbye Обратите внимание на метки типа `TFS_C35189`; это помогает проассоциировать Git коммиты с наборами изменений TFVC. Это очень удобно, потому что вы можете узнать, какие из коммитов ассоциированы со слепком в TFVC с помощью простой команды. -Это не обязательное поведение (вы можете выключить его, вызвав `git config git-tf.tag false`) — `git-tf` и так хранит соответствия в файле `.git/git-tf`. +Это не обязательное поведение (вы можете выключить его, вызвав `git config git-tf.tag false`) -- `git-tf` и так хранит соответствия в файле `.git/git-tf`. ===== Начало работы: `git-tfs` @@ -136,8 +136,8 @@ Date: Fri Aug 1 03:41:59 2014 +0000 git-tfs-id: [https://username.visualstudio.com/DefaultCollection]$/myproject/Trunk;C16 ---- -Видим две локальные ветки — `master` и `featureA` — представляющие соответственно основную ветку разработки (`Trunk` в TFVC) и дочернюю ветку `featureA` в TFVC. -Также вы можете видеть, что "удалённый репозиторий" `tfs` имеет две ссылки — `default` и `featureA` — соответствующие тем же веткам в TFVC. +Видим две локальные ветки -- `master` и `featureA` -- представляющие соответственно основную ветку разработки (`Trunk` в TFVC) и дочернюю ветку `featureA` в TFVC. +Также вы можете видеть, что "удалённый репозиторий" `tfs` имеет две ссылки -- `default` и `featureA` -- соответствующие тем же веткам в TFVC. `git-tfs` также называет ветку с которой вы инициировали копирование `tfs/default`, имена остальных веток соответствуют таковым в TFVC. Ещё одна стоящая внимание вещь: строки `git-tfs-id:` в сообщениях коммитов. @@ -417,7 +417,7 @@ PS> git log --oneline --graph --decorate --all ===== Заключение по Git и TFS -`git-tf` и `git-tfs` — отличные инструменты для взаимодействия с TFVC сервером. +`git-tf` и `git-tfs` -- отличные инструменты для взаимодействия с TFVC сервером. Они позволяют использовать преимущества Git для работы в локальном репозитории, избегая постоянных взаимодействий с центральным TFVC сервером. Это упрощает вашу жизнь, но не заставляет ваших коллег также переходить на Git. Если вы работаете под Windows (что вполне вероятно, раз уж вы используете TFS), тогда `git-tfs` будет наиболее разумным выбором, так как его функциональность наиболее полна; но если вы используете другую платформу, вам придётся использовать более ограниченный `git-tf`. diff --git a/book/09-git-and-other-scms/sections/import-bzr.asc b/book/09-git-and-other-scms/sections/import-bzr.asc index f10bbea3..76e0ff2e 100644 --- a/book/09-git-and-other-scms/sections/import-bzr.asc +++ b/book/09-git-and-other-scms/sections/import-bzr.asc @@ -81,7 +81,7 @@ $ bzr fast-export --plain . | git fast-import ===== Проект с основной и рабочей ветками Вы так же можете импортировать Bazaar репозиторий с несколькими ветками. -Предположим, что в вашем репозитории две ветки: одна является основной веткой проекта (myProject.trunk), другая - рабочей (myProject.work). +Предположим, что в вашем репозитории две ветки: одна является основной веткой проекта (myProject.trunk), другая -- рабочей (myProject.work). [source,console] ---- @@ -118,7 +118,7 @@ git fast-import --import-marks=../marks.git --export-marks=../marks.git ===== Синхронизация индекса -Вне зависимости от количества веток и выбранного метода импорта, индекс не синхронизируется с `HEAD`, а при импорте нескольких веток - так же не синхронизируется рабочая директория. +Вне зависимости от количества веток и выбранного метода импорта, индекс не синхронизируется с `HEAD`, а при импорте нескольких веток -- так же не синхронизируется рабочая директория. Эту ситуацию можно легко исправить следующей командой: [source,console] @@ -129,7 +129,7 @@ $ git reset --hard HEAD ===== Игнорирование файлов из .bzrignore Теперь давайте посмотрим на файлы, которые следует игнорировать. -Первое, что нужно сделать - это переименовать `.bzrignore` в `.gitignore`. +Первое, что нужно сделать -- это переименовать `.bzrignore` в `.gitignore`. Если файл `.bzrignore` содержит одну или несколько строк начинающихся с "!!" или "RE:", нужно их изменить и, возможно, создать несколько файлов `.gitignore`, чтобы заставить Git игнорировать точно те же файлы, которые игнорируются Bazaar. Наконец, создайте коммит со всеми изменениями, внесенными во время миграции: diff --git a/book/09-git-and-other-scms/sections/import-custom.asc b/book/09-git-and-other-scms/sections/import-custom.asc index f43112d1..016c2ccb 100644 --- a/book/09-git-and-other-scms/sections/import-custom.asc +++ b/book/09-git-and-other-scms/sections/import-custom.asc @@ -3,8 +3,8 @@ (((git commands, fast-import))) (((Importing, from others))) -Если вы пользуетесь какой-либо другой системой контроля версий, не перечисленной выше, вам следует поискать инструмент для импорта в Сети — качественные решения доступны для CVS, Clear Case, Visual Source Safe и даже директорий с архивами. -Если всё же существующие решения вам не подошли, вы пользуетесь менее известной СКВ или вам нужно больше контроля над процессом импорта — используйте `git fast-import`. +Если вы пользуетесь какой-либо другой системой контроля версий, не перечисленной выше, вам следует поискать инструмент для импорта в Сети -- качественные решения доступны для CVS, Clear Case, Visual Source Safe и даже директорий с архивами. +Если всё же существующие решения вам не подошли, вы пользуетесь менее известной СКВ или вам нужно больше контроля над процессом импорта -- используйте `git fast-import`. Эта команда читает простые инструкции из потока ввода и записывает данные в Git. Создать Git-объекты таким путём намного проще, чем через низкоуровневые Git-команды или пытаясь воссоздать их вручную (обратитесь к <> за деталями). Таким образом, вы можете написать небольшой скрипт, считывающий нужную информацию из вашего хранилища и выводящий инструкции в стандартный поток вывода. @@ -30,7 +30,7 @@ current Итак, мы пробежимся по всем слепкам, создадим коммит для каждого из них и свяжем каждый новый коммит с предыдущим. Как и в разделе <>, мы проделаем это на Ruby, потому что это мы любим этот язык и его понять. -Вы можете использовать любой другой язык — всё что требуется, это вывести нужную информацию в стандартный поток вывода. +Вы можете использовать любой другой язык -- всё что требуется, это вывести нужную информацию в стандартный поток вывода. Если вы работаете на Windows, будьте особо осторожными с переводами строк: `fast-import` ожидает лишь символы перевода строки (`LF`), но не возврат каретки + перевод строки (`CRLF`), как принято в Windows. Для начала зайдём в исходную директорию и определим поддиректории, содержащие состояния проекта в разные моменты времени, которые будут использованы для построения соответствующих коммитов. @@ -145,7 +145,7 @@ end ---- Осталось лишь задать содержимое каждого коммита. -Это довольно просто, потому что все данные хранятся в отдельных директориях — достаточно напечатать команду `deleteall` и содержимое всех файлов в директории. +Это довольно просто, потому что все данные хранятся в отдельных директориях -- достаточно напечатать команду `deleteall` и содержимое всех файлов в директории. После этого Git запишет слепки: [source,ruby] @@ -170,7 +170,7 @@ data (size) (file contents) ---- -Здесь `644` — это права доступа к файлу. +Здесь `644` -- это права доступа к файлу. Если файл должен быть исполняемым, вам нужно определить это и передать `755`. Слово `inline` говорит о том, что вы выведете содержимое файла после этой строки. Таким образом, метод `inline_data` может выглядеть так: @@ -186,7 +186,7 @@ end Мы используем определённый ранее метод `export_data` потому что форматы содержимого коммитов и их сообщений одинаковы. -И последнее что нужно сделать — это вернуть метку для последующих вызовов: +И последнее что нужно сделать -- это вернуть метку для последующих вызовов: [source,ruby] ---- diff --git a/book/09-git-and-other-scms/sections/import-hg.asc b/book/09-git-and-other-scms/sections/import-hg.asc index fbb69b55..6cc7e82e 100644 --- a/book/09-git-and-other-scms/sections/import-hg.asc +++ b/book/09-git-and-other-scms/sections/import-hg.asc @@ -110,7 +110,7 @@ $ git shortlog -sn ---- Вот, собственно, и всё. -Все Mercurial метки были преобразованы в метки Git, а ветки и закладки — в ветки Git. +Все Mercurial метки были преобразованы в метки Git, а ветки и закладки -- в ветки Git. Теперь можно отправить репозиторий на новый Git сервер: [source,console] diff --git a/book/09-git-and-other-scms/sections/import-p4.asc b/book/09-git-and-other-scms/sections/import-p4.asc index ba6128b3..5342edb8 100644 --- a/book/09-git-and-other-scms/sections/import-p4.asc +++ b/book/09-git-and-other-scms/sections/import-p4.asc @@ -71,7 +71,7 @@ Date: Tue Jul 7 01:35:51 2009 -0800 `git-p4` оставил идентификаторы в сообщениях всех коммитов. Ничего страшного нет в том, чтобы оставить всё как есть, особенно если вы захотите сослаться на номер ревизии в Perforce в будущем. -Если же вы хотите убрать эти строки, теперь — прежде чем приступать к работе с репозиторием — самое время для этого. +Если же вы хотите убрать эти строки, теперь -- прежде чем приступать к работе с репозиторием -- самое время для этого. (((git commands, filter-branch))) Вы можете использовать `git filter-branch` чтобы удалить идентификаторы из всех сообщений одним махом: diff --git a/book/09-git-and-other-scms/sections/import-svn.asc b/book/09-git-and-other-scms/sections/import-svn.asc index 612956d8..ac4cd6b0 100644 --- a/book/09-git-and-other-scms/sections/import-svn.asc +++ b/book/09-git-and-other-scms/sections/import-svn.asc @@ -7,7 +7,7 @@ Сразу же после клонирования вам будет доступная вся история репозитория, хотя сам процесс получения копии может затянуться. В добавок к этому импортирование не идеально, так что вы, возможно, захотите сделать его как можно более правильно с первой попытки. -И первая проблема — это информация об авторстве. +И первая проблема -- это информация об авторстве. В Subversion на каждого участника рабочего процесса заведён пользователь, информация о пользователе сохраняется вместе с каждой ревизией. В предыдущем разделе вы могли видеть пользователя `schacon` в некоторых местах, типа вывода команды `blame` или `git svn log`. Если вы хотите видеть подробную информацию об авторстве в Git, вам потребуется задать соответствие между пользователями Subversion и авторами в Git. @@ -104,7 +104,7 @@ $ for t in $(git for-each-ref --format='%(refname:short)' refs/remotes/tags); do $ for b in $(git for-each-ref --format='%(refname:short)' refs/remotes); do git branch $b refs/remotes/$b && git branch -D -r $b; done ---- -Возможно, для одной ветки Subversion будут созданы дополнительные ветки с суффиксом `@xxx` (где ххх - это число). +Возможно, для одной ветки Subversion будут созданы дополнительные ветки с суффиксом `@xxx` (где ххх -- это число). Это связано с особенностью Subversion, которая называется ``peg-revisions'', для которой Git не имеет синтаксического аналога. Поэтому, `git svn` просто добавляет номер версии svn в название ветки, точно так же как вы бы это сделали в svn при добавлении peg-revision для ветки. Если эти ревизии вам больше не нужны, то просто удалите их используя команду: @@ -114,7 +114,7 @@ $ for b in $(git for-each-ref --format='%(refname:short)' refs/remotes); do git $ for p in $(git for-each-ref --format='%(refname:short)' | grep @); do git branch -D $p; done ---- -Теперь все ветки стали настоящими Git ветками, а тэги - настоящими Git тэгами. +Теперь все ветки стали настоящими Git ветками, а тэги -- настоящими Git тэгами. К сожалению, `git svn` создаёт дополнительную ветку с названием `trunk`, которая соответствует ветке по умолчанию в Subversion и аналогична ветке `master`. Так как `master` больше подходит для Git, удалим лишнюю ветку: @@ -124,7 +124,7 @@ $ for p in $(git for-each-ref --format='%(refname:short)' | grep @); do git bran $ git branch -d trunk ---- -Последнее, что нужно сделать — это добавить ваш Git сервер в качестве удалённого репозитория и залить данные на него. +Последнее, что нужно сделать -- это добавить ваш Git сервер в качестве удалённого репозитория и залить данные на него. Вот пример добавления удалённого репозитория: [source,console] diff --git a/book/09-git-and-other-scms/sections/import-tfs.asc b/book/09-git-and-other-scms/sections/import-tfs.asc index 4877747f..b54ce0d1 100644 --- a/book/09-git-and-other-scms/sections/import-tfs.asc +++ b/book/09-git-and-other-scms/sections/import-tfs.asc @@ -21,7 +21,7 @@ PS> tf history $/myproject -recursive > AUTHORS_TMP ---- Эта команда пробегается по всем ревизиям проекта и сохраняет информацию о них в файл `AUTHORS_TMP`, из которого мы впоследствии вытянем пользователей (2-я колонка). -Откройте этот файл и запомните начало и конец колонки с пользователями, а затем используйте следующую команду (параметр `11-20` — это и есть границы колонки с пользователями): +Откройте этот файл и запомните начало и конец колонки с пользователями, а затем используйте следующую команду (параметр `11-20` -- это и есть границы колонки с пользователями): [source,powershell] ---- @@ -38,7 +38,7 @@ PS> cat AUTHORS_TMP | cut -b 11-20 | tail -n+3 | uniq | sort > AUTHORS DOMAIN\username = User Name ---- -Часть слева от знака равенства — это поле "User" из TFVC, а часть справа — соответствующий ему автор в Git. +Часть слева от знака равенства -- это поле "User" из TFVC, а часть справа -- соответствующий ему автор в Git. Как только этот файл готов, необходимо сделать полную копию TFVC проекта: diff --git a/book/10-git-internals/sections/environment.asc b/book/10-git-internals/sections/environment.asc index f8357fb3..cf6691e7 100644 --- a/book/10-git-internals/sections/environment.asc +++ b/book/10-git-internals/sections/environment.asc @@ -32,19 +32,19 @@ Git всегда запущен в bash и использует некоторы Git использует некоторые переменные среды, чтобы определить как она взаимодействует с конкретным репозиторием. -*`GIT_DIR`* — это месторасположение директории `.git`. +*`GIT_DIR`* -- это месторасположение директории `.git`. Если эта переменная не задана, Git будет переходить вверх по дереву директорий, пока не достигнет `~` (домашней директории пользователя) или `/` (корневой директории), проверяя на каждом шагу наличие директории `.git`. *`GIT_CEILING_DIRECTORIES`* управляет процессом поиска директории `.git`. Если вы работаете с медленной файловой системой (типа ленточного накопителя или сетевой папки), вы можете запретить Git доступ к `.git` без надобности, например, для построения строки приветствия. -*`GIT_WORK_TREE`* — это путь к рабочей директории для не-серверного репозитория (с непустой рабочей директорией). Если эта переменная не задана, будет использована родительская директория `$GIT_DIR`. +*`GIT_WORK_TREE`* -- это путь к рабочей директории для не-серверного репозитория (с непустой рабочей директорией). Если эта переменная не задана, будет использована родительская директория `$GIT_DIR`. -*`GIT_INDEX_FILE`* — это путь к файлу индекса (только для репозиториев с непустой рабочей директорией). +*`GIT_INDEX_FILE`* -- это путь к файлу индекса (только для репозиториев с непустой рабочей директорией). *`GIT_OBJECT_DIRECTORY`* может быть использована для указания директории с объектами вместо `.git/objects`. -*`GIT_ALTERNATE_OBJECT_DIRECTORIES`* — это список разделённых двоеточием директорий (типа `/dir/one:/dir/two:…`), в которых Git будет пытаться найти объекты, которых нет в `GIT_OBJECT_DIRECTORY`. +*`GIT_ALTERNATE_OBJECT_DIRECTORIES`* -- это список разделённых двоеточием директорий (типа `/dir/one:/dir/two:…`), в которых Git будет пытаться найти объекты, которых нет в `GIT_OBJECT_DIRECTORY`. Это может быть полезным, если вы работаете над несколькими проектами с одинаковым содержимым, чтобы не дублировать файлы. @@ -101,14 +101,14 @@ Git использует библиотеку `curl` для работы с се ==== Сравнение файлов и слияния -*`GIT_DIFF_OPTS`* — слегка громкое название для этой переменной. +*`GIT_DIFF_OPTS`* -- слегка громкое название для этой переменной. Единственными допустимыми значениями являются `-u` и `--unified=`, задающие количество контекстных строк, показываемых командой `git diff`. *`GIT_EXTERNAL_DIFF`* замещает конфигурационный параметр `diff.external`. Если значение задано, Git вызовет указанную программу вместо `git diff`. *`GIT_DIFF_PATH_COUNTER`* и *`GIT_DIFF_PATH_TOTAL`* используются внутри программы, заданной через `GIT_EXTERNAL_DIFF` или `diff.external`. -Первая содержит порядковый номер сравниваемого на данный момент файла (начиная с 1), вторая — полное количество файлов, подлежащих сравнению. +Первая содержит порядковый номер сравниваемого на данный момент файла (начиная с 1), вторая -- полное количество файлов, подлежащих сравнению. *`GIT_MERGE_VERBOSITY`* задаёт уровень детализированности вывода при рекурсивном слиянии. Возможные значения перечислены ниже: @@ -125,11 +125,11 @@ Git использует библиотеку `curl` для работы с се ==== Отладка Хотите знать что _на самом деле_ делает Git? -Git ведёт достаточно подробный лог выполняемых действий и всё что вам нужно — включить его. +Git ведёт достаточно подробный лог выполняемых действий и всё что вам нужно -- включить его. Возможные значения приведённых ниже переменных следующие: -* "true", "1", или "2" – вывод осуществляется в стандартный поток ошибок (stderr). -* Абсолютный путь, начинающийся с `/` – вывод будет производиться в указанный файл. +* "true", "1", или "2" -- вывод осуществляется в стандартный поток ошибок (stderr). +* Абсолютный путь, начинающийся с `/` -- вывод будет производиться в указанный файл. *`GIT_TRACE`* задаёт журналирование действий, не подпадающий под какую-либо определённую категорию. Это включает в себя разворачивание алиасов и вызовы внешних программ. @@ -146,7 +146,7 @@ $ GIT_TRACE=true git lga ---- *`GIT_TRACE_PACK_ACCESS`* задаёт журналирование обращений к pack-файлам. -При этом первое выводимое значение – файл, к которому происходит обращение, а второе значение – смещение внутри этого файла. +При этом первое выводимое значение -- файл, к которому происходит обращение, а второе значение -- смещение внутри этого файла. [source,console] ---- @@ -214,7 +214,7 @@ nothing to commit, working directory clean ==== Разное -*`GIT_SSH`* – указанная программа (если значение задано) будет использоваться вместо `ssh` когда Git работает по SSH протоколу. +*`GIT_SSH`* -- указанная программа (если значение задано) будет использоваться вместо `ssh` когда Git работает по SSH протоколу. Порядок вызова этой программы будет таков: `$GIT_SSH [имя пользователя@]хост [-p <порт>] <команда>`. На самом деле, это не самый простой способ настроить поведение `ssh`: дополнительные параметры командной строки не поддерживаются, и вам, скорее всего, придётся писать скрипт-обёртку и указать `GIT_SSH` на него. Возможно, проще будет использовать `~/.ssh/config`. diff --git a/book/10-git-internals/sections/maintenance.asc b/book/10-git-internals/sections/maintenance.asc index 5bb8a2da..de1b7e62 100644 --- a/book/10-git-internals/sections/maintenance.asc +++ b/book/10-git-internals/sections/maintenance.asc @@ -1,6 +1,6 @@ === Уход за репозиторием и восстановление данных -Изредка вам потребуется делать "уборку" — сделать репозиторий более компактным, очистить импортированный репозиторий от лишних файлов или восстановить потерянные данные. +Изредка вам потребуется делать "уборку" -- сделать репозиторий более компактным, очистить импортированный репозиторий от лишних файлов или восстановить потерянные данные. Данный раздел охватывает некоторые из этих сценариев. [[r_git_gc]] @@ -8,7 +8,7 @@ Время от времени Git выполняет автоматическую сборку мусора. Чаще всего эта команда ничего не делает. -Однако, если у вас накопилось слишком много "рыхлых" объектов (не в pack-файлах), или, наоборот, отдельных pack-файлов, Git запускает полноценный сборщик — `git gc`. +Однако, если у вас накопилось слишком много "рыхлых" объектов (не в pack-файлах), или, наоборот, отдельных pack-файлов, Git запускает полноценный сборщик -- `git gc`. Здесь "gc" это сокращение от "garbage collect", что означает "сборка мусора". Эта команда выполняет несколько действий: собирает все рыхлые объекты и упаковывает их в pack-файлы; объединяет несколько упакованных файлов в один большой; удаляет недостижимые объекты, хранящиеся дольше нескольких месяцев. @@ -23,7 +23,7 @@ $ git gc --auto Нужно иметь примерно 7000 несжатых объектов или более 50 pack-файлов, чтобы запустился настоящий gc. Эти значения можно изменить с помощью параметров `gc.auto` и `gc.autopacklimit` соответственно. -Ещё одно действие, выполняемое gc — упаковка ссылок в единый файл. +Ещё одно действие, выполняемое gc -- упаковка ссылок в единый файл. Предположим, репозиторий содержит следующие ветки и теги: [source,console] @@ -54,7 +54,7 @@ cac0cab538b970a37ea1e769cbbde608743bc96d refs/tags/v1.0 Так что, если вы не можете найти ссылку в директории `refs`, скорее всего она упакована в файле `packed-refs`. Обратите внимание, последняя строка файла начинается с `^`. -Это означает, что метка на предыдущей строке является аннотированной меткой и данная строка — это коммит, на который аннотированная метка указывает. +Это означает, что метка на предыдущей строке является аннотированной меткой и данная строка -- это коммит, на который аннотированная метка указывает. [[r_data_recovery]] ==== Восстановление данных @@ -88,14 +88,14 @@ cac0cab538b970a37ea1e769cbbde608743bc96d second commit fdf4fc3344e67ab068f836878b6c4951e3b15f3d first commit ---- -Итак, теперь два последних коммита по-настоящему потеряны — они не достижимы ни из одной ветки. +Итак, теперь два последних коммита по-настоящему потеряны -- они не достижимы ни из одной ветки. Необходимо найти SHA-1 последнего коммита и создать ветку, указывающую на неё. Сложность в том, чтобы узнать этот самый SHA-1, ведь вряд ли вы его запомнили, да? -Зачастую самый быстрый способ — использование команды `git reflog`. +Зачастую самый быстрый способ -- использование команды `git reflog`. Дело в том, что во время вашей работы Git записывает все изменения HEAD. Каждый раз при переключении веток и коммитов изменений, добавляется запись в reflog. -reflog также обновляется командой `git update-ref` — это, кстати, хорошая причина использовать именно эту команду, а не вручную записывать SHA-1 в ref-файлы, как было показано в <>. +reflog также обновляется командой `git update-ref` -- это, кстати, хорошая причина использовать именно эту команду, а не вручную записывать SHA-1 в ref-файлы, как было показано в <>. Вы можете посмотреть где находился указатель HEAD в любой момент времени, запустив `git reflog`: [source,console] @@ -129,7 +129,7 @@ Date: Fri May 22 18:15:24 2009 -0700 modified repo.rb a bit ---- -Похоже, что последний коммит — это и есть тот, который мы потеряли; и его можно восстановить, создав ветку, указывающую на него. +Похоже, что последний коммит -- это и есть тот, который мы потеряли; и его можно восстановить, создав ветку, указывающую на него. Например, создадим ветку с именем `recover-branch`, указывающую на этот коммит (`ab1afef`): [source,console] @@ -156,7 +156,7 @@ $ rm -Rf .git/logs/ Данные reflog хранятся в директории `.git/logs/`, которую мы только что удалили, поэтому теперь у нас нет reflog. Как теперь восстановить коммиты? -Один из вариантов — использование утилиты `git fsck`, проверяющую внутреннюю базу данных на целостность. +Один из вариантов -- использование утилиты `git fsck`, проверяющую внутреннюю базу данных на целостность. Если выполнить её с ключом `--full`, будут показаны все объекты, недостижимые из других объектов: [source,console] @@ -176,7 +176,7 @@ dangling blob 7108f7ecb345ee9d0084193f147cdad4d2998293 [[r_removing_objects]] ==== Removing Objects -Git — замечательный инструмент с кучей классных фич, но некоторые из них способны и навредить. +Git -- замечательный инструмент с кучей классных фич, но некоторые из них способны и навредить. Например, команда `git clone` загружает проект вместе со всей историей, включая все версии всех файлов. Это нормально, если в репозитории хранится только исходный код, так как Git хорошо оптимизирован под такой тип данных и может эффективно сжимать их. Однако, если когда-либо в проект был добавлен большой файл, каждый, кто потом захочет клонировать проект, будет вынужден скачивать этот файл, даже если он был удалён в следующем же коммите. @@ -243,8 +243,8 @@ garbage: 0 size-garbage: 0 ---- -Строка `size-pack` — это размер pack-файлов в килобайтах, то есть всего занято почти 5 MБ. -Перед последним коммитом использовалось около 2 КБ — очевидно, удаление файла не удалило его из истории. +Строка `size-pack` -- это размер pack-файлов в килобайтах, то есть всего занято почти 5 MБ. +Перед последним коммитом использовалось около 2 КБ -- очевидно, удаление файла не удалило его из истории. Всякий раз, когда кто-либо захочет склонировать этот репозиторий, ему придётся скачивать все 5 МБ для того, чтобы заполучить этот крошечный проектик, просто потому, что однажды вы имели неосторожность добавить большой блоб! Давайте же исправим это! @@ -264,7 +264,7 @@ dadf7258d699da2c8d89b09ef6670edb7d5f91b4 commit 229 159 12 82c99a3e86bb1267b236a4b6eff7868d97489af1 blob 4975916 4976258 1438 ---- -Большой объект в самом внизу, его размер — 5 МБ. +Большой объект в самом внизу, его размер -- 5 МБ. Для того чтобы узнать, что это за файл, воспользуемся командой `rev-list`, которая уже упоминалась в главе <>. Если передать ей ключ `--objects`, она выдаст хеши всех коммитов, а также хеши объектов и соответствующие им имена файлов. Воспользуемся этим для определения имени выбранного объекта: @@ -300,7 +300,7 @@ Ref 'refs/heads/master' was rewritten Опция `--index-filter` похожа на `--tree-filter`, использовавшуюся в главе <>, за исключением того, что вместо передачи команды, модифицирующей файлы на диске, мы используем команду, изменяющую файлы в индексе. Вместо удаления файла чем-то вроде `rm file`, мы используем `git rm --cached`, так как нам надо удалить файл из индекса, а не с диска. -Причина, по которой мы делаем именно так — скорость: нет необходимости извлекать каждую ревизию на диск, чтобы применить фильтр, а это может очень сильно ускорить процесс. +Причина, по которой мы делаем именно так -- скорость: нет необходимости извлекать каждую ревизию на диск, чтобы применить фильтр, а это может очень сильно ускорить процесс. Если хотите, можете использовать и `tree-filter` для получения аналогичного результата. Опция `--ignore-unmatch` команды `git rm` отключает вывод сообщения об ошибке в случае отсутствия файлов, соответствующих шаблону. Ещё один момент: мы указали команде `filter-branch` переписывать историю, начиная с коммита `7b30847`, потому что мы знаем, что именно в этом изменении впервые появилась проблема. diff --git a/book/10-git-internals/sections/objects.asc b/book/10-git-internals/sections/objects.asc index e459813d..4f06304f 100644 --- a/book/10-git-internals/sections/objects.asc +++ b/book/10-git-internals/sections/objects.asc @@ -1,10 +1,10 @@ [[r_objects]] === Объекты Git -Git — контентно-адресуемая файловая система. +Git -- контентно-адресуемая файловая система. Здорово. Что это означает? -А означает это, по сути, что Git — простое хранилище ключ-значение. +А означает это, по сути, что Git -- простое хранилище ключ-значение. Можно добавить туда любые данные, в ответ будет выдан ключ по которому их можно извлечь обратно. Например, можно воспользоваться служебной командой `hash-object`, добавляющей данные в директорию `.git` и возвращающей ключ. Для начала создадим новый Git-репозиторий и убедимся, что директория `objects` пуста: @@ -32,8 +32,8 @@ d670460b4b4aece5915caf5c68d12f560a9fe3e4 Ключ `-w` указывает команде `hash-object`, что объект необходимо сохранить, иначе команда просто вернёт ключ. Флаг `--stdin` указывает, что данные необходимо считать из потока стандартного ввода, в противном случае `hash-object` ожидает путь к файлу в качестве аргумента. -Вывод команды — 40-символьная контрольная сумма. -Это хеш SHA-1 — контрольная сумма содержимого и заголовка, который будет рассмотрен позднее. +Вывод команды -- 40-символьная контрольная сумма. +Это хеш SHA-1 -- контрольная сумма содержимого и заголовка, который будет рассмотрен позднее. Теперь можно увидеть, в каком виде сохранены ваши данные: [source,console] @@ -43,8 +43,8 @@ $ find .git/objects -type f ---- Мы видим новый файл в директории `objects`. -Это и есть начальное внутреннее представление данных в Git — один файл на единицу хранения с именем, являющимся контрольной суммой содержимого и заголовка. -Первые два символа SHA-1 определяют поддиректорию файла внутри `objects`, остальные 38 — собственно, имя. +Это и есть начальное внутреннее представление данных в Git -- один файл на единицу хранения с именем, являющимся контрольной суммой содержимого и заголовка. +Первые два символа SHA-1 определяют поддиректорию файла внутри `objects`, остальные 38 -- собственно, имя. Получить обратно содержимое объекта можно командой `cat-file`. Она подобна швейцарскому ножу для проверки объектов в Git. @@ -106,7 +106,7 @@ version 2 ---- Однако запоминать хеш для каждой версии неудобно, к тому же теряется имя файла, сохраняется лишь содержимое. -Объекты такого типа называют блобами (англ. blob — binary large object). +Объекты такого типа называют блобами (англ. blob -- binary large object). Имея SHA-1 объекта, можно попросить Git показать нам его тип с помощью команды `cat-file -t`: [source,console] @@ -118,7 +118,7 @@ blob [[r_tree_objects]] ==== Деревья -Следующий тип объектов, который мы рассмотрим, — деревья — решают проблему хранения имён файлов, а также позволяют хранить группы файлов вместе. +Следующий тип объектов, который мы рассмотрим, -- деревья -- решают проблему хранения имён файлов, а также позволяют хранить группы файлов вместе. Git хранит данные сходным с файловыми системами UNIX способом, но в немного упрощённом виде. Содержимое хранится в деревьях и блобах, где дерево соответствует директории на файловой системе, а блоб более или менее соответствует inode или содержимому файла. Дерево может содержать одну или более записей, содержащих SHA-1 хеш, соответствующий блобу или поддереву, права доступа к файлу, тип и имя файла. @@ -133,7 +133,7 @@ $ git cat-file -p master^{tree} ---- Запись `master^{tree}` указывает на дерево, соответствующее последнему коммиту ветки `master`. -Обратите внимание, что поддиректория `lib` — не блоб, а указатель на другое дерево: +Обратите внимание, что поддиректория `lib` -- не блоб, а указатель на другое дерево: [source,console] ---- @@ -149,7 +149,7 @@ image::images/data-model-1.png[Упрощённая модель данных Gi Можно создать дерево самому. Обычно Git создаёт деревья на основе индекса, затем сохраняя их в БД. Поэтому для создания дерева необходимо проиндексировать какие-нибудь файлы. -Для создания индекса из одной записи — первой версии файла test.txt — воспользуемся низкоуровневой командой `update-index`. +Для создания индекса из одной записи -- первой версии файла test.txt -- воспользуемся низкоуровневой командой `update-index`. Данная команда может искусственно добавить более раннюю версию test.txt в новый индекс. Необходимо передать опции `--add`, т.к. файл ещё не существует в индексе (да и самого индекса ещё нет), и `--cacheinfo`, т.к. добавляемого файла нет в рабочей директории, но он есть в базе данных. Также необходимо передать права доступа, хеш и имя файла: @@ -160,12 +160,12 @@ $ git update-index --add --cacheinfo 100644 \ 83baae61804e65cc73a7201a7252750c76066a30 test.txt ---- -В данном случае права доступа — `100644`, означают обычный файл. -Другие возможные варианты: `100755` — исполняемый файл, `120000` — символическая ссылка. -Права доступа в Git сделаны по аналогии с режимами доступа в UNIX, но они гораздо менее гибки: данные три режима — единственные доступные для файлов (блобов) в Git (хотя существуют и другие режимы, используемые для директорий и дочерних модулей). +В данном случае права доступа -- `100644`, означают обычный файл. +Другие возможные варианты: `100755` -- исполняемый файл, `120000` -- символическая ссылка. +Права доступа в Git сделаны по аналогии с режимами доступа в UNIX, но они гораздо менее гибки: данные три режима -- единственные доступные для файлов (блобов) в Git (хотя существуют и другие режимы, используемые для директорий и дочерних модулей). Теперь можно воспользоваться командой `write-tree` для сохранения индекса в виде дерева. -Здесь опция `-w` не требуется — вызов `write-tree` автоматически создаёт дерево из индекса, если такого дерева ещё не существует: +Здесь опция `-w` не требуется -- вызов `write-tree` автоматически создаёт дерево из индекса, если такого дерева ещё не существует: [source,console] ---- @@ -231,7 +231,7 @@ image::images/data-model-2.png[Структура данных Git для пос У вас есть три дерева, соответствующих разным состояниям проекта, но предыдущая проблема с необходимостью запоминать все три значения SHA-1, чтобы иметь возможность восстановить какое-либо из этих состояний, ещё не решена. К тому же у нас нет никакой информации о том, кто, когда и почему сохранил их. -Такие данные — основная информация, хранимая в коммите. +Такие данные -- основная информация, хранимая в коммите. Для создания коммита необходимо вызвать команду `commit-tree` и задать SHA-1 нужного дерева и, если необходимо, родительские коммиты. Для начала создадим коммит для самого первого дерева: @@ -303,8 +303,8 @@ Date: Fri May 22 18:09:34 2009 -0700 Здорово, правда? Мы только что выполнили несколько низкоуровневых операций и получили "настоящий" Git-репозиторий с историей без единой высокоуровневой команды! -Именно так и работает Git, когда выполняются команды `git add` и `git commit` — сохраняет блобы для изменённых файлов, обновляет индекс, записывает его в виде дерева, и, наконец, фиксирует изменения в коммите, ссылающемся на это дерево и предшествующие коммиты. -Эти три основных вида объектов Git — блоб, дерево и коммит — сохраняются в виде отдельных файлов в директории `.git/objects`. +Именно так и работает Git, когда выполняются команды `git add` и `git commit` -- сохраняет блобы для изменённых файлов, обновляет индекс, записывает его в виде дерева, и, наконец, фиксирует изменения в коммите, ссылающемся на это дерево и предшествующие коммиты. +Эти три основных вида объектов Git -- блоб, дерево и коммит -- сохраняются в виде отдельных файлов в директории `.git/objects`. Вот все объекты, которые сейчас находятся в директории, с примером с комментариями чему они соответствуют: [source,console] @@ -331,7 +331,7 @@ image::images/data-model-3.png[Все объекты в директории Git Ранее мы упоминали, что заголовок сохраняется вместе с содержимым. Давайте посмотрим, как Git сохраняет объекты на диске. -Мы рассмотрим сохранение блоба — в данном случае это будет строка "как дела, Док?" — на языке Ruby. +Мы рассмотрим сохранение блоба -- в данном случае это будет строка "как дела, Док?" -- на языке Ruby. Для запуска интерактивного интерпретатора воспользуйтесь командой `irb`: @@ -376,7 +376,7 @@ Git сжимает новые данные при помощи zlib, в Ruby э ---- После этого запишем сжатую zlib'ом строку в объект на диск. -Определим путь к файлу, который будет записан (первые два символа хеша используются в качестве названия директории, оставшиеся 38 — в качестве имени файла в ней). +Определим путь к файлу, который будет записан (первые два символа хеша используются в качестве названия директории, оставшиеся 38 -- в качестве имени файла в ней). В Ruby для безопасного создания нескольких вложенных директорий можно использовать функцию `FileUtils.mkdir_p()`. Далее, откроем файл вызовом `File.open()` и запишем сжатые данные вызовом `write()` для полученного файлового дескриптора: diff --git a/book/10-git-internals/sections/packfiles.asc b/book/10-git-internals/sections/packfiles.asc index 26c5265a..50bc2e11 100644 --- a/book/10-git-internals/sections/packfiles.asc +++ b/book/10-git-internals/sections/packfiles.asc @@ -21,7 +21,7 @@ $ find .git/objects -type f Git использует zlib для сжатия содержимого этих файлов; к тому же у нас не так уж и много данных, поэтому все эти файлы вместе занимают всего 925 байт. Для того, чтобы продемонстрировать одну интересную особенность Git, добавим файл побольше. -Добавим файл `repo.rb` из библиотеки Grit — он занимает примерно 22 Кб: +Добавим файл `repo.rb` из библиотеки Grit -- он занимает примерно 22 Кб: [source,console] ---- @@ -87,7 +87,7 @@ $ git cat-file -s b042a60ef7dff760008df33cee372b945b6e884e Оказывается, Git так и делает. Первоначальный формат для сохранения объектов в Git называется "рыхлым" форматом (loose format). -Однако, время от времени Git упаковывает несколько таких объектов в один pack-файл (pack в пер. с англ. — упаковывать, уплотнять) для сохранения места на диске и повышения эффективности. +Однако, время от времени Git упаковывает несколько таких объектов в один pack-файл (pack в пер. с англ. -- упаковывать, уплотнять) для сохранения места на диске и повышения эффективности. Это происходит, когда "рыхлых" объектов становится слишком много, а также при вызове `git gc` вручную, и при отправке изменений на удалённый сервер. Чтобы посмотреть, как происходит упаковка, можно выполнить команду `git gc`: @@ -113,13 +113,13 @@ $ find .git/objects -type f .git/objects/pack/pack-978e03944f5c581011e6998cd0e9e30000905586.pack ---- -Оставшиеся объекты — это блобы, на которые не указывает ни один коммит. +Оставшиеся объекты -- это блобы, на которые не указывает ни один коммит. В нашем случае это созданные ранее объекты: содержащий строку "what is up, doc?", и "test content". В силу того, что ни в одном коммите данные файлы не присутствуют, они считаются "висячими" и не упаковываются. -Остальные файлы — это pack-файл и его индекс. -Pack-файл — это файл, который теперь содержит все удалённые объекты. -Индекс — это файл, в котором записаны смещения прежних объектов в pack-файле для быстрого поиска. +Остальные файлы -- это pack-файл и его индекс. +Pack-файл -- это файл, который теперь содержит все удалённые объекты. +Индекс -- это файл, в котором записаны смещения прежних объектов в pack-файле для быстрого поиска. Упаковка данных положительно повлияла на общий размер файлов: если до вызова gc они занимали примерно 22 Кб, то pack-файл занимает всего 7 Кбайт. Мы только что освободили ⅔ занимаемого дискового пространства! @@ -158,9 +158,9 @@ chain length = 1: 3 objects ---- Здесь блоб `033b4`, который, как мы помним, был первой версией файла `repo.rb`, ссылается на блоб `b042a`, который хранит вторую его версию. -Третья колонка в выводе — это размер содержимого объекта. -Как видите, `b042a` занимает 22 Кб, а `033b4` — всего 9 байт. -Что интересно, вторая версия файла сохраняется "как есть", а первая — в виде дельты: ведь скорее всего вам понадобится быстрый доступ к самым последним версиям файла. +Третья колонка в выводе -- это размер содержимого объекта. +Как видите, `b042a` занимает 22 Кб, а `033b4` -- всего 9 байт. +Что интересно, вторая версия файла сохраняется "как есть", а первая -- в виде дельты: ведь скорее всего вам понадобится быстрый доступ к самым последним версиям файла. Также здорово, что переупаковку можно выполнять в любое время. Время от времени Git будет выполнять её автоматически, чтобы сэкономить место на диске, но всегда можно инициировать упаковку, выполнив `git gc`. diff --git a/book/10-git-internals/sections/plumbing-porcelain.asc b/book/10-git-internals/sections/plumbing-porcelain.asc index 636a25c8..9f33f2f6 100644 --- a/book/10-git-internals/sections/plumbing-porcelain.asc +++ b/book/10-git-internals/sections/plumbing-porcelain.asc @@ -3,7 +3,7 @@ В этой книге было описано, как пользоваться Git, применяя примерно три десятка команд, например, `checkout`, `branch`, `remote` и т.п. Но так как сначала Git был скорее инструментарием для создания СКВ, чем СКВ, удобной для пользователей, в нём полно команд, выполняющих низкоуровневые операции, которые спроектированы так, чтобы их можно было использовать в цепочку в стиле UNIX, а также использовать в сценариях. -Эти команды, как правило, называют служебными ("plumbing" — трубопровод), а ориентированные на пользователя называют пользовательскими ("porcelain" — фарфор). +Эти команды, как правило, называют служебными ("plumbing" -- трубопровод), а ориентированные на пользователя называют пользовательскими ("porcelain" -- фарфор). Первые девять глав книги были посвящены практически лишь пользовательским командам. В данной главе же рассматриваются именно низкоуровневые служебные команды, дающие контроль над внутренними процессами Git и показывающие, как он работает и почему он работает так, а не иначе. @@ -26,12 +26,12 @@ objects/ refs/ ---- -Там могут быть и другие файлы, но выше приведён листинг свежесозданного репозитория — это то, что вы увидите непосредственно после `git init`. +Там могут быть и другие файлы, но выше приведён листинг свежесозданного репозитория -- это то, что вы увидите непосредственно после `git init`. Файл `description` используется только программой GitWeb, не обращайте на него внимание. -Файл `config` содержит специфичные для этого репозитория конфигурационные параметры, а в директории `info` расположен файл с глобальными настройкам игнорирования файлов (((excludes))) — он позволяет исключить файлы, которые вы не хотите помещать в .gitignore. +Файл `config` содержит специфичные для этого репозитория конфигурационные параметры, а в директории `info` расположен файл с глобальными настройкам игнорирования файлов (((excludes))) -- он позволяет исключить файлы, которые вы не хотите помещать в .gitignore. В директории `hooks` располагаются клиентские и серверные триггеры, подробно рассмотренные в главе <>. Итак, осталось четыре важных элемента: файлы `HEAD` и `index` (ещё не созданный) и директории `objects` и `refs`. Это ключевые элементы Git. -В директории `objects` находится, собственно, база данных объектов Git; в `refs` — ссылки на объекты коммитов в этой базе (ветки); файл `HEAD` указывает на текущую ветку, a в файле `index` хранится содержимое индекса. +В директории `objects` находится, собственно, база данных объектов Git; в `refs` -- ссылки на объекты коммитов в этой базе (ветки); файл `HEAD` указывает на текущую ветку, a в файле `index` хранится содержимое индекса. Сейчас мы детально разберёмся с этими элементами, чтобы понять как работает Git. diff --git a/book/10-git-internals/sections/refs.asc b/book/10-git-internals/sections/refs.asc index ef00ac4a..5aaaf5df 100644 --- a/book/10-git-internals/sections/refs.asc +++ b/book/10-git-internals/sections/refs.asc @@ -34,14 +34,14 @@ fdf4fc3344e67ab068f836878b6c4951e3b15f3d first commit ---- Тем не менее, редактировать файлы ссылок вручную не рекомендуется. -Git предоставляет более безопасную и удобную команду — `update-ref` — для изменения ссылок: +Git предоставляет более безопасную и удобную команду -- `update-ref` -- для изменения ссылок: [source,console] ---- $ git update-ref refs/heads/master 1a410efbd13591db07496601ebc7a059dd55cfe9 ---- -Вот что такое, по сути, ветка в Git — простой указатель (ссылка) на последнюю версию цепочки коммитов. +Вот что такое, по сути, ветка в Git -- простой указатель (ссылка) на последнюю версию цепочки коммитов. Для создания ветки, соответствующей предыдущему коммиту, можно выполнить следующее: [source,console] @@ -71,7 +71,7 @@ image::images/data-model-4.png[Объекты в директории .git, а Как же Git получает хеш последнего коммита при выполнении `git branch (имя ветки)`? Ответ кроется в файле HEAD. -Файл HEAD — это символическая ссылка (не в терминах файловой системы) на текущую ветку. +Файл HEAD -- это символическая ссылка (не в терминах файловой системы) на текущую ветку. Символическая ссылка отличается от обычной тем, что она содержит не сам хеш SHA-1, а указатель на другую ссылку. Если вы заглянете внутрь HEAD, то увидите следующее: @@ -133,7 +133,7 @@ $ git update-ref refs/tags/v1.0 cac0cab538b970a37ea1e769cbbde608743bc96d ---- Вот и всё! -Легковесная метка — это ветка, которая никогда не перемещается. +Легковесная метка -- это ветка, которая никогда не перемещается. Аннотированная метка имеет более сложную структуру. При создании аннотированной метки Git создаёт специальный объект, на который будет указывать ссылка, а не просто указатель на коммит. Мы можем увидеть это, создав аннотированную метку (`-a` задаёт аннотированные метки): @@ -178,7 +178,7 @@ $ git cat-file blob junio-gpg-pub ==== Ссылки на удалённые ветки -Третий тип ссылок, который мы рассмотрим — ссылки на удалённые ветки. +Третий тип ссылок, который мы рассмотрим -- ссылки на удалённые ветки. Если вы добавили удалённый репозиторий и отправили в него какие-нибудь изменения, Git сохранит последнее отправленное значение SHA-1 в директории `refs/remotes` для каждой отправленной ветки. Например, можно добавить удалённый репозиторий `origin` и отправить туда ветку `master`: diff --git a/book/10-git-internals/sections/refspec.asc b/book/10-git-internals/sections/refspec.asc index fc3befa1..aed6ad5a 100644 --- a/book/10-git-internals/sections/refspec.asc +++ b/book/10-git-internals/sections/refspec.asc @@ -18,7 +18,7 @@ $ git remote add origin https://github.com/schacon/simplegit-progit fetch = +refs/heads/*:refs/remotes/origin/* ---- -Формат спецификации следующий: опциональный `+`, далее пара `:`, где `` — шаблон ссылок в удалённом репозитории, а `` — соответствующий шаблон локальных ссылок. +Формат спецификации следующий: опциональный `+`, далее пара `:`, где `` -- шаблон ссылок в удалённом репозитории, а `` -- соответствующий шаблон локальных ссылок. Символ `+` сообщает Git, что обновление необходимо выполнять даже в том случае, если оно не является перемоткой (fast-forward). По умолчанию, после выполнения `git remote add`, Git забирает все ссылки из `refs/heads/` на сервере, и записывает их в `refs/remotes/origin/` локально. @@ -93,7 +93,7 @@ fetch = +refs/heads/qa*:refs/remotes/origin/qa* fetch = +refs/heads/qa/*:refs/remotes/origin/qa/* ---- -Если у вас сложный рабочий процесс при котором все команды — разработчики, QA и специалисты по внедрению — ведут работы в одном репозитории, вы можете разграничить их с помощью пространств имён. +Если у вас сложный рабочий процесс при котором все команды -- разработчики, QA и специалисты по внедрению -- ведут работы в одном репозитории, вы можете разграничить их с помощью пространств имён. [[r_pushing_refspecs]] ==== Спецификации ссылок для отправки данных на сервер diff --git a/book/10-git-internals/sections/transfer-protocols.asc b/book/10-git-internals/sections/transfer-protocols.asc index d2772b40..9c7ed78f 100644 --- a/book/10-git-internals/sections/transfer-protocols.asc +++ b/book/10-git-internals/sections/transfer-protocols.asc @@ -65,7 +65,7 @@ committer Scott Chacon 1240030591 -0700 changed the version number ---- -Далее, необходимо загрузить ещё два объекта: дерево `cfda3b` — содержимое только что загруженного коммита, и `085bb3` — родительский коммит: +Далее, необходимо загрузить ещё два объекта: дерево `cfda3b` -- содержимое только что загруженного коммита, и `085bb3` -- родительский коммит: [source] ---- @@ -92,7 +92,7 @@ changed the version number (empty file) ---- -Если бы этот запрос вернул непустой список альтернатив, Git проверил бы указанные репозитории на наличие файла в "рыхлом" формате – довольно полезная фишка для проектов-форков, позволяющая устранить дублирование. +Если бы этот запрос вернул непустой список альтернатив, Git проверил бы указанные репозитории на наличие файла в "рыхлом" формате -- довольно полезная фишка для проектов-форков, позволяющая устранить дублирование. Так как в данном случае альтернатив нет, объект, должно быть, упакован в pack-файле. Чтобы посмотреть доступные на сервере pack-файлы, нужно скачать файл `objects/info/packs`, содержащий их список. Этот файл тоже обновляется командой `update-server-info`: @@ -155,7 +155,7 @@ $ ssh -x git@server "git-receive-pack 'simplegit-progit.git'" 0000 ---- -Команда `git-receive-pack` тут же посылает в ответ по одной строке на каждую из имеющихся в наличии ссылок — в данном случае только ветку `master` и её SHA-1. +Команда `git-receive-pack` тут же посылает в ответ по одной строке на каждую из имеющихся в наличии ссылок -- в данном случае только ветку `master` и её SHA-1. Первая строка также содержит список возможностей сервера (здесь это `report-status`, `delete-refs` и парочка других, включая версию используемого процесса). Каждая строка начинается с 4-байтового шестнадцатеричного значения, содержащего длину оставшейся части строки. @@ -178,11 +178,11 @@ $ ssh -x git@server "git-receive-pack 'simplegit-progit.git'" Git посылает по строке, содержащей собственную длину, старый хэш, новый хэш и имя ссылки; для каждой обновляемой ссылки. В первой строке также посылаются возможности клиента. -Хэш, состоящий из нулей, говорит о том, что раньше такой ссылки не было – вы ведь добавляете новую ветку `experiment`. +Хэш, состоящий из нулей, говорит о том, что раньше такой ссылки не было -- вы ведь добавляете новую ветку `experiment`. При удалении ветки всё было бы наоборот: нули были бы справа. Затем клиент посылает pack-файл c объектами, которых нет на сервере. -В конце сервер передаёт статус операции – успех или ошибка: +В конце сервер передаёт статус операции -- успех или ошибка: [source] ---- @@ -260,7 +260,7 @@ $ ssh -x git@server "git-upload-pack 'simplegit-progit.git'" ====== HTTP(S) "Рукопожатие" для процесса получения недостающих данных занимает два HTTP запроса. -Первый — это `GET` запрос на тот же URL, что и в случае глупого протокола: +Первый -- это `GET` запрос на тот же URL, что и в случае глупого протокола: [source] ---- @@ -290,5 +290,5 @@ $ ssh -x git@server "git-upload-pack 'simplegit-progit.git'" ==== Заключение В этом разделе мы вкратце рассмотрели протоколы передачи данных. -Протоколы обмена данных в Git включают в себя множество фич — типа `multi_ack` или `side-band` — рассмотрение которых выходит за пределы этой книги. -Мы описали формат сообщений между клиентом и сервером не вдаваясь в детали, если хотите покопаться в этой теме глубже — обратитесь к исходному коду Git. +Протоколы обмена данных в Git включают в себя множество фич -- типа `multi_ack` или `side-band` -- рассмотрение которых выходит за пределы этой книги. +Мы описали формат сообщений между клиентом и сервером не вдаваясь в детали, если хотите покопаться в этой теме глубже -- обратитесь к исходному коду Git. diff --git a/book/A-git-in-other-environments/sections/bash.asc b/book/A-git-in-other-environments/sections/bash.asc index b428e285..854f96a9 100644 --- a/book/A-git-in-other-environments/sections/bash.asc +++ b/book/A-git-in-other-environments/sections/bash.asc @@ -5,7 +5,7 @@ Вообще-то, Git поставляется с плагинами для нескольких шеллов, но они выключены из коробки. Для начала, скачайте файл `contrib/completion/git-completion.bash` из репозитория с исходным кодом Git. -Поместите его в укромное место — например, в вашу домашнюю директорию — и добавьте следующие строки в `.bashrc`: +Поместите его в укромное место -- например, в вашу домашнюю директорию -- и добавьте следующие строки в `.bashrc`: [source,console] ----- @@ -33,7 +33,7 @@ export GIT_PS1_SHOWDIRTYSTATE=1 export PS1='\w$(__git_ps1 " (%s)")\$ ' ----- -Часть `\w` означает текущую рабочую директорию, `\$` — индикатор суперпользователя (обычно `$` или `#`), а `__git_ps1 " (%s)"` вызывает функцию, объявленную в `git-prompt.sh`, с аргументом ` (%s)` — строкой форматирования. +Часть `\w` означает текущую рабочую директорию, `\$` -- индикатор суперпользователя (обычно `$` или `#`), а `__git_ps1 " (%s)"` вызывает функцию, объявленную в `git-prompt.sh`, с аргументом ` (%s)` -- строкой форматирования. Теперь ваша строка приветствия будет похожа на эту, когда вы зайдёте в директорию с Git репозиторием: .Кастомизированная строка приветствия `bash`. diff --git a/book/A-git-in-other-environments/sections/guis.asc b/book/A-git-in-other-environments/sections/guis.asc index edb0960d..3085f75e 100644 --- a/book/A-git-in-other-environments/sections/guis.asc +++ b/book/A-git-in-other-environments/sections/guis.asc @@ -1,21 +1,21 @@ === Графические интерфейсы (((GUIs)))(((Graphical tools))) -Родная среда обитания Git — это терминал. +Родная среда обитания Git -- это терминал. Новые фичи вначале доступны только там, и лишь терминал поможет вам полностью контролировать всю мощь Git. -Но текстовый интерфейс — не лучший выбор для всех задач; иногда графическое представление более предпочтительно, а некоторые пользователи чувствуют себя комфортней, орудуя мышкой. +Но текстовый интерфейс -- не лучший выбор для всех задач; иногда графическое представление более предпочтительно, а некоторые пользователи чувствуют себя комфортней, орудуя мышкой. Также стоит понимать, что разные интерфейсы служат разным целям. Некоторые Git клиенты ограничиваются лишь той функциональностью, которую их автор считает наиболее востребованным или эффективным. Учитывая это, ни один из представленных ниже инструментов не может быть "лучше" остальных: они просто заточены под разные задачи. -Также стоит помнить, что всё, что можно сделать с помощью графического интерфейса, может быть выполнено и из консоли. Командная строка — по прежнему место где у вас больше всего мощи и контроля над репозиторием. +Также стоит помнить, что всё, что можно сделать с помощью графического интерфейса, может быть выполнено и из консоли. Командная строка -- по прежнему место где у вас больше всего мощи и контроля над репозиторием. ==== `gitk` и `git-gui` (((git commands, gitk)))(((git commands, gui)))(((gitk))) Установив Git, вы также получаете два графических инструмента: `gitk` и `git-gui`. -`gitk` — это графический просмотрщик истории. +`gitk` -- это графический просмотрщик истории. Что-то типа улучшенных `git log` и `git grep`. Это тот инструмент, который вы будете использовать для поиска событий и визуализации истории. @@ -28,18 +28,18 @@ $ gitk [git log options] ---- Gitk принимает кучу различных опций, большинство из которых передаются в `git log` (который, в свою очередь, используется в Gitk). -Возможно, наиболее используемая опция — `--all`, которая указывает Gitk выводить коммиты, доступные из _любой_ ссылки, а не только HEAD. +Возможно, наиболее используемая опция -- `--all`, которая указывает Gitk выводить коммиты, доступные из _любой_ ссылки, а не только HEAD. Интерфейс Gitk выглядит так: .`gitk`- инструмент для просмотра истории. image::images/gitk.png[`gitk`- инструмент для просмотра истории.] Интерфейс на картинке похож на вывод `git log --graph`; каждая точка соответствует коммиту, линии отражают родство коммитов, а ссылки изображены цветными прямоугольниками. -Жёлтая точка обозначает HEAD, а красная — изменения, которые попадут в следующий коммит. -Внизу экрана расположены элементы интерфейса для просмотра выделенного коммита: слева показаны изменения и комментарий, а справа — общая информация по изменённым файлам. +Жёлтая точка обозначает HEAD, а красная -- изменения, которые попадут в следующий коммит. +Внизу экрана расположены элементы интерфейса для просмотра выделенного коммита: слева показаны изменения и комментарий, а справа -- общая информация по изменённым файлам. В центре экрана расположены элементы для поиска по истории. -`git-gui`, в отличие от `gitk` — это инструмент редактирования отдельных коммитов. +`git-gui`, в отличие от `gitk` -- это инструмент редактирования отдельных коммитов. Его тоже очень просто вызвать из консоли: [source,console] @@ -49,10 +49,10 @@ $ git gui И его интерфейс выглядит так: -.`git gui` — инструмент редактирования коммитов. -image::images/git-gui.png[`git gui` — инструмент редактирования коммитов.] +.`git gui` -- инструмент редактирования коммитов. +image::images/git-gui.png[`git gui` -- инструмент редактирования коммитов.] -Слева находится область редактирования Git индекса: изменения в рабочей директории наверху, добавленные в индекс изменения — снизу. +Слева находится область редактирования Git индекса: изменения в рабочей директории наверху, добавленные в индекс изменения -- снизу. Вы можете перемещать файлы целиком между двумя состояниями, кликая на иконки, или же вы можете просмотреть изменения в конкретном файле, выбрав его имя. Справа вверху расположена область просмотра изменений выделенного файла. @@ -62,15 +62,15 @@ image::images/git-gui.png[`git gui` — инструмент редактиро Также можно изменить предыдущий коммит, выбрав радиокнопку "Amend". Это действие также обновить область добавленных в индекс изменений содержимое предыдущего коммита. После этого вы можете как обычно добавлять или удалять файлы, а также изменить сообщение коммита. По нажатию кнопки "Commit" новый коммит затрёт предыдущий. -`gitk` и `git-gui` — это примеры инструментов, ориентированных на задачи. +`gitk` и `git-gui` -- это примеры инструментов, ориентированных на задачи. Каждый из них заточен под определённую задачу (просмотр истории или создание коммитов, соответственно) и не поддерживает фичи Git, ненужные для этой задачи. ==== GitHub для Mac и Windows (((GitHub for Mac)))(((GitHub for Windows))) -Компания GitHub выпустила два инструмента, ориентированных на рабочий процесс, а не на конкретные задачи: один для Windows, второй — для Mac. -Эти клиенты — хороший пример процесс-ориентированного ПО: вместо предоставления доступа ко всей функциональности Git, они концентрируются на небольшом наборе фич, работающих вместе для достижения цели. +Компания GitHub выпустила два инструмента, ориентированных на рабочий процесс, а не на конкретные задачи: один для Windows, второй -- для Mac. +Эти клиенты -- хороший пример процесс-ориентированного ПО: вместо предоставления доступа ко всей функциональности Git, они концентрируются на небольшом наборе фич, работающих вместе для достижения цели. Выглядят они примерно так: .GitHub для Mac. @@ -85,7 +85,7 @@ image::images/github_win.png[GitHub для Windows.] * Слева расположен список отслеживаемых репозиториев; можно добавить репозиторий (склонировав его, либо указав путь к существующей копии) нажатием кнопки "+" над списком. * В центре экрана расположена область редактирования коммита: тут можно ввести сообщение коммита и выбрать файлы для включение в него. (На Windows, история коммитов расположена под этой областью, на Mac это отдельная вкладка.) -* Справа — просмотр изменений: что изменилось в рабочей директории, какие изменения войдут в коммит. +* Справа -- просмотр изменений: что изменилось в рабочей директории, какие изменения войдут в коммит. * И стоит обратить внимание на кнопку "Sync" справа вверху, которая используется для синхронизации по сети. [NOTE] @@ -96,14 +96,14 @@ image::images/github_win.png[GitHub для Windows.] ===== Установка -GitHub для Windows можно скачать на https://windows.github.com[], а для Mac — на https://mac.github.com[]. +GitHub для Windows можно скачать на https://windows.github.com[], а для Mac -- на https://mac.github.com[]. При первом запуске обе программы проведут первоначальную настройку Git, например, сконфигурируют ваше имя и email, а также установят разумные значения по умолчанию для распространённых опций типа CRLF-поведение и хранилище паролей. -Оба инструмента поддерживают автообновление в фоне — это означает, что у вас всегда будет последняя версия. -Это также относится к поставляемому в комплекте с ними Git — вам никогда не придётся обновлять его вручную. +Оба инструмента поддерживают автообновление в фоне -- это означает, что у вас всегда будет последняя версия. +Это также относится к поставляемому в комплекте с ними Git -- вам никогда не придётся обновлять его вручную. На Windows вы также получаете ярлык для запуска PowerShell с Posh-git, который мы рассмотрим далее в этой главе. -Следующий шаг — скормить программе парочку репозиториев для работы. +Следующий шаг -- скормить программе парочку репозиториев для работы. Клиент для GitHub показывает список репозиториев, доступных вам на GitHub, и вы можете склонировать любой в один клик. Если же у вас уже есть склонированный репозиторий, просто перетяните его из окна Finder (или Windows Explorer) в окно клиента GitHub, и он будет включён в список репозиториев слева. diff --git a/book/B-embedding-git/sections/command-line.asc b/book/B-embedding-git/sections/command-line.asc index 49a0786e..7cf6cd24 100644 --- a/book/B-embedding-git/sections/command-line.asc +++ b/book/B-embedding-git/sections/command-line.asc @@ -1,14 +1,14 @@ === Git из командной строки -Первый вариант встраивания Git — порождение шелла и использование Git из него для выполнения задач. +Первый вариант встраивания Git -- порождение шелла и использование Git из него для выполнения задач. Плюсом данного подхода является каноничность и поддержка всех возможностей Git. Это наиболее простой подход, так как большинство сред исполнения предоставляют достаточно простые средства вызова внешних процессов с параметрами командной строки. Тем не менее, у этого подхода есть некоторые недостатки. -Первый — результат выполнения команд представлен в виде простого текста. +Первый -- результат выполнения команд представлен в виде простого текста. Это означает, что вам придётся анализировать вывод команд (который может поменяться со временем) чтобы получить результат выполнения, что неэффективно и подвержено ошибкам. -Следующий недостаток — отсутствие восстановления после ошибок. +Следующий недостаток -- отсутствие восстановления после ошибок. Если репозиторий был повреждён, или если пользователь указал неверный параметр конфигурации, Git просто откажется выполнять большинство операций. Ещё одним недостатком является необходимость управления порождённым процессом. diff --git a/book/B-embedding-git/sections/dulwich.asc b/book/B-embedding-git/sections/dulwich.asc index 11d11564..98f0dd0a 100644 --- a/book/B-embedding-git/sections/dulwich.asc +++ b/book/B-embedding-git/sections/dulwich.asc @@ -1,7 +1,7 @@ === Dulwich (((Dulwich)))(((Python))) -Так же существует реализация Git на чистом Python - Dulwich. +Так же существует реализация Git на чистом Python -- Dulwich. Проект размещается здесь https://www.dulwich.io/ Целью проекта является предоставление интерфейса к Git репозиториям (как локальным, так и удаленным) используя чистый Python, а не вызывая Git. В нём используются дополнительные расширения на С, которые существенно увеличивают производительность. diff --git a/book/B-embedding-git/sections/go-git.asc b/book/B-embedding-git/sections/go-git.asc index f91013dd..c0d52ecc 100644 --- a/book/B-embedding-git/sections/go-git.asc +++ b/book/B-embedding-git/sections/go-git.asc @@ -41,8 +41,8 @@ for _, c := range history { ==== Расширенная функциональность -go-git обладает некоторыми дополнительными функциями, одна из которых - это подключаемое хранилище, что близко по смыслу с бэкендами Libgit2. -Реализация по умолчанию - хранилище в памяти, которое очень быстро работает. +go-git обладает некоторыми дополнительными функциями, одна из которых -- это подключаемое хранилище, что близко по смыслу с бэкендами Libgit2. +Реализация по умолчанию -- хранилище в памяти, которое очень быстро работает. [source, go] ----- @@ -54,10 +54,10 @@ r, err := git.Clone(memory.NewStorage(), nil, &git.CloneOptions{ Подключаемое хранилище предоставляет много интересных возможностей. Например, https://github.com/src-d/go-git/tree/master/_examples/storage[] позволяет вам сохранять ссылки, объекты и конфигурацию в базе данных Aerospike. -Другая особенность - гибкая абстракция файловой системы. +Другая особенность -- гибкая абстракция файловой системы. Используя https://godoc.org/github.com/src-d/go-billy#Filesystem[] легко сохранять все файлы по-разному, т.е. упаковав их все в один архив хранить на диске или держать в памяти. -Ещё одна продвинутая возможность - это тонко настраиваемый HTTP клиент, как например вот этот https://github.com/src-d/go-git/blob/master/_examples/custom_http/main.go[]. +Ещё одна продвинутая возможность -- это тонко настраиваемый HTTP клиент, как например вот этот https://github.com/src-d/go-git/blob/master/_examples/custom_http/main.go[]. [source, go] ----- diff --git a/book/B-embedding-git/sections/jgit.asc b/book/B-embedding-git/sections/jgit.asc index a35b64e7..c4bf7a30 100644 --- a/book/B-embedding-git/sections/jgit.asc +++ b/book/B-embedding-git/sections/jgit.asc @@ -8,7 +8,7 @@ ==== Приступая к работе Существует несколько способов добавить JGit в проект и начать писать код с использованием предоставляемого API. -Возможно, самый простой путь — использование Maven. Подключение библиотеки происходит путём добавления следующих строк в секцию `` в вашем pom.xml: +Возможно, самый простой путь -- использование Maven. Подключение библиотеки происходит путём добавления следующих строк в секцию `` в вашем pom.xml: [source,xml] ---- @@ -36,7 +36,7 @@ java -cp .:org.eclipse.jgit-3.5.0.201409260305-r.jar App У JGit есть два уровня API: служебный ("plumbing" API, "трубопровод") и пользовательский ("porcelain" API, "фарфор"). Эта терминология заимствована из самого Git и JGit разделён на две части: "фарфоровый" API предоставляет удобные методы для распространённых задач прикладного уровня (тех, для решения которых вы бы использовали обычные Git-команды) и "сантехнический" API для прямого взаимодействия с низкоуровневыми объектами репозитория. -Начальная точка большинства сценариев использования JGit — класс `Repository` и первое, что необходимо сделать — это создать объект данного класса. +Начальная точка большинства сценариев использования JGit -- класс `Repository` и первое, что необходимо сделать -- это создать объект данного класса. Для репозиториев основанных на файловой системе (да, JGit позволяет использовать другие модели хранения) эта задача решается с помощью класса `FileRepositoryBuilder`: [source,java] @@ -110,12 +110,12 @@ ObjectId представляют SHA-1 хэш объекта, который, Созданный объект Config будет использовать открытый ранее репозиторий для чтения локальной конфигурации, также он автоматически находит файлы глобальной и системной конфигурации и использует их для чтения значений. Это лишь малая часть служебного API JGit; в вашем распоряжении окажется гораздо больше классов и методов. -Мы не показали как JGit обрабатывает ошибки. JGit использует механизм исключений Java; иногда он бросает стандартные исключения (типа `IOException`), иногда — специфичные для JGit (например `NoRemoteRepositoryException`, `CorruptObjectException` и `NoMergeBaseException`). +Мы не показали как JGit обрабатывает ошибки. JGit использует механизм исключений Java; иногда он бросает стандартные исключения (типа `IOException`), иногда -- специфичные для JGit (например `NoRemoteRepositoryException`, `CorruptObjectException` и `NoMergeBaseException`). ==== Пользовательский API Служебные API достаточно всеобъемлющи, но сложны в использовании для простых задач вроде добавления файла в индекс или создания нового коммита. -У JGit есть API более высокого уровня, входная точка в который — это класс `Git`: +У JGit есть API более высокого уровня, входная точка в который -- это класс `Git`: [source,java] ---- @@ -125,7 +125,7 @@ Git git = new Git(repo); ---- В классе Git можно найти отличный набор высокоуровневых "текучих" методов (builder-style / fluent interface). -Давайте взглянем на пример — результат выполнения этого кода смахивает на `git ls-remote`: +Давайте взглянем на пример -- результат выполнения этого кода смахивает на `git ls-remote`: [source,java] ---- @@ -141,7 +141,7 @@ for (Ref ref : remoteRefs) { } ---- -Тут показан частый случай использования класса Git: методы возвращают тот же объект, на котором вызваны, что позволяет чередовать их друг за другом, устанавливая параметры. Финальный аккорд — непосредственное выполнение команды с помощью метода `.call()`. +Тут показан частый случай использования класса Git: методы возвращают тот же объект, на котором вызваны, что позволяет чередовать их друг за другом, устанавливая параметры. Финальный аккорд -- непосредственное выполнение команды с помощью метода `.call()`. В этом примере мы запрашиваем список тегов (но не "головы" веток) с удалённого репозитория `origin`. Обратите внимание на использование класса `CredentialsProvider` для аутентификации. diff --git a/book/B-embedding-git/sections/libgit2.asc b/book/B-embedding-git/sections/libgit2.asc index 4c9c4524..4b50b94d 100644 --- a/book/B-embedding-git/sections/libgit2.asc +++ b/book/B-embedding-git/sections/libgit2.asc @@ -1,8 +1,8 @@ === Libgit2 (((libgit2)))(((C))) -Другой доступный вам вариант — это использование библиотеки Libgit2. -Libgit2 — это свободная от внешних зависимостей реализация Git, фокусирующаяся на предоставлении приятного API другим программам. +Другой доступный вам вариант -- это использование библиотеки Libgit2. +Libgit2 -- это свободная от внешних зависимостей реализация Git, фокусирующаяся на предоставлении приятного API другим программам. Вы можете найти её на http://libgit2.github.com[]. Для начала, давайте посмотрим на что похож C API. @@ -33,23 +33,23 @@ git_repository_free(repo); Первая пара строк открывают Git репозиторий. Тип `git_repository` представляет собой ссылку на репозиторий с кешем в памяти. Это самый простой метод, его можно использовать если вы знаете точный путь к рабочей директории репозитория или к `.git` директории. -Существует расширенный вариант — `git_repository_open_ext` — который принимает набор параметров для поиска репозитория. Функция `git_clone` с компаньонами используется для клонирования удалённого репозитория. И, наконец, `git_repository_init` используется для создания нового репозитория с нуля. +Существует расширенный вариант -- `git_repository_open_ext` -- который принимает набор параметров для поиска репозитория. Функция `git_clone` с компаньонами используется для клонирования удалённого репозитория. И, наконец, `git_repository_init` используется для создания нового репозитория с нуля. Следующий кусок кода использует `rev-parse` синтаксис (см. <>) чтобы получить коммит на который указывает HEAD. -Возвращаемый тип — это указатель на структуру `git_object`, которая представляет любой объект, хранящийся во внутренней БД Git. -`git_object` — родительский тип для нескольких других; внутренняя структура всех этих типов одинаковая, так что вы можете относительно безопасно преобразовывать типы друг в друга. +Возвращаемый тип -- это указатель на структуру `git_object`, которая представляет любой объект, хранящийся во внутренней БД Git. +`git_object` -- родительский тип для нескольких других; внутренняя структура всех этих типов одинаковая, так что вы можете относительно безопасно преобразовывать типы друг в друга. В нашем случае `git_object_type(head_commit)` вернёт `GIT_OBJ_COMMIT`, так что мы вправе привести типы для `git_commit`. Затем мы получаем некоторые свойства коммита. -Последняя строчка в этом фрагменте кода использует тип `git_oid` — это внутреннее представление SHA-1 в Libgit2. +Последняя строчка в этом фрагменте кода использует тип `git_oid` -- это внутреннее представление SHA-1 в Libgit2. Глядя на этот пример, можно сделать несколько выводов: * Если вы объявили указатель и передали его в одну из функций Libgit2, она, возможно, вернёт целочисленный код ошибки. - Значение `0` означает успешное выполнение операции, всё что меньше — означает ошибку. + Значение `0` означает успешное выполнение операции, всё что меньше -- означает ошибку. * Если Libgit2 возвращает вам указатель, вы ответственны за очистку ресурсов * Если Libgit2 возвращает `const`-указатель, вам не нужно заботится о его очистке, но он может оказаться невалидным, если объект на который он ссылается будет уничтожен. -* Писать на C — сложно. +* Писать на C -- сложно. (((Ruby))) Последний пункт намекает на маловероятность использования C при работе с Libgit2. @@ -68,7 +68,7 @@ tree = commit.tree Как видите, код гораздо менее загромождён. Во-первых, Rugged использует исключения: он может кинуть ошибку типа `ConfigError` или `ObjectError` чтобы просигнализировать о сбое. Во-вторых, нет необходимости явно подчищать ресурсы, потому что в Ruby есть сборщик мусора. -Давайте посмотрим на более сложный пример — создание коммита с нуля: +Давайте посмотрим на более сложный пример -- создание коммита с нуля: [source,ruby] ---- @@ -103,7 +103,7 @@ commit = repo.lookup(commit_id) # <8> <6> При создании коммита нужно указать его предков. Для этих целей мы используем HEAD как единственного родителя. <7> Rugged (как и Libgit2) дополнительно могут обновить HEAD-указатель. -<8> Результирующее значение — это SHA-1 хэш нового коммита, по которому его можно вычитать из репозитория для получения объекта типа `Commit`. +<8> Результирующее значение -- это SHA-1 хэш нового коммита, по которому его можно вычитать из репозитория для получения объекта типа `Commit`. Код на Ruby приятен и чист, а благодаря тому что Libgit2 делает основную работу ещё и выполняется довольно быстро. На случай если вы пишете не на Ruby, мы рассмотрим другие обёртки над Libgit2 в <>. @@ -112,7 +112,7 @@ commit = repo.lookup(commit_id) # <8> ==== Расширенная функциональность У Libgit2 есть несколько фич, выходящих за рамки стандартного Git. -Одна из таких фич — расширяемость: Libgit2 позволяет использовать нестандартные "бэкэнды" для некоторых операций; таким образом вы можете хранить объекты по-иному, нежели это делает Git из коробки. +Одна из таких фич -- расширяемость: Libgit2 позволяет использовать нестандартные "бэкэнды" для некоторых операций; таким образом вы можете хранить объекты по-иному, нежели это делает Git из коробки. Например, Libgit2 позволяет использовать нестандартные хранилища для конфигурации, ссылок и внутренней базы данных объектов. Давайте взглянем, как это работает. @@ -172,7 +172,7 @@ int git_odb_backend_mine(git_odb_backend **backend_out, /*…*/) return GIT_SUCCESS; } ---- -Важный момент: первое поле структуры `my_backend_struct` имеет тип `git_odb_backend` — это обеспечивает расположение полей в памяти в формате, ожидаемом Libgit2. +Важный момент: первое поле структуры `my_backend_struct` имеет тип `git_odb_backend` -- это обеспечивает расположение полей в памяти в формате, ожидаемом Libgit2. Оставшиеся поля можно располагать произвольно; сама структура может быть любого нужного вам размера. Функция инициализации выделяет память под структуру, устанавливает произвольный контекст и заполняет поля структуры `parent`, которые необходимо поддерживать. @@ -190,7 +190,7 @@ int git_odb_backend_mine(git_odb_backend **backend_out, /*…*/) ===== LibGit2Sharp (((.NET)))(((C#)))(((Mono))) -Если вы пишете под платформы .NET / Mono, LibGit2Sharp (https://github.com/libgit2/libgit2sharp[]) — то, что прописал вам доктор. +Если вы пишете под платформы .NET / Mono, LibGit2Sharp (https://github.com/libgit2/libgit2sharp[]) -- то, что прописал вам доктор. Эта библиотека написана на C# и все прямые вызовы методов Libgit2 тщательно обёрнуты в управляемый CLR код. Вот как будет выглядеть наш пример: diff --git a/book/dedication.asc b/book/dedication.asc index d7d826b8..a405536a 100644 --- a/book/dedication.asc +++ b/book/dedication.asc @@ -1,8 +1,8 @@ [dedication] == Dedications -_To my wife, Becky, without whom this adventure never would have begun. — Ben_ +_To my wife, Becky, without whom this adventure never would have begun. -- Ben_ _This edition is dedicated to my girls. To my wife Jessica who has supported me for all of these years and to my daughter Josephine, -who will support me when I'm too old to know what's going on. — Scott_ +who will support me when I'm too old to know what's going on. -- Scott_ diff --git a/book/introduction.asc b/book/introduction.asc index 9e65cd7e..a518227e 100644 --- a/book/introduction.asc +++ b/book/introduction.asc @@ -5,7 +5,7 @@ В *Главе 1* мы охватим Системы Контроля Версий (VCS) и азы Git. Никаких технических штучек, только то, что, собственно, такое Git, почему он пришел на землю уже полную систем контроля версий, что его отличает и почему так много людей им пользуются. Затем мы объясним как впервые скачать и настроить Git, если в вашей системе его ещё нет. -В *Главе 2* мы перейдём к основам использования Git — как использовать Git в 80% случаев с которыми вы столкнётесь. После прочтения этой главы вы сможете клонировать репозитории, смотреть изменения в истории проекта, изменять файлы и публиковать эти изменения. Если на этом моменте книга самопроизвольно воспламенится, вы уже достаточно оцените время, потраченное на знакомство с Git, чтобы сходить за ещё одной копией. +В *Главе 2* мы перейдём к основам использования Git -- как использовать Git в 80% случаев с которыми вы столкнётесь. После прочтения этой главы вы сможете клонировать репозитории, смотреть изменения в истории проекта, изменять файлы и публиковать эти изменения. Если на этом моменте книга самопроизвольно воспламенится, вы уже достаточно оцените время, потраченное на знакомство с Git, чтобы сходить за ещё одной копией. *Глава 3* про модель ветвления в Git, часто описываемую как киллер-фичу Git. Отсюда вы узнаете, что на самом деле отличает Git от обычного пакета. Когда вы дочитаете, возможно, вам понадобится ещё немного времени на размышления о том, как же вы существовали до того как Git ветвление вошло в вашу жизнь. diff --git a/book/preface_scott.asc b/book/preface_scott.asc index 20680a86..ec30bdd0 100644 --- a/book/preface_scott.asc +++ b/book/preface_scott.asc @@ -12,7 +12,7 @@ С тех пор его приняло практически всё сообщество свободного программного обеспечения. Git достиг невероятного прогресса в Windows, взрывными темпами получил графический интерфейс для всех платформ, поддержку сред разработки и стал использоваться в бизнесе. Pro Git четырехлетней давности ничего подобного не подозревал. -Одна из главных целей издания — затронуть в Git сообществе эти рубежи. +Одна из главных целей издания -- затронуть в Git сообществе эти рубежи. Сообщество свободного программного обеспечения тоже испытало взрывной рост. Когда я лет пять назад впервые сел писать книгу (первая версия потребовала времени), я как раз начал работать в крохотной компании, разрабатывающей сайт для Git хостинга под названием Гитхаб.