С.Чакон, Б.Штрауб - Git

Git - распределённая система управления версиями (Version Control System, VCS). Проект был создан Линусом Торвальдсом для управления разработкой ядра Linux, первая версия выпущена 7 апреля 2005 года.

Все изменения хранятся в так называемом хранилище - удаленный Git репозиторий.

Git умеет:

  • История разработки;
  • Права доступа к коду;
  • Конроль версий;

Три популярных решения (аналоги Git):

  • Git
  • SVN
  • Mercurial

Репозиторий - папка с файлами (в которой есть скрытая папка .git - содержится вся нужная служебная информация), в которой Git отслеживает изменения (добавление, удаление, изменение содержимого файла). Иногда отмечают еще и перенос файла (спорный момент, Git не отслеживает перенос - это частный случай переименования). Git не следит за пустыми папками, они для него не существуют. Если хотите добавить к своему проекту пустую папку, добавьте в неё и пустой файл (readme, например).

Установили Git. С чего начать?

Всего две настройки – ваше имя и почта:

$ git config --global user.name "Orkhan Alyshov"
$ git config --global user.email "orkhanalyshov@gmail.com"

Параметры установки окончаний строк:

git config --global core.autocrlf true
git config --global core.safecrlf true

Создаем репозиторий в пустой папке:

$ cd work
$ git init

В результате мы создали в нужной нам папке репозиторий – то есть служебную папку .git с необходимой информацией.

Добавим файл и посмотрим статус нашего репозитория:

$ git status
# On branch master
# No commits yet
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
# readme.txt
# nothing added to commit but untracked files present (use "git add" # to track)

Добавленный нами файл readme.txt не отслеживается (untracked) Git-ом. Однако Git его видит!

Для того, чтобы передать под контроль Git:

$ git add readme.txt

Снова посмотрим статус нашего репозитория:

$ git status
# On branch master
# No commits yet
# Changes to be committed:
# (use "git rm --cached <file>..." to unstage)
# new file: readme.txt

Теперь файл находится под управлением Git (… to be committed) и изменение, которое мы сделали (добавили файл) готово к фиксации.

В Git'е файлы могут находиться в одном из четырёх состояний:

  • неотслеживаемый (untracked)
  • не изменившийся, в индексе (unmodified)
  • изменившийся по сравнению с индексом (modified)
  • подготовленный для фиксации изменений (staged)

git add – универсальная команда:

  • Добавляет новый файл под контроль Git
  • Сообщает Git, что файл изменился и подготавливает изменения (индексирует файл)

git commit – фиксация изменений:

  • Фиксируются только те изменения, которые вы подготовили!
  • Используйте форму $ git commit –m "комментарий"
  • git rm FILE – удаляет файл из индекса и из рабочей папки
  • git rm --cached FILE – удаляет файл только из индекса Git
$ git commit -m "Добавлен новый файл readme.txt"
# [master (root-commit) 38b589e] Добавлен новый файл readme.txt
# 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 readme.txt

История

git log – просмотр коммитов (фиксаций изменений, истории)

$ git log
# commit 38b589ec019c6ea74f8346b1f7e35cd86b238ddd (HEAD -> master)
# Author: Orkhan Alyshov <orkhanalyshov@gmail.com>
# Date:   Sun Apr 15 10:24:43 2018 +0400
#    Добавлен новый файл readme.txt

git commit --amend – добавление изменений к последнему коммиту

$ git commit -m 'initial commit'
$ git add forgotten_file
$ git commit --amend

git reset HEAD - откат к последнему коммиту (отмена индексации)

git reset --hard <commit> - самая мощная и самая опасная команда – откат к указанному коммиту с потерей всех изменений!


Master - основная ветвь истории ваших изменений. Главная. И пока что для вас – единственная.

Remote

Работа с удаленными репозиториями:

git remote add NAME PATH
git remote
git remote –v
git remote show NAME

Fetch

Получение из удаленного репозитория информации, которой еще нет в локальном, например, ссылки на ветки, которых у нас еще нет. Внимание! Команда git fetch никак не изменяет наши файлы!

git fetch NAME

Checkout

Вообще эта команда применяется для переключения между ветками. Но мы ее используем для того, чтобы связать нашу ветку master и ветку master удаленного репозитория:

git checkout --track REMOTENAME/master

GitHub - платформа для совместной работы. Она позволяет: создавать свои репозитории в облаке, на сервере GitHub; удобно управлять ими; и многое другое...

Регистрируемся на github.com. Создаем репозиторий. При создании просим сразу создать в нём файл README (это упростит нам дальнейшую работу). Запоминаем адрес нашего репозитория (clone URL). Клонируем этот репозиторий к себе на компьютер:

git clone CLONE_URL PROJECT_FOLDER

В результате мы получаем у себя репозиторий, являющийся точной копией удалённого репозитория.

Отправляет наши наборы изменений на удалённый репозиторий:

git push

Не просто «достаёт» изменения, но и пытается применить изменения с удаленного репозитория к нашему (влить удаленную ветку в локальную):

git pull

Что такое «ветка»?

  • Репозиторий хранит в себе информацию о состояниях репозитория. Они называются «снапшоты»
  • Каждое состояние - это коммит. Коммит - это снапшот и данные об авторстве
  • Коммит снабжен указателями на его родительские коммиты:
    Ноль - если это первый коммит
    Один - если это «обычный»
    Несколько - в случае слияния изменений

Ветка в Git - это просто указатель на один из коммитов в истории.

При создании репозитория автоматически создается ветка master. Она (то есть указатель) автоматически сдвигается вперед при каждом коммите. Ветка master считается «основной» веткой, хотя это просто договоренность.

Создание новой ветки:

git branch testing

Эта команда создаст новую ветку testing. То есть создаст новый указатель на текущее состояние репозитория и даст ему имя testing.

Как переключиться на новую ветку?

git checkout testing

Слияние веток

Допустим, мы хотим объединить две ветки, слив изменения в одну.

git checkout master
git merge hotfix

В нашем случае ветки master и hotfix находятся на одной линии истории. И для их слияния достаточно просто «перемотать» историю вперед, это называется fast-forward. И кстати, ненужную ветку можно сразу удалить:

git branch -d hotfix

Лог всех изменений:

git reflog

В чем состоит отличие Git от Subversion?

Главное отличие Git от Subversion заключается в том, что Git - распределенная система контроля версий. Звучит ужасающе, но на практике это означает очень простую вещь. Каждый разработчик держит у себя на диске отдельный репозиторий. Обратите внимание - не копию репозитория, не некоторые бранчи, а тупо отдельный и при этом абсолютно полноценный репозиторий.

Пока мы работаем в рамках своего репозитория, все происходит в точности, как в Subversion. Мы коммитим и откатываем изменения, создаем, мержим и удаляем бранчи, разрешаем конфликты и тд. Помимо этого, предусмотрены команды для работы с репозиториями на удаленных машинах. Например, «git push» означает мерж локальных изменений в удаленный репозиторий, а «git pull» - наоборот, мерж изменений из удаленного репозитория в локальный. Обмен данными по сети обычно происходит с использованием протокола SSH.