Відстеження змін
Останнє оновлення 2025-01-24 | Редагувати цю сторінку
Приблизний час: 20 хвилин
Огляд
Питання
- Як зберегти зміни в Git?
- Як перевірити стан свого репозиторію?
- Як зробити нотатки про те, які зміни було внесено і чому?
Цілі
- Пройти цикл зміни-додавання-коміту для одного або декількох файлів.
- Пояснити де зберігається інформація на кожному етапі цього циклу.
- Пояснити різницю між інформативними та неінформативними повідомленнями комітів.
Спочатку переконаймося, що ми все ще у правильному каталозі. Ви
повинні знаходитися у каталозі recipes
.
Тепер створимо файл під назвою guacamole.md
з нашим
рецептом. Ми будемо використовувати редактор nano
для
редагування файлу; ви можете використовувати будь-який редактор, який
вам подобається. Зокрема, це не обовʼязково повинен бути
core.editor
, який ви раніше вказали глобально. Але
пам’ятайте, що команда bash для створення або редагування нового файлу
буде залежати від обраного редактора (який не обов’язково буде
nano
). Для довідки щодо текстових редакторів, дивіться “Which
Editor?” в уроці The Unix
Shell.
Введіть наведений нижче текст у файл guacamole.md
:
ВИХІД
# Guacamole
## Ingredients
## Instructions
Збережіть файл і вийдіть з редактора. Далі переконайтеся, що файл був
створений належним чином, запустивши команду ls
:
ВИХІД
guacamole.md
guacamole.md
містить три рядки, які ми можемо побачити,
запустивши:
ВИХІД
# Guacamole
## Ingredients
## Instructions
Якщо ми знову перевіримо статус нашого проєкту, Git повідомляє нам, що він помітив новий файл:
ВИХІД
On branch main
No commits yet
Untracked files:
(use "git add <file>..." to include in what will be committed)
guacamole.md
nothing added to commit but untracked files present (use "git add" to track)
Повідомлення “untracked files” означає, що в каталозі існує файл,
який Git не відстежує. Ми можемо повідомити Git, що цей файл треба
відстежувати за допомогою команди git add
:
та згодом переконатися, що все виглядає правильно:
ВИХІД
On branch main
No commits yet
Changes to be committed:
(use "git rm --cached <file>..." to unstage)
new file: guacamole.md
Git тепер знає, що він повинен стежити за файлом
guacamole.md
, але він ще не записав ці зміни як коміт. Щоб
зробити це, нам потрібно виконати ще одну команду:
ВИХІД
[main (root-commit) f22b25e] Create a template for recipe
1 file changed, 1 insertion(+)
create mode 100644 guacamole.md
Коли ми запускаємо git commit
, Git бере все, що ми
раніше запросили його зберегти за допомогою git add
, та
зберігає постійну копію цих змін у спеціальному каталозі
.git
. Ця постійна копія називається commit (або revision). У цьому прикладі коміт має
скорочений ідентифікатор f22b25e
. У вашого коміту може бути
інший ідентифікатор.
Ми використовуємо команду -m
(від “message”) щоб надати
короткий, інформативний та конкретний коментар, який допоможе нам
згадати пізніше про те, що ми зробили та чому. Якщо ми просто запустимо
git commit
без опції -m
, Git запустить
nano
(або будь-який інший редактор, який ми вказали як
core.editor
), щоб ми могли написати довше повідомлення.
Гарні повідомлення
комітів починаються з короткого (< 50 символів) тексту про зміни,
внесені в коміт. Загалом, повідомлення має завершувати речення “If
applied, this commit will”
Якщо ми тепер запустимо git status
:
ВИХІД
On branch main
nothing to commit, working tree clean
Git говорить нам, що поточний стан файлів відповідає їх стану, який
збережений у репозиторії. Якщо ми хочемо знати, що саме ми зробили
нещодавно - ми можемо попросити Git показати нам історію проєкту,
використовуючи git log
:
ВИХІД
commit f22b25e3233b4645dabd0d81e651fe074bd8e73b
Author: Alfredo Linguini <a.linguini@ratatouille.fr>
Date: Thu Aug 22 09:51:46 2013 -0400
Create a template for recipe
git log
виводить перелік усіх комітів, які були внесені
до репозиторію, у зворотному хронологічному порядку. Для кожного коміту
буде надруковано повний ідентифікатор коміту (який починається з тих же
символів, що і скорочений ідентифікатор, попередньо надрукований
командою git commit
), автор коміту, дата його створення, і
повідомлення Git, яке було додано під час запису коміту.
Де зберігаються мої зміни?
Якщо ми тепер запустимо ls
, ми все одно побачимо лише
один файл, який називається guacamole.md
. Це відбувається
тому, що Git зберігає інформацію про історію файлів у спеціальному
каталозі .git
, згаданому раніше, щоб наша файлова система
не засмічувалася (і щоб ми випадково не могли змінити або видалити стару
версію).
Тепер припустимо, що Альфредо додає нову інформацію до файлу. (Знову
ж таки, ми будемо редагувати його за допомогою nano
, і
потім перевіряти його зміст за допомогою cat
; ви можете
користуватися іншим редактором, та можете не використовувати
cat
.)
ВИХІД
# Guacamole
## Ingredients
* avocado
* lemon
* salt
## Instructions
Тепер, коли ми запускаємо git status
, Git повідомляє
нам, що файл, про який він вже знає, був змінений:
ВИХІД
On branch main
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: guacamole.md
no changes added to commit (use "git add" and/or "git commit -a")
Ключова фраза - це останній рядок: “no changes added to commit”. Ми
змінили цей файл, але ми ще не зберегли їх (що ми робимо за допомогою
git commit
), та навіть не сказали Git, що ми маємо намір
зберегти ці зміни у майбутньому (що ми робимо за допомогою
git add
). Тож зробімо це зараз. Хорошою рекомендацією є
перегляд наших змін кожного разу перед їх збереженням. Це робиться за
допомогою git diff
. Результат показує нам відмінності між
поточним станом файлу та його останньою збереженою версією:
ВИХІД
diff --git a/guacamole.md b/guacamole.md
index df0654a..315bf3a 100644
--- a/guacamole.md
+++ b/guacamole.md
@@ -1,3 +1,6 @@
# Guacamole
## Ingredients
+* avocado
+* lemon
+* salt
## Instructions
Результат цієї команди важко зрозуміти, тому що це насправді серія
команд для таких інструментів, як редактори або patch
, яка
повідомляє їм, як змінити один файл за допомогою іншого. Якщо розділити
цей результат на фрагменти:
- Перший рядок вказує на те, що результат цієї команди у Git подібний
до Unix команди
diff
, яка порівнює стару та нову версії файлу. - Другий рядок повідомляє які саме версії файлу Git порівнює;
df0654a
та315bf3a
є унікальними ідентифікаторами цих версій. - Третій та четвертий рядки ще раз показують назву файлу, що змінюється.
- Решта рядків найцікавіші, вони показують нам фактичні відмінності і
рядки, у яких вони відбуваються. Зокрема, значок
+
в першому стовпці вказує де ми додали рядок.
Після того, як ми переглянули наші зміни, прийшов час зберегти їх:
ВИХІД
On branch main
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: guacamole.md
no changes added to commit (use "git add" and/or "git commit -a")
Але це не спрацює: Git не буде додавати зміни, тому що ми не
використали спочатку git add
. Давайте це виправимо:
ВИХІД
[main 34961b1] Add basic guacamole's ingredient
1 file changed, 3 insertions(+)
Git наполягає, щоб ми додали файли до набору змін, які ми хочемо записати, перед тим як ми зробимо коміт. Це дозволяє зберігати зміни поступово та обʼєднувати їх у логічні блоки, аніж у великі набори змін. Наприклад, припустимо, ми робимо коміт кількох цитат відповідних досліджень у нашій дисертації. Можливо, ми бажаємо зберегти ці зміни, та відповідні записи у бібліографії, але не зберігати деякі інші зміни в нашій роботі (наприклад, висновок, який ми ще не закінчили).
Щоб це було можливо зробити, Git має спеціальну зону стейджингу (staging area), де він відстежує речі, які були додані до поточного набору змін (changeset) проте, ще не були збережені.
Зона стейджингу (staging area)
Якщо ви будете уявляти, ніби Git робить знімки змін протягом життя
проєкту, то git add
вказує що буде на знімку (додаючи речі
в зоні стейджингу), а git commit
після того насправді
робить знімок, та назавжди зберігає його (як коміт). Якщо у зоні
стейджингу нічого немає, то коли ви введете git commit
, Git
запропонує вам використати git commit -a
або
git commit --all
, який ніби збирає разом всіх, щоб зробити
групове фото! Однак майже завжди краще явним чином додати речі до зони
стейджингу, тому що без цього ви можете випадково зберегти інші зміни,
про які ви забули. (Повертаючись до порівняння з груповим фото, якщо ви
використали команду “-а”, до вашої фотографії може потрапити зайва
людина!) Тому додавайте речі в зону стейджингу власноруч - > в іншому
випадку вам може знадобитися шукати як використовувати “git undo commit”
частіше, ніж вам хотілося б!
Подивімося, як наші зміни у файлі проходять шлях від текстового редактора до зони стейджингу і далі у довгострокове зберігання. По-перше, ми покращимо наш рецепт, змінивши лимон на лайм:
ВИХІД
# Guacamole
## Ingredients
* avocado
* lime
* salt
## Instructions
ВИХІД
diff --git a/guacamole.md b/guacamole.md
index 315bf3a..b36abfd 100644
--- a/guacamole.md
+++ b/guacamole.md
@@ -1,6 +1,6 @@
# Guacamole
## Ingredients
* avocado
-* lemon
+* lime
* salt
## Instructions
Поки що все добре: ми замінили один рядок (позначений -
)
на новий рядок (позначений +
). Тепер помістімо цю зміну у
зону стейджингу та подивимося що після цього звітує
git diff
:
Результату немає: це виглядає ніби для Git немає різниці між тим, що вже було збережено назавжди та тим, що зараз міститься у робочій директорії. Проте, якщо ми зробимо наступне:
ВИХІД
diff --git a/guacamole.md b/guacamole.md
index 315bf3a..b36abfd 100644
--- a/guacamole.md
+++ b/guacamole.md
@@ -1,6 +1,6 @@
# Guacamole
## Ingredients
* avocado
-* lemon
+* lime
* salt
## Instructions
то ми побачимо різницю між останніми збереженими змінами та тими, які знаходяться в зоні стейджингу. Збережімо наші зміни:
ВИХІД
[main 005937f] Modify guacamole to the traditional recipe
1 file changed, 1 insertion(+)
Перевіримо наш статус:
ВИХІД
On branch main
nothing to commit, working tree clean
і подивимося на історію попередніх змін:
ВИХІД
commit 005937fbe2a98fb83f0ade869025dc2636b4dad5 (HEAD -> main)
Author: Alfredo Linguini <a.linguini@ratatouille.fr>
Date: Thu Aug 22 10:14:07 2013 -0400
Modify guacamole to the traditional recipe
commit 34961b159c27df3b475cfe4415d94a6d1fcd064d
Author: Alfredo Linguini <a.linguini@ratatouille.fr>
Date: Thu Aug 22 10:07:21 2013 -0400
Add basic guacamole's ingredients
commit f22b25e3233b4645dabd0d81e651fe074bd8e73b
Author: Alfredo Linguini <a.linguini@ratatouille.fr>
Date: Thu Aug 22 09:51:46 2013 -0400
Create a template for recipe
Порівняння з підсвіткою змінених слів у рядках
Інколи, наприклад, у випадку текстових документів, результат
diff
дуже важко зрозуміти. Саме тут
--color-words
опція для git diff
є надзвичайно
зручною, бо вона виділяє кольором змінені слова.
Перегляд історії змін за сторінками
Коли розмір результату git log
перевищує розмір вашого
екрану, git
використовує спеціальну програму “пейджер”, щоб
поділити результат на сторінки розміром з ваш екран. Після виклику
“пейджера”, ви помітите, що останній рядок на екрані - це
:
, замість звичайного запрошення командного рядка.
- Натисніть Q, щоб вийти з пейджеру.
- Натисніть пробіл, щоб перейти на наступну сторінку.
- Щоб шукати
some_word
на всіх сторінках, натисніть / і введітьsome_word
. Натисніть N для навігації між результатами пошуку.
Обмеження розміру зображуваної історії змін
Щоб запобігти випадку, коли git log
повністю займає ваш
термінал, ви можете обмежувати кількість комітів які відображує Git,
використовуючи опцію -N
, де N
- кількість
комітів які б ви бажали бачити на екрані. Наприклад, якщо ви бажаєте
побачити лише останній коміт, використовуйте команду
ВИХІД
commit 005937fbe2a98fb83f0ade869025dc2636b4dad5 (HEAD -> main)
Author: Alfredo Linguini <a.linguini@ratatouille.fr>
Date: Thu Aug 22 10:14:07 2013 -0400
Modify guacamole to the traditional recipe
Ви також можете зменшити кількість інформації, використовуючи опцію
--oneline
:
ВИХІД
005937f (HEAD -> main) Modify guacamole to the traditional recipe
34961b1 Add basic guacamole's ingredients
f22b25e Create a template for recipe
Ви також можете комбінувати опцію --oneline
з іншими
опціями. Наступна корисна комбінація використовує опцію
--graph
для графічного зображення історії комітів за
допомогою псевдографіки, вказуючи при цьому які коміти пов’язані з
поточним HEAD
, поточною гілкою main
, або іншими
обʼєктами у репозиторії’:
ВИХІД
* 005937f (HEAD -> main) Modify guacamole to the traditional recipe
* 34961b1 Add basic guacamole's ingredients
* f22b25e Create a template for recipe
Каталоги
Дві важливі речі, які ви повинні знати про каталоги в Git.
- Git не відстежує каталоги самостійно, тільки файли всередині них. Спробуйте власноруч:
Зауважте, наш новостворений порожній каталог cakes
не
зʼявляється в переліку невідстежуваних файлів, навіть якщо ми конкретно
додали його (через git add
) до нашого репозиторію.
Ось чому ви іноді бачите файли .gitkeep
в інших порожніх
каталогах. На відміну від .gitignore
, ці файли не є
особливими і їх єдиною метою є заповнити каталог, щоб Git додав його до
репозиторію. Насправді ви можете назвати такі файли до вашої
вподоби.
- Якщо ви створюєте каталог у вашому репозиторії Git і заповнюєте його файлами, ви можете додати всі файли в каталозі одразу:
Спробуйте власноруч:
Перш ніж рухатися далі, ми збережемо ці зміни.
Для повторення: коли ми хочемо додати зміни до нашого репозиторію,
спочатку нам потрібно додати змінені файли в зону стейджингу
(git add
) а потім зберегти заплановані зміни до репозиторію
(git commit
):
{alt=‘Два документи окремо
додаються до зони стейджингу за допомогою git add, а потім об’єднуються
в один коміт за допомогою git commit’}
Вибір повідомлення коміту
Яке з наступних повідомлень буде найдоречнішим для останнього коміту
до guacamole.md
?
- “Changes”
- “Changed lemon for lime”
- “Guacamole modified to the traditional recipe”
Відповідь 1 є недостатньо детальною, а мета коміту неясна; відповідь 2 дублює результат команди “git diff” яка покаже зміни, зроблені у цьому коміті; відповідь 3 - оптимальна: коротка, інформативна, та імперативна.
Збереження змін у Git
Яка(які) з наведених нижче команд збережуть зміни у файлі
myfile.txt
до мого локального Git репозиторію?
Створить коміт, лише якщо файли вже були у зоні стейджінгу.
Намагатиметься створити новий репозиторій.
Правильна відповідь: спочатку додайте файл до зони стейджингу, потім зробіть коміт.
Спробує записати коміт файлу з назвою “my recent changes” з повідомленням myfile.txt.
Коміт декількох файлів
Зона стейджингу може зберігати зміни в будь-якій кількості файлів, які ви хочете записати в один коміт.
- Додайте до
guacamole.md
текст про приблизну ціну інгредієнтів. - Створіть новий файл
groceries.md
зі списком товарів та їх цінами на різних ринках. - Додайте зміни в обох файлах до зони стейджінгу, та зробіть коміт цих змін.
Спочатку ми оновимо файли guacamole.md
та
groceries.md
:
ВИХІД
# Guacamole
## Ingredients
* avocado (1.35)
* lime (0.64)
* salt (2)
ВИХІД
# Market A
* avocado: 1.35 per unit.
* lime: 0.64 per unit
* salt: 2 per kg
Тепер ви можете додати обидва файли до зони стейджингу. Ми можемо зробити це однією командою:
Або кількома:
Тепер файли готові до коміту. Ви можете перевірити це за допомогою
git status
. Якщо ви готові зробити коміт, використайте:
ВИХІД
[main cc127c2]
Write prices for ingredients and their source
2 files changed, 7 insertions(+)
create mode 100644 groceries.md
Вправа: репозиторій з вашою автобіографією
- Створіть новий репозиторій Git на вашому компʼютері під назвою
bio
. - Напишіть три рядки своєї біографії у файлі під назвою
me.txt
, та зробіть коміт цих змін. - Змініть один з рядків та додайте четвертий рядок.
- Покажіть відмінності між оновленим файлом та його попередньою версією.
За потреби вийдіть з каталогу recipes
:
Створіть новий каталог bio
та перейдіть до нього:
Ініціалізуйте репозиторій Git:
Створіть файл me.txt
з вашою біографією, використовуючи
nano
або інший текстовий редактор. Коли будете готові,
додайте його до зони стейджингу та запишіть коміт до репозиторію:
Змініть файл як вказано (змініть один рядок, додайте четвертий
рядок). Для того, щоб показати зміни між оновленим файлом та його
попередньою версією, використайте git diff
:
Ключові моменти
-
git status
показує стан репозиторію. - Файли можуть зберігатися в робочому каталозі проєкту (де їх бачать користувачі), зоні стейджингу (де будується наступний коміт) і локальному репозиторії (де коміти зберігаються постійно).
-
git add
додає файли до зони стейджингу. -
git commit
зберігає все, що міститься у зоні стейджингу, як новий коміт у локальному репозиторії. - Повідомлення коміту треба складати так, щоб воно чітко описувало ваші зміни.