Git за 30 хвилин

15 хв. читання

Git став особливо популярним за останні роки. Система контролю версіями використовується багатьма великими Open Source проектами, наприклад, Linux.

Початківці не рідко лякаються через загадкові команди і аргументи, які вимагає 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-клієнт, і емулятор командного рядка BASH
  • OS X: Найпростіший спосіб - встановити homebrew, а потім просто запустити brew install git з вашого терміналу

Якщо ви новачок, то графічний клієнт Git - ідеальний для вас варіант. Рекомендуємо GitHub Desktop або Sourcetree, але є ще багато інших чудових і безкоштовних додатків. Знати основні команди git все ж важливо, навіть якщо ви використовуєте GUI, тож в цьому туторіалі ми будемо фокусуватися на них.

2. Налаштування Git

Тепер, коли ми встановили git на наш комп'ютер, нам потрібно буде зробити деякі налаштування. Є багато опцій, з якими можна ще погратися, але спочатку про найголовніші з них: ім'я користувача та адреса електронної пошти. Відкрийте термінал і запустіть наступні команди:

$ 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_exercise, відкрийте новий термінал і введіть наступні команди:

$ cd Desktop/git_exercise/
$ git init

Командний рядок повинен відповісти наступним чином:

Initialized empty Git repository in /home/user/Desktop/git_exercise/.git/

Це означає, що наш репозиторій був успішно створений, але він все ще порожній. Тепер створіть простий текстовий файл hello.txt та збережіть його в папці git_exercise.

4. Перевірка статусу – git status

Git status - ще одна команда, яку необхідно знати. Вона повертає інформацію про поточний стан репозиторія: що нового, що змінилося тощо. Запуск 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

Наш файл тепер готовий до коміту. Статус також каже нам, що саме змінилося у файлах - в нашому випадку новий файл, але він може бути змінений або видалений, в залежності від того, що відбулося з ним з моменту останнього git add.

6. Внесення коміту – git commit

Коміт відображає стан нашого репозиторія у момент, коли він був зроблений. Це як знімок, до якого ми можемо повернутися і побачити, як усе було, коли ми його тільки зробили.

Для створення нового коміту нам потрібно мати принаймні одну зміну, додану до проміжної області (ми тільки що зробили це з git add), і виконати наступне:

$ git commit -m "Initial commit."

Це створить новий коміт з усіма змінами з проміжної області (додавання hello.txt). Частина з -m "Initial commmit" призначена для опису, який узагальнює усі зміни, які були зроблені користувачем. Рекомендовано часто робити коміти і писати змістовні коміт-повідомлення до них.

Дистанційні репозиторії

На даний момент наш коміт лише локальний - він існує тільки в папці _.git _. Хоча локальні репозиторії корисні самі по собі, не рідко ми хочемо поділитися своєю роботою і завантажити її на сервер або сервіс хостингу репозиторіїв.

1. Підключення до дистанційного репозиторія – git remote add

Для того, щоб завантажити щось на дистанційний репозиторій, нам подрібно встановити з ним зв'язок. У цьому туторіалі адресою нашого сховища буде https://github.com/codeguida/nolink. Ми рекомендуємо вам створити свій власний порожній репозиторій на GitHub, BitBucket або інших подібних сайтах. Реєстрація та налаштування може зайняти деякий час, але усі сервіси пропонують свої step-by-step гіди, щоб допомогти вам.

Для того, щоб зв'язати наш локальний репозиторій з репозиторієм на GitHub, ми запускаємо наступний рядок в терміналі:

# Це лише приклад. Замініть URI адресою вашого репозиторія.
$ git remote add origin https://github.com/codeguida/nolink.git

Проект може мати безліч дистанційних репозиторіїв одночасно. Для того, щоб відрізнити їх один від одного ми даємо їм різні назви. Традиційно основний дистанційний репозиторій в git називається origin.

2. Завантаження но сервер – git push

Час завантижити свої коміти на сервер. Цей процес називається push, і це робиться щоразу, коли ми хочемо оновити наш дистанційний репозиторій.

Команда git, яка це виконує, 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/codeguida/nolink.git
 * [new branch]      master -> master

Залежно від сервісу, який ви використовуєте, вам потрібно буде ідентифікувати себе перед завантаженням коміту. Якщо все було зроблено правильно, зайшовши на віддалений репозиторій у вашому браузері, ви помітите hello.txt.

3. Клонування репозиторія – git clone

Зараз, люди можуть бачити ваш віддалений репозиторій на GitHub. Але вони також можуть завантажити його локально і мати повністю робочу копію проекту за допомогою команди git clone:

$ git clone https://github.com/codeguida/nolink.git

Автоматично створюється новий локальний репозиторій, з github версією налаштованою як дистанційний репозиторій.

4. Отримання змін з серверу – git pull

Якщо ви зробили зміни у своєму репозиторії, люди можуть завантажити ці зміни за допомогою однієї команди - pull:

$ git pull origin master

From https://github.com/codeguida/nolink
 * branch            master     -> FETCH_HEAD
Already up-to-date.

Так як ніяких комітів не було після того, як ми клонували репозиторій, нема чого і завантажувати.

Гілки Git

Гілки

При розробці чогось нового, вважається гарною практикою працювати над копією оригінального проекту, яка називається гілкою. Гілки мають свою історію та ізолюють свої зміни одна від одної, поки ви не вирішите з'єднати їх. Це робиться по деяким причинам:

  • Вже працююча, стабільна версія коду не буде порушена
  • Багато додатків можуть бути безпечно розроблені одночасно різними людьми
  • Розробники можуть працювати на своїй власній гілці, без ризику зміни свого коду кимось іншим
  • Коли не впевнені, що краще. Кілька версій одного і того ж додатку можуть бути розроблені на окремих гілках, і потім порівнюватися

