Настройка репозитория Git
Репозиторий Git или репозиторий — это папка, в которую Git отслеживается изменения. На компьютере может быть любое количество репозиториев, хранящихся в собственной папке. Каждый репозиторий Git в системе является независимым, поэтому изменения, сохраненные в одном репозитории Git, не влияют на содержимое другого.
Репозиторий Git содержит каждую версию каждого файла, сохраненного в репозитории. Это отличается от других систем управления версиями, которые хранят только различия между файлами. Git сохраняет версии файлов в скрытой папке .git вместе с другими сведениями, которыми он должен управлять кодом. Git экономит эти файлы очень эффективно, поэтому наличие большого количества версий не означает, что он использует много места на диске. Хранение каждой версии файла помогает Git объединить код лучше и упрощает работу с несколькими версиями кода.
Разработчики работают с Git с помощью команд, выданных при работе в локальном репозитории на компьютере. Даже при совместном использовании кода или получении обновлений из команды выполняется из команд, которые обновляют локальный репозиторий. Этот локальный дизайн — это то, что делает Git распределенной системой управления версиями. Каждый репозиторий является автономным, и владелец репозитория отвечает за сохранение его актуальности с изменениями от других.

Большинство команд используют центральный репозиторий, размещенный на сервере, который каждый может получить доступ к координации своих изменений. Центральный репозиторий обычно размещается в решении управления версиями, например GitHub или Azure DevOps. Решение управления версиями добавляет функции и упрощает совместную работу.
Создание репозитория Git
Существует два варианта создания репозитория Git. Вы можете создать один из кода в папке на компьютере или клонировать его из существующего репозитория. При работе с кодом, который находится только на локальном компьютере, создайте локальный репозиторий с помощью кода в этой папке. Но большую часть времени, когда код уже предоставлен в репозитории Git, поэтому клонирование существующего репозитория на локальный компьютер рекомендуется использовать.
Создание репозитория из существующего кода
git init Используйте команду, чтобы создать репозиторий из существующей папки на компьютере. В командной строке перейдите в корневую папку, содержащую код и выполните следующую команду:
для создания репозитория. Затем добавьте все файлы в папку в первую фиксацию с помощью следующих команд:
> git commit -m «Initial commit»
Создание репозитория из удаленный репозиторий
git clone Используйте команду, чтобы скопировать содержимое существующего репозитория в папку на компьютере. В командной строке перейдите в папку, чтобы содержать клонированного репозитория, а затем выполните следующую команду:
Не забудьте использовать фактический URL-адрес существующего репозитория вместо URL-адреса заполнителя, показанного в этом примере. Этот URL-адрес, называемый URL-адресом клонирования, указывает на сервер, где команда координирует изменения. Получите этот URL-адрес из команды или с кнопки клонирования на сайте, где размещен репозиторий.
Не обязательно добавлять файлы или создавать начальную фиксацию при клонировании репозитория, так как он был скопирован вместе с журналом из существующего репозитория во время операции клонирования.
Следующие шаги
GitHub и Azure Repos предоставляют неограниченные бесплатные общедоступные и частные репозитории Git.
Являетесь пользователем Visual Studio? Дополнительные сведения о создании и клонировании репозиториев из Visual Studio см. в этом руководстве по Git.
Где лучше всего хранить репозиторий Git?
Мы небольшой распределенной командой беремся за разработку крупного проекта Unity. До сих пор работал с BitBucket, но на последнем проекте сайт уже стал нас предупреждать, что у нас слишком большой репозиторий и он не должен превышать 2Gb. Поскольку проект у нас содержит много бинарных данных (модели, текстуры, видео и т.п.) размер его может расти существенно. Поделитесь опытом кто где хранит свои репозитории? Как решаете вопросы с безопасностью? Буду рад любой полезной информации.
Отслеживать
25.1k 4 4 золотых знака 46 46 серебряных знаков 81 81 бронзовый знак
задан 20 фев 2017 в 17:19
2,680 1 1 золотой знак 12 12 серебряных знаков 27 27 бронзовых знаков
GitHub за 7$ в месяц ничем вас не ограничивает 🙂
20 фев 2017 в 17:21
GitLab.com storage limit raised to 10GB per repo
20 фев 2017 в 17:25
Может не стоило нагружать репу бинарными артифактами?
20 фев 2017 в 17:30
Gitlab можно поднять на своём сервере…
20 фев 2017 в 18:30
Может быть выделить место в своем серваке, сделать там чистый репозиторий, дать доступ нужным людям и не париться
20 фев 2017 в 18:44
2 ответа 2
Сортировка: Сброс на вариант по умолчанию
Хм, не забрасывайте камнями но я храню их в cloud.mail.ru
как альтернатива яндекс.диск.
#Создаем локальный репозиторий mkdir /mnt/data/Project/test_repo cd /mnt/data/Project/test_repo git init #Создаем файл hello_world.txt c произвольным содержимым touch hello_world.txt nano hello_world.txt #Помещаем только что созданный файл под контроль Git git add . #Фиксируем изменения git commit -m "First commit" #Создаем удаленный репозиторий mkdir /mnt/data/Яндекс.Диск/git_repo/test_repo.git cd /mnt/data/Яндекс.Диск/git_repo/test_repo.git #Создаем репозиторий без рабочей копии git init --bare #Возвращаемся в локальный репозиторий cd /mnt/data/Project/test_repo #В локальном репозитории указываем где искать удаленный #yandex_disk - псевдоним для полного пути к удаленному репозиторию git remote add yandex_disk /mnt/data/Яндекс.Диск/git_repo/test_repo.git #Передаем изменения из локального репозитория в удаленный #master - текущая ветка разработки git push yandex_disk master
8.1 Настройка Git — Конфигурация Git
До этого момента мы описывали основы того, как Git работает и как его использовать, а так же мы познакомились с некоторыми инструментами Git, которые делают его использование простым и эффективным. В этой главе мы рассмотрим некоторые настройки Git и систему хуков, что позволяет настроить поведение Git. Таким образом, вы сможете заставить Git работать именно так как нужно вам или вашей компании.
Конфигурация Git
В главе Введение кратко упоминалось, что вы можете настроить Git, используя команду git config . Первое, что вы делали, это установили своё имя и e-mail адрес:
$ git config --global user.name "John Doe" $ git config --global user.email johndoe@example.com
Сейчас вы познакомитесь с несколькими наиболее интересными опциями, которые можно установить для настройки поведения Git.
Кратко: Git использует набор конфигурационных файлов для изменения стандартного поведения, если это необходимо. Вначале, Git ищет настройки в файле /etc/gitconfig , который содержит настройки для всех пользователей в системе и всех репозиториев. Если передать опцию —system команде git config , то операции чтения и записи будут производиться именно с этим файлом.
Следующее место, куда смотрит Git — это файл ~/.gitconfig (или ~/.config/git/config ), который хранит настройки конкретного пользователя. Вы можете указать Git читать и писать в него, используя опцию —global .
Наконец, Git ищет параметры конфигурации в файле настроек в каталоге Git ( .git/config ) текущего репозитория. Эти значения относятся только к текущему репозиторию и доступны при передаче параметра —local команде git config . (Если уровень настроек не указан явно, то подразумевается локальный.)
Каждый из этих уровней (системный, глобальный, локальный) переопределяет значения предыдущего уровня, например, значения из .git/config важнее значений из /etc/gitconfig .
Примечание
Конфигурация Git это обычные текстовые файлы, поэтому можно вручную установить необходимые значения используя соответствующий синтаксис. Как правило, это проще чем вызывать команду git config для каждого параметра.
Базовая конфигурация клиента
Конфигурационные параметры Git разделяются на две категории: настройки клиента и настройки сервера. Большая часть — клиентские, для настройки ваших личных предпочтений в работе. Существует много, очень много настроек, но подавляющее большинство из них применимо только в конкретных случаях; мы рассмотрим только самые основные и самые полезные из них. Для просмотра полного списка настроек, поддерживаемых вашей версией Git, выполните команду:
$ man git-config
Эта команда выведет список доступных настроек с довольно подробным описанием. Так же, соответствующую документацию можно найти здесь https://git-scm.com/docs/git-config.html.
core.editor
По умолчанию, Git использует ваш редактор по умолчанию ( $VISUAL или $EDITOR ), если значение не задано — переходит к использованию редактора vi при создании и редактировании сообщений коммитов или тегов. Чтобы изменить редактор по умолчанию, воспользуйтесь настройкой core.editor :
$ git config --global core.editor emacs
Теперь, вне зависимости от того, какой редактор является основным для вашего окружения, Git будет вызывать Emacs для редактирования сообщений.
commit.template
Если указать путь к существующему файлу, то он будет использован как сообщение по умолчанию при создании коммита. Смысл создания шаблона сообщения коммита в том, чтобы лишний раз напомнить себе (или другим) о требованиях к формату или стилю оформления сообщения коммита.
Например, предположим что вы создали файл ~/.gitmessage.txt , который выглядит так:
Subject line (try to keep under 50 characters) Multi-line description of commit, feel free to be detailed. [Ticket: X]
Обратите внимание, что шаблон напоминает коммитеру о том, чтобы строка заголовка сообщения была короткой (для поддержки однострочного вывода команды git log —oneline ), что дополнительную информацию в сообщении следует располагать ниже, а так же о том, что было бы неплохо при наличии добавить ссылку на номер задачи или сообщения в системе отслеживания ошибок.
Чтобы заставить Git отображать содержимое этого файла в редакторе каждый раз при выполнении команды git commit , следует установить значение параметра commit.template :
$ git config --global commit.template ~/.gitmessage.txt $ git commit
Теперь, при создании коммита, в вашем редакторе будет отображаться сообщение изменённого вида:
Subject line (try to keep under 50 characters) Multi-line description of commit, feel free to be detailed. [Ticket: X] # Please enter the commit message for your changes. Lines starting # with '#' will be ignored, and an empty message aborts the commit. # On branch master # Changes to be committed: # (use "git reset HEAD . " to unstage) # # modified: lib/test.rb # ~ ~ ".git/COMMIT_EDITMSG" 14L, 297C
Если ваша команда придерживается требований к сообщениям коммитов, то создание шаблона такого сообщения и настройка Git на его использование увеличит вероятность соответствия заданным требованиям.
core.pager
Данная настройка определяет какая программа будет использована для разбиения текста на страницы при выводе такой информации как log и diff . Вы можете указать more или любую другую (по умолчанию используется less ), а так же выключить совсем, установив пустое значение:
$ git config --global core.pager ''
В таком случае, Git будет выводить весь текст полностью, вне зависимости от его длины.
user.signingkey
Если вы создаёте подписанные аннотированные теги (как описано в разделе Подпись главы 7), то установка GPG ключа в настройках облегчит вам задачу. Установить ключ можно следующим образом:
$ git config --global user.signingkey
Теперь, вам не нужно указывать ключ для подписи каждый раз при вызове команды git tag :
$ git tag -s
core.excludesfile
В разделе Игнорирование файлов главы 2 сказано, что вы можете указывать шаблоны исключений в файле .gitignore вашего проекта, чтобы Git не отслеживал их и не добавлял в индекс при выполнении команды git add .
Однако, иногда вам нужно игнорировать определённые файлы во всех ваших репозиториях. Если на вашем компьютере работает Mac OS X, вероятно вы знакомы с файлами .DS_Store . Если вы используете Emacs или Vim, то вы знаете про файлы, имена которых заканчиваются на ~ или .swp .
Данная настройка позволяет вам определить что-то вроде глобального файла .gitignore . Если вы создадите файл ~/.gitignore_global с содержанием:
*~ .*.swp .DS_Store
… и выполните команду git config —global core.excludesfile ~/.gitignore_global , то Git больше не потревожит вас на счёт этих файлов.
help.autocorrect
Если вы ошибётесь в написании команды, Git покажет вам что-то вроде этого:
$ git chekcout master git: 'chekcout' is not a git command. See 'git --help'. The most similar command is checkout
Git старается угадать, что вы имели ввиду, но при этом команду не выполняет. Если вы установите help.autocorrect в значение 1, то Git будет выполнять эту команду:
$ git chekcout master WARNING: You called a Git command named 'chekcout', which does not exist. Continuing under the assumption that you meant 'checkout' in 0.1 seconds automatically.
Обратите внимание, что команда выполнилась через «0.1» секунды. help.autocorrect — это число, указываемое в десятых долях секунды. Поэтому, если вы установите значение 50, то Git даст вам 5 секунд изменить своё решение перед тем, как выполнить скорректированную команду.
Цвета в Git
Git полностью поддерживает цветовой вывод в терминале, что позволяет быстро и легко визуально анализировать вывод команд. Существует несколько опций для настройки цветов.
color.ui
Git автоматически подсвечивает большую часть своего вывода, но это можно отключить, если вам не нравится такое поведение. Для отключения цветового вывода в терминал, выполните следующую команду:
$ git config --global color.ui false
Значение по умолчанию — auto , при котором цвета используются при непосредственном выводе в терминал, но исключаются при перенаправлении вывода в именованный канал или файл.
Вы так же можете установить значение always , что делает вывод одинаковым как в терминал, так и в именованный канал. Скорее всего, вам это не понадобится; в большинстве случаев, при желании использовать цвета в перенаправленном выводе, указывается флаг —color команде Git для принудительного использования цветовых кодов. Практически всегда стандартное значение подходит лучше всего.
color.*
Если вы хотите явно указать вывод каких команд должен быть подсвечен и как, Git предоставляет соответствующие настройки. Каждая из них может быть установлена в значения true , false или always :
color.branch color.diff color.interactive color.status
Каждая из них имеет вложенную конфигурацию, которую можно использовать для настройки отдельных частей вывода при желании переопределить их цвет. Например, чтобы установить для метаинформации вывода команды diff синий цвет, чёрный фон и полужирный шрифт, выполните команду:
$ git config --global color.diff.meta "blue black bold"
Для установки цвета доступны следующие значения: normal , black , red , green , yellow , blue , magenta , cyan , или white . Для указания атрибутов текста, как bold в предыдущем примере, доступны значения: bold , dim , ul (подчёркнутый), blink и reverse (поменять местами цвет фона и цвет текста).
Внешние программы слияния и сравнения
Хоть в Git и есть встроенная программа сравнения, которая описывается в этой книге, вы можете установить вместо неё другую. Вы также можете настроить графический инструмент разрешения конфликтов слияния вместо того, чтобы разрешать конфликты вручную. Мы покажем как настроить Perforce Visual Merge Tool (P4Merge) для разрешения конфликтов слияния, так как это прекрасный и бесплатный инструмент.
Если у вас есть желание попробовать P4Merge, то она работает на всех основных платформах, так что у вас должно получиться. В примерах мы будем использовать пути к файлам, которые работают в системах Linux и Mac; для Windows вам следует изменить /usr/local/bin на путь к исполняемому файлу у вас в системе.
Для начала скачайте P4Merge. Затем, создайте скрипты обёртки для вызова внешних программ. Мы будем использовать путь к исполняемому файлу в системе Mac; в других системах — это путь к файлу p4merge . Создайте скрипт с названием extMerge для вызова программы слияния и передачи ей заданных параметров:
$ cat /usr/local/bin/extMerge #!/bin/sh /Applications/p4merge.app/Contents/MacOS/p4merge $*
Скрипт вызова программы сравнения проверяет наличие 7 аргументов и передаёт 2 из них в скрипт вызова программы слияния. По умолчанию, Git передаёт следующие аргументы программе сравнения:
path old-file old-hex old-mode new-file new-hex new-mode
Так как вам нужны только old-file и new-file , следует использовать скрипт, который передаст только необходимые параметры.
$ cat /usr/local/bin/extDiff #!/bin/sh [ $# -eq 7 ] && /usr/local/bin/extMerge "$2" "$5"
Так же следует убедиться, что созданные скрипты могут исполняться:
$ sudo chmod +x /usr/local/bin/extMerge $ sudo chmod +x /usr/local/bin/extDiff
Теперь можно изменить файл конфигурации для использования ваших инструментов слияния и сравнения. Для этого необходимо изменить ряд настроек: merge.tool — чтобы сказать Git какую стратегию использовать, mergetool..cmd — чтобы сказать Git как запускать команду, mergetool..trustExitCode — чтобы сказать Git как интерпретировать код выхода из программы, diff.external — чтобы сказать Git какую команду использовать для сравнения. Таким образом, команду конфигурации нужно запустить четыре раза:
$ git config --global merge.tool extMerge $ git config --global mergetool.extMerge.cmd \ 'extMerge "$BASE" "$LOCAL" "$REMOTE" "$MERGED"' $ git config --global mergetool.extMerge.trustExitCode false $ git config --global diff.external extDiff
или вручную отредактировать файл ~/.gitconfig добавив соответствующие строки:
[merge] tool = extMerge [mergetool "extMerge"] cmd = extMerge "$BASE" "$LOCAL" "$REMOTE" "$MERGED" trustExitCode = false [diff] external = extDiff
После этого, вы можете запускать команды diff следующим образом:
$ git diff 32d1776b1^ 32d1776b1
Вместо отображения вывода diff в терминале Git запустит P4Merge, выглядеть это будет примерно так:

Рисунок 142. P4Merge
Если при слиянии двух веток у вас возникнут конфликты, выполните команду git mergetool ; она запустит P4Merge чтобы вы могли разрешить конфликты используя графический интерфейс.
Используя скрипт обёртку для вызова внешних программ, вы можете легко изменить вызываемую программу. Например, чтобы начать использовать KDiff3 вместо P4Merge, достаточно изменить файл extMerge :
$ cat /usr/local/bin/extMerge #!/bin/sh /Applications/kdiff3.app/Contents/MacOS/kdiff3 $*
Теперь, Git будет использовать программу KDiff3 для сравнения файлов и разрешения конфликтов слияния.
Git изначально настроен на использование ряда других инструментов для разрешения конфликтов слияния, поэтому вам не нужно дополнительно что-то настраивать. Для просмотра списка поддерживаемых инструментов, выполните команду:
$ git mergetool --tool-help 'git mergetool --tool=' may be set to one of the following: emerge gvimdiff gvimdiff2 opendiff p4merge vimdiff vimdiff2 The following tools are valid, but not currently available: araxis bc3 codecompare deltawalker diffmerge diffuse ecmerge kdiff3 meld tkdiff tortoisemerge xxdiff Some of the tools listed above only work in a windowed environment. If run in a terminal-only session, they will fail.
Если вы хотите использовать KDiff3 только для разрешения конфликтов слияния, но не для сравнения, выполните команду:
$ git config --global merge.tool kdiff3
Если выполнить эту команду вместо настройки использования файлов extMerge и extDiff , то Git будет использовать KDiff3 для разрешения конфликтов слияния, а для сравнения — стандартную программу diff.
Форматирование и пробелы
Проблемы форматирования и пробелов являются одними из самых неприятных и незаметных проблем, с которыми сталкивают разработчики при совместной работе, особенно используя разные платформы. Это легко может произойти с патчами или с любой другой совместной работой, так как редакторы молча исправляют несоответствия, и если ваши файлы когда либо касаются систем Windows, то переносы строк могут быть заменены. В Git есть несколько настроек, чтобы справиться с этими проблемами.
core.autocrlf
Если вы программируете в Windows и работаете с людьми, которые не используют её (или наоборот), рано или поздно, вы столкнётесь с проблемами переноса строк. Это происходит потому, что Windows при создании файлов использует для обозначения переноса строки два символа «возврат каретки» и «перевод строки», в то время как Mac и Linux используют только один — «перевод строки». Это незначительный, но невероятно раздражающий факт кроссплатформенной работы; большинство редакторов в Windows молча заменяют переносы строк вида LF на CRLF или вставляют оба символа, когда пользователь нажимает клавишу ввод.
Git может автоматически конвертировать переносы строк CRLF в LF при добавлении файла в индекс и наоборот — при извлечении кода. Такое поведение можно включить используя настройку core.autocrlf . Если у вас Windows, то установите значение true — при извлечении кода LF окончания строк будут преобразовываться в CRLF:
$ git config --global core.autocrlf true
Если у вас система Linux или Mac, то вам не нужно автоматически конвертировать переносы строк при извлечении файлов; однако, если файл с CRLF окончаниями строк случайно попал в репозиторий, то Git может его исправить. Можно указать Git конвертировать CRLF в LF во время коммита, но не наоборот, установив настройке core.autocrlf значение input :
$ git config --global core.autocrlf input
Такая конфигурация позволит вам использовать CRLF переносы строк в Windows, при этом в репозитории и системах Mac и Linux будет использован LF.
Если вы используете Windows и программируете только для Windows, то вы можете отключить описанный функционал задав значение false , сохраняя при этом CR символы в репозитории:
$ git config --global core.autocrlf false
core.whitespace
Git поставляется настроенным на обнаружение и исправление некоторых проблем с пробелами. Он в состоянии найти шесть основных проблем, обнаружение трёх из них включено по умолчанию, а трёх других — выключено.
Те, что включены по умолчанию — это blank-at-eol , что ищет пробелы в конце строки; blank-at-eof , что ищет пробелы в конце файла; и space-before-tab , что ищет пробелы перед символом табуляции в начале строки.
Те, что выключены по умолчанию — это indent-with-non-tab , что ищет строки с пробелами вначале вместо символа табуляции (и контролируется настройкой tabwidth ); tab-in-indent , что ищет символы табуляции в отступах в начале строки; и cr-at-eol , которая указывает Git на валидность наличия CR в конце строки.
Указав через запятую значения для настройки core.whitespace , можно сказать Git какие из этих опций должны быть включены. Чтобы отключить ненужные проверки, достаточно удалить их из строки значений или поставить знак — перед каждой из них. Например, чтобы включить все проверки, кроме space-before-tab , выполните команду (при этом trailing-space является сокращением и охватывает как blank-at-eol , так и blank-at-eof ):
$ git config --global core.whitespace \ trailing-space,-space-before-tab,indent-with-non-tab,tab-in-indent,cr-at-eol
Или можно указать только часть проверок:
$ git config --global core.whitespace \ -space-before-tab,indent-with-non-tab,tab-in-indent,cr-at-eol
Git будет искать указанные проблемы при выполнении команды git diff и пытаться подсветить их, чтобы вы могли исправить их перед коммитом. Так же эти значения будут использоваться во время применения патчей командой git apply . При применении патчей, можно явно указать Git информировать вас в случае нахождения проблем с пробелами:
$ git apply --whitespace=warn
Так же можно указать Git автоматически исправлять эти проблемы перед применением патча:
$ git apply --whitespace=fix
Эти настройки так же применяются при выполнении команды git rebase . Если проблемные пробелы попали в коммит, но ещё не отправлены в удалённую ветку, можно выполнить git rebase —whitespace=fix для автоматического исправления этих проблем.
Конфигурация сервера
Для серверной части Git не так много настроек, но есть несколько интересных, на которые стоит обратить внимание.
receive.fsckObjects
Git способен убедиться, что каждый объект, отправленный командой push , валиден и соответствует своему SHA-1-хешу. По умолчанию эта функция отключена; это очень дорогая операция и может привести к существенному замедлению, особенно для больших объёмов отправляемых данных или для больших репозиториев. Вы можете включить проверку целостности объектов для каждой операции отправки, установив значение receive.fsckObjects в true :
$ git config --system receive.fsckObjects true
Теперь, Git будет проверять целостность репозитория до принятия новых данных для уверенности, что неисправные или злонамеренные клиенты не смогут отправить повреждённые данные.
receive.denyNonFastForwards
Если вы перебазируете коммиты, которые уже отправлены, и попытаетесь отправить их снова или попытаетесь отправить коммит в удалённую ветку, в которой не содержится коммит, на который она указывает, то данные приняты не будут. В принципе, это правильная политика; но в случае перебазирования — вы знаете, что делаете и можете принудительно обновить удалённую ветку используя флаг -f для команды push .
Для запрета перезаписи истории установите receive.denyNonFastForwards :
$ git config --system receive.denyNonFastForwards true
Сделать то же самое можно другим способом — используя хук на стороне сервера, мы рассмотрим его немного позже. Этот подход позволяет более гибко настроить ограничения, например, запретить перезапись истории определённой группе пользователей.
receive.denyDeletes
Политику denyNonFastForwards можно обойти, удалив ветку и создав новую с таким же именем. Для предотвращения этого, установите receive.denyDeletes в значение true :
$ git config --system receive.denyDeletes true
Эта команда запретит удаление веток и тегов всем пользователям. Чтобы удалить ветку, придётся удалить все соответствующие ей файлы на сервере вручную. Куда более интересный способ — это настроить права пользователей, с ним вы познакомитесь в разделе Пример принудительной политики Git.
Где хранятся репозитории git
Для сложных проектов с множеством файлов следует использовать систему контроля версий (Version Control System, VCS). Она позволяет возвращать в предыдущее состояние как отдельные файлы, так и целый проект, сравнивать сделанные изменения, смотреть, кто и когда последним редактировал файл, являющийся источником проблемы, и многое другое. Наличие VCS в общем случае означает, что при сбое или потере файлов вы можете легко вернуться в рабочее состояние.
Многие разработчики в качестве метода контроля версий выбирают простое копирование файлов в другую папку с говорящими именами, например, датой создания. Этот подход крайне популярен в силу своей простоты, но при этом он ненадёжен. Можно легко забыть, в какой папке вы работаете, и случайно сделать запись не в тот файл или скопировать вовсе не те файлы, которые вы хотели.
Люди бились над этой проблемой и стали создавать различные локальные системы контроля версий. Затем возникла потребность совместной работы над одним проектом группой разработчиков. Системы стали усложняться. Появились централизованные системы контроля версий (Centralized Version Control System, CVCS). Они обладали единым сервером, содержащим все версии файлов, и набором клиентов, выгружающих файлы с сервера. На протяжении многих лет это было стандартом управления версиями. Таким является Subversion.
Такая схема имеет много преимуществ перед локальными системами контроля версий. Каждый разработчик, работающий над проектом, может узнать, чем занимаются его коллеги. Администраторы могут контролировать права допуска прочих сотрудников. Однако у этой схемы есть и серьезные недостатки. Центральный сервер может дать сбой и тогда любые взаимодействия невозможны. Вы не сможете сохранять вносимые изменения. При повреждении жесткого диска центральной базы данных и отсутствии нужных резервных копий теряется вся информация — вся история разработки проекта за исключением единичных снимков состояния, которые могут остаться на локальных компьютерах пользователей. Впрочем, та же самая проблема характерна и для локальных систем контроля версий — храня историю разработки проекта в одном месте, вы рискуете потерять все.
На смену им пришли распределённые системы контроля версий (Distributed Version Control System, DVCS). В DVCS (к примеру, Git, Mercurial, Bazaar или Darcs) клиенты не просто выгружают последние снимки файлов, они создают полную зеркальную копию репозитория. В случае выхода из строя одного из серверов его работоспособность можно восстановить, скопировав один из клиентских репозиториев. Каждая такая выгрузка сопровождается полным резервным копированием всех данных.
Основы Git
Главным отличием Git от любой другой системы контроля версий является восприятие данных. Большинство систем хранит информацию в виде списка изменений, связанных с файлами. Эти системы рассматривают хранимые данные как набор файлов и изменений, которые вносились в эти файлы в течение их жизни.
Git не воспринимает и не хранит файлы подобным образом. Для неё данные представляют собой набор снимков состояния миниатюрной файловой системы. Каждый раз, когда вы создаете новую версию или сохраняете состояние проекта в Git, по сути, делается снимок всех файлов в конкретный момент времени и сохраняется ссылка на этот снимок. Для повышения продуктивности вместо файлов, которые не претерпели изменений, сохраняется всего лишь ссылка на их ранее сохраненные версии. Git воспринимает данные скорее как поток снимков состояния(stream of snapshots).
Для осуществления практически всех операций системе Git требуются только локальные файлы и ресурсы — в общем случае информация с других компьютеров сети не нужна. Например, для просмотра истории проекта системе Git нет нужды обращаться к серверу, получать там историю и выводить ее на экран — система просто читает все непосредственно из локальной базы данных. То есть вы видите историю проекта практически сразу же. Если вы хотите посмотреть, чем текущая версия файла отличается от версии месячной давности, Git ищет старый файл и вычисляет внесенные в него правки, вместо того чтобы просить об этой операции удаленный сервер или считывать с этого сервера старую версию файла для локального сравнения.
В системе Git для всех данных перед сохранением вычисляется контрольная сумма, по которой они впоследствии ищутся. То есть сохранить содержимое файла или папки таким образом, чтобы система Git об этом не узнала, невозможно. Эта функциональность встроена в Git на самом низком уровне и является неотъемлемым принципом ее работы. Невозможно потерять информацию или повредить файл скрытно от Git.
Механизм, которым пользуется Git для вычисления контрольных сумм, называется хешем SHA-1. Это строка из 40 символов, включающая в себя числа в шестнадцатеричной системе (0–9 и a–f) и вычисляемая на основе содержимого файла или структуры папки в Git. Хеш SHA-1 выглядит примерно так: 24b9da6552252987aa493b52f8696cd6d3b00373. Вы будете постоянно наталкиваться на эти хеш-значения, так как Git использует их повсеместно. По сути, Git сохраняет данные в базе не по именам файлов, а по хешу их содержимого.
Практически все операции в Git приводят к добавлению данных в базу. Систему сложно заставить выполнить неотменяемое действие или каким-то образом стереть данные. Как и при работе с любой VCS, незафиксированные данные можно потерять или повредить; но как только снимок состояния зафиксирован, потерять его становится крайне сложно, особенно если вы регулярно копируете базу в другой репозиторий. Это делает работу с Git крайне комфортной, так как можно экспериментировать, не опасаясь серьезно навредить проекту.
Файлы в Git могут находиться в трёх основных состояниях: зафиксированном, модифицированном и индексированном.
Зафиксированное(committed) состояние означает, что данные надежно сохранены в локальной базе. Модифицированное(modified) состояние означает, что изменения уже внесены в файл, но пока не зафиксированы в базе данных. Индексированное (staged) состояние означает, что вы пометили текущую версию модифицированного файла как предназначенную для следующей фиксации.
В результате Git-проект разбивается на три основные области: папка Git, рабочая папка и область индексирования.
Папка Git — это место, где Git хранит метаданные и объектную базу данных проекта. Это наиболее важная часть Git, которая копируется при дублировании репозитория (хранилища) с другого компьютера.
Рабочая папка — это место, куда выполняется выгрузка одной из версий проекта. Эти файлы извлекаются из сжатой базы данных в папке Git и помещаются на жесткий диск вашего компьютера, готовые к использованию или редактированию.
Область индексирования — это файл, обычно находящийся в папке Git и хранящий информацию о том, что именно войдет в следующую операцию фиксации. Иногда ее еще называют промежуточной областью.
Базовый рабочий процесс в Git выглядит так:
- Вы редактируете файлы в рабочей папке.
- Вы индексируете файлы, добавляя их снимки в область индексирования.
- Вы выполняете фиксацию, беря файлы из области индексирования и сохраняя снимки в папке Git.
При наличии конкретной версии файла в папке Git файл считается зафиксированным. Если после внесения изменений в файл он был перемещен в область индексирования, он называется проиндексированным. А отредактированный после выгрузки, но не проиндексированный файл называется модифицированным.
Командная строка
Использовать Git можно с помощью командной строки или графических интерфейсов. Для полного понимания Git рекомендуется изучить возможности командной строки, а потом по желанию можете использовать графический интерфейс.
Установка Git
Перед тем как приступить к работе с Git, эту систему следует установить на компьютер. Для Windows есть несколько способов установки.
Один из них — это установка GitHub для Windows. Пакет установки включает в себя версию как с командной строкой, так и с GUI. Он хорошо работает с оболочкой Powershell и обеспечивает надежное кэширование учетных данных и работоспособные настройки CRLF. Загрузить эту версию можно с сайта http://windows.github.com.
После установки на Рабочем столе появятся два ярлыка — Git Shell (для работы с командами Git в Powershell) и GitHub для работы с GitHub в графическом режиме.
После установки, нужно настроить ее окружение. Эта процедура проводится только один раз; при обновлениях все настройки сохраняются. Вы можете изменить их в любой момент, снова воспользовавшись указанными командами.
Второй вариант — пакет Git с сайта https://git-scm.com/. Включает несколько утилит командной строки — git-bash.exe и git-cmd.exe. Желательно использовать первый вариант.
Для других операционных систем существуют аналоги.
После установки в контекстном меню Рабочего стола и Проводника появятся пункты Git GUI Here и Git Bash Here.
Настройка
Для начала введём первую команду для получения версии Git.
git --version
Система Git поставляется с инструментом git config, позволяющим получать и устанавливать переменные конфигурации, которые задают все аспекты внешнего вида и работы Git. Эти переменные хранятся в разных местах.
В системах семейства Windows Git ищет файл .gitconfig в папке $HOME (в большинстве случаев она вложена в папку C:\Users\$USER). Кроме того, ищется файл /etc/gitconfig, но уже относительно корневого каталога, расположение которого вы сами выбираете при установке Git.
При установке Git первым делом следует указать имя пользователя и адрес электронной почты. Это важно, так как данную информацию Git будет включать в каждую фиксируемую вами версию, и она обязательно включается во все создаваемые вами коммиты (зафиксированные данные):
Передача параметра —global позволяет сделать эти настройки всего один раз, так как в этом случае Git будет использовать данную информацию для всех ваших действий в системе. Если для конкретного проекта требуется указать другое имя или адрес электронной почты, войдите в папку с проектом и выполните эту команду без параметра —global.
Соответственно, вы можете переключаться между разными пользователями, входя под нужным именем.
Проверить выбранные настройки позволяет команда git config —list, выводящая список всех обнаруженных в текущий момент параметров.
Некоторые ключи могут появляться более одного раза, так как Git считывает один и тот же ключ из разных файлов. В этом случае система использует последнее значение для каждого обнаруженного ею уникального ключа.
Можно проверить значение конкретного ключа, воспользовавшись командой git config [ключ]:
git config user.name
Существует три способа доступа к странице со справочной информацией по любой Git-команде:
git help [команда] git [команда] --help man git-[команда]
К примеру, справка по команде config открывается так:
git help config
Работа с Git
Будем учиться настраивать и инициализировать репозитории, начинать и прекращать слежение за файлами, индексировать и фиксировать изменения. Заодно узнаем, как заставить Git игнорировать отдельные файлы и их группы, как быстро и просто отменить ошибочные изменения, как посмотреть историю проекта и изменения, вносившиеся в каждую версию, как отправить файл в удаленный репозиторий и извлечь его оттуда.
Есть два подхода к созданию Git-проекта. Можно взять существующий проект или папку и импортировать в Git. А можно клонировать уже существующий репозиторий с другого сервера.
Инициализация репозитория в существующей папке
Чтобы начать слежение за существующим проектом, перейдите в папку этого проекта и введите команду:
git init
В результате в существующей папке появится еще одна папка с именем .git и всеми нужными вам файлами репозитория — это будет основа вашего Git-репозитория. По умолчанию вы можете не увидеть эту папку с файлами. Поэтому вручную введите полный путь к папке в Проводнике, чтобы открыть её (или включите показ скрытых папок и файлов в настройках).
Создайте в папке проекта какой-нибудь текстовый файл для опытов.
Пока контроль ваших файлов отсутствует. Чтобы начать управление версиями существующих файлов (в противовес пустому каталогу), укажите файлы, за которыми должна следить система, и выполните первую фиксацию изменений. Для этого потребуется несколько команд git add, добавляющих файлы, за которыми вы хотите следить, а затем команда git commit:
git add *.txt git add LICENSE git commit -m 'первоначальная версия проекта'
У нас появился первый репозиторий Git с добавленными туда файлами и первой зафиксированной версией.
Можно указывать конкретный файл вместо *.txt.
Клонирование существующего репозитория
Получение копии существующего репозитория, например проекта, в котором вы хотите принять участие, выполняется командой git clone. Вы получаете полную копию практически всех данных с сервера. Команда git clone по умолчанию забирает все версии всех файлов за всю историю проекта. Это означает, что при повреждении серверного диска практически любой клон на любом из клиентов может использоваться для возвращения сервера в состояние, в котором он пребывал до момента клонирования (при этом может быть утрачена часть хуков со стороны сервера, но все данные, относящиеся к версиям, будут на месте).
Клонирование репозитория осуществляется командой git clone [url]. К примеру, вот как клонируется подключаемая Git-библиотека libgit2:
git clone https://github.com/libgit2/libgit2
Команда создает папку с именем libgit2, инициализирует в ней папку .git, считывает из репозитория все данные и выгружает рабочую копию последней версии.
В папке libgit2 вы найдете все файлы проекта, подготовленные к работе. Репозиторий можно клонировать и в другое место, достаточно указать имя нужной папки в следующем параметре командной строки:
git clone https://github.com/libgit2/libgit2 mylibgit
Эта команда делает то же самое, что и предыдущая, но все файлы оказываются в папке mylibgit.
Для работы Git применяются разные транспортные протоколы. В предыдущем примере использовался протокол https://, но можно также встретить вариант git:// или user@server:path/to/repo.git. В последнем случае применяется протокол SSH.
Запись изменений в репозиторий
Итак, у вас есть настоящий Git-репозиторий и некая выгрузка, то есть рабочие копии файлов нашего проекта. Теперь в файлы можно вносить изменения и фиксировать их, как только проект достигнет состояния, которое вы хотели бы сохранить. Помните, что каждый файл в рабочей папке может пребывать в одном из двух состояний: отслеживаемом и неотслеживаемом. Первый случай — это файлы, входящие в последний снимок системы; они могут быть неизмененными, измененными и подготовленными к фиксации. Второй случай — это все остальные файлы рабочей папки, не вошедшие в последний снимок системы и не проиндексированные для последующей фиксации. После первого клонирования репозитория все файлы оказываются отслеживаемыми и неизмененными, потому что вы просто выгрузили их и пока не отредактировали.
Отредактированный файл Git рассматривает как измененный, ведь его состояние отличается от последнего зафиксированного. Вы индексируете эти измененные файлы, фиксируете все проиндексированные изменения, после чего цикл повторяется.
Проверка состояния файлов
Основным инструментом определения состояния файлов является команда git status. Непосредственно после клонирования она дает примерно такой результат:
$ git status On branch master nothing to commit, working tree clean
Это означает, что в рабочей папке отсутствуют отслеживаемые и измененные файлы. Кроме того, система Git не обнаружила неотслеживаемых файлов, в противном случае они были бы перечислены в выводимых командой данных. Наконец, команда сообщает имя ветки, на которой вы в данный момент находитесь, и информирует о совпадении состояний этой ветки и аналогичной ветки на сервере. Пока мы будем работать только с веткой master, предлагаемой по умолчанию.
Если отредактировать какой-нибудь файл и снова запустить команду, то ответ будет уже другим.
Предположим, вы добавили в проект простой файл README. Если до этого момента он не существовал, команда git status покажет данный неотслеживаемый файл примерно так:
$ echo 'My Project' > README $ git status On branch master Untracked files: (use "git add . " to include in what will be committed) README nothing added to commit but untracked files present (use "git add" to track)
Понять, что новый файл README является неотслеживаемым, можно по заголовку Untracked files в выводимых командой status данных. Указанное состояние, по сути, означает, что Git видит файл, отсутствующий в предыдущем снимке состояния (в коммите); без явного указания с вашей стороны Git не будет добавлять этот файл в число коммитов. Подобный подход гарантирует, что в репозитории не сможет случайно появиться сгенерированный бинарный файл или другие файлы, которые вы не собирались туда добавлять. Однако файл README туда добавить нужно, поэтому давайте сделаем его отслеживаемым.
Чтобы начать слежение за новым файлом, воспользуйтесь командой git add. К примеру, для файла README она будет выглядеть так:
git add README
Теперь команда status покажет, что этот файл является отслеживаемым и проиндексированным:
$ git status On branch master Changes to be committed: (use "git reset HEAD . " to unstage) new file: README
Все проиндексированные файлы перечисляются под заголовком Changes to be committed. Если в этот момент произвести фиксацию, версия файла, существовавшая на момент выполнения команды git add, попадет в историю снимков состояния. Надеюсь, вы помните, что за командой git init следовала команда git add (имена файлов), что заставило систему начать слежение за файлами в папке. Команда git add работает с маршрутом доступа к файлу или к папке; если указан путь к папке, команда рекурсивно добавляет все находящиеся в ней файлы.
Индексация изменённых файлов
Внесём изменения в файл, находящийся под наблюдением. Если отредактировать ранее отслеживаемый файл и воспользоваться командой git status, результат будет примерно таким:
$ git status On branch master Changes to be committed: (use "git reset HEAD . " to unstage) new file: README Changes not staged for commit: (use "git add . " to update what will be committed) (use "git checkout -- . " to discard changes in working directory) modified: cat.txt
Файл cat.txt появляется под заголовком Changed but not staged for commit — это означает, что отслеживаемый файл из рабочей папки был изменен, но пока не проиндексирован. Индексирование выполняется уже знакомой вам командой git add. Это многоцелевая команда, позволяющая начать слежение за новыми файлами, произвести индексирование файлов, а также пометить файлы с конфликтом слияния как разрешенные. Возможно, целесообразнее воспринимать эту команду как «добавление содержимого к следующему коммиту», а не как «добавление файла к проекту». Итак, воспользуемся командой git add для индексирования файла cat.txt, а затем запустим команду git status:
$ git add cat.txt $ git status On branch master Changes to be committed: (use "git reset HEAD . " to unstage) new file: README modified: cat.txt
Теперь оба файла проиндексированы и войдут в следующий коммит. Но предположим, что вы вспомнили про небольшое изменение, которое следует внести в файл cat.txt до его фиксации. Вы снова открываете файл, редактируете его, после чего все готово к фиксации. Но сначала еще раз воспользуемся командой git status:
Теперь утверждается, что файл одновременно является и проиндексированным, и непроиндексированным. Как такое может быть? Оказывается, Git индексирует файл в том состоянии, в котором он пребывал на момент выполнения команды git add. Если сейчас зафиксировать изменения, в коммит войдет версия файла, появившаяся после последнего запуска команды git add, а не версия, находившаяся в рабочей папке при запуске команды git commit. Редактирование файла после выполнения команды git add требует повторного запуска этой команды для индексирования самой последней версии файла.
Команда git status дает многословный результат. Существует флаг, позволяющий получить сведения в более компактной форме — git status -s или git status —short.
Рядом с именами новых неотслеживаемых файлов будет стоять знак . новые файлы, добавленные в область предварительной подготовки, помечаются буквой A, а модифицированные файлы — буквой M и т. п. Пометки выводятся в два столбца: в первом указывается, индексирован ли файл, а во втором — вносились ли в него изменения.
Игнорирование файлов
Бывает так, что некоторый класс файлов вы не хотите ни автоматически добавлять в репозиторий, ни видеть в списке неотслеживаемых. В эту категорию, как правило, попадают автоматически генерируемые файлы, например журналы регистрации или файлы, генерируемые системой сборки. В подобных случаях создается файл .gitignore со списком соответствующих паттернов. Вот пример такого файла:
$ cat .gitignore *.[oa] *~
Первая строка заставляет Git игнорировать любые файлы, заканчивающиеся на «.o» или «.a», — объектные и архивные файлы, которые могут появляться в процессе сборки кода. Вторая строка предписывает игнорировать файлы, заканчивающиеся на тильду (~). Этим значком многие текстовые редакторы, в том числе Emacs, обозначают временные файлы. В этот список можно включить также папки log, tmp или pid, автоматически генерируемую документацию и т. п. Работу всегда имеет смысл начинать с настройки файла .gitignore, так как это защищает от случайного добавления в репозиторий файлов, которые там не нужны.
Правила для паттернов, которые можно вставлять в файл .gitignore:
- Игнорируются пустые строки и строки, начинающиеся с символа #
- Работают стандартные глобальные паттерны
- Паттерны можно заканчивать слешем (/), указывая папку
- Можно инвертировать паттерн, начав его с восклицательного знака (!)
Глобальные паттерны напоминают упрощенные регулярные выражения, используемые интерпретаторами команд. Звездочка (*) замещает произвольное число символов, запись [abc] соответствует любому символу из указанных в скобках (в данном случае это символ a, b или c), знак вопроса (?) замещает собой один символ, а разделенные дефисом символы в квадратных скобках ([0-9]) совпадают с любым символом из указанного диапазона (в данном случае от 0 до 9). Кроме того, две звездочки применяются для обозначения вложенных папок; запись a/**/z может означать a/z, a/b/z, a/b/c/z и т. д.
Вот еще один пример файла .gitignore:
# комментарий – это игнорируется *.a # пропускать файлы, заканчивающиеся на .a !lib.a # но отслеживать файлы lib.a, несмотря на пропуск файлов на .a /TODO # игнорировать только корневой файл TODO, а не файлы вида subdir/TODO build/ # игнорировать все файлы в папке build/ doc/*.txt # игнорировать doc/notes.txt, но не doc/server/arch.txt
Книги
Git для профессионального программиста — авторы книги имеют непосредственное отношение к GitHub и детально рассказывают о возможностях Git.