20. Переміщення файлів

Цілі

  • Навчитися переміщати файли в межах репозиторія.

Я задоволений нашими змінами CSS, але є лише одна річ, яку я хотів би вирішити, перш ніж ми зіллємо наші зміни в main. Давайте перейменуємо файл hello.html на index.html. Також перемістимо наш файл стилів у окрему директорію css.

01 Перегляд історії змін конкретного файлу

Git дозволяє переглядати історію змін певного файлу. Подивімося історію змін файлу hello.html перед тим, як його перейменувати.

Виконайте

git log hello.html
git log style.css

Результат

$ git log hello.html
903eb1d 2023-11-28 | Included stylesheet into hello.html (HEAD -> style) [Alexander Shvets]
9288a33 2023-11-28 | Added copyright statement with email (main) [Alexander Shvets]
b7614c1 2023-11-28 | Added HTML header (tag: v1) [Alexander Shvets]
46afaff 2023-11-28 | Added standard HTML page tags (tag: v1-beta) [Alexander Shvets]
78433de 2023-11-28 | Added h1 tag [Alexander Shvets]
5836970 2023-11-28 | Initial commit [Alexander Shvets]
$ git log style.css
555372e 2023-11-28 | Added css stylesheet [Alexander Shvets]

02 Перегляд різниці між версіями певного файлу

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

Команда show використовується для перегляду змін у конкретному коміті. Давайте подивимося зміни у файлі hello.html в коміті з тегом v1 (ви можете використовувати будь-яке посилання на коміт, наприклад, позначку HEAD, хеш коміту, назву тегу або гілки тощо).

Виконайте

git show v1

Результат

$ git show v1
b7614c1 2023-11-28 | Added HTML header (tag: v1) [Alexander Shvets]

diff --git a/hello.html b/hello.html
index 6da0629..0d576c4 100644
--- a/hello.html
+++ b/hello.html
@@ -1,4 +1,6 @@
 <html>
+  <head>
+  </head>
   <body>
     <h1>Hello, World!</h1>
   </body>

03 Перейменуйте hello.html.

Як бачите, дуже зручно мати можливість бачити історію змін певного файлу. Але коли ви перейменовуєте або переміщуєте щось, є ризик втратити цю історію, якщо ви виконаєте цю операцію неправильно.

Давайте перейменуємо наш файл hello.html на index.html за допомогою стандартної команди mv і подивимося, що станеться.

Виконайте

mv hello.html index.html
git status

Результат

$ mv hello.html index.html
$ git status
On branch style
Changes not staged for commit:
  (use "git add/rm <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
	deleted:    hello.html

Untracked files:
  (use "git add <file>..." to include in what will be committed)
	index.html

no changes added to commit (use "git add" and/or "git commit -a")

Git розуміє нашу зміну так, ніби файл було видалено і створено новий. Це тривожний знак. Нам потрібно повідомити Git, що ми саме перейменували файл, а не видалили та створили новий. Але в простих ситуаціях Git сам зрозуміє, що файл було перейменовано, щойно ми додамо його до індексу:

Виконайте

git add .
git status

Результат

$ git add .
$ git status
On branch style
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
	renamed:    hello.html -> index.html

Бачите, файл вказано як перейменований. Однак це Git просто намагається виглядати розумним. Це не завжди спрацьовує. Наприклад, якщо ви перейменували та змінили декілька файлів, Git може не розібратися, що саме було перейменовано. У цьому випадку ви можете втратити інформацію про історію файлу перед перейменуванням, оскільки файл буде вважатися щойно доданим.

04 Безпечне переміщення файлу `style.css

У більшості операційних систем перейменування і переміщення файлів — це одне і те ж саме. Отже, давайте перемістимо наш файл style.css до директорії css, але цього разу зробимо це безпечно за допомогою команди git mv. Ця команда гарантує, що переміщення буде записано в історії Git як переміщення.

Виконайте

mkdir css
git mv style.css css/style.css
git status

Результат

$ mkdir css
$ git mv style.css css/style.css
$ git status
On branch style
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
	renamed:    style.css -> css/style.css
	renamed:    hello.html -> index.html

Давайте закомітимо наші зміни і перевіримо історію змін у файлі css/styles.css. Нам потрібно буде додати опцію --follow, щоб побачити історію файлу до того, як він був переміщений. Запустимо обидва варіанти команди, щоб побачити різницю.

Виконайте

git commit -m "Renamed hello.html; moved style.css"
git log css/style.css
git log --follow css/style.css

Результат

$ git commit -m "Renamed hello.html; moved style.css"
[style 0ee0113] Renamed hello.html; moved style.css
 2 files changed, 0 insertions(+), 0 deletions(-)
 rename style.css => css/style.css (100%)
 rename hello.html => index.html (100%)
$ git log css/style.css
0ee0113 2023-11-28 | Renamed hello.html; moved style.css (HEAD -> style) [Alexander Shvets]
$ git log --follow css/style.css
0ee0113 2023-11-28 | Renamed hello.html; moved style.css (HEAD -> style) [Alexander Shvets]
555372e 2023-11-28 | Added css stylesheet [Alexander Shvets]