1. Створення нової гілки – git branch

За замовчуванням гілка будь-якого репозиторія називається master. Щоб створити додаткові гілки ми використовуємо команду git branch <ім'я>:

$ 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 більше не потрібна і може бути видалена.

git branch -d awesome_new_feature

Додатково

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

1. Перевірка різниці між комітами

Кожен коміт має унікальний ID у вигляді рядка цифр і символів. Щоб побачити список всіх комітів і їх ID, ми використовуємо 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 [коміт]:

$ 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 з [коміт з-] .. [коміт до]:

$ 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 і повернемо все у початковий стан. Для цього ми повинні знати ID коміту до якого ми хочемо повернутися, а також повний шлях до нашого файлу.

$ git checkout 09bd8cc1 hello.txt

3. Редагування коміту

Якщо ви помітили, що ви зробили помилку у вашому коміт-повідомленні, або ви забули додати файл після того, як зробили коміт, ви можете легко виправити це за допомогою git commit --amend. Це додасть все з останнього коміту в проміжну область для нового виправленого коміту.

Для більш складних виправлень, які знаходяться не в останньому коміті (або якщо ви вже завантажили свої зміни через push), можна використати git revert. Це дасть змогу взяти всі зміни, які були у коміті, відмінити їх, і створити новий комміт.

Новий коміт можна отримати через HEAD.

$ git revert HEAD

Для інших комітів краще використовувати ID.

$ git revert b10cc123

Коли ви повертаєтесь до старих комітів, майте на увазі, що виникає ризик отримати т.з. "конфлікти злиття". Це відбувається, коли файл змінюється через інший пізніший коміт, і тепер git не може знайти правильні рядки, до яких треба повернутися, так як їх там вже нема.

4. Вирішення конфлікту злиття

Крім сценарію, показаного в попередньому пункті, конфлікти регулярно з'являються при злитті гілок або отриманні змін (git pull). Іноді git автоматично обробляє конфлікти, але в інших випадках користувач повинен вирішити (і, як правило, ретельно підібрати), який код залишити, а який видалити.

Давайте розглянемо приклад, де ми намагаємося об'єднати дві гілки, ivan_branch і mukola_branch. Обидва Іван і Микола пишуть в тому ж файлі функцію, яка відображає всі елементи в масиві.

Іван використовує for-цикл:

// використання for-циклу для console.log.
for(var i=0; i < arr.length; i++) {
    console.log(arr[i]);
}

Миколі більше подобається forEach:

// використання forEach для console.log.
arr.forEach(function(item) {
    console.log(item);
});

Вони обидва комітять свій код на їх гілках. Тепер, якщо вони вирішать об'єднати дві гілки, то побачать таке повідомлення про помилку:

$ git merge mukola_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-циклу для console.log.
for(var i=0; i < arr.length; i++) {
    console.log(arr[i]);
}
=======
// використання forEach для console.log.
arr.forEach(function(item) {
    console.log(item);
});
>>>>>>> Commit Миколи.

Над ===== ми маємо нинішній HEAD коміт, і нижче конфліктуючий коміт. Таким чином, ми можемо ясно бачити відмінності, і вирішити, яка з версій краща, або написати нову гілку з потрібним нам результатом. У цій ситуації ми йдемо назад і переписуємо все, видаливши маркери, щоб дати знати git, що ми закінчили.

// не використовуючи for-цикл або forEach.
// використання Array.toString() для console.log.
console.log(arr.toString());

Коли все зроблено, потрібно зробити злиття комітів, щоб завершити процес.

$ git add -A
$ git commit -m "Array printing conflict resolved."

Як ви бачите цей процес досить виснажливий і може бути дуже важким у великих проектах. Більшість розробників вважають, що краще вирішувати дані конфлікти за допомогою GUI клієнту. Щоб запустити графічний клієнт використовують git mergetool.

5. Налаштування .gitignore

У більшості проектів є файли або цілі папки, які ми не хочемо комітити. Ми можемо зробити, щоб вони не були випадково включені в git add -A шляхом створення файлу .gitignore:

  1. Вручну створіть текстовий файл під назвою.gitignore і збережіть його в директорії вашого проекту.
  2. Всередині, напишіть назви файлів / директорій, які мають бути проігноровані, починаючи кожну назву з нового рядка.
  3. Сам .gitignore потрібно додати, закомітити і завантажити так само, як і будь-який інший файл у проекті.

Приклади файлів, які ігноруються:

  • лог-файли
  • інструменти для збірки
  • папка node_modules у проектах node.js
  • папки, створені IDE такі як Netbeans та IntelliJ
  • персональні записи розробника

.gitignore, який ігнорує файли, приведені вище, буде виглядати приблизно так:

*.log
build/
node_modules/
.idea/
my_notes.txt

Слеш в кінці деяких рядків попереджує, що це папка, і потрібно рекурсивно ігнорувати все те, що всередині неї.

Помітили помилку? Повідомте автору, для цього достатньо виділити текст з помилкою та натиснути Ctrl+Enter
Codeguida 5.9K
Приєднався: 8 місяців тому
Коментарі (1)
  1. p.s.

    GIT - це така штука, що можна вивчати все життя, таке враження що його придумав якийсь сатоші накамото :)

    Дякую за матеріал!

    1 місяць тому ·
    0
Щоб залишити коментар необхідно авторизуватися.

Вхід / Реєстрація