falbar Как пользоваться GIT – разбираемся за 30 минут

Как пользоваться GIT – разбираемся за 30 минут

8 апреля 2018 Перевод Туториал 935 0

В последние годы 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

udalyonnye-repozitorii-i-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

vetvi-v-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, ещё больше полезных команд

prodvinutyj-uroven-git-eshhyo-bolshe-poleznyh-komand

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

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 файл онлайн.
Реклама
Комментариев еще не оставлено
no_avatar