//Эта страница доступна также на следующих языках:// [[scm|English]]

====== gEDA/gaf и git ======

В gEDA для управления исходными текстами программ используется **git**.
**git** --- это распределённая система управления версиями, которая
позволяет каждому пользователю иметь свою собственную полную копию истории
изменений проекта.

  * [[http://git.or.cz/|Официальная веб-страница git]]
  * [[http://www.kernel.org/pub/software/scm/git/docs/|Интерактивная документация по git]]
  * [[wp>Git_(software)|Страница википедии по git]]

===== Установка git и других вспомогательных программ =====

Конечно, в первую очередь для использования репозитория необходимы основные
инструменты **git**, и всегда полезна документация. Но часто для работы с
**git** удобно пользоваться и другими средствами:

  * [[http://www.kernel.org/pub/software/scm/git/docs/gitk.html|gitk]], программа просмотра истории репозитория
  * [[http://www.procode.org/stgit/|Stacked Git]], для работы с наборами заплат


Для дистрибутивов на основе Debian:

  apt-get install git-core git-doc gitk stgit

Ещё может пригодиться следующее:

  apt-get install git-email git-completion


Fedora Linux:

  yum install git stgit




===== Изучение git =====

Главная страница документации **git**:

  * [[http://www.kernel.org/pub/software/scm/git/docs/|Официальная документация git]]

Руководство пользователя **git**:

  * [[http://www.kernel.org/pub/software/scm/git/docs/user-manual.html|Руководство пользователя git]]

Текущее руководство можно найти по ссылке:

  * [[http://www.kernel.org/pub/software/scm/git/docs/gitcore-tutorial.html|Введение в основы git]]

Другие замечательные руководства/веб-страницы:

  * [[http://wiki.sourcemage.org/Git_Guide|Руководство по Git]]
  * [[http://git.or.cz/course/index.html|Аварийные курсы по git]]

Имейте в виду, что некоторые из этих руководств немного устарели и могут не
совсем полно отражать текущий синтаксис **git**.








===== Анонимный доступ к репозиторию =====

Клонирование (создание точной локальной копии) репозитория **geda-gaf.git**
(или любого другого репозитория, поддерживаемого на
[[http://git.geda-project.org|git.geda-project.org]]) с использованием
анонимного доступа **git** производится так:

  git clone git://git.geda-project.org/geda-gaf.git

или

  git clone git://git.geda-project.org/pcb.git

Для клонирования других репозиториев, поддерживаемых на
''git.geda-project.org'', достаточно поправить последнюю часть вышеуказанной
ссылки.

Для репозиториев различных проектов существует
[[http://hjemli.net/git/cgit/about/|cgit]]-интерфейс. Открыть его можно,
просто набрав в строке адреса браузера [[http://git.geda-project.org/]].
===== Доступ к репозиторию с правами на запись =====

Для доступа в **git** с правами разработчика вам нужно связаться с //DJ
Delorie//, чтобы он установил ваш открытый ключ SSH на сервере, после этого
для отправки своих изменений можно использовать следующие адреса:

  ssh://git@git.geda-project.org/geda-gaf.git
или
  ssh://git@git.geda-project.org/pcb.git

Вам также будет нужно отредактировать у себя файл //''~/.ssh/config''//
(создать, если он ещё не существует) и вставить туда следующий текст:

  Host git.geda-project.org
  Port 65

Примечание: если у вас проблемы с отправкой изменений в основной репозиторий
проекта, убедитесь, что у вас используется **git** версии 1.5 или выше.

Если для доступа к **git** вы отдали администратору ключ, специально
созданный для gEDA, вам может быть также нужно добавить к своим настройкам
ещё одну строку, где указать этот дополнительный ключ:

  Host git.geda-project.org
  Port 65
  IdentityFile ~/.ssh/gedaproject_dsa

Учтите, что файл, на который вы ссылаетесь здесь, это ваш закрытый ключ
(«private key»), а файл, который нужно послать на сервер, это
соответствующий ему открытый ключ («public key»).


===== Создание и внесение изменений =====


==== Настройка информации о пользователе ====

Сначала вам нужно обеспечить, чтобы в файле настроек **git** у вас были
заданы ваше имя и ваш адрес электронной почты.

  $ git config --global user.name "Здесь должно быть ваше имя"
  $ git config --global user.email вы@ваш_домен.example.com



==== Внесение заплат других участников проекта ====

При наложении чужой заплаты (например, из записи о заплате в ''launchpad''),
следует иметь в виду некоторые моменты. Для вносимых изменений **git**
сохраняет по два имени и по два адреса электронной почты: «автора» заплаты
(«author») и «вносящего» заплату («committer»), и при внесении изменений эти
данные должны быть правильными.

Прежде всего, убедитесь, что:
  * ваша версия заплаты --- последняя;
  * автор заплаты будет рад, что его заплату внесут в репозиторий (и всё ещё не работает над ней);
  * вы довольны заплатой и возьмёте на себя ответственность за вносимые изменения.

Для простоты начать можно с неизменённого дерева самой последней версии
(**''git status''** не должен показывать никаких изменений).

Заплата накладывается обычным способом (как этом в примере):

  $ patch -p1 < example_changes.patch

Можно также использовать команду **''git apply''**:

  $ git apply example_changes.patch

Если перед внесением в репозиторий заплату нужно чуть подкорректировать
(например, поправить пробелы), проинформируйте об этом автора. Может быть на
основе этой заплаты он делает что-то другое, и тогда он должен знать, какие
изменения появились в наложенной версии.

Примечание: //очень легко допустить случайную ошибку, если ваш редактор
заменяет пробелы знаками табуляции. Не разрешайте ему этого!//

Прежде чем вносить изменения, **git** нужно проинформировать о всех
изменённых, добавленных или, наоборот, удалённых файлах. Чтобы посмотреть,
какие файлы изменены, можно запустить:

  $ git status

Для скорости, командой

  $ git add -u

можно обновить все файлы, отслеживаемые **git**, включая удалённые.

Добавление новых файлов, вводимых в репозиторий с этой заплатой,
производится командой

  $ git add new_file.c

Примечание: параметры **''git add''** могут также задаваться и с помощью
метасимволов.

При внесении заплаты обязательно следует указать имя и адрес электронной
почты автора:

  $ git commit --author "Здесь должно быть имя автора <author@example.com>"

Как вариант, если заранее настроить переменные окружения ''GIT_AUTHOR_NAME''
и ''GIT_AUTHOR_EMAIL'', команду **''git commit''** можно запускать как
обычно.


==== Написание хороших сообщений о вносимых изменениях ====


Формат сообщения о вносимых изменениях ["commit message"] следующий:
**строго** однострочное изложение сути заплаты, за которым следует пустая
строка, а затем длинное описание. Если можно уместить полное описание
заплаты в одной строке, --- прекрасно, --- тогда и не стоит забивать голову
насчёт длинного описания.

Однострочные описания используются для создания темы электронного письма и
для отображения в журналах **gitk** и **gitweb**. Очень удобно, когда они
написаны хорошо, потому что это значит, что пользователь этих программ
сможет быстро находить интересные изменения.

**Не добавляйте** в сообщения о вносимых изменениях перечни изменённых файлов.  Эту информацию очень просто извлечь с помощью инструментария **git**.

Пример:

<code>
Added new GedaList class derived from GObject

This abstracts a GList with API for write access. Its main use is in list
change notification, as it emits a "changed" g_signal when modified.  Read
only access to the underlying GList is provided by an accessor, currenly
implemented as a macro.  </code>

==== Операция push - разрушительна ====

**Предупреждение: добавление изменений с помощью //push// в удалённый репозиторий разрушительно**

В отличие от CVS, командой **''git-push''** изменения не просто добавляются
в основной репозиторий, но «продвигается» локальная версия. Всегда нужно
дважды (или даже трижды) проверить, что «продвигаемые» вами изменения в
самом деле предназначены для основного репозитория.



===== Как мне ... ? =====

Более подробную информацию можно найти в
[[http://wiki.sourcemage.org/Git_Guide|Руководстве по Git]].

==== ... получить копию репозитория git проекта gEDA/gaf? ====

При анонимном доступе только на чтение:

  $ git clone git://git.geda-project.org/geda-gaf

Для разработчиков с доступом на чтение и запись:

  $ git clone ssh://git@git.geda-project.org/geda-gaf

==== ... поддерживать соответствие своей локальной копии текущей версии? ====

Те, кто не собирается отправлять свои изменения в центральный репозиторий
**git**, могут запустить:

  $ git pull

Однако тем из вас, кто собирается «продвигать» свои изменения в центральный
репозиторий **git**, использование **''git pull''** испортит историю
сообщениями об объединении веток («Merge branch 'master'»). Чтобы избежать
этого, нужно запустить:

  $ git fetch
  $ git rebase origin

==== ... внести свои изменения в локальный репозиторий git? ====

  $ git commit -a

Эта команда найдёт все изменённые файлы, о которых знает **git**
(добавленные с помощью **''git-add''**) и запросит у вас сообщение о
вносимых изменениях.  Непременно следуйте указанному выше соглашению по
написанию таких сообщений, если планируете отправлять свои изменения в
центральный репозиторий.

Если вы хотите внести файлы из текущего каталога, или хотите внести только
явно определённые файлы, не указывайте флаг ''-a'' и (или) укажите имена
выбранных файлов в командной строке, например:

  $ git commit filename1 filename2



==== ... отменить все локальные изменения, ещё не внесённые в репозиторий? ====

  $ git checkout -f

Учтите, что при этом все изменения в любых файлах, отслеживаемых в
**git**-репозитории, будут отвергнуты.

Если нужно отменить изменения только в одном файле, достаточно запустить:

  $ git checkout путь/к/нужному/файлу

Если нужно отменить все изменения в текущем каталоге и рекурсивно во всех
его подкаталогах, достаточно запустить:

  $ git checkout .


==== ... исправить/отредактировать изменения, внесённые последний раз? ====

  $ ... изменение каких-то файлов ...
  $ git commit --amend filename1..filenameN

Этой командой все новые изменения объединяются с внесёнными в последний раз
и заново вносятся в репозиторий со старым сообщением.

==== ... отслеживать ветку? ====

  $ git checkout --track -b <локальная_ветка> origin/<удалённая_ветка>

Этой командой создаётся ветка //<локальная_ветка>//, в которой отслеживается
удалённая ветка //<удалённая_ветка>//.

==== ... создать ветку (начиная с определённого тега)? ====

Нужно запустить следующие команды (для примера используется ветка
//stable-1.4//):

   $ git branch stable-1.4 1.4.0-20080127
   $ git checkout stable-1.4
   <что-то редактируем>
   $ git commit -a

Чтобы опубликовать эту ветку в центральном репозитории (требуется доступ в
него на запись):

   $ git push origin stable-1.4

==== ... получить ветку разработки другого разработчика? ====
Кроме репозитория [[http://git.geda-project.org/]], у нас есть его зеркало
на [[http://repo.or.cz/w/geda-gaf.git]]. Некоторые разработчики имеют свои
ответвления («fork») данного репозитория с ветками («branch») разработки
новых возможностей.

Если вы хотите попробовать одну из веток с новыми возможностями, нужно
получить её из репозитория разработчика. Самый лёгкий способ получения ветки
--- использовать команду **''git fetch''**.

    $ git fetch ссылка_на_репозиторий название_удалённой_ветки:название_локальной_ветки

**Примеры:**
Получение ветки //cairo_experiment// от //Peter C.// выглядело бы так:

    $ git fetch git://repo.or.cz/geda-gaf/pcjc2.git cairo_experiment:peters_cairo_experiment

Теперь вы можете переключиться на локальную копию ветки
//peters_cairo_experiment// и поиграться с ней.

Более того, в локальный репозиторий можно добавить несколько удалённых ответвлений:
    $ git remote add <название> <url>
    $ git fetch <название>
При условии, что <название> уникально, у вас появится возможность следить за
их развитием, не создавая локальных веток. С помощью таких
программ, как **gitk**, можно следить за прогрессом в ветках разработки различных возможностей в разных ответвлениях:
    $ gitk --all

**Примеры:**
    $ git remote add peter-b https://github.com/peter-b/geda-gaf.git
    $ git fetch peter-b
    $ git remote add gareth8118 https://github.com/gareth8118/geda-gaf.git
    $ git fetch gareth8118
    $ git remote add bert https://github.com/bert/geda-gaf.git
    $ git fetch bert
    $ gitk --all

Теперь gitk будет забит до отказа, но с помощью **//Файл//** -> **//Список
ссылок//** [**//File//** -> **//List references//**] (<key>F2</key>) можно
открыть диалоговое окно для более лёгкой навигации.

Обновление любимых веток сократится тогда до:
    $ git fetch --all
==== ... сделать заплату, чтобы отправить её разработчикам? ====
Самый простой способ, в котором в заплату включаются все изменения с тех пор, как локальный репозиторий синхронизировался с репозиторием на geda-project.org:
  $ git diff > имя_файла_заплаты

Более сложный способ с бóльшим контролем над содержимым заплаты:
  $ git add -i           # выбрать файлы для внесения изменений
  $ git status           # проверить, что будут внесены именно те изменения,
                         # которые вы намеревались внести
  $ git commit           # внести изменения
  $ git format-patch -1  # сделать файл заплаты, основанный на данных изменениях
Последняя команда выведет имя файла, содержащего заплату. Чтобы больше узнать об этой команде, обязательно взгляните на документацию по **git-format-patch**. Полученный файл можно отправить по электронной почте разработчикам, имеющим доступ на запись, и они смогут наложить заплату с помощью **''git apply''**.

==== ... восстановить на самом деле испорченный локальный репозиторий? ====

Прежде всего, не вздумайте никуда «продвигать» командой **''git push''**
никаких изменений из локального репозитория, если вы думаете, что в нём
что-то испорчено. Спросите сначала кого-нибудь более опытного в **git**.

Во-вторых, команда, которая в самом деле спасёт вашу шкуру --- это
**git-reflog**. Она используется примерно так:

   $ git reflog
   086908e... HEAD@{0}: cherry-pick: Last minute updates to the READMEs for all pro
   2a79a23... HEAD@{1}: checkout: moving to master
   2a79a23... HEAD@{2}: checkout: moving to master
   ...
   $ git reset --hard HEAD@{1}

Последняя команда (**''%%git reset --hard ...%%''**) откатит все ваши
изменения к шагу «checkout: moving to master».  Помните: не паникуйте! С
помощью **git** можно многое починить.
