В последние годы GIT стремительно набрал популярность. Эта система управления версиями используется масштабными проектами с открытым исходным кодом, такими как Linux, с тысячами составных частей, большими и маленькими коллективами, отдельными разработчиками и даже студентами.
Начинающего учиться, как пользоваться GIT, часто пугают загадочные команды и их параметры, коими он изобилует. Но вам не нужно знать всё досконально, чтобы использовать GIT не вдаваясь в подробности. Вы можете начать с нескольких наиболее часто используемых функций, а затем медленно осваивать программу дальше. И это именно то, чему мы научимся сегодня. Начнем!
Основы основ работы с GIT
GIT - это определённый набор утилит командной строки, отслеживающих и записывающих изменения в файлах. При помощи его, возможно, восстанавливать предыдущие версии ваших программ, сравнивать, анализировать, совмещать изменения и многое другое. Такой процесс принято называть контроль версий. На сегодняшний день есть много систем контроля версий, выполняющих такую же работу. Вы могли уже слышать ранее о некоторых из них – SVN, Mercurial, Perforce, CVS, Bitkeeper.
GIT децентрализован, что означает его независимость от центрального сервера для сохранения старых версий ваших файлов. Он работает полностью локально, сохраняя данные в виде папки на вашем жестком диске, которая называется репозиторием. Но вы можете хранить копию репозитория так же и в «облаке» для взаимодействия между несколькими людьми, работающих над одним кодом. Как раз для таких целей используют GitHub и BitBucket.
1. Установка GIT
Установить GIT на ваш компьютер несложно:
Linux – просто откройте терминал и установите GIT через менеджер пакетов вашего дистрибутива. Команда для Ubuntu: sudo apt-get install git
;
Windows – можно воспользоваться установщиком на официально сайте или более лучший вариант GIT для Windows, так как он включает и графический клиент (GUI client), и эмулятор командной строки BASH;
OS X – легче всего воспользоваться homebrew и ввести команду brew install git
в вашем терминале.
Если же вам не хотеться возиться с консолью или терминалом, то можно установить себе графический клиент GIT. Вот два наиболее популярных Sourcetree и GitHub Desktop, если поискать, то можно найти и другие не менее хорошие, чем эти. Но не стоит забывать, что умение работать с GIT-командами является хорошей практикой и в некоторых случаях это гораздо удобней, потому в оставшейся части урока мы с фокусируемся именно на этом.
2. Первоначальная настройка GIT
Теперь, когда GIT установлен на ваш компьютер, нужно добавить несколько несложных настроек. И хотя их достаточно много, но мы собираемся указать только самое важное: ваше имя пользователя и email. Откройте терминал и введите следующие команды:
$ git config --global user.name "My Name"
$ git config --global user.email myEmail@example.com
Каждое действие, совершаемое в GIT, теперь будет подписано вашим именем и адресом электронной почты. Таким образом, пользователи всегда знают, кто что сделал, и вся работа станет более организованной и удобной.
3. Создание нового репозитория – git init
Как упоминалось ранее, GIT хранит свои файлы и историю непосредственно как папка в вашем проекте. Чтобы создать новый репозиторий, откройте терминал, укажите адрес директории проекта и введите команду git init
. Тем самым вы позволите GIT создать скрытый директорий .git для этой конкретной папки, в котором будут храниться история и конфигурация.
Для примера создайте папку на рабочем столе под названием git_exersice, откройте терминал и введите следующее:
$ cd Desktop/git_exercise/
$ git init
Командная строка должна ответить подобным образом:
Initialized empty Git repository in /home/user/Desktop/git_exercise/.git/
Это означает, что репозиторий успешно создан, но всё ещё пуст. А теперь создайте простой текстовый файл hello.txt и сохраните в папку git_exersice.
4. Проверка статуса – git status
GIT статус это ещё одна необходимая для изучения команда, которая возвращает информацию о текущем состоянии репозитория: всё ли сохранилось, что сохранилось нового, что поменялось и так далее. На команду git status
в нашем новом репозитории должен прийти такой ответ:
$ git status
On branch master
Initial commit
Untracked files:
(use "git add ..." to include in what will be committed)
hello.txt
Полученное сообщение показывает, что файл hello.txt не отслеживается. Это означает, что файл новый, и GIT ещё не знает, должен ли отслеживать вносимые в него изменения или же игнорировать. Для подтверждения файла следует его добавить в индекс.
5. Индексирование – git add
У GIT есть понятие «области индексирования». Его можно представить себе, как пустой холст для хранения изменений, которые вы хотели бы зафиксировать. Изначально область появляется пустой, но вы можете добавлять к ней файлы (или даже отдельные строки и части файлов) с помощью команды git add
и, наконец, всё сохранить (создать своеобразный «скриншот») с помощью git commit
.
В нашем случае у нас есть только один файл, поэтому его и добавим:
$ git add hello.txt
Если нам нужно добавить всё из каталога, мы можем воспользоваться командой:
$ git add –A
Вновь проверив статус, мы должны получить уже другой ответ:
$ git status
On branch master
Initial commit
Changes to be committed:
(use "git rm --cached ..." to unstage)
new file: hello.txt
Файл готов для сохранения (создания коммита)! Это сообщение о статусе также говорит нам, что было изменено в отношении файлов в области индексирования, в данном случае о появлении нового файла (new file), но файл может показываться как modified или deleted, в зависимости от действий с ним с момента прошлой команды git add
.
6. Сохранение изменений – git commit
Зафиксированные изменения показывают состояние репозитория в определённый момент времени. Как скриншот, с помощью которого мы просматриваем состояние вещей в прошлом.
Для создания новой сохранённой версии файлов нам нужно добавить как минимум одно изменение в область индексирования (мы только что это сделали с git add
) и ввести следующую команду:
$ git commit -m "Initial commit."
Эта команда создаст новый «скриншот» со всеми сделанными изменениями (включая hello.txt). Часть -m "Initial commmit"
– это краткий комментарий, написанный пользователем, к данной версии файлов. Хорошая привычка – регулярно фиксировать и всегда писать внятный комментарий.
Удалённые репозитории и GIT
Сейчас наша информация об изменениях храниться локально – она находиться в каталоге .git. Несмотря на то, что локальный репозиторий полезен сам по себе, во многих случаях мы захотим поделиться своей работой и разместить его на сервере.
1. Подключение к удалённому репозиторию – git remote add
Для того чтобы загрузить что-то в удалённый репозиторий, для начала нам нужно установить соединение с ним. Для этого урока наш адрес репозитория будет https://github.com/tutorialzine/awesome-project. Конечно лучше самому создать собственный пустой репозиторий на GitHub, BitBucket или другом сервисе. Регистрация и установка могут занять время, но все сервисы предлагают пошаговые инструкции в помощь вам.
Для соединения нашего локального репозитория с удалённым на GitHub, мы должны в терминале вести следующую строку:
$ git remote add origin https://github.com/tutorialzine/awesome-project.git
Один проект может иметь несколько удалённых репозиториев одновременно. Для их разделения нужно дать им разные имена. Традиционно основной удалённый GIT-репозиторий называют origin.
2. Загрузка на сервер – git push
Настало время для перемещения наших локальных GIT-записей на сервер. Этот процесс называется push, и он выполняется каждый раз, когда мы хотим обновить удалённый репозиторий.
Команда GIT для push, git push
, имеет два параметра – имя удалённого репозитория (мы назвали наш origin) и ветка для отправки (ветка по умолчанию для каждого удалённого репозитория – master).
$ git push origin master
Counting objects: 3, done.
Writing objects: 100% (3/3), 212 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To https://github.com/tutorialzine/awesome-project.git
* [new branch] master -> master
В зависимости от сервиса, используемого вами, необходимо пройти аутентификацию для push. Если все было сделано правильно, то когда вы зайдёте через веб-браузер в удаленный репозиторий, созданный ранее, там должен быть доступен hello.txt.
3. Клонирование репозитория – git clone
После клонирования другие люди смогут увидеть и изучить ваш удалённый репозиторий на GitHub. Также будет возможно загрузить его локально и иметь полную рабочую копию вашего проекта с командой git clone
:
$ git clone https://github.com/tutorialzine/awesome-project.git
Новый локальный репозиторий создаётся автоматически, с GitHub-версией, настроенной как удалённый репозиторий.
4. Получение изменений с сервера – git pull
Если вы обновите свой репозиторий, другие смогут загрузить внесённые изменения с командой pull.
$ git pull origin master
From https://github.com/tutorialzine/awesome-project
* branch master -> FETCH_HEAD
Already up-to-date.
Поскольку никто не сохранил в репозиторий новые версии файлов с момента клонирования, изменений для загрузки нет.
Ветви в GIT
При разработке новой версии программы лучше всего работать над копией исходного проекта, называемой ветвью. Ветви имеют свою собственную историю, а их изменения изолированы от основного репозитория до тех пор, пока вы не решите снова объединить их. Это делается по нескольким причинам:
- Исправная, стабильная версия кода не будет повреждена;
- Люди могут безопасно разрабатывать собственные версии отдельно друг от друга;
- Разработчики могут работать на своей ветви без опасения, что кто-то изменит их код;
- Когда разработчики не уверены, как сделать лучше, они могут работать над своими версиями в отдельных ветвях, а затем сравнить результаты между собой.
1. Создание новых ветвей – git branch
Ветвь по умолчанию для каждого репозитория называется master. Для создания другой используйте команду git branch <name>
.
$ git branch amazing_new_feature
Тем самым вы создаёте новую ветвь, на данном этапе одинаковую с master.
2. Смена ветвей – git checkout
Теперь, когда мы выполнили команду git branch
, мы получили доступ к двум опциям:
$ git branch
amazing_new_feature
* master
Master – текущая ветвь и помечена звёздочкой. Однако мы хотим работать над новыми замечательными версиями программы, поэтому нам нужно переключиться на другую ветвь. Это делается командой git checkout
с указанием одного параметра – ветвь для переключения.
$ git checkout amazing_new_feature
3. Объединение ветвей – git merge
Наша «новая версия» будет просто другим текстовым файлом под названием feature.txt. Мы создадим его, добавим и зафиксируем.
$ git add feature.txt
$ git commit -m "New feature complete."
Далее мы вернемся в ветвь master.
$ git checkout master
Теперь, если мы откроем наш проект в файловом менеджере, мы заметим, что feature.txt исчез. Это потому, что мы вернулись в master-ветвь, и здесь feature.txt так и не был создан. Чтобы перенести его сюда, нам нужно объединить две ветви вместе командой git merge
, применив изменения, сделанные в amazing_new_feature, к основной версии проекта.
$ git merge amazing_new_feature
Ветвь master обновлена, а ветвь awesome_new_feature branch больше не нужна и мы можем её удалить.
$ git branch -d amazing_new_feature
Продвинутый уровень GIT, ещё больше полезных команд
В последнем разделе урока мы рассмотрим другие, более сложные методы работы, которые с большой вероятностью могут пригодиться.
1. Просмотр отличий между сохранёнными версиями
Каждая зафиксированная версия программы имеет уникальный идентификационный номер в формате строки из чисел и символов. Для просмотра списка коммитов (сохранённых версий) с их идефикаторами мы можем использовать команду git log
:
$ git log
commit ba25c0ff30e1b2f0259157b42b9f8f5d174d80d7
Author: Tutorialzine
Date: Mon May 30 17:15:28 2016 +0300
New feature complete
commit b10cc1238e355c02a044ef9f9860811ff605c9b4
Author: Tutorialzine
Date: Mon May 30 16:30:04 2016 +0300
Added content to hello.txt
commit 09bd8cc171d7084e78e4d118a2346b7487dca059
Author: Tutorialzine
Date: Sat May 28 17:52:14 2016 +0300
Initial commit
Как видите, id-номера действительно длинные, но для работы с ними необязательно копировать строку полностью – нескольких первых символов обычно достаточно. Увидеть, что было изменено в каждой версии, позволяет команда git show [commit]
:
$ git show b10cc123
commit b10cc1238e355c02a044ef9f9860811ff605c9b4
Author: Tutorialzine
Date: Mon May 30 16:30:04 2016 +0300
Added content to hello.txt
diff --git a/hello.txt b/hello.txt
index e69de29..b546a21 100644
--- a/hello.txt
+++ b/hello.txt
@@ -0,0 +1 @@
+Nice weather today, isn't it?
Просмотреть отличия двух любых коммитов можно с помощью команды git diff
с указанием на требуемые версии: [commit-from]..[commit-to].
$ git diff 09bd8cc..ba25c0ff
diff --git a/feature.txt b/feature.txt
new file mode 100644
index 0000000..e69de29
diff --git a/hello.txt b/hello.txt
index e69de29..b546a21 100644
--- a/hello.txt
+++ b/hello.txt
@@ -0,0 +1 @@
+Nice weather today, isn't it?
Мы сравнили первый коммит с последним и увидели все изменения, когда-либо внесённые. Обычно это проще сделать, используя команду git difftool
, которая покажет все различия между началом и концом в графическом клиенте.
2. Возвращение файла в предыдущую версию
GIT позволяет нам вернуть любой выбранный файл назад в одно из сохранённых его состояний. Это делается через команду git checkout
, которую мы уже использовали для смены ветвей, но она также может переключать версии (достаточно часто в GIT одна команда используется для нескольких кажущихся совершенно не связанных между собой действий).
В следующем примере мы отменим абсолютно все изменения в файле hello.txt, сделанные после первой фиксации. Нам необходимо указать идентификатор версии, к которой мы хотим вернуться, а также полный путь к нашему файлу.
$ git checkout 09bd8cc1 hello.txt
3. Исправление коммита
Если вы заметили, что вы сделали опечатку в своей команде к сохранению, или вы забыли добавить файл, и заметили сразу после фиксации, вы можете легко исправить это с помощью команды git commit --amend
. Она добавит всё из последней версии обратно в область индексирования и попытается создать новую фиксацию. Это дает вам возможность исправить вашу неправильную команду или добавить дополнительные файлы в область индексирования.
Для корректировок потруднее, которые должны быть не в последней версии (или вы уже успели отправить свои изменения на сервер), используйте команду git revert
. Она отменит все изменения в этой фиксации и создаст новую, которая будет полностью противоположна исходной.
Ей может быть присвоено имя HEAD.
$ git revert HEAD
В подобных случаях лучше всего использовать id-номер.
$ git revert b10cc123
Во время возвращения к предыдущим версиям помните, что во время объединения есть большая вероятность конфликта. Такое случается, если файл был изменен в другой, более поздней фиксации, и теперь GIT не может найти правильные строки для возвращения, поскольку их больше нет.
4. Разрешение конфликтов объединения
Помимо сценария, описанного в предыдущем пункте, конфликты регулярно появляются при объединении ветвей или загрузки на сервер чужой работы. Иногда конфликты GIT устраняет автоматически, но в других случаях человек, имеющий дело с ними, должен решить (и обычно подбирать), какой код остается и что удаляется.
Давайте посмотрим на пример, где мы будем пытаться объединить две ветви, называющиеся john_branch и tim_branch. И Джон, и Тим записывают в одном и том же файле функцию, которая отображает все элементы в массиве.
Джон использует цикл for:
for(var i=0; i<arr.length; i++) {
console.log(arr[i]);
}
Тим же предпочёл forEach:
arr.forEach(function(item) {
console.log(item);
});
Они оба фиксируют свой код на собственных ветвях. Теперь, если они попытаются объединить эти две ветви, то увидят следующее сообщение об ошибке:
$ git merge tim_branch
Auto-merging print_array.js
CONFLICT (content): Merge conflict in print_array.js
Automatic merge failed; fix conflicts and then commit the result.
GIT не смог объединить ветви автоматически, так что разработчикам придётся вручную разрешить конфликт. Если они откроют файл с конфликтом, они увидят, что GIT пометил проблемные строки.
<<<<<<< HEAD
for(var i=0; i<arr.length; i++) {
console.log(arr[i]);
}
=======
arr.forEach(function(item) {
console.log(item);
});
>>>>>>> Tim's commit.
Выше черты из знаков «равно» мы видим текущую фиксацию HEAD и ниже -конфликтующую. Таким образом, мы можем четко видеть различия и решить, какая версия лучше, или же вовсе написать новую. В данной ситуации мы пойдём до последнего и перепишем все это, удаляя маркеры, чтобы GIT знал, что мы закончили.
console.log(arr.toString());
Как только всё будет отлажено, должна появиться объединённая фиксация.
$ git add -A
$ git commit -m "Array printing conflict resolved."
Как видите, процесс достаточно утомительный, а в больших проектах справиться с конфликтом может быть чрезвычайно трудно. Большинство разработчиков предпочитают разрешать конфликты с помощью графического клиента, значительно упрощающего действия. Для его запуска воспользуйтесь командой git mergetool
.
5. Настройка .gitignore
Во многих проектах присутствуют файлы или папки, которые мы не хотим фиксировать. Мы можем «железно» заблокировать их включение в наш git add –A
созданием файла .gitignore:
- Вручную создайте текстовый файл и назовите его .gitignore, сохраните в каталоге своего проекта;
- В файле пропишите имена всех файлов/каталогов, которые должны игнорироваться, каждое название с новой строки;
- .gitignore должен самостоятельно добавиться, зафиксироваться и отправиться на сервер, как любой другой файл в проекте.
Хорошие примеры игнорируемых файлов:
- лог-файлы;
- сборщик задач;
- папка node_modules в проектах node.js;
- папки, созданные такими IDE (интегрированные среды разработки), как Netbeans и IntelliJ;
- личные примечания разработчика.
Файл .gitignore блокирует всё вышеуказанное примерно подобным образом:
*.log
build/
node_modules/
.idea/
my_notes.txt
Слэш в конце некоторых строк сигнализирует, что это папка, и всё её содержимое рекурсивно игнорируется. Звёздочка выполняет свою обычную функцию универсального символа.
Заключение
Наш урок на тему того, как пользоваться GIT, подходит к концу. Мы старались преподнести вам лишь самую важную информацию так коротко и чётко, как это возможно.
GIT достаточно сложен и имеет кучу функций и трюков. Если вы хотите узнать больше, то ниже мы перечислили некоторые рекомендуемые обучающие ресурсы:
Официальная документация GIT, включая полную книгу и видеоуроки;
Получение прав GIT– коллекция уроков и статей Atlassian;
Список графических клиентов;
Памятка о GIT (PDF);
Создать .gitignore файл онлайн.