Content from Автоматизований контроль версій


Останнє оновлення 2024-06-04 | Редагувати цю сторінку

Огляд

Питання

  • Що таке контроль версій і навіщо його використовувати?

Цілі

  • Зрозуміти переваги автоматизованої системи контролю версій.
  • Зрозуміти основи функціонування автоматизованих систем контролю версій.

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

Comic: аспірант надсилає «FINAL.doc» своєму науковому керівнику. Декілька дедалі інтенсивніших та неприємних раундів обміну коментарями і версіями закінчуються файлом під назвою "FINAL_rev.22.comments49.corrections.10.#@$%HYDIDCOMETOGRADSCHOOL????.doc"
“notFinal.doc” Хорхе Чам, https://www.phdcomics.com

Ми всі були в цій ситуації раніше: здається непотрібним мати кілька майже ідентичних версій одного документа. Деякі текстові процесори дозволяють нам впоратися з цим трохи краще, наприклад, Microsoft Word може відстежувати зміни, Google Docs підтримує історію версій, а LibreOffice - запис та відображення змін.

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

Зміни зберігаються у послідовності

Якщо ви будете розглядати зміни, як щось окреме від самого документу, ви можете уявити собі процес «відтворення» різних наборів змін на базовому документі, який, зрештою, призведе до різних версій цього документа. Наприклад, два користувачі можуть робити незалежні набори змін в одному документі.

Різні версії можна зберегти

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

Різні версії можна обʼєднати

Система управління версіями - це інструмент, який відстежує ці зміни для нас, по суті створюючи різні версії наших файлів. Це дозволяє нам вирішити, які зміни будуть внесені до наступної версії (кожен запис цих змін називається коміт (commit)), і зберігає корисні метадані про зміни. Повна історія комітів для конкретного проєкту та їх метадані складають репозиторій (repository). Репозиторії, які знаходяться на різних комп’ютерах, можуть бути синхронізовані, що сприяє співпраці між різними людьми.

Давня історія систем управління версіями

Автоматизовані системи управління версіями не є чимось новим. Інструменти, такі як RCS, CVS, або Subversion існують з початку 1980-х років і використовуються багатьма великими компаніями. Однак багато з них зараз вважаються застарілими системами через різні обмеження у своїх можливостях. Більш сучасні системи, такі як Git та Mercurial, є розподіленими , що означає, що їм не потрібен централізований сервер для розміщення репозиторію. Ці сучасні системи також включають потужні інструменти злиття змін (merging), які дозволяють багатьом авторам працювати над одними й тими ж файлами одночасно.

Написання статті

  • Уявіть, що ви склали чудовий абзац для статті, яку ви пишете, але пізніше ви зіпсували його. Як би ви відродили попередню чудову версію вашого висновку? Чи можливо це взагалі?

  • Уявіть, що у вас є 5 співавторів. Як би ви відстежували зміни та коментарі, які вони вносять до вашої статті? Якщо ви використовуєте LibreOffice Writer або Microsoft Word, що станеться, якщо ви приймете зміни, внесені за допомогою опції Відстежувати зміни (“Track Changes”)? Чи будете ви мати історію цих змін?

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

  • Спільна робота над документами за допомогою традиційних текстових процесорів є громіздкою. Або кожен співробітник повинен працювати над документом послідовно (сповільнюючи процес написання), або ви повинні відправляти нову версію всім співробітникам і вручну додавати їх коментарі у документ. Режими ‘відстеження змін’ (‘track changes’) або ‘запису змін’ (‘record changes’) можуть зробити зміни більш помітними та спростити їх додавання, але як тільки ви погоджуєтесь прийняти зміни, ви втрачаєте їх історію. Після цього ви більше не будете знати хто запропонував цю зміну, чому вона була запропонована, або коли вона була додана до документа. Навіть текстові онлайн-процесори, такі як Google Docs або Microsoft Office Online, не вирішують повністю ці проблеми.

Ключові моменти

  • Контроль версій схожий на необмежене «undo».
  • Контроль версій також дозволяє багатьом людям працювати паралельно.

Content from Налаштування Git


Останнє оновлення 2024-06-04 | Редагувати цю сторінку

Огляд

Питання

  • Як треба налаштувати Git для його використання?

Цілі

  • Налаштувати git під час його першого використання на комп’ютері.
  • Зрозуміти значення опції конфігурації --global.

Коли ми користуємося Git на новому комп’ютері вперше, нам потрібно налаштувати декілька речей. Нижче наведено кілька прикладів з налаштувань, які ми зробимо, коли почнемо працювати з Git:

  • ваше ім’я та адреса електронної пошти,
  • ваш бажаний текстовий редактор,
  • а також те, що ми хочемо використовувати ці параметри глобально (тобто для кожного проєкту).

В командному рядку (command line), команди Git виглядають як git verb options, де verb - це те що ми фактично хочемо зробити, та options - це додаткова інформація, яка може бути потрібна для verb. Отже, ось як Dracula налаштовує свій новий ноутбук:

BASH

Вихід з Vim

Будь ласка, використовуйте своє власне ім’я та електронну пошту замість “Dracula”. Ці ім’я користувача та електронна пошта будуть асоційовані з вашою подальшою діяльністю Git, а це означає, що будь-які зміни надіслані в GitHub, BitBucket, GitLab або інший хост-сервер Git після цього уроку будуть містити цю інформацію.

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

Збереження конфіденційності вашої електронної адреси

Якщо ви вирішили приховати власну електронну адресу на GitHub, то використовуйте у user.email свою “no-reply” електронну адресу, яку GitHub повʼязує з вашим обліковим записом. Вона має вигляд, схожий на ID+username@users.noreply.github.com. Ви можете знайти цю адресу у налаштуваннях електронної пошти для вашого облікового запису GitHub.

Закінчення рядків

Як і з іншими клавішами, коли ви натискаєте на клавіатурі Enter або (або Return на комп’ютері Mac), ваш комп’ютер кодує це як символ. Різні операційні системи використовують різні символи для позначення кінця рядка. (Ви також можете почути, що їх називають новими рядками або розривами рядків.) Оскільки Git використовує ці символи для порівняння файлів, це може спричинити несподівані проблеми під час редагування файлу на різних машинах. Хоча це поза межами цього уроку, ви можете більше прочитати про це питання у книзі “Pro Git”.

Ви можете змінити спосіб, у який Git розпізнає та кодує закінчення рядків, використовуючи git config з аргументом core.autocrlf. Рекомендуються наступні налаштування:

Для macOS і Linux:

BASH

$ git config --global core.autocrlf input

Для Windows:

BASH

$ git config --global core.autocrlf true

Dracula також повинен налаштувати для використання з Git свій улюблений текстовий редактор, як наведено в таблиці нижче:

Редактор Команда конфігурації
Atom $ git config --global core.editor "atom --wait"
nano $ git config --global core.editor "nano -w"
BBEdit (Mac, з інструментами командного рядка) $ git config --global core.editor "bbedit -w"
Sublime Text (Mac) $ git config --global core.editor "/Applications/Sublime\ Text.app/Contents/SharedSupport/bin/subl -n -w"
Sublime Text (Windows, 32-бітна інсталяція) $ git config --global core.editor "'c:/program files (x86)/sublime text 3/sublime_text.exe' -w"
Sublime Text (Windows, 64-бітна інсталяція) $ git config --global core.editor "'c:/program files/sublime text 3/sublime_text.exe' -w"
Notepad (Windows) $ git config --global core.editor "c:/Windows/System32/notepad.exe"
Notepad++ (Windows, 32-бітна інсталяція) $ git config --global core.editor "'c:/program files (x86)/Notepad++/notepad++.exe' -multiInst -notabbar -nosession -noPlugin"
Notepad++ (Windows, 64-бітна інсталяція) $ git config --global core.editor "'c:/program files/Notepad++/notepad++.exe' -multiInst -notabbar -nosession -noPlugin"
Kate (Linux) $ git config --global core.editor "kate"
Gedit (Linux) $ git config --global core.editor "gedit --wait --new-window"
Scratch (Linux) $ git config --global core.editor "scratch-text-editor"
Emacs $ git config --global core.editor "emacs"
Vim $ git config --global core.editor "vim"
VS Code $ git config --global core.editor "code --wait"

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

Вихід з Vim

Зауважте, що Vim є редактором за замовчуванням для багатьох програм. Якщо ви раніше не користувалися Vim і бажаєте вийти із сеансу без збереження змін, натисніть Esc, потім введіть :q! і натисніть Enter або (або Return на Mac). Якщо ви хочете зберегти зміни та вийти, натисніть Esc, потім введіть :wq і натисніть Enter або (або Return на Mac).

Git (2.28+) дозволяє конфігурувати назву гілки, яка створюється під час ініціалізації будь-якого нового репозиторію. Dracula вирішив використати цю можливість, щоб назвати її main, щоб це відповідало налаштуванням у хмарному сервісі, який він зрештою використовуватиме.

BASH

$ git config --global init.defaultBranch main

Назва гілки Git за замовчуванням

Зміни у змісті репозиторію пов’язані з “гілкою”. Для початківців у цьому уроці буде достатньо знати, що гілки існують, і що в цьому уроці використовується тільки одна гілка.
За замовчуванням, коли ви створюєте новий репозиторій за допомогою git init, Git створить гілку під назвою master (як пояснюється в наступному епізоді). Цей термін нагадує про расистську практику людського рабства, і тому спільнота розробників програмного забезпечення перейшла до більш інклюзивної мови.

В 2020, більшість сервісів хостингу репозиторіїв Git перейшли до використання main як стандартної гілки. Наприклад, будь-який новий репозиторій, створений у GitHub і GitLab, за замовчуванням буде використовувати гілку main. Проте Git ще не зробив таких самих змін. Як наслідок, локальні репозиторії повинні бути налаштовані вручну, щоб мати ту саму назву головної гілки, що й більшість хмарних сервісів.

При використанні попередніх версій Git (до 2.28), зміни можуть бути внесені на рівні окремого репозиторію. Команда для цього знаходиться в наступному епізоді. Зауважте, що якщо це значення не встановлено у вашій локальній конфігурації Git, то init.defaultBranch за замовчуванням має значення master.

П’ять команд, які ми щойно запустили вище, потрібно виконати лише один раз: параметр --global повідомляє Git про налаштування для кожного проєкту у вашому обліковому записі користувача на цьому комп’ютері.

Погляньмо на ці налаштування і протестуємо core.editor прямо зараз:

BASH

$ git config --global --edit

Закриймо відкритий файл без внесення додаткових змін. Пам’ятайте, оскільки помилки у файлі конфігурації спричинять проблеми, безпечніше переглядати конфігурацію за допомогою

BASH

$ git config --list

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

Проксі-сервер

У деяких мережах потрібно використовувати проксі-сервер. Якщо це так, вам також може знадобитися повідомити про це Git:

BASH

$ git config --global http.proxy proxy-url
$ git config --global https.proxy proxy-url

Щоб вимкнути проксі, використовуйте

BASH

$ git config --global --unset http.proxy
$ git config --global --unset https.proxy

Довідка про Git та посібник користувача

Завжди пам’ятайте, що якщо ви забули підкоманди чи параметри команди git, ви можете отримати відповідний список параметрів, ввівши git <command> -h або подивитись документацію до Git, ввівши git <command> --help, наприклад:

BASH

$ git config -h
$ git config --help

Під час перегляду посібника пам’ятайте, що : — це підказка, яка вказує на очікування команди, і ви можете натиснути Q, щоб вийти з посібника.

Загалом, ви можете отримати список доступних команд git і подальші ресурси за допомогою цієї команди:

BASH

$ git help

Ключові моменти

  • Використовуйте git config з опцією --global, щоб налаштувати ім’я користувача, адресу електронної пошти, редактор та інші параметри. Це треба робити один раз для кожної машини.

Content from Створення репозиторію


Останнє оновлення 2024-06-04 | Редагувати цю сторінку

Огляд

Питання

  • Де Git зберігає інформацію?

Цілі

  • Створити локальний репозиторій Git.
  • Пояснити призначення каталогу .git.

Після налаштування Git ми можемо почати його використання.

Ми продовжимо нашу вигадану історію, у якій Wolfman та Dracula досліджують, чи можливо відправити планетарний посадковий модуль на Марс.

motivatingexampleWerewolf vs dracula by b-maze / Deviant Art. Mars by European Space Agency / CC-BY-SA 3.0 IGO. Pluto / Courtesy NASA/JPL-Caltech. Mummy © Gilad Fried / The Noun Project / CC BY 3.0. Moon © Luc Viatour / https://lucnix.be / CC BY-SA 3.0.

Перш за все, створімо новий каталог у каталозі Desktop для нашої роботи, а потім змінимо поточний робочий каталог на новостворений:

BASH

$ cd ~/Desktop
$ mkdir planets
$ cd planets

Потім ми кажемо Git зробити planets репозиторієм -- місцем, де Git може зберігати версії наших файлів:

BASH

$ git init

Важливо пам’ятати, що git init створить репозиторій, який може включати підкаталоги та їх файли—немає потреби створювати окремі репозиторії вкладені в репозиторій planets, незалежно від того чи були підкаталоги присутні від початку або були додані пізніше. Крім того, зверніть увагу, що створення каталогу planets та його ініціалізація як репозиторію є повністю окремими процесами.

Якщо ми використаємо ls, щоб передивитись зміст каталогу, то здається, що нічого не змінилося:

BASH

$ ls

Але якщо ми додамо опцію -a, щоб показати усе, то побачимо, що Git створив у каталозі planets прихований каталог під назвою .git:

BASH

$ ls -a

ВИХІД

.	..	.git

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

Далі, ми вкажемо, що гілка, яка використовується за замовчуванням, має назву main (залежно від ваших налаштувань і версії Git, вона може вже мати цю назву). Перегляньте епізод про налаштування, щоб дізнатися більше про цю зміну.

BASH

$ git checkout -b main

ВИХІД

Switched to a new branch 'main'

Ми можемо перевірити, що все налаштовано правильно, запитавши Git про стан нашого проєкту:

BASH

$ git status

ВИХІД

On branch main

No commits yet

nothing to commit (create/copy files and use "git add" to track)

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

Де створювати репозиторії Git

Разом із відстеженням інформації про планети (проєкт, який ми вже створили), Dracula також хотів би відстежувати інформацію про супутники. Попри занепокоєння Wolfman, Dracula створює проєкт moons всередині проєкту planets за допомогою наступної послідовності команд:

BASH

$ cd ~/Desktop   # повернутися до каталогу Desktop
$ cd planets     # перейти до каталогу planets, який вже є репозиторієм Git
$ ls -a          # перевірити, що підкаталог .git все ще присутній у каталозі planets
$ mkdir moons    # створити підкаталог planets/moons
$ cd moons       # перейти у підкаталог moons
$ git init       # створити репозиторій Git у підкаталозі moons
$ ls -a          # перевірити наявність підкаталогу .git, що підтверджує створення нового репозиторію

Чи потрібна команда git init, яка виконується в підкаталозі moons, для відстеження файлів, що зберігаються в підкаталозі moons?

Ні. Dracula не має необхідності робити підкаталог moons репозиторієм Git, тому що репозиторій planets може відстежувати будь-які файли, підкаталоги, та файли у підкаталогах, вкладені (на будь-якому рівні) у каталог planets. Таким чином, для того, щоб відстежувати всю інформацію про супутники, Dracula повинен був лише додати підкаталог moons до каталогу planets.

Крім того, репозиторії Git можуть заважати один одному, якщо вони “вкладені”: зовнішній репозиторій намагатиметься відстежувати зміни у внутрішньому репозиторії. Тому найкраще кожного разу створювати новий репозиторій Git в окремому каталозі. Щоб переконатися, що каталог не є репозиторієм, перевірте результат команди git status. Якщо він виглядає як показано нижче, ви можете створити новий репозиторій, як було показано вище:

BASH

$ git status

ВИХІД

fatal: Not a git repository (or any of the parent directories): .git

Виправлення помилок git init

Wolfman пояснив, як вкладений репозиторій є зайвим і може призвести до плутанини у майбутньому. Тепер Dracula хотів би видалити вкладений репозиторій. Як Dracula може скасувати свою останню команду git init виконану у підкаталозі moons?

Контекст

Видалення файлів з репозиторію Git слід виконувати з обережністю. Проте, ми ще не навчилися вказувати Git як відстежувати певний файл; про це ми дізнаємося в наступному епізоді. Файли, які не відстежуються Git, можна легко видалити, як і будь-які інші “звичайні” файли:

BASH

$ rm filename

Подібним чином каталог можна видалити за допомогою rm -r dirname або rm -rf dirname. Якщо файли чи каталоги, які видаляються таким чином, вже відстежуються Git, тоді їх видалення стає ще однією зміною, яку нам потрібно буде відстежувати (ми побачимо як це робити в наступному епізоді).

Відповідь

Git зберігає всі свої файли в каталозі .git. Щоб виправити цю маленьку помилку, Dracula може просто видалити каталог .git > в підкаталозі moons, виконавши наступну команду всередині каталогу planets:

BASH

$ rm -rf moons/.git

Проте, будьте обережні! Виконання цієї команди у неправильному каталозі призведе до видалення всієї історії змін проєкту, яку ви хотіли б зберегти. Тому завжди перевіряйте свій поточний каталог за допомогою команди pwd.

Ключові моменти

  • git init ініціалізує репозиторій.
  • Git зберігає всі дані репозиторію в каталозі .git.

Content from Відстеження змін


Останнє оновлення 2024-06-04 | Редагувати цю сторінку

Огляд

Питання

  • Як зберегти зміни в Git?
  • Як перевірити стан свого репозиторію?
  • Як зробити нотатки про те, які зміни було внесено і чому?

Цілі

  • Пройти цикл зміни-додавання-коміту для одного або декількох файлів.
  • Пояснити де зберігається інформація на кожному етапі цього циклу.
  • Пояснити різницю між інформативними та неінформативними повідомленнями комітів.

Спочатку переконаймося, що ми все ще у правильному каталозі. Ви повинні знаходитися у каталозі planets.

BASH

$ cd ~/Desktop/planets

Тепер створимо файл під назвою mars.txt, який буде містити деякі нотатки про придатність Марса як бази. Ми будемо використовувати редактор nano для редагування файлу; ви можете використовувати будь-який редактор, який вам подобається. Зокрема, це не обовʼязково повинен бути core.editor, який ви раніше вказали глобально. Але пам’ятайте, що команда bash для створення або редагування нового файлу буде залежати від редактора, який ви оберете (це може бути не nano). Для довідки щодо текстових редакторів, дивіться “Which Editor?” в уроці The Unix Shell.

BASH

$ nano mars.txt

Введіть наведений нижче текст у файл mars.txt:

ВИХІД

Cold and dry, but everything is my favorite color

Давайте спочатку перевіримо, що файл був правильно створений, запустивши команду ls:

BASH

$ ls

ВИХІД

mars.txt

mars.txt містить тільки один рядок, який ми можемо побачити, запустивши:

BASH

$ cat mars.txt

ВИХІД

Cold and dry, but everything is my favorite color

Якщо ми знову перевіримо статус нашого проєкту, Git повідомляє нам, що він помітив новий файл:

BASH

$ git status

ВИХІД

On branch main

No commits yet

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

	mars.txt

nothing added to commit but untracked files present (use "git add" to track)

Повідомлення “untracked files” означає, що в каталозі існує файл, який Git не відстежує. Ми можемо повідомити Git, що цей файл треба відстежувати за допомогою команди git add:

BASH

$ git add mars.txt

та згодом переконатися, що все виглядає правильно:

BASH

$ git status

ВИХІД

On branch main

No commits yet

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)

	new file:   mars.txt

Git тепер знає, що він повинен стежити за файлом mars.txt, але він ще не записав ці зміни як коміт. Щоб зробити це, нам потрібно виконати ще одну команду:

BASH

$ git commit -m "Start notes on Mars as a base"

ВИХІД

[main (root-commit) f22b25e] Start notes on Mars as a base
 1 file changed, 1 insertion(+)
 create mode 100644 mars.txt

Коли ми запускаємо git commit, Git бере все, що ми раніше запросили його зберегти за допомогою git add, та зберігає постійну копію цих змін у спеціальному каталозі .git. Ця постійна копія називається commit (або revision). У цьому прикладі коміт має скорочений ідентифікатор f22b25e. У вашого коміту може бути інший ідентифікатор.

Ми використовуємо команду -m (від “message”) щоб надати короткий, інформативний та конкретний коментар, який допоможе нам згадати пізніше про те, що ми зробили та чому. Якщо ми просто запустимо git commit без опції -m, Git запустить nano (або будь-який інший редактор, який ми вказали як core.editor), щоб ми могли написати довше повідомлення.

Гарні повідомлення комітів починаються з короткого (< 50 символів) тексту про зміни, внесені в коміт. Загалом, повідомлення має завершувати речення “If applied, this commit will” (“Якщо застосовано, цей коміт буде” <0>). Якщо ви хочете детальніше перейти до подробиць, додайте порожній рядок між першим рядком та вашими додатковими примітками. Використовуйте додаткові примітки, щоб пояснити, чому ви внесли зміни та/або яким буде їх вплив.

Якщо ми тепер запустимо git status:

BASH

$ git status

ВИХІД

On branch main
nothing to commit, working tree clean

Git говорить нам, що поточний стан файлів відповідає їх стану, який збережений у репозиторії. Якщо ми хочемо знати, що саме ми зробили нещодавно - ми можемо попросити Git показати нам історію проєкту, використовуючи git log:

BASH

$ git log

ВИХІД

commit f22b25e3233b4645dabd0d81e651fe074bd8e73b
Author: Vlad Dracula <vlad@tran.sylvan.ia>
Date:   Thu Aug 22 09:51:46 2013 -0400

    Start notes on Mars as a base

git log виводить перелік усіх комітів, які були внесені до репозиторію, у зворотному хронологічному порядку. Для кожного коміту буде надруковано повний ідентифікатор коміту (який починається з тих же символів, що і скорочений ідентифікатор, попередньо надрукований командою git commit), автор коміту, дата його створення, і повідомлення Git, яке було додано під час запису коміту.

Де зберігаються мої зміни?

Якщо ми тепер запустимо ls, ми все одно побачимо лише один файл, який називається mars.txt. Це відбувається тому, що Git зберігає інформацію про історію файлів у спеціальному каталозі .git, згаданому раніше, щоб наша файлова система не засмічувалася (і щоб ми випадково не могли змінити або видалити стару версію).

Тепер припустимо, що Dracula додає нову інформацію до файлу. (Знову ж таки, ми будемо редагувати його за допомогою nano, і потім перевіряти його зміст за допомогою cat; ви можете користуватися іншим редактором, та можете не використовувати cat.)

BASH

$ nano mars.txt
$ cat mars.txt

ВИХІД

Cold and dry, but everything is my favorite color
The two moons may be a problem for Wolfman

Тепер, коли ми запускаємо git status, Git повідомляє нам, що файл, про який він вже знає, був змінений:

BASH

$ git status

ВИХІД

On branch main
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

	modified:   mars.txt

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. Результат показує нам відмінності між поточним станом файлу та його останньою збереженою версією:

BASH

$ git diff

ВИХІД

diff --git a/mars.txt b/mars.txt
index df0654a..315bf3a 100644
--- a/mars.txt
+++ b/mars.txt
@@ -1 +1,2 @@
 Cold and dry, but everything is my favorite color
+The two moons may be a problem for Wolfman

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

  1. Перший рядок вказує на те, що результат цієї команди у Git подібний до Unix команди diff, яка порівнює стару та нову версії файлу.
  2. Другий рядок повідомляє які саме версії файлу Git порівнює; df0654a та 315bf3a є унікальними ідентифікаторами цих версій.
  3. Третій та четвертий рядки ще раз показують назву файлу, що змінюється.
  4. Решта рядків найцікавіші, вони показують нам фактичні відмінності і рядки, у яких вони відбуваються. Зокрема, значок + в першому стовпці вказує де ми додали рядок.

Після того, як ми переглянули наші зміни, прийшов час зберегти їх:

BASH

$ git commit -m "Add concerns about effects of Mars' moons on Wolfman"

ВИХІД

On branch main
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

	modified:   mars.txt

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

Але це не спрацює: Git не буде додавати зміни, тому що ми не використали спочатку git add. Давайте це виправимо:

BASH

$ git add mars.txt
$ git commit -m "Add concerns about effects of Mars' moons on Wolfman"

ВИХІД

[main 34961b1] Add concerns about effects of Mars' moons on Wolfman
 1 file changed, 1 insertion(+)

Git наполягає, щоб ми додали файли до набору змін, які ми хочемо записати, перед тим як ми зробимо коміт. Це дозволяє зберігати зміни поступово та обʼєднувати їх у логічні блоки, аніж у великі набори змін. Наприклад, припустимо, ми робимо коміт кількох цитат відповідних досліджень у нашій дисертації. Можливо, ми бажаємо зберегти ці зміни, та відповідні записи у бібліографії, але не зберігати деякі інші зміни в нашій роботі (наприклад, висновок, який ми ще не закінчили).

Щоб це було можливо зробити, Git має спеціальну зону стейджингу (staging area), де він відстежує речі, які були додані до поточного набору змін (changeset) проте, ще не були збережені.

Зона стейджингу (staging area)

Якщо ви будете уявляти, ніби Git робить знімки змін протягом життя проєкту, то git add вказує що буде на знімку (додаючи речі в зоні стейджингу), а git commit після того насправді робить знімок, та назавжди зберігає його (як коміт). Якщо у зоні стейджингу нічого немає, то коли ви введете git commit, Git запропонує вам використати git commit -a або git commit --all, який ніби збирає разом всіх, щоб зробити групове фото! Однак майже завжди краще явним чином додати речі до зони стейджингу, тому що без цього ви можете випадково зберегти інші зміни, про які ви забули. (Повертаючись до порівняння з груповим фото, якщо ви використали команду “-а”, до вашої фотографії може потрапити зайва людина!) Тому додавайте речі в зону стейджингу власноруч - > в іншому випадку вам може знадобитися шукати як використовувати “git undo commit” частіше, ніж вам хотілося б!

Зона стейджингу (Git staging area)

Подивімося, як наші зміни у файлі проходять шлях від текстового редактора до зони стейджингу і далі у довгострокове зберігання. Спочатку, ми додамо новий рядок у наш файл:

BASH

$ nano mars.txt
$ cat mars.txt

ВИХІД

Cold and dry, but everything is my favorite color
The two moons may be a problem for Wolfman
But the Mummy will appreciate the lack of humidity

BASH

$ git diff

ВИХІД

diff --git a/mars.txt b/mars.txt
index 315bf3a..b36abfd 100644
--- a/mars.txt
+++ b/mars.txt
@@ -1,2 +1,3 @@
 Cold and dry, but everything is my favorite color
 The two moons may be a problem for Wolfman
+But the Mummy will appreciate the lack of humidity

Поки що все добре: ми додали один рядок в кінці файлу (що зазначає + у першій колонці). Тепер помістімо цю зміну у зону стейджингу та подивимося що після цього звітує git diff:

BASH

$ git add mars.txt
$ git diff

Результату немає: це виглядає ніби для Git немає різниці між тим, що вже було збережено назавжди та тим, що зараз міститься у робочій директорії. Проте, якщо ми зробимо наступне:

BASH

$ git diff --staged

ВИХІД

diff --git a/mars.txt b/mars.txt
index 315bf3a..b36abfd 100644
--- a/mars.txt
+++ b/mars.txt
@@ -1,2 +1,3 @@
 Cold and dry, but everything is my favorite color
 The two moons may be a problem for Wolfman
+But the Mummy will appreciate the lack of humidity

то ми побачимо різницю між останніми збереженими змінами та тими, які знаходяться в зоні стейджингу. Збережімо наші зміни:

BASH

$ git commit -m "Discuss concerns about Mars' climate for Mummy"

ВИХІД

[main 005937f] Discuss concerns about Mars' climate for Mummy
 1 file changed, 1 insertion(+)

Перевіримо наш статус:

BASH

$ git status

ВИХІД

On branch main
nothing to commit, working tree clean

і подивимося на історію попередніх змін:

BASH

$ git log

ВИХІД

commit 005937fbe2a98fb83f0ade869025dc2636b4dad5 (HEAD -> main)
Author: Vlad Dracula <vlad@tran.sylvan.ia>
Date:   Thu Aug 22 10:14:07 2013 -0400

    Discuss concerns about Mars' climate for Mummy

commit 34961b159c27df3b475cfe4415d94a6d1fcd064d
Author: Vlad Dracula <vlad@tran.sylvan.ia>
Date:   Thu Aug 22 10:07:21 2013 -0400

    Add concerns about effects of Mars' moons on Wolfman

commit f22b25e3233b4645dabd0d81e651fe074bd8e73b
Author: Vlad Dracula <vlad@tran.sylvan.ia>
Date:   Thu Aug 22 09:51:46 2013 -0400

    Start notes on Mars as a base

Порівняння з підсвіткою змінених слів у рядках

Інколи, наприклад, у випадку текстових документів, результат diff дуже важко зрозуміти. Саме тут --color-words опція для git diff є надзвичайно зручною, бо вона виділяє кольором змінені слова.

Перегляд історії змін за сторінками

Коли розмір результату git log перевищує розмір вашого екрану, git використовує спеціальну програму “пейджер”, щоб поділити результат на сторінки розміром з ваш екран. Після виклику “пейджера”, ви помітите, що останній рядок на екрані - це :, замість звичайного запрошення командного рядка.

  • Натисніть Q, щоб вийти з пейджеру.
  • Натисніть пробіл, щоб перейти на наступну сторінку.
  • Щоб шукати some_word на всіх сторінках, натисніть / і введіть some_word. Натисніть N для навігації між результатами пошуку.

Обмеження розміру зображуваної історії змін

Щоб запобігти випадку, коли git log повністю займає ваш термінал, ви можете обмежувати кількість комітів які відображує Git, використовуючи опцію -N, де N - кількість комітів які б ви бажали бачити на екрані. Наприклад, якщо ви бажаєте побачити лише останній коміт, використовуйте команду

BASH

$ git log -1

ВИХІД

commit 005937fbe2a98fb83f0ade869025dc2636b4dad5 (HEAD -> main)
Author: Vlad Dracula <vlad@tran.sylvan.ia>
Date:   Thu Aug 22 10:14:07 2013 -0400

   Discuss concerns about Mars' climate for Mummy

Ви також можете зменшити кількість інформації, використовуючи опцію --oneline:

BASH

$ git log --oneline

ВИХІД

005937f (HEAD -> main) Discuss concerns about Mars' climate for Mummy
34961b1 Add concerns about effects of Mars' moons on Wolfman
f22b25e Start notes on Mars as a base

Ви також можете комбінувати опцію --oneline з іншими опціями. Наступна корисна комбінація використовує опцію --graph для графічного зображення історії комітів за допомогою псевдографіки, вказуючи при цьому які коміти пов’язані з поточним HEAD, поточною гілкою main, або іншими обʼєктами у репозиторії’:

BASH

$ git log --oneline --graph

ВИХІД

* 005937f (HEAD -> main) Discuss concerns about Mars' climate for Mummy
* 34961b1 Add concerns about effects of Mars' moons on Wolfman
* f22b25e Start notes on Mars as a base

Каталоги

Дві важливі речі, які ви повинні знати про каталоги в Git.

  1. Git не відстежує каталоги самостійно, тільки файли всередині них. Спробуйте власноруч:

BASH

$ mkdir spaceships
$ git status
$ git add spaceships
$ git status

Зауважте, наш новостворений порожній каталог spaceships не зʼявляється в переліку невідстежуваних файлів, навіть якщо ми конкретно додали його (виконав git add) до нашого> репозиторію Ось чому ви іноді бачите файли .gitkeep в інших порожніх каталогах. На відміну від .gitignore, ці файли не є особливими і їх єдиною метою є заповнити каталог, щоб Git додав його до репозиторію. Насправді ви можете назвати такі файли до вашої вподоби.

  1. Якщо ви створюєте каталог у вашому репозиторії Git і заповнюєте його файлами, ви можете додати всі файли в каталозі одразу:

BASH

git add <directory-with-files>

Спробуйте власноруч:

BASH

$ touch spaceships/apollo-11 spaceships/sputnik-1
$ git status
$ git add spaceships
$ git status

Перш ніж рухатися далі, ми збережемо ці зміни.

BASH

$ git commit -m "Add some initial thoughts on spaceships"

Для повторення: коли ми хочемо додати зміни до нашого репозиторію, спочатку нам потрібно додати змінені файли в зону стейджингу (git add) а потім зберегти заплановані зміни до репозиторію (git commit):

Послідовність дій для коміту

Вибір повідомлення коміту

Які з наступних повідомлень коміту будуть найбільш оптимальними для останнього коміту в mars.txt?

  1. “Changes”
  2. “Added line ‘But the Mummy will appreciate the lack of humidity’ to mars.txt”
  3. “Discuss effects of Mars’ climate on the Mummy”

Відповідь 1 є недостатньо детальною, а мета коміту неясна; відповідь 2 дублює результат команди “git diff” яка покаже зміни, зроблені у цьому коміті; відповідь 3 - оптимальна: коротка, інформативна, та імперативна.

Збереження змін у Git

Яка(які) з наведених нижче команд збережуть зміни у файлі myfile.txt до мого локального Git репозиторію?

  1. BASH

       $ git commit -m "my recent changes"
  2. BASH

       $ git init myfile.txt
       $ git commit -m "my recent changes"
  3. BASH

       $ git add myfile.txt
       $ git commit -m "my recent changes"
  4. BASH

       $ git commit -m myfile.txt "my recent changes"
  1. Створить коміт, лише якщо файли вже були у зоні стейджінгу.

  2. Намагатиметься створити новий репозиторій.

  3. Правильна відповідь: спочатку додайте файл до зони стейджингу, потім зробіть коміт.

  4. Спробує записати коміт файлу з назвою “my recent changes” з повідомленням myfile.txt.

Коміт декількох файлів

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

  1. Додайте текст до mars.txt про те, що ви вирішили розглянути побудову бази на Венері
  2. Створіть новий файл venus.txt з вашими думками стосовно Венери як бази для вас та ваших друзів
  3. Додайте зміни в обох файлах до зони стейджінгу, та зробіть коміт цих змін.

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

Спочатку ми робимо зміни у файлах mars.txt та venus.txt

BASH

$ nano mars.txt
$ cat mars.txt

ВИХІД

Maybe I should start with a base on Venus.

BASH

$ nano venus.txt
$ cat venus.txt

ВИХІД

Venus is a nice planet and I definitely should consider it as a base.

Тепер ви можете додати обидва файли до зони стейджингу. Ми можемо зробити це однією командою:

BASH

$ git add mars.txt venus.txt

Або за допомогою декількох команд:

BASH

$ git add mars.txt
$ git add venus.txt

Тепер файли готові до коміту. Ви можете перевірити це за допомогою git status. Якщо ви готові зробити коміт, використовуйте

BASH

$ git commit -m "Write plans to start a base on Venus"

ВИХІД

[main cc127c2]
 Write plans to start a base on Venus
 2 files changed, 2 insertions(+)
 create mode 100644 venus.txt

Вправа: репозиторій з вашою автобіографією

  • Створіть новий репозиторій Git на вашому компʼютері під назвою bio.
  • Напишіть три рядки своєї біографії у файлі під назвою me.txt, та зробіть коміт цих змін
  • Змініть один з рядків, додайте четвертий рядок
  • Покажіть відмінності між оновленим файлом та його попередньою версією.

Якщо необхідно, вийдіть з каталогу planets:

BASH

$ cd ..

Створіть новий каталог bio та перейдіть до нього:

BASH

$ mkdir bio
$ cd bio

Ініціалізуйте репозиторій Git:

BASH

$ git init

Створіть файл me.txt з вашою біографією, використовуючи nano або інший текстовий редактор. Коли будете готові, додайте його до зони стейджингу та запишіть коміт до репозиторію:

BASH

$ git add me.txt
$ git commit -m "Add biography file" 

Змініть файл як вказано (змініть один рядок, додайте четвертий рядок). Для того, щоб показати зміни між оновленим файлом та його попередньою версією, використайте git diff:

BASH

$ git diff me.txt

Ключові моменти

  • git status показує стан репозиторію.
  • Файли можуть зберігатися в робочому каталозі проєкту (де їх бачать користувачі), зоні стейджингу (де будується наступний коміт) і локальному репозиторії (де коміти зберігаються постійно).
  • git add додає файли до зони стейджингу.
  • git commit зберігає все, що міститься у зоні стейджингу, як новий коміт у локальному репозиторії.
  • Повідомлення коміту треба складати так, щоб воно акуратно описувало ваші зміни.

Content from Дослідження історії


Останнє оновлення 2024-06-04 | Редагувати цю сторінку

Огляд

Питання

  • Як визначити старі версії файлів?
  • Як переглянути свої зміни?
  • Як відновити старі версії файлів?

Цілі

  • Пояснення, що таке HEAD репозиторію та як його використовувати.
  • Визначення та використання ідентифікаторів комітів Git.
  • Порівняння різних версій відстежуваних файлів.
  • Відновлення старих версій файлів.

Як ми побачили у попередньому епізоді, ми можемо посилатися на коміти за їх ідентифікаторами. Ви можете звернутися до останнього коміту робочого каталогу за допомогою ідентифікатора HEAD.

Оскільки кожного разу ми додавали тільки один рядок до mars.txt, зараз нам буде легко простежити досягнутий прогрес. Зробімо це, використовуючи HEAD. Перш ніж ми почнемо, давайте змінимо значення на mars.txt, додавши ще один рядок.

BASH

$ nano mars.txt
$ cat mars.txt

ВИХІД

Cold and dry, but everything is my favorite color
The two moons may be a problem for Wolfman
But the Mummy will appreciate the lack of humidity
An ill-considered change

Тепер подивимося на наш результат.

BASH

$ git diff HEAD mars.txt

ВИХІД

diff --git a/mars.txt b/mars.txt
index b36abfd..0848c8d 100644
--- a/mars.txt
+++ b/mars.txt
@@ -1,3 +1,4 @@
 Cold and dry, but everything is my favorite color
 The two moons may be a problem for Wolfman
 But the Mummy will appreciate the lack of humidity
+An ill-considered change.

Це те саме, що ви отримаєте, якщо пропустите HEAD (спробуйте це).
Але справжня користь полягає у тому, що ви таким чином можете посилатися на попередні коміти. Наприклад, додаючи ~1 (де “~” - це тільда), ми посилаємось на коміт зроблений безпосередньо перед HEAD.

BASH

$ git diff HEAD~1 mars.txt

Якщо ми хочемо побачити різницю між старішими комітами, ми можемо знову використовувати git diff, використовуючи для послання на них HEAD~1, HEAD~2 тощо:

BASH

$ git diff HEAD~3 mars.txt

ВИХІД

diff --git a/mars.txt b/mars.txt
index df0654a..b36abfd 100644
--- a/mars.txt
+++ b/mars.txt
@@ -1 +1,4 @@
 Cold and dry, but everything is my favorite color
+The two moons may be a problem for Wolfman
+But the Mummy will appreciate the lack of humidity
+An ill-considered change

Ми також можемо використати команду git show, яка показує які зміни ми внесли у будь-якому попередньо зробленому коміті, а також і повідомлення коміту (на відміну від команди git diff яка покаже різницю між комітом та нашим робочим каталогом).

BASH

$ git show HEAD~3 mars.txt

ВИХІД

commit f22b25e3233b4645dabd0d81e651fe074bd8e73b
Author: Vlad Dracula <vlad@tran.sylvan.ia>
Date:   Thu Aug 22 09:51:46 2013 -0400

    Start notes on Mars as a base

diff --git a/mars.txt b/mars.txt
new file mode 100644
index 0000000..df0654a
--- /dev/null
+++ b/mars.txt
@@ -0,0 +1 @@
+Cold and dry, but everything is my favorite color

Таким чином, ми можемо побудувати ланцюжок комітів. Останній кінець ланцюжка називається HEAD; ми можемо посилатися на попередні коміти, використовуючи нотацію ~, тому HEAD~1 означає “попередній коміт”, тоді як HEAD~123 повертається на 123 коміти назад від того місця, де ми зараз знаходимось.

Ми також можемо вказувати на коміти, використовуючи ті довгі рядки цифр і букв, які показує git log. Це унікальні ідентифікатори змін, де “унікальний” насправді означає унікальний: кожна зміна будь-якого набору файлів на будь-якому комп’ютері буде мати унікальний 40-символьний ідентифікатор. Наш перший коміт отримав ідентифікатор f22b25e3233b4645dabd0d81e651fe074bd8e73b, тож спробуймо наступне:

BASH

$ git diff f22b25e3233b4645dabd0d81e651fe074bd8e73b mars.txt

ВИХІД

diff --git a/mars.txt b/mars.txt
index df0654a..93a3e13 100644
--- a/mars.txt
+++ b/mars.txt
@@ -1 +1,4 @@
 Cold and dry, but everything is my favorite color
+The two moons may be a problem for Wolfman
+But the Mummy will appreciate the lack of humidity
+An ill-considered change

Це правильна відповідь, проте, введення випадкових рядків з 40 символів дуже незручно. Тож Git дозволяє нам використовувати тільки перші кілька символів (як правило, сім для проєктів нормального розміру):

BASH

$ git diff f22b25e mars.txt

ВИХІД

diff --git a/mars.txt b/mars.txt
index df0654a..93a3e13 100644
--- a/mars.txt
+++ b/mars.txt
@@ -1 +1,4 @@
 Cold and dry, but everything is my favorite color
+The two moons may be a problem for Wolfman
+But the Mummy will appreciate the lack of humidity
+An ill-considered change

Це чудово! Отже, ми можемо зберегти зміни у файлах і побачити, що ми змінили. Наступне питання - а як ми можемо відновити їх старіші версії? Припустимо, що ми передумали щодо останнього оновлення файлу mars.txt (рядок “ill-considered change”).

git status зараз каже нам, що файл був змінений, але ці зміни не були додані до зони стейджингу:

BASH

$ git status

ВИХІД

On branch main
Changes not staged for commit:
   (use "git add/rm <file>..." to update what will be committed)
   (use "git checkout -- <file>..." to discard changes in working directory)

    deleted:    nibiru.txt

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

Отже, ми можемо повернути цей файл до його попереднього стану за допомогою git checkout:

BASH

$ git checkout HEAD mars.txt
$ cat mars.txt

ВИХІД

Cold and dry, but everything is my favorite color
The two moons may be a problem for Wolfman
But the Mummy will appreciate the lack of humidity

Як ви можете здогадатися з назви цієї команди, git checkout знаходить (тобто відновлює) стару версію файлу. У цьому випадку ми повідомляємо Git, що хочемо відновити версію файлу, записану в HEAD (тобто в останньому зробленому коміті). Якщо ми хочемо повернутися ще раніше, замість цього ми можемо використовувати ідентифікатор коміту:

BASH

$ git checkout f22b25e mars.txt

BASH

$ cat mars.txt

ВИХІД

Cold and dry, but everything is my favorite color

BASH

$ git status

ВИХІД

On branch main
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    modified:   mars.txt

Звернуть увагу, що зміни зараз знаходяться у зоні стейджінгу. Знову ж таки, ми можемо повернути усе як було за допомогою git checkout:

BASH

$ git checkout HEAD mars.txt

Не втрачайте голову (тобто, HEAD)

Вище ми використовували

BASH

$ git checkout f22b25e mars.txt

щоб повернути mars.txt до його стану після коміту f22b25e. Проте, будьте обережні! Команда checkout має інші важливі варіанти використання, та Git не зрозуміє ваших намірів, якщо ви будете неточно вводити команди. Наприклад, якщо ви забудете mars.txt у попередній команді.

BASH

$ git checkout f22b25e

ПОМИЛКА

Note: checking out 'f22b25e'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:

 git checkout -b <new-branch-name>

HEAD is now at f22b25e Start notes on Mars as a base

Таким чином, стан “detached HEAD” схожий на “дивися, але не чіпай”, тому ви не повинні робити жодних змін у цьому стані. Після дослідження стану вашого репозиторію у минулому, знову “приєднайте” свій HEAD за допомогою команди git checkout main.

Важливо пам’ятати, що ми повинні використовувати номер коміту, який ідентифікує стан репозиторію до зміни, яку ми намагаємося скасувати. Поширеною помилкою є використання номеру коміту, в якому ми зробили зміни, які намагаємося скасувати. У наведеному нижче прикладі ми хочемо отримати стан перед самим останнім комітом (HEAD~1), тобто коміт f22b25e:

Використання git checkout

Отже, якщо скласти це все разом, то Git працює як зображено у цьому коміксі:

https://figshare.com/articles/How\_Git\_works\_a\_cartoon/1328266

Спрощення загального випадку

Якщо уважно прочитати результат команди git status, ви побачите, що він містить цю підказку:

ВИХІД

(use "git checkout -- <file>..." to discard changes in working directory)

Як сказано раніше, git checkout без ідентифікатора версії відновлює файли до стану, збереженого в HEAD. Подвійне тире -- необхідне, щоб відділити імена файлів, які відновлюються, від самої команди: без подвійного тире Git буде намагатися використати назву файлу як ідентифікатор коміту.

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

Відновлення старих версій файлу

Дженніфер зробила цього ранку деякі зміни у скрипті Python, над яким вона до цього працювала тижнями, та “зламала” його - він більше не запускається. Вона витратила майже годину, намагаючись виправити його, але безрезультатно…

На щастя, вона використовує Git для відстеження змін у свому проєкті! Які з наведених нижче команд допоможуть їй відновити останню збережену у Git версію її скрипту, який називається data_cruncher.py?

  1. $ git checkout HEAD

  2. $ git checkout HEAD data_cruncher.py

  3. $ git checkout HEAD~1 data_cruncher.py

  4. $ git checkout <unique ID of last commit> data_cruncher.py

  5. Як 2, так і 4

Відповідь (5) - як 2, так і 4.

Команда checkout відновлює файли з репозиторію, перезаписуючи файли у ваш робочий каталог. Обидві відповіді 2 та 4 відновлюють останню збережену в репозиторії версію файлу data_cruncher.py. Відповідь 2 використовує HEAD, щоб вказати останній коміт, тоді як відповідь 4 використовує унікальний ідентифікатор останнього коміту, що саме й означає HEAD.

Відповідь 3 замінить data_cruncher.py його версією з коміту перед HEAD, що НЕ є тим, що ми хотіли.

Відповідь 1 може бути небезпечною! Без назви файлу, git checkout відновить всі файли у поточному каталозі (і усіх підкаталогах нижче нього) до їх стану згідно із вказаним комітом. Ця команда відновить data_cruncher.py до його останньої збереженої версії, але вона також відновить всі інші файли, які було змінено на ту ж саму версію, стираючи будь-які зміни, які ви могли внести до цих файлів! Як обговорювалося вище, ви перейдете у стан “detached HEAD”, але ж ви не хочете там бути.

Скасування коміту

Дженніфер співпрацює з колегами над її скриптом Python. Вона зрозуміла, що її останній коміт до репозиторію проєкту містив помилку, і хоче його скасувати. Дженніфер хоче скасувати його правильним чином, щоб всі користувачі репозиторію цього проєкту отримали правильні зміни. Команда git revert [erroneous commit ID] створить новий коміт, який скасує помилковий коміт.

Команда git revert відрізняється від git checkout [commit ID], оскільки git checkout повертає файли, зміни у яких ще не ввійшли до нового коміту у локальному репозиторії, до їх попереднього стану, тоді як git revert скасовує зміни, які вже внесені до локального та віддаленого репозиторіїв.

Нижче наведені правильні кроки та пояснення для Дженніфер щодо користування git revert. Яка команда відсутня?

  1. ________ # Подивіться на історію змін, щоб знайти ідентифікатор коміту

  2. Скопіюйте цей ID (перші кілька символів ID, наприклад 0b1d055).

  3. git revert [commit ID]

  4. Введіть повідомлення для нового коміту.

  5. Збережіть його та закрийте редактор.

Команда git log зображує історію проєкту з ідентифікаторами комітів.

Команда git show HEAD покаже зміни, зроблені в останньому коміті, і покаже його ID; однак Дженніфер повинна перевірити, що це правильний коміт, а не нові зміни, які зробив у спільному репозиторії хтось інший.

Розуміння послідовності дій та історії

Який результат останньої команди в цій послідовності?

BASH

$ cd planets
$ echo "Venus is beautiful and full of love" > venus.txt
$ git add venus.txt
$ echo "Venus is too hot to be suitable as a base" >> venus.txt
$ git commit -m "Comment on Venus as an unsuitable base"
$ git checkout HEAD venus.txt
$ cat venus.txt #this will print the contents of venus.txt to the screen
  1. ВИХІД

Venus is too hot to be suitable as a base

2. ```output
Venus is beautiful and full of love
  1. ВИХІД

Venus is beautiful and full of love Venus is too hot to be suitable as a base

4. ```output
Error because you have changed venus.txt without committing the changes

Правильною є відповідь 2.

Команда git add venus.txt розміщує поточну версію ‘venus.txt’ в зоні стейджингу. Зміни до файлу з другої команди echo будуть зроблені лише у робочій копії цього файлу, але не у його версії в зоні стейджингу.

Тож, коли виконується команда git commit -m "Comment on Venus as an unsuitable base", версія venus.txt, яка буде збережена у коміті, буде з зони стейджингу та буде мати тільки один рядок.

На цей час робоча копія файлу ще має другий рядок (і тому git status покаже, що файл змінено). Однак git checkout HEAD venus.txt замінить робочу копію останньою збереженою версією venus.txt.

Тож, cat venus.txt покаже

ВИХІД

Venus is beautiful and full of love.

Перевірка розуміння git diff

Розглянемо цю команду: git diff HEAD~9 mars.txt. Що, на вашу думку, зробить ця команда, якщо ви її виконаєте? Що станеться, коли ви її виконаєте? Чому?

Спробуйте іншу команду, git diff [ID] mars.txt, де [ID] замінено на унікальний ідентифікатор вашого останнього коміту. Як ви думаєте, що вона зробить? Виконайте її та перевірте, чи це так.

Скасування змін у зоні стейджингу

Команда git checkout може бути використана для відновлення попереднього коміту, коли зміни були зроблені, але ще не додані до зони стейджингу. Але чи спрацює вона і для змін, які були додані до зони стейджингу, але не ще збережені у коміті? Зробіть зміни у mars.txt, додайте їх до зони стейджингу за допомогою git add, та використайте git checkout, щоб побачити чи можете ви скасувати свої зміни.

Після додавання зміни за допомогою git add, команду git checkout не можна використовувати безпосередньо. Подивіться на результат git status:

ВИХІД

On branch main
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        modified:   mars.txt

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

Використання команди git checkout -- mars.txt тепер не дає помилки, але також не відновлює файл. Git зображує корисне повідомлення - нам потрібно спочатку використати git reset, щоб видалити файл з зони стейджингу:

BASH

$ git reset HEAD mars.txt

ВИХІД

Unstaged changes after reset:
M	mars.txt

Тепер git status зображує наступне:

BASH

$ git status

ВИХІД

On branch main
Changes not staged for commit:
   (use "git add/rm <file>..." to update what will be committed)
   (use "git checkout -- <file>..." to discard changes in working directory)

    deleted:    nibiru.txt

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

Це означає, що тепер ми можемо використовувати git checkout, щоб відновити файл до попереднього коміту:

BASH

$ git checkout -- mars.txt
$ git status

ВИХІД

On branch main
nothing to commit, working tree clean

Перегляд історії

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

Уявіть, що проєкт planets має більш ніж 50 файлів. Ви хотіли б знайти коміт, який змінює певний текст у mars.txt. Коли ви вводите git log, з’являється дуже довгий список. Як можна звузити коло пошуку?

Нагадаємо, що команда git diff може використовуватись для одного конкретного файлу, наприклад, git diff mars.txt. Ми можемо застосувати тут подібну ідею.

BASH

$ git log mars.txt

На жаль, деякі з цих повідомлень комітів дуже неоднозначні, наприклад, update files. Як же переглянути усі ці версії файлу?

Обидві команди git diff та git log дуже корисні для отримання звітів про різні деталі історії проєкту. Але чи можна об’єднати їх результат в одну команду? Давайте спробуємо наступне:

BASH

$ git log --patch mars.txt

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

Питання: Що робить наступна команда?

BASH

$ git log --patch HEAD~9 *.txt

Ключові моменти

  • git diff відображає відмінності між комітами.
  • git checkout відновлює старі версії файлів.

Content from Ігнорування файлів


Останнє оновлення 2024-06-04 | Редагувати цю сторінку

Огляд

Питання

  • Як зробити так, щоб Git ігнорував файли, які я не хочу відстежувати?

Цілі

  • Налаштувати Git для ігнорування певних файлів.
  • Зрозуміти чому ігнорування файлів може бути корисним.

Що робити, якщо у нас є файли, які ми не хочемо відстежувати у Git, наприклад, резервні файли, створені нашим редактором або проміжні файли, створені під час аналізу даних? Створімо декілька фіктивних файлів:

BASH

$ mkdir results
$ touch a.csv b.csv c.csv results/a.out results/b.out

і подивимося, що скаже Git:

BASH

$ git status

ВИХІД

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

	a.csv
	b.csv
	c.csv
	results/

nothing added to commit but untracked files present (use "git add" to track)

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

Ми можемо зробити це, створюючи у кореневому каталозі нашого проєкту файл під назвою .gitignore:

BASH

$ nano .gitignore
$ cat .gitignore

ВИХІД

*.csv
results/

Це шаблони, які наказують Git ігнорувати будь-який файл, ім’я якого закінчується на .dat, а також усе, що знаходиться у каталозі results. (Якщо будь-які з цих файлів вже відстежуються, то Git продовжить їх відстежувати.)

Як тільки ми створили цей файл, результат команди git status стає набагато зрозумілішим:

BASH

$ git status

ВИХІД

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

	.gitignore

nothing added to commit but untracked files present (use "git add" to track)

Єдина річ, яку Git помічає зараз - це новостворений файл .gitignore. Ви можете подумати, що його не треба відстежувати, але всі, з ким ми ділимося нашим репозиторієм, ймовірно, захочуть ігнорувати ті самі речі, які ігноруємо ми. Додамо до репозиторію та здійснимо коміт файлу .gitignore:

BASH

$ git add .gitignore
$ git commit -m "Ignore data files and the results folder"
$ git status

ВИХІД

On branch main
nothing to commit, working tree clean

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

BASH

$ git add a.csv

ВИХІД

The following paths are ignored by one of your .gitignore files:
a.csv
Use -f if you really want to add them.

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

BASH

$ git status --ignored

ВИХІД

On branch main
Ignored files:
 (use "git add -f <file>..." to include in what will be committed)

        a.csv
        b.csv
        c.csv
        results/

nothing to commit, working tree clean

Ігнорування вкладених файлів

Враховуючи структуру каталогу, яка виглядає так:

BASH

results/data
results/plots

Як зробити так, щоб Git ігнорував тільки results/plots, а не results/data?

Якщо ви хочете ігнорувати лише вміст results/plots, ви можете зробити це шляхом додавання наступного рядка до вашого .gitignore:

ВИХІД

results/plots/

Цей рядок забезпечить ігнорування лише вмісту results/plots, але не вмісту results/data.

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

Додавання конкретних файлів

Як ігнорувати всі файли .dat у кореневому каталозі, за винятком final.csv? Підказка: дізнайтеся, що робить ! (оператор знаку оклику).

Треба додати наступні два рядки до вашого файлу .gitignore:

ВИХІД

*.csv           # ігнорувати усі файли з даними
!final.csv      # окрім final.csv

Знак оклику призведе до включення раніше виключеного запису.

Зверніть увагу також на те, що, оскільки ви раніше вже зберегли файли .csv у комітах, зроблених в цьому уроці, вони не будуть проігноровані після додавання цього нового правила. Тільки майбутні додавання .csv файлів до кореневого каталогу будуть проігноровані.

Варіант ігнорування вкладених файлів

Нехай ми маємо структуру каталогів, яка виглядає подібно до попередньої вправи “Ігнорування файлів у підкаталогах”, проте дещо відрізняється:

BASH

results/data
results/images
results/plots
results/analysis

Як би ви проігнорували весь вміст у каталозі results, окрім results/data?

Підказка: подумайте про те, як ви раніше зробили виняток за допомогою оператору !.

Якщо ви хочете ігнорувати вміст каталогу results/, але не каталогу results/data/, ви можете змінити ваш.gitignore, щоб ігнорувати вміст каталогу results, але створити виняток для вмісту підкаталогу results/data. Ваш .gitignore буде виглядати так:

ВИХІД

results/*               # ігнорувати все в каталозі results
!results/data/          # не ігнорувати вміст results/data/

Ігнорування всіх файлів з даними у каталозі

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

BASH

results/data/position/gps/a.csv
results/data/position/gps/b.csv
results/data/position/gps/c.csv
results/data/position/gps/info.txt
results/plots

Яке найкоротше правило ви можете додати до .gitignore, щоб ігнорувати всі файли з розширенням .csv у каталозі result/data/position/gps? При цьому, не ігноруйте info.txt.

Додавання results/data/position/gps/*.csv призведе до ігнорування усіх файлів у results/data/position/gps, які закінчуються на .csv. Файл results/data/position/gps/info.txt не буде проігноровано.

Ігнорування всіх файлів з даними у репозиторії

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

BASH

results/a.csv
data/experiment_1/b.csv
data/experiment_2/c.csv
data/experiment_2/variation_1/d.csv

Як ігнорувати всі файли .csv без явного переліку усіх відповідних каталогів?

Додайте наступний рядок до файлу .gitignore:

ВИХІД

**/*.csv

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

Порядок застосування правил

Нехай нам дано файл .gitignore з наступним вмістом:

BASH

*.csv
!*.csv

Який вплив це буде мати на ігнорування файлів?

Оператор ! скасує запис з попередньо визначеного шаблону ігнорування. Оскільки запис ! *.csv скасовує всі попередні файли .csv в .gitignore, жоден з них не буде проігноровано, і всі файли .csv будуть відстежуватися.

Log-файли

Ви написали скрипт, який створює багато проміжних log-файлів з назвами log_01, log_02, log_03 тощо. Ви хочете зберегти їх, але не бажаєте відстежувати їх за допомогою git.

  1. Додайте до .gitignore один рядок, який виключає файли log_01, log_02 тощо.

  2. Перевірте свій “шаблон ігнорування”, створивши деякі фіктивні файли з назвами log_01, log_02 тощо.

  3. Уявіть тепер, що файл log_01 дуже важливий, та додайте його до відстежуваних файлів, не змінюючи .gitignore.

  4. Обговоріть з сусідом, які інші типи файлів можуть перебувати у вашому проєкті, які ви не бажаєте відстежувати і тому бажаєте проігнорувати за допомогою .gitignore.

  1. додайте або log_* або log* як новий рядок до вашого .gitignore

  2. відстежуйте log_01 за допомогою git add -f log_01

Ключові моменти

  • Файл .gitignore інформує Git про те, які файли треба ігнорувати.

Content from Віддалені репозиторії у GitHub


Останнє оновлення 2024-06-04 | Редагувати цю сторінку

Огляд

Питання

  • Як я можу поділитися своїми змінами з іншими через Інтернет?

Цілі

  • Зрозуміти, що таке віддалені репозиторії та чому вони корисні.
  • Навчитися надсилати до та отримувати зміни з віддаленого репозиторію.

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

Такі системи, як Git, дозволяють пересилати інформацію про зміни між будь-якими двома репозиторіями. Однак на практиці найпростіше використовувати одну копію як центральний вузол у мережі репозиторіїв, і зберігати його в мережі, аніж на чиємусь ноутбуці. Багато програмістів використовують послуги хостингу, такі як GitHub, Bitbucket або GitLab щоб зберігати основні копії; ми розглянемо плюси та мінуси цього в іншому епізоді.

Ми почнемо з того, що поділимося зі світом змінами, які ми внесли до нашого поточного проєкту. З цією метою ми збираємося створити віддалений репозиторій, який буде пов’язаний з нашим локальним репозиторієм.

1. Створіть віддалений репозиторій


Увійдіть до GitHub, потім натисніть на значок у верхньому правому куті, щоб створити новий репозиторій під назвою planets:

Створення репозиторію на GitHub (крок 1)

Назвіть ваш репозиторій “planets” і потім натисніть на “Create Repository”.

Зауважте: оскільки цей репозиторій буде підʼєднано до локального репозиторію, він має бути порожнім. Залиште “Initialize this repository with a README” непозначеним, та оберіть “None” як опції для обох “Add .gitignore” та “Add a license”. Дивіться вправу “Файли ліцензії та README” нижче для повного пояснення того, чому репозиторій повинен бути порожнім.

Створення репозиторію на GitHub (крок 2)

Як тільки репозиторій створено, GitHub відображає сторінку з URL і певною інформацією про те, як налаштувати локальний репозиторій:

Створення репозиторію на GitHub (крок 3)

Насправді це робить наступне на сервері GitHub:

BASH

$ mkdir planets
$ cd planets
$ git init

Якщо ви пам’ятаєте, у одному з попередніх епізодів, де ми додавали та зберігали нашу попередню роботу над mars.txt, в нас була діаграма, яка зображувала локальний репозиторій, та виглядала так:

Локальний репозиторій із зоною стейджингу

Тепер, коли ми маємо два репозиторії, нам потрібна така діаграма:

Щойно створений репозиторій GitHub

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

2. Підʼєднання локального репозиторію до віддаленого


Тепер підключаємо два сховища одне до одного. Ми робимо це вказуючи GitHub репозиторій у якості віддаленого для локального репозиторію. Домашня сторінка репозиторію на GitHub містить URL, який нам потрібен, щоб його ідентифікувати:

Як знайти URL репозиторію у GitHub

Натисніть на кнопку ‘SSH’, щоб змінити протокол з HTTPS на SSH.

HTTPS в порівнянні з SSH

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

Зміна URL репозиторію у GitHub

Скопіюйте цю URL-адресу з браузера, перейдіть до локального репозиторію planets, та виконайте цю команду:

BASH

$ git remote add origin git@github.com:vlad/planets.git

Make sure to use the URL for your repository rather than Vlad’s: the only difference should be your username instead of vlad.

origin - імʼя, яке використовується локально для позначення віддаленого репозиторію. Його можна було б назвати як завгодно, але origin - це домовленість, яка часто використовується за замовчуванням в git та GitHub, так що корисно дотримуватися її, якщо немає особливої причини це не робити.

Ми можемо перевірити, що команда спрацювала за допомогою git remote -v:

BASH

$ git remote -v

ВИХІД

origin   git@github.com:vlad/planets.git (fetch)
origin   git@github.com:vlad/planets.git (push)

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

3. Необхідна інформація про SSH протокол та його налаштування


Перш ніж Dracula зможе підʼєднатися до віддаленого репозиторію, він має налаштувати спосіб автентифікації свого комп’ютера у GitHub. Це потрібно для того, щоб GitHub міг розпізнати його, коли він намагається підʼєднатися до свого віддаленого репозиторію.

Ми збираємось налаштувати метод, який зазвичай використовується багатьма різними службами для автентифікації доступу з командного рядка. Цей метод називається Secure Shell Protocol (SSH). SSH - це кріптографічний мережевий протокол, який дозволяє безпечний зв’язок між комп’ютерами через ненадійну комунікаційну мережу.

SSH використовує так звану пару ключів. Ці два ключі працюють разом для надання доступу. Один ключ публічно відомий - він називається відкритим ключем, інший ключ називається приватним ключем, та має бути доступним тільки його власнику. Дуже логічні назви!

Ви можете уявити відкритий ключ як навісний замок, від якого тільки у вас є ключ (тобто ваш приватний ключ), щоб відчинити його. Ви використовуєте свій відкритий ключ тоді, коли вам потрібно мати безпечний спосіб зв’язку, наприклад, щоб використовувати ваш обліковий запис на GitHub. Тоді ви даєте GitHub цей замок (відкритий ключ) та кажете: “Заблокувати доступ до мого облікового запису таким чином, щоб тільки комп’ютери, які мають мій закритий ключ, могли розблокувати зв’язок та виконувати команди git від імені мого облікового запису на GitHub.”

Те, що ми зараз зробимо - це мінімум, необхідний для налаштування SSH-ключів та додання відкритого ключа до вашого акаунту на GitHub.

Подальша інформація про SSH

Тепер ми розглянемо SSH та пари ключів більш глибоко і детально.

Перше, що ми зробимо - це перевіримо, чи необхідні налаштування вже були зроблені на комп’ютері, на якому ви працюєте зараз. Тому що, зазвичай, ці налаштування треба зробити тільки один раз для кожного комп’ютера, а після цього про них можна забути.

Тримайте ваші ключі у надійному місці

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

Ми запустимо команду ls (список), щоб перевірити, які пари ключів вже існують на вашому комп’ютері.

BASH

ls -al ~/.ssh

Ваш результат буде виглядати трохи інакше в залежності від того, чи був коли-небудь SSH налаштований на комп’ютері, який ви використовуєте, чи ні.

Dracula ще не налаштував SSH на його комп`ютері, тож його результат виглядає так

ВИХІД

ls: cannot access '/c/Users/Vlad Dracula/.ssh': No such file or directory

Якщо SSH вже налаштований на комп’ютері, який ви використовуєте, то ви побачите перелік пар відкритих та приватних ключів. Назви файлів будуть або id_ed25519/id_ed25519.pub, або id_rsa/id_rsa.pub у залежності від того, як ці пари ключів були створені.
Оскільки Dracula не має цих файлів на його комп`ютері, він переходить до наступного кроку, щоб їх створити.

3.1 Створення пари ключів SSH

Для створення пари SSH ключів Dracula використовує наступну команду, де параметр -t визначає який тип алгоритму використати, а параметр -C прикріплює до ключа коментар (який у даному випадку є електронною поштою його власника):

BASH

$ ssh-keygen -t ed25519 -C "vlad@tran.sylvan.ia"

Якщо ви використовуєте старішу систему, яка не підтримує алгоритм Ed25519, то використовуйте: $ ssh-keygen -t rsa -b 4096 -C "your_email@example.com"

ВИХІД

Generating public/private ed25519 key pair.
Enter file in which to save the key (/c/Users/Vlad Dracula/.ssh/id_ed25519):

Ми бажаємо використовувати імʼя та розташування файлу за замовчуванням, тому просто натисніть Enter.

ВИХІД

Created directory '/c/Users/Vlad Dracula/.ssh'.
Enter passphrase (empty for no passphrase):

Тепер Dracula має обрати пароль. Він хоче створити пароль, оскільки він використовує ноутбук зі своєї лабораторії, до якого іноді мають доступ інші люди. Обов’язково використовуйте пароль, який можна запам’ятати, або збережіть пароль десь у надійному місці, оскільки тут немає опції «змінити мій пароль».

ВИХІД

Enter same passphrase again:

Після введення того ж самого пароля вдруге ми отримуємо підтвердження

ВИХІД

Your identification has been saved in /c/Users/Vlad Dracula/.ssh/id_ed25519
Your public key has been saved in /c/Users/Vlad Dracula/.ssh/id_ed25519.pub
The key fingerprint is:
SHA256:SMSPIStNyA00KPxuYu94KpZgRAYjgt9g4BA4kFy3g1o vlad@tran.sylvan.ia
The key's randomart image is:
+--[ED25519 256]--+
|^B== o.          |
|%*=.*.+          |
|+=.E =.+         |
| .=.+.o..        |
|....  . S        |
|.+ o             |
|+ =              |
|.o.o             |
|oo+.             |
+----[SHA256]-----+

Насправді під “identification” тут мається на увазі приватний ключ. Ви ніколи не повинні ділитися ним з іншими. На відміну від приватного ключа, відкритий ключ у цьому повідомленні так і називається - “public key”. Щодо “key fingerprint”, він є коротшою версією відкритого ключа.

Тепер, коли ми створили ключі SSH, відповідні файли будуть знайдені:

BASH

ls -al ~/.ssh

ВИХІД

drwxr-xr-x 1 Vlad Dracula 197121   0 Jul 16 14:48 ./
drwxr-xr-x 1 Vlad Dracula 197121   0 Jul 16 14:48 ../
-rw-r--r-- 1 Vlad Dracula 197121 419 Jul 16 14:48 id_ed25519
-rw-r--r-- 1 Vlad Dracula 197121 106 Jul 16 14:48 id_ed25519.pub

3.2 Копіювання відкритого ключа у GitHub

Тепер ми маємо пару ключів SSH, та можемо запустити наступну команду, щоб перевірити, чи може GitHub дозволити нашу автентифікацію.

BASH

ssh -T git@github.com

ВИХІД

The authenticity of host 'github.com (192.30.255.112)' can't be established.
RSA key fingerprint is SHA256:nThbg6kXUpJWGl7E1IGOCspRomTxdCARLviKw6E5SY8.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])? y
Please type 'yes', 'no' or the fingerprint: yes
Warning: Permanently added 'github.com' (RSA) to the list of known hosts.
git@github.com: Permission denied (publickey).

Отже, ми забули, що нам спочатку потрібно надати GitHub наш відкритий ключ!

По-перше, нам потрібно скопіювати відкритий ключ. Не забудьте додати .pub в кінці цієї команди - в іншому випадку ви будете дивитись на приватний ключ.

BASH

cat ~/.ssh/id_ed25519.pub

ВИХІД

ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDmRA3d51X0uu9wXek559gfn6UFNF69yZjChyBIU2qKI vlad@tran.sylvan.ia

Тепер, перейшовши до GitHub.com, натисніть на іконку свого облікового запису у верхньому правому куті, щоб відкрити відповідне меню. У цьому меню натисніть “Settings,” потім на сторінці налаштувань ліворуч знайдіть та натисніть “SSH and GPG keys”. Далі натисніть “New SSH key” кнопку праворуч. Тепер ви можете додати назву ключа (Dracula використовує назву “Vlad’s Lab Laptop” щоб запамʼятати, де розташовані оригінальні пари ключів), вставити відкритий SSH ключ, який ви попередньо скопіювали, у відповідне поле, та натиснути кнопку “Add SSH key”, щоб завершити налаштування.

Тепер, коли ми усе налаштували, ми знову перевіримо нашу автентифікацію з командного рядка.

BASH

$ ssh -T git@github.com

ВИХІД

You've successfully authenticated, but GitHub does not provide shell access.

Добре! Цей результат підтверджує, що ключ SSH працює як очікується. Тепер ми готові завантажити нашу роботу до віддаленого репозиторію.

4. Завантаження локальних змін до віддаленого репозиторію


Тепер, коли аутентифікація налаштована, ми можемо повернутися до віддаленого репозиторію. Наступна команда завантажить зміни з нашого локального репозиторію до репозиторію на GitHub:

BASH

$ git push origin main

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

ВИХІД

Enumerating objects: 16, done.
Counting objects: 100% (16/16), done.
Delta compression using up to 8 threads.
Compressing objects: 100% (11/11), done.
Writing objects: 100% (16/16), 1.45 KiB | 372.00 KiB/s, done.
Total 16 (delta 2), reused 0 (delta 0)
remote: Resolving deltas: 100% (2/2), done.
To https://github.com/vlad/planets.git
 * [new branch]      main -> main

Проксі-сервер

Якщо мережа, до якої ви підключені, використовує проксі-сервер, то можливо, що ваша остання команда зазнала невдачі з повідомленням про помилку “Could not resolve hostname”. Щоб розвʼязати цю проблему, потрібно проінформувати Git про проксі-сервер:

BASH

$ git config --global http.proxy http://user:password@proxy.url
$ git config --global https.proxy https://user:password@proxy.url

Коли ви підключаєтеся до іншої мережі, яка не використовує проксі-сервер, вам буде потрібно відключити використання проксі у Git за допомогою наступних команд:

BASH

$ git config --global --unset http.proxy
$ git config --global --unset https.proxy

Менеджери паролів

Якщо у вашій операційній системі налаштовано менеджер паролів, git push спробує використати його, коли йому знадобляться ваші імʼя користувача і пароль. Наприклад, це є стандартною поведінкою Git Bash у Windows. Якщо ви бажаєте вводити своє ім`я користувача та пароль в терміналі замість використання менеджеру паролів, то введіть:

BASH

$ unset SSH_ASKPASS

у терміналі, перед тим як виконати git push. Незважаючи на імʼя змінної SSH_ASKPASS, Git використовує значення SSH_ASKPASS для усіх методів автентифікації записів, тож ви можете відмінити SSH_ASKPASS незалежно від того, чи ви використовуєте Git через SSH або автентифікацію через https-протокол.

Ви також можете додати unset SSH_ASKPASS в кінці вашого файлу ~/.bashrc, щоб зробити запит імен користувачів та паролів стандартною поведінкою Git.

Тепер наші локальний та віддалений репозиторії перебувають у такому стані:

Репозиторій GitHub після першого виконання команди push

Опція ‘-u’

У документації ви можете іноді побачити використання git push з опцією -u. Це є синонімом опції --set-upstream-to для команди git branch і використовується для звязку поточної гілки з віддаленою гілкою таким чином, щоб командаgit pullмогла надалі бути використана без будь-яких аргументів. Щоб зробити це, просто використайтеgit push -u origin main` один раз після налаштування віддаленого репозиторію.

Ми також можемо завантажувати зміни з віддаленого репозиторію до локального:

BASH

$ git pull origin main

ВИХІД

From https://github.com/vlad/planets
 * branch            main     -> FETCH_HEAD
Already up-to-date.

У цьому випадку ця команда не має ніякого ефекту, оскільки два репозиторії вже синхронізовані. Але якщо хтось ще вніс якісь зміни до репозиторію на GitHub, то ця команда завантажить їх у наш локальний репозиторій.

Користування вебінтерфейсом GitHub

Перейдіть до вашого репозиторію planets на GitHub. Під кнопкою “Code”, знайдіть та натисніть на текст “XX commits” (де “XX” - якесь число). Наведіть курсор та натисніть на три кнопки праворуч від кожного коміту. Яку інформацію ви можете отримати/вивчити за допомогою цих кнопок? Як би ви отримали ту саму інформацію в shell?

Ліва кнопка (з зображенням буфера обміну) копіює повний ідентифікатор коміту до буфера обміну. В shell, git log покаже вам для кожного коміту його повний ідентифікатор.

Коли ви натиснете на середню кнопку, ви побачите всі зміни, які були зроблені в цьому конкретному коміті. Зелені затінені лінії вказують на додавання, а червоні - видалення. В shell ми можемо зробити те ж саме за допомогою git diff. А саме, git diff ID1..ID2, де ID1 та ID2 - ідентифікатори комітів (наприклад, git diff a3bf1e5..041e637) покаже відмінності між цими двома комітами.

Найправіша кнопка дозволяє переглянути всі файли в репозиторії під час цього коміту. Для того, щоб зробити це в shell, нам потрібно було б змінити стан файлів у репозиторії на їх стан під час відповідного коміту. Ми можемо зробити це за допомогою git checkout ID, де ID - ідентифікатор коміту, на який ми хочемо подивитися. Якщо ми це зробимо, нам потрібно пам’ятати про те, що після цього репозиторій потрібно повернути до попереднього стану!

Завантаження файлів до GitHub у браузері

Github також дозволяє нам уникнути використання командного рядка і завантажити файли безпосередньо до вашого репозиторію без необхідності залишати браузер. Для цього є два варіанти. Перший - ви можете натиснути кнопку “Upload files” на панелі інструментів у верхній частині переліку файлів. Другий - ви можете перетягнути файли з робочого столу до переліку файлів. Ви можете більше прочитати про це на цій сторінці у GitHub.

Показ дати у GitHub

Створіть віддалений репозиторій на GitHub. Завантажте вміст вашого локального репозиторію до віддаленого. Зробіть нові зміни у вашому локальному репозиторії та завантажте їх теж. Перейдіть до щойно створеного на GitHub репозиторію і перевірте дати модифікацїї файлів. Як GitHub їх відображає, і чому?

GitHub відображає дати у відносному форматі, який легко читається людиною (наприклад, “22 години тому” або “три тижні тому”). Однак, якщо ви наведете курсор на дату, ви можете побачити точний час, коли відбулася остання зміна файлу.

Завантаження змін чи коміт змін?

В цьому епізоді ми познайомилися з командою git push. Як git push відрізняється від git commit?

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

Файли ліцензії та README

У цьому епізоді ми дізналися про створення віддаленого репозиторію на GitHub, але коли ми ініціалізували наш GitHub репозиторій, ми не додали README.md або файл ліцензії. Якби ми це зробили, що, на вашу думку, сталося, якби ми намагалися зв`язати локальний та віддалений репозиторії?

У цьому випадку ми побачимо конфлікт злиття через неспоріднені історії. Коли GitHub створює файл README.md, він виконує коміт у віддаленому репозиторії. Коли ви намагаєтеся отримати зміни з віддаленого репозиторію до вашого локального, Git виявить, що вони мають історії, які не мають спільного походження, та відмовиться від злиття.

BASH

$ git pull origin main

ВИХІД

warning: no common commits
remote: Enumerating objects: 3, done.
remote: Counting objects: 100% (3/3), done.
remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (3/3), done.
From https://github.com/vlad/planets
 * branch            main     -> FETCH_HEAD
 * [new branch]      main     -> origin/main
fatal: refusing to merge unrelated histories

Ви можете змусити git об’єднати два сховища, використав опцію --allow-unrelated-histories. Будьте обережні, коли ви використовуєте цей параметр і уважно перевірте вміст локального і віддаленого репозиторіїв перед об’єднанням.

BASH

$ git pull --allow-unrelated-histories origin main

ВИХІД

From https://github.com/vlad/planets
 * branch            main     -> FETCH_HEAD
Merge made by the 'recursive' strategy.
README.md | 1 +
1 file changed, 1 insertion(+)
create mode 100644 README.md

Ключові моменти

  • Локальний репозиторій Git можна під’єднати до одного або декількох віддалених репозиторіїв.
  • Для підключення до віддалених репозиторіїв використовується протокол SSH.
  • git push копіює зміни з локального репозиторію до віддаленого репозиторію.
  • git pull копіює зміни з віддаленого репозиторію в локальний репозиторій.

Content from Співпраця


Останнє оновлення 2024-06-04 | Редагувати цю сторінку

Огляд

Питання

  • Як я можу використовувати контроль версій для співпраці з іншими?

Цілі

  • Клонування віддаленого репозиторію.
  • Співпраця шляхом надсилання змін до спільного репозиторію.
  • Загальний вигляд процесу співпраці.

Для наступного кроку слухачам потрібно розбитися на пари. Одна людина буде “Власником”, а інша - “Співавтором”. Мета полягає в тому, щоб Співавтор додав зміни в репозиторій Власника. У подальшому слухачі поміняються ролями так, щоб обидві людини спробували грати ролі як Власника, так і Співавтора.

Практика без партнера

Якщо ви працюєте над цим уроком самостійно, ви можете імітувати подібний сценарій, відкривши ще одне вікно терміналу. Це вікно буде представляти вашого партнера, який працює на іншому комп’ютері. Вам не буде потрібно надавати нікому доступ до GitHub, тому що обидва “партнери” - це ви.

Власник репозиторію повинен надати Співавтору доступ. У GitHub, натисніть кнопку “Settings” праворуч, оберіть “Collaborators”, натисніть “Add people”, та потім введіть ім`я користувача GitHub, повідомлене вашим партнером.

Сторінка репозиторію після вибору Settings -> Collaborators, яка показує додавання співавторів у GitHub

Щоб отримати доступ до репозиторію Власника, Співавтору потрібно відкрити https://github.com/notifications або перевірити наявність повідомлення електронною поштою. Потім треба прийняти відповідне запрошення, яке ви там знайдете.

Далі, Співавтор повинен завантажити копію репозиторію Власника на свій комп`ютер. Це називається “клонування репозиторію”.

Співавтор не хоче втратити свою власну версію planets.git, і тому йому потрібно клонувати репозиторій Власника в інше місце, аніж у свій власний репозиторій з такою ж назвою.

Щоб клонувати репозиторій Власника у каталог Desktop, Співавтор вводить:

BASH

$ git clone git@github.com:vlad/planets.git ~/Desktop/vlad-planets

(обовʼязково замініть ‘vlad’ на ім`я користувача GitHub Власника).

Якщо ви вирішите клонувати без додавання шляху клонування (~/Desktop/vlad-planets) вказаного в кінці команди, ви будете клонувати всередину вашого власного каталогу planets! Переконайтеся, що спочатку ви перейшли до каталогу Desktop.

Після клонування репозиторію

Співавтор тепер може зробити зміни у своєму клоні репозиторію Власника так само, як ми робили раніше:

BASH

$ cd ~/Desktop/vlad-planets
$ nano pluto.txt
$ cat pluto.txt

ВИХІД

It is so a planet!

BASH

$ git add pluto.txt
$ git commit -m "Add notes about Pluto"

ВИХІД

 1 file changed, 1 insertion(+)
 create mode 100644 pluto.txt

Далі, відправте зміни до репозиторію Власника на GitHub:

BASH

$ git push origin main

ВИХІД

Enumerating objects: 4, done.
Counting objects: 4, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 306 bytes, done.
Total 3 (delta 0), reused 0 (delta 0)
To https://github.com/vlad/planets.git
   9272da5..29aba7c  main -> main

Зауважте, що нам не потрібно було вказувати віддалений репозиторій під назвою origin: Git визначає його за замовчуванням, коли ми клонуємо репозиторій. (Ось чому origin був розумним вибором раніше, коли ми налаштовували віддалені репозиторії вручну.)

Подивіться знову на репозиторій Власника на GitHub, і ви маєте побачити новий коміт, зроблений Співавтором. Можливо, вам доведеться оновити ваш браузер, щоб побачити новий коміт.

Деякі інші відомості про віддалені репозиторії

У цьому і попередньому епізодах, наш локальний репозиторій мав єдиний “віддалений” репозиторій, під назвою origin. Віддалений - це копія репозиторію, яка знаходиться в іншому місці, з якою ми можемо обмінюватися комітами через git pull та git push, і немає жодних причин працювати тільки з одним віддаленим репозиторієм. Наприклад, у деяких великих проєктах у вас може бути власна копія у вашому власному обліковому записі GitHub (ви, ймовірно, назвете її origin), а також так званий “upstream” - головний репозиторій проєкту (ми назвемо його upstream для прикладу). Час від часу ви будете за допомогою git pull отримувати зміни з upstream, щоб отримати останні оновлення, які зробили інші.

Пам’ятайте, що ім’я, яке ви надаєте віддаленому репозиторію, існує лише локально. Це псевдонім, який ви вибираєте - будь то origin, чи upstream, чи fred - а не щось притаманне віддаленому репозиторію.

Сімейство команд git remote використовується для налаштування та зміни віддалених репозиторіїв, пов’язаних з локальним репозиторієм. Ось деякі з найбільш корисних:

  • git remote -v друкує всі віддалені репозиторії, які налаштовані (ми вже використовували це в останньому епізоді)
  • git remote add [name] [url] використовується для додавання нового віддаленого репозиторію
  • git remote remove [name] видаляє віддалений репозиторій. Зауважте, що це взагалі не впливає на віддалений репозиторій - він просто видаляє посилання на нього з локального репозиторію.
  • git remote set-url [name] [newurl] змінює URL, який пов`язаний з віддаленим репозиторієм. Це корисно, якщо він перейшов, наприклад, на інший обліковий запис GitHub або з GitHub на іншу платформу хостингу. Або, якщо ми зробили помилку при його додаванні!
  • git remote rename [oldname] [newname] змінює локальний псевдонім, під яким відомий віддалений репозиторій - тобто його назву. Наприклад, можна використовувати це, щоб змінити upstream на fred.

Тепер, щоб завантажити з GitHub зміни, які зробив Співавтор, Власник вводить:

BASH

$ git pull origin main

ВИХІД

remote: Enumerating objects: 4, done.
remote: Counting objects: 100% (4/4), done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 0), reused 3 (delta 0), pack-reused 0
Unpacking objects: 100% (3/3), done.
From https://github.com/vlad/planets
 * branch            main     -> FETCH_HEAD
   9272da5..29aba7c  main     -> origin/main
Updating 9272da5..29aba7c
Fast-forward
 pluto.txt | 1 +
 1 file changed, 1 insertion(+)
 create mode 100644 pluto.txt

Тепер три репозиторії (локальний Власника, локальний Співавтора, і репозиторій Власника на GitHub) знову синхронізуються.

Загальний вигляд процесу співпраці

На практиці добре бути впевненим, що у вас є оновлена версія репозиторію, над яким ви співпрацюєте, тому перед внесенням наших змін слід зробити git pull. Основним робочим процесом буде наступне:

  • оновити локальний репозиторій за допомогою git pull origin main,
  • робити свої зміни і додати їх до зони стейджингу за допомогою git add,
  • зберегти зміни за допомогою git commit -m, та
  • завантажити зміни на GitHub за допомогою git push origin main

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

Обмін ролями та повторення

Тепер поміняйтеся ролями та повторіть увесь процес.

Перегляд Змін

Власник надіслав коміти до репозиторію, не надаючи жодної інформації Співавтору. Як Співавтор може дізнатися, що змінилося, за допомогою командного рядка? А як дізнатися про це на GitHub?

В командному рядку, Співавтор може використати git fetch origin main, щоб завантажити віддалені зміни до локального репозиторію, але без їх об’єднання із версією Співавтора. Потім запустивши git diff main origin/main, Співавтор може побачити зміни у терміналі.

На GitHub, Співавтор може перейти у репозиторій і натиснути на “commits”, щоб переглянути найновіші коміти, що були надіслані до репозиторію.

Коментування змін в GitHub

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

У GitHub можна залишити коментар у вікні перегляду змін, зроблених у коміті. Наведіть курсор миші на рядок, який ви бажаєте прокоментувати, і тоді зліва з’явиться синій значок коментаря, який відкриє, якщо його натиснути, вікно для введення коментаря.

Таким чином, Співавтор публікує свої коментарі та пропозиції за допомогою інтерфейсу GitHub.

Історія версій, Резервне Копіювання та Контроль Версій

Деякі програми резервного копіювання можуть зберігати історію версій ваших файлів. Вони також дозволяють відновити певні версії. Чим їх функціональність відрізняється від контролю версій? Які переваги має використання контролю версій, Git та GitHub?

Ключові моменти

  • git clone копіює віддалений репозиторій у локальний репозиторій та автоматично налаштовує віддалений репозиторій як origin.

Content from Конфлікти


Останнє оновлення 2024-06-04 | Редагувати цю сторінку

Огляд

Питання

  • Що робити, коли мої зміни конфліктують зі змінами інших?

Цілі

  • Що таке конфлікти і коли вони можуть виникати.
  • Вирішення конфліктів, що виникають внаслідок злиття змін.

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

Щоб побачити, як ми можемо розвʼязувати конфлікти, спочатку ми повинні їх створити. Файл mars.txt наразі для обох партнерів виглядає однаково в їх клонах репозиторію planets:

BASH

$ cat mars.txt

ВИХІД

Cold and dry, but everything is my favorite color
The two moons may be a problem for Wolfman
But the Mummy will appreciate the lack of humidity

Тепер додамо один рядок до копії співавтора:

BASH

$ nano mars.txt
$ cat mars.txt

ВИХІД

Cold and dry, but everything is my favorite color
The two moons may be a problem for Wolfman
But the Mummy will appreciate the lack of humidity
This line added to Wolfman's copy

а потім відправимо наші зміни на GitHub:

BASH

$ git add mars.txt
$ git commit -m "Add a line in our home copy"

ВИХІД

[main 5ae9631] Add a line in our home copy
 1 file changed, 1 insertion(+)

BASH

$ git push origin main

ВИХІД

Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 8 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 331 bytes | 331.00 KiB/s, done.
Total 3 (delta 2), reused 0 (delta 0)
remote: Resolving deltas: 100% (2/2), completed with 2 local objects.
To https://github.com/vlad/planets.git
   29aba7c..dabb4c8  main -> main

Тепер нехай власник зробить іншу зміну у своїй копії без отримання нових змін з GitHub:

BASH

$ nano mars.txt
$ cat mars.txt

ВИХІД

Cold and dry, but everything is my favorite color
The two moons may be a problem for Wolfman
But the Mummy will appreciate the lack of humidity
We added a different line in the other copy

Ми можемо зробити коміт наших змін локально:

BASH

$ git add mars.txt
$ git commit -m "Add a line in my copy"

ВИХІД

[main 07ebc69] Add a line in my copy
 1 file changed, 1 insertion(+)

але Git не дозволить нам відправити зміни на GitHub:

BASH

$ git push origin main

ВИХІД

To https://github.com/vlad/planets.git
 ! [rejected]        main -> main (fetch first)
error: failed to push some refs to 'https://github.com/vlad/planets.git'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
Суперечливі зміни

Git не дозволяє цю операцію, оскільки виявляє, що віддалений репозиторій має нові оновлення, які не були включені до локальної гілки. Що ми повинні зробити - це отримати зміни з GitHub, обʼєднати їх з копією репозиторію, у якій ми зараз працюємо, а тільки потім надіслати їх на GitHub. Давайте почнемо з отримання змін:

BASH

$ git pull origin main

ВИХІД

remote: Enumerating objects: 5, done.
remote: Counting objects: 100% (5/5), done.
remote: Compressing objects: 100% (1/1), done.
remote: Total 3 (delta 2), reused 3 (delta 2), pack-reused 0
Unpacking objects: 100% (3/3), done.
From https://github.com/vlad/planets
 * branch            main     -> FETCH_HEAD
    29aba7c..dabb4c8  main     -> origin/main
Auto-merging mars.txt
CONFLICT (content): Merge conflict in mars.txt
Automatic merge failed; fix conflicts and then commit the result.

Команда git pull оновлює локальний репозиторій, щоб додати до нього ті зміни, які вже містяться у віддаленому репозиторії. Після того, як зміни з віддаленої гілки отримані, Git виявляє, що зміни, внесені до локальної копії, накладаються на ті, що були додані до віддаленого репозиторію, і тому Git відмовляється об’єднати дві версії, щоб уберегти нас від зіпсування нашої попередньої роботи. У файлі, де є конфлікт, він позначається наступним чином:

BASH

$ cat mars.txt

ВИХІД

Cold and dry, but everything is my favorite color
The two moons may be a problem for Wolfman
But the Mummy will appreciate the lack of humidity
<<<<<<< HEAD
We added a different line in the other copy
=======
This line added to Wolfman's copy
>>>>>>> dabb4c8c450e8475aee9b14b4383acc99f42af1d

Нашим змінам передує <<<<<<< HEAD. Потім Git вставив ======= як роздільник між змінами, що конфліктують, та позначив кінець вмісту, завантаженого з GitHub, за допомогою . (Рядок букв і цифр після цього маркера ідентифікує щойно завантажений коміт.)

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

BASH

$ cat mars.txt

ВИХІД

Cold and dry, but everything is my favorite color
The two moons may be a problem for Wolfman
But the Mummy will appreciate the lack of humidity
We removed the conflict on this line

Щоб закінчити злиття, ми додаємо mars.txt до зони стейджингу для цього злиття, а потім робимо коміт:

BASH

$ git add mars.txt
$ git status

ВИХІД

On branch main
All conflicts fixed but you are still merging.
  (use "git commit" to conclude merge)

Changes to be committed:

	modified:   mars.txt

BASH

$ git commit -m "Merge changes from GitHub"

ВИХІД

[main 2abf2b1] Merge changes from GitHub

Тепер ми можемо відправити наші зміни на GitHub:

BASH

$ git push origin main

ВИХІД

Enumerating objects: 10, done.
Counting objects: 100% (10/10), done.
Delta compression using up to 8 threads
Compressing objects: 100% (6/6), done.
Writing objects: 100% (6/6), 645 bytes | 645.00 KiB/s, done.
Total 6 (delta 4), reused 0 (delta 0)
remote: Resolving deltas: 100% (4/4), completed with 2 local objects.
To https://github.com/vlad/planets.git
   dabb4c8..2abf2b1  main -> main

Git відстежує, що ми об’єднали з чим, тому нам не потрібно знову виправляти речі вручну коли співавтор, який зробив першу зміну, знову виконує git pull:

BASH

$ git pull origin main

ВИХІД

remote: Enumerating objects: 10, done.
remote: Counting objects: 100% (10/10), done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 6 (delta 4), reused 6 (delta 4), pack-reused 0
Unpacking objects: 100% (6/6), done.
From https://github.com/vlad/planets
 * branch            main     -> FETCH_HEAD
    dabb4c8..2abf2b1  main     -> origin/main
Updating dabb4c8..2abf2b1
Fast-forward
 mars.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Ми отримуємо файл з об’єднаними змінами:

BASH

$ cat mars.txt

ВИХІД

Cold and dry, but everything is my favorite color
The two moons may be a problem for Wolfman
But the Mummy will appreciate the lack of humidity
We removed the conflict on this line

Нам не потрібно знову робити злиття змін, тому що Git знає, що хтось це вже зробив.

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

  • Отримуйте зміни частіше, особливо перед початком нової роботи
  • Використовуйте тематичні гілки для розділення роботи, з їх подальшим об’єднанням до гілки main, коли робота буде завершена
  • Робіть коміти невеликими та атомарними
  • Надсилайте свою роботу, коли вона закінчена, до спільного репозиторію, та заохочуйте свою команду робити те ж саме, щоб зменшити обсяг незавершеної роботи та, відповідно, ймовірність конфліктів
  • Там, де логічно доречно, розбивайте великі файли на менші, щоб було менше шансів, що два автори змінять один і той самий файл одночасно

Конфлікти також можна мінімізувати за допомогою дотримання деяких стратегій управління проєктами:

  • Домовляйтеся з вашими співавторами про те, хто відповідає за які аспекти проєкту
  • Обговоріть зі своїми співавторами, у якому порядку слід виконувати задачі, щоб ті, які можуть змінити одні і ті ж самі рядки, не виконувались одночасно
  • Якщо конфлікти є стилістичними (наприклад, табуляції або пробіли), домовтеся про стиль коду, яким ви будете керуватися, та використовуйте, якщо необхідно, інструменти для перевірки цього стилю (наприклад, htmltidy, perltidy, rubocop, та ін.) для забезпечення єдиного стилю

Вправа: створення та вирішення конфліктів

Клонуйте репозиторій, створений вашим інструктором. Додайте до нього новий файл та змініть деякий файл, що вже існує (ваш інструктор скаже, який саме). Потім, після підтвердження від вашого інструктора, отримайте нові зміни з цього репозиторію, щоб створити конфлікт, а потім вирішіть його.

Конфлікти у бінарних файлах

Що робить Git, коли виникає конфлікт у зображенні або іншому бінарному файлі, що зберігається у системі контролю версій?

Спробуймо це дослідити. Припустимо, Dracula робить фотографію марсіанської поверхні та називає її mars.jpg.

Якщо у вас немає файлу із зображенням Марса, ви можете створити фіктивний бінарний файл ось так:

BASH

$ head -c 1024 /dev/urandom > mars.jpg
$ ls -lh mars.jpg

ВИХІД

-rw-r--r-- 1 vlad 57095 1.0K Mar  8 20:24 mars.jpg

ls показує, що було створено файл розміром 1 кілобайт. Він містить випадкові байти, які були зчитані зі спеціального файлу /dev/urandom.

Тепер припустимо, що Dracula додає mars.jpg до свого репозиторію:

BASH

$ git add mars.jpg
$ git commit -m "Add picture of Martian surface"

ВИХІД

[main 8e4115c] Add picture of Martian surface
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 mars.jpg

Припустимо, що Wolfman тим часом додав схожу фотографію. Його зображення - марсіанське небо, але воно також названо mars.jpg. Коли Dracula намагається відправити зміни до віддаленого репозиторію, він отримує знайоме повідомлення:

BASH

$ git push origin main

ВИХІД

To https://github.com/vlad/planets.git
 ! [rejected]        main -> main (fetch first)
error: failed to push some refs to 'https://github.com/vlad/planets.git'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

Як ми вже дізналися раніше, ми повинні спочатку отримати зміни та вирішити будь-які конфлікти:

BASH

$ git pull origin main

Коли конфлікт виникає у зображенні або іншому бінарному файлі, git друкує повідомлення на кшталт наступного:

ВИХІД

$ git pull origin main
remote: Counting objects: 3, done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
From https://github.com/vlad/planets.git
 * branch            main     -> FETCH_HEAD
   6a67967..439dc8c  main     -> origin/main
warning: Cannot merge binary files: mars.jpg (HEAD vs. 439dc8c08869c342438f6dc4a2b615b05b93c76e)
Auto-merging mars.jpg
CONFLICT (add/add): Merge conflict in mars.jpg
Automatic merge failed; fix conflicts and then commit the result.

Повідомлення про конфлікт в основному виглядає так само як і для mars.txt, але воно має один додатковий рядок:

ВИХІД

warning: Cannot merge binary files: mars.jpg (HEAD vs. 439dc8c08869c342438f6dc4a2b615b05b93c76e)

Git не може автоматично вставляти маркери конфлікту у зображення, як він це робить для текстових файлів. Отже, замість редагування файлу зображення, ми повинні викликати з історії змін ту його версію, яку ми хочемо зберегти. Після цього ми можемо виконати відповідні команди git add та git commit, щоб зберегти цю версію.

В додатковому рядку вище, Git зручно надав нам ідентифікатори коміту для обох версій mars.jpg. Наша версія - HEAD, а Wolfman зберіг версію 439dc8c0.... Якщо ми хочемо використовувати нашу версію, ми можемо застосувати git checkout:

BASH

$ git checkout HEAD mars.jpg
$ git add mars.jpg
$ git commit -m "Use image of surface instead of sky"

ВИХІД

[main 21032c3] Use image of surface instead of sky

Якщо замість цього ми хочемо використовувати версію, яку додав Wolfman, ми можемо застосувати git checkout з ідентифікатором коміту, який зробив Wolfman - 439dc8c0:

BASH

$ git checkout 439dc8c0 mars.jpg
$ git add mars.jpg
$ git commit -m "Use image of sky instead of surface"

ВИХІД

[main da21b34] Use image of sky instead of surface

Ми також можемо зберегти обидва зображення. Але ж проблема у тому, що ми не зможемо залишити їх під однією й тією ж назвою. Проте ми можемо викликати з історії кожну версію послідовно та перейменувати файл, а потім додати перейменовані версії до репозиторію за допомогою git add. Спочатку відновіть з історії змін кожне зображення та перейменуйте його:

BASH

$ git checkout HEAD mars.jpg
$ git mv mars.jpg mars-surface.jpg
$ git checkout 439dc8c0 mars.jpg
$ mv mars.jpg mars-sky.jpg

Потім видаліть старий mars.jpg та додайте два нових файли:

BASH

$ git rm mars.jpg
$ git add mars-surface.jpg
$ git add mars-sky.jpg
$ git commit -m "Use two images: surface and sky"

ВИХІД

[main 94ae08c] Use two images: surface and sky
 2 files changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 mars-sky.jpg
 rename mars.jpg => mars-surface.jpg (100%)

Тепер обидва зображення Марса містяться у репозиторії, а файл mars.jpg більше не існує.

Типова робоча сесія

Ви сідаєте за комп’ютер, щоб працювати над спільним проєктом, який відстежується у віддаленому репозиторії Git. Під час сеансу роботи ви виконуєте наступні дії, але не в тому порядку, як вони перелічені нижче:

  • Зробити зміни, додавши число ‘100’ до текстового файлу numbers.txt
  • Оновити віддалений репозиторій, щоб він відповідав локальному репозиторію
  • Відсвяткувати свій успіх
  • Оновити локальний репозиторій, щоб він відповідав віддаленому репозиторію
  • Додати зміни до зони стейджингу
  • Зробити коміт у локальному репозиторії

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

крок дія . . . . . . . . . . команда . . . . . . . . . .
1
2 echo 100 >> numbers.txt
3
4
5
6 Відсвяткувати! AFK (Away From Keyboard)
крок дія . . . . . . команда . . . . . . . . . . . . . . . . . . .
1 Оновити локальний репозиторій git pull origin main
2 Зробити зміни echo 100 >> numbers.txt
3 Додати зміни до зони стейджингу git add numbers.txt
4 Зробити коміт git commit -m "Add 100 to numbers.txt"
5 Оновити віддалений репозиторій git push origin main
6 Відсвяткувати! AFK (Away From Keyboard)

Ключові моменти

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

Content from Відкрита наука


Останнє оновлення 2024-06-04 | Редагувати цю сторінку

Огляд

Питання

  • Як контроль версій допоможе мені зробити мою роботу більш відкритою?

Цілі

  • Пояснити, як систему контролю версій можна використовувати як електронний лабораторний журнал для обчислювальної роботи.

Протилежність “відкритої” не є “закрита”. Протилежність “відкритої” є “зламана”.

-– John Wilbanks

Мати вільний обмін інформацією було б ідеальним для науки, але реальність часто набагато складніша. Звичайна практика сьогодні виглядає приблизно так:

  • Вчений збирає деякі дані і зберігає їх у машині, резервна копія якої іноді робиться його відділом.
  • Потім він пише або змінює кілька невеликих програм (які також знаходяться на його машині), щоб аналізувати ці дані.
  • Отримавши певні результати, він описує їх і подає свою статтю для публікації. Вчений може надати свої дані - все більша кількість журналів вимагає цього - але він, ймовірно, не надасть свій код.
  • Проходить час.
  • Журнал надсилає йому відгуки рецензентів, написані анонімно кількома іншими фахівцями в його галузі. Він переглядає свою статтю, щоб задовольнити їх (протягом цього часу він також може змінити скрипти, які він написав раніше), та повторно подає статтю.
  • Проходить ще більше часу.
  • Зрештою стаття опублікована. Вона може містити посилання на онлайн-копію його даних, але сама стаття буде платною: тільки люди, які мають особистий або інституційний доступ зможуть її прочитати.

Хоча для все більшої кількості вчених процес виглядає так:

  • Дані, які збирає вчений, зберігаються у сховищі відкритого доступу на кшталт figshare або Zenodo (можливо, як тільки ці дані були зібрані), та отримують свій Цифровий ідентифікатор об’єкта (DOI). Або дані вже були опубліковані і зберігаються в Dryad.
  • Вчений створює новий репозиторій на GitHub для зберігання своєї роботи.
  • Під час аналізу він надсилає зміни до своїх скриптів (і, можливо, деякі вихідні файли) до цього репозиторію. Він також використовує його для своєї статті; цей репозиторій тепер стає платформою для співпраці з його колегами.
  • Коли вчений задоволений станом своєї статті, він публікує версію на arXiv або на іншому сервері препринтів, щоб отримати відгуки від колег.
  • На основі цих відгуків, він може опублікувати ще кілька редакцій перед тим, як нарешті подати свою статтю до журналу.
  • Опублікована стаття містить посилання на препринт, а також на місця зберігання коду та даних, що значно полегшує іншим вченим використання його роботи як відправної точки для власних досліджень.

Ця відкрита модель прискорює дослідження: чим більш відкрита робота, тим частіше її цитують і повторно використовують. Однак людям, які хочуть працювати таким чином, потрібно прийняти певні рішення щодо того, що саме означає “відкрито”, і як це зробити. Ви можете знайти більше інформації про різні аспекти відкритої науки в цій книзі.

Це одна з (багатьох) причин чому ми викладаємо контроль версій. Коли він використовується старанно, то він відповідає на питання “як?”, діючи як спільний електронний лабораторний блокнот для обчислювальної роботи:

  • Концептуальні етапи вашої роботи фіксуються, зокрема, хто зробив що і коли. Кожен крок позначається унікальним ідентифікатором (а саме, ідентифікатором коміту).
  • Ви можете прив’язати документацію з обґрунтуваннями, ідеями та іншою інтелектуальною роботою безпосередньо до змін, які випливають з них.
  • Ви можете перевірити, що ви використовували у своїх попередніх дослідженнях для того, щоб отримати результати обчислень однозначним та відновлюваним способом.
  • За допомогою системи контролю версій, такої як Git, всю історію репозиторію легко зберегти на необмежений термін.

Робіть код можливим для цитування

Все, що зберігається у репозиторії системи контролю версій (дані, код, статті тощо) можна перетворити на об’єкт для цитування. Ви дізнаєтеся, як це зробити в пізнішому епізоді “Цитування”.

Наскільки відтворюваною є моя робота?

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

Як знайти відповідне сховище для даних?

Протягом декількох хвилин перегляньте сховища даних, згадані вище:: Figshare, Zenodo, Dryad. Залежно від вашої галузі досліджень, ви можете знайти сховища, визнані спільнотою, які добре відомі у вашій області. Вам також можуть бути корисні ці сховища даних, які рекомендовані Nature. Обговоріть зі своїм сусідом, яке сховище даних може підійти для вашого поточного проєкту, і поясніть, чому.

Як відстежувати великі файли з даними або зображеннями за допомогою Git?

Великі файли даних або зображень, такі як файли .md5 або .psd можуть бути відстежені в репозиторії github, використовуючи розширення Git Large File Storage. Це розширення (до речі, з відкритим кодом) автоматично завантажує вміст великого файлу на віддалений сервер і замінює цей файл текстовим вказівником у репозиторії GitHub.

Спробуйте завантажити та встановити розширення Git Large File Storage, а потім додати великий файл до репозиторію GitHub. Попросіть колегу клонувати ваш репозиторій та перевірте, що вони бачать, коли відкривають цей великий файл.

Ключові моменти

  • Відкрита наукова робота є більш корисною та частіше цитованою, ніж закрита.

Content from Ліцензування


Останнє оновлення 2024-06-04 | Редагувати цю сторінку

Огляд

Питання

  • Яку інформацію про ліцензію має містити моя робота?

Цілі

  • Пояснити, чому важливо додавати інформацію про ліцензування до репозиторію.
  • Як обрати відповідну ліцензію?
  • Пояснити відмінності в ліцензуванні та соціальних очікуваннях.

Коли репозиторій з вихідним кодом, рукописом або іншими творчими роботами стає публічним, він повинен містити у головному каталозі репозиторію файл під назвою LICENSE або LICENSE.txt, у якому чітко вказано, під якою ліцензією надається контент. Це пояснюється тим, що творчі роботи автоматично мають право на захист інтелектуальної власності (і, отже, авторських прав). Повторне використання творчих робіт без ліцензії є небезпечним, оскільки правовласники можуть подати на вас до суду за порушення авторських прав.

Ліцензія вирішує цю проблему, надаючи іншим особам (ліцензіатам) права, яких вони в іншому випадку не мали б. Те, які права надаються, і за яких умов, може відрізнятися, але часто не дуже, у різних ліцензіях. На практиці, деякі ліцензії на сьогодні є найпопулярнішими, і choosealicense.com може допомогти вам знайти поширену ліцензію, яка відповідає вашим потребам. Важливими міркуваннями є:

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

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

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

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

Чи можу я використовувати відкриту ліцензію?

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

З якими ліцензіями ми вже погодились?

Багато програм, якими ми користуємося щодня (у тому числі і на цьому семінарі) доступні як програмне забезпечення з відкритим вихідним кодом. Виберіть на GitHub проєкт зі списку нижче, або інший проєкт на ваш вибір. Знайдіть його ліцензію (зазвичай у файлі під назвою LICENSE або COPYING) і подивіться як вона обмежує використання програмного забезпечення. Чи це одна з ліцензій обговорювана у цьому епізоді? Якщо ні, то чим вона відрізняється?

  • Git - інструмент для управління вихідним кодом
  • CPython - стандартна реалізація мови Python
  • Jupyter - проєкт, який стоїть за вебноутбуками Python, які ми будемо використовувати
  • EtherPad - редактор для спільної роботи в реальному часі

Ключові моменти

  • Файли з імʼям LICENSE, LICENSE.md, або LICENSE.txt часто використовуються у репозиторіях, щоб вказати, як їх вміст може застосовуватися іншими.
  • Розробники, які створюють власне програмне забезпечення, яке містить в собі інший код, розповсюджуваний за General Public License (GPL), також повинні зробити своє програмне забезпечення відкритим під ліцензією GPL; більшість інших відкритих ліцензій цього не вимагають.
  • Сімейство ліцензій Creative Commons дозволяє авторам гнучко комбінувати вимоги та обмеження щодо зазначення авторства, створення похідних творів, подальшого поширення та комерціалізації.
  • Люди, які не є юристами, не повинні намагатися писати ліцензії з нуля.

Content from Цитування


Останнє оновлення 2024-06-04 | Редагувати цю сторінку

Огляд

Питання

  • Як полегшити цитування моєї роботи?

Цілі

  • Зробити вашу роботу легкою для цитування

Ви можете додати файл під назвою CITATION або CITATION.txt, який описує, як цитувати ваш проєкт; наприклад, для Software Carpentry цей файл зазначає:

To reference Software Carpentry in publications, please cite both of the following:

Greg Wilson: "Software Carpentry: Getting Scientists to Write Better
Code by Making Them More Productive".  Computing in Science &
Engineering, Nov-Dec 2006.

Greg Wilson: "Software Carpentry: Lessons Learned". arXiv:1307.5448,
July 2013.

@article{wilson-software-carpentry-2006,
    author =  {Greg Wilson},
    title =   {Software Carpentry: Getting Scientists to Write Better Code by Making Them More Productive},
    journal = {Computing in Science \& Engineering},
    month =   {November--December},
    year =    {2006},
}

@online{wilson-software-carpentry-2013,
  author      = {Greg Wilson},
  title       = {Software Carpentry: Lessons Learned},
  version     = {1},
  date        = {2013-07-20},
  eprinttype  = {arxiv},
  eprint      = {1307.5448}
}

Більш детальні поради та інші способи зробити ваш код цитованим можна знайти у блозі Software Sustainability Institute, а також у:

Smith AM, Katz DS, Niemeyer KE, FORCE11 Software Citation Working Group. (2016) Software citation
principles. [PeerJ Computer Science 2:e86](https://peerj.com/articles/cs-86/)
https://doi.org/10.7717/peerj-cs.8

Існує також тип запису @software{... для BibTeX на випадок, якщо для проєкту, який ви хочете процитувати, немає «джерела-парасольки» для цитування, такого як стаття або книга.

Ключові моменти

  • Додайте файл CITATION до репозиторію, щоб пояснити у ньому, як ви хочете бачити посилання на свою роботу.

Content from Хостинг


Останнє оновлення 2024-06-04 | Редагувати цю сторінку

Огляд

Питання

  • Де я можу розміщувати репозиторії контролю версій?

Цілі

  • Пояснити різні варіанти хостингу наукової роботи.

Друге велике питання для груп, які хочуть розмістити свою роботу у відкритому доступі, полягає в тому, де розмістити свій код і дані. Один із варіантів полягає в тому, щоб лабораторія, кафедра чи університет надали сервер, керували обліковими записами та резервними копіями тощо. Основна перевага цього полягає в тому, що при цьому зʼясується кому що належить. Це особливо важливо, коли будь-який матеріал є чутливим (тобто стосується експериментів за участю людей або може бути використаний у патентній заявці). Основними недоліками цього є вартість надання послуги та її довговічність: вчений, який витратив десять років на збір даних, бажав би бути впевненим, що дані все ще будуть існувати через десять років. Але це значно перевищує термін більшості грантів, які фінансують академічну інфраструктуру.

Інший варіант - придбати домен і заплатити інтернет-провайдеру (ISP) за його підтримку. Це дає індивіду або групі більше контролю, і обходить проблеми, які можуть виникнути при переході з однієї установи в іншу. Але це вимагає більше часу і зусиль для налаштування, ніж попередній варіант або наступний варіант.

Третім варіантом є використання публічного хостингу, як GitHub, GitLab, або BitBucket. Кожна з цих платформ надає вебінтерфейс, який дозволяє людям створювати, переглядати та редагувати свої репозиторії. Ці платформи також надають засоби комунікації та управління проєктами, такі як: відстеження проблем, вікі-сторінки, автоматичні сповіщення електронною поштою, та перегляд коду. Вони отримують перевагу від того, що легше добре підтримувати одну велику платформу, ніж запустити багато менших сервісів з тим самим рівнем якості. Також, на великих платформах легше співпрацювати. Їх використання може допомогти звʼязати ваш проєкт зі спільнотами, які вже використовують ту ж саму платформу.

Наприклад, Software Carpentry знаходиться на GitHub, де ви можете знайти джерело для цієї сторінки. Будь-хто з обліковим записом GitHub може запропонувати зміни до цього тексту.

Репозиторіям GitHub також можуть бути присвоєні DOI, шляхом підключення їх релізів до Zenodo. Наприклад, 10.5281/zenodo.57467 - це DOI, який був “викарбуваний” для цього введення до Git.

Використання великих, добре налагоджених сервісів також може допомогти вам швидко скористатися перевагами потужних інструментів. Один з таких інструментів, безперервна інтеграція (БI), може автоматично запускати програмні збірки та тести щоразу, коли виконується код або надходять запити на отримання змін. Пряма інтеграція БI з онлайн-хостингом означає, що ця інформація присутня в будь-якому запиті на отримання змін, і допомагає підтримувати цілісність коду та стандарти якості. Хоча БI може бути доступна у варіантах із самостійним хостингом, використання онлайн-сервісу вимагає набагато менше зусиль з налаштування та обслуговування. Крім того, такі інструменти часто надаються безкоштовно для проєктів з відкритим вихідним кодом, а також доступні для приватних репозиторіїв за окрему плату.

Інституційні бар’єри

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

Чи може моя робота бути у відкритому доступі?

Дізнайтеся, чи дозволено вам відкрито розміщувати свою роботу в публічному репозиторії. Чи можете ви зробити це в односторонньому порядку, або вам потрібен дозвіл від когось у вашому закладі? Якщо так, то від кого?

Де я можу розмістити свою роботу у відкритому доступі?

Чи є у вашій установі репозиторій або репозиторії, які ви можете використовувати для обміну документами, даними та програмним забезпеченням? Чим інституційні репозиторії відрізняються від таких сервісів, як arXiV, figshare, GitHub або GitLab?

Ключові моменти

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

Content from Додатково: Використання Git з RStudio


Останнє оновлення 2024-06-04 | Редагувати цю сторінку

Огляд

Питання

  • Як я можу використовувати Git з RStudio?

Цілі

  • Зрозуміти, як використовувати Git з RStudio.

Контроль версій може бути дуже корисним під час розробки скриптів для аналізу даних. Для цього популярне середовище розробки для мови програмування R, яке називається RStudio, має вбудовану інтеграцію з Git. Хоча для деяких розширених функцій Git все ще потрібен командний рядок, RStudio має зручний інтерфейс для найбільш поширених операцій Git.

RStudio дозволяє створити проєкт, пов’язаний з вказаним каталогом, для відстеження відповідних файлів. Використання Git для контролю версій у проєкті Rstudio надасть нам можливість відстежувати розвиток проєкту з часом, повертатися до попередніх версій, та співпрацювати з іншими. Для того, щоб почати використовувати Git в RStudio, ми створимо новий проєкт:

Знімок екрана RStudio, що показує меню файлу з вибраним пунктом "New Project..."

Цей крок відкриває діалогове вікно із запитанням про те, як саме ми хочемо створити проєкт. Тут ми маємо кілька варіантів. Припустимо, що ми хочемо використовувати RStudio з репозиторієм planets, який ми вже створили раніше. Оскільки цей репозиторій міститься в каталозі на нашому комп’ютері, ми обираємо опцію “Existing Directory”:

Знімок екрана RStudio, що показує діалогове вікно New Project з обраним пунктом "Create project from existing directory"

Перевірте, чи бачите ви опцію “Version Control”

Хоча ми не збираємося використовувати її тут, в цьому меню повинна бути опція “version control”. Це те, що ви б обрали, якщо захочете створити проєкт на своєму комп’ютері шляхом клонування репозиторію з GitHub. Якщо ця опція відсутня, це, ймовірно, означає, що RStudio не знає, де знаходиться ваш виконуваний файл Git, і ви не зможете просуватися далі в цьому уроці, поки ви не скажете RStudio, де він.

Знайдіть виконуваний файл Git

Спочатку переконаймося, що Git встановлено на вашому комп’ютері. Відкрийте термінал у Mac або Linux, або відкрийте командний рядок у Windows, і введіть:

  • which git (macOS, Linux)
  • where git (Windows)

Якщо на вашому комп’ютері немає ніякої версії Git, будь ласка, дотримуйтесь інструкцій зі встановлення Git з цього ж самого уроку, щоб встановити Git зараз. Далі відкрийте термінал або командний рядок і знов введіть which git (macOS, Linux), або where git (Windows). Скопіюйте шлях до виконуваного файлу git.

Наприклад, на деякому комп’ютері Windows, на якому встановлено GitHub Desktop, шлях може бути таким: C:/Users/UserName/AppData/Local/GitHubDesktop/app-1.1.1/resources/app/git/cmd/git.exe

ПРИМІТКА: Шлях на вашому комп’ютері буде дещо іншим.

Повідомте RStudio, де знайти Git

У RStudio перейдіть до меню Tools > Global Options > Git/SVN, а потім перейдіть до виконуваного файлу Git, який ви знайшли в командному рядку або терміналі. Тепер перезапустіть RStudio. Примітка: Навіть якщо у вас встановлений Git, якщо ви використовуєте macOS, то вам може знадобитися прийняти ліцензію Xcode.

Далі RStudio запитає, який наявний каталог ми хочемо використовувати. Натисніть “Browse…” і перейдіть до відповідного каталогу, потім натисніть”Create Project”:

Чудово! Ми створили новий проєкт в RStudio в рамках наявного репозиторію planets. Зверніть увагу на вертикальне меню “Git” у панелі меню. RStudio визнав, що поточний каталог є репозиторієм Git, і пропонує нам ряд інструментів для використання Git:

Вікно RStudio після створення нового проєкту з великою стрілкою, що вказує на вертикальну панель меню Git.

Щоб редагувати наявні файли в репозиторії, ми можемо натискати на них у панелі “Files” у правому нижньому куті. Тепер додамо деяку інформацію про Плутон:

Після того, як ми зберегли наші відредаговані файли, ми можемо використати RStudio для збереження змін, натиснувши на “Commit…” в меню Git:

Знімок екрана RStudio, що показує меню Git з обраним пунктом "Commit..."

Це відкриє діалогове вікно, де ми можемо вказати, які файли зберігати у коміті (обираючи відповідні поля у стовпці “Staged”), та ввести повідомлення коміту (у верхній правій панелі). Піктограми у стовпці “Status” вказують поточний стан кожного файлу. Натискання на файлі показує інформацію про зміни у нижній панелі (використовуючи результат команди git diff). Як тільки все виглядає так, як ми хочемо, ми натискаємо “Commit”:

Зміни можна відправити до віддаленого репозиторію, обравши “Push Branch” з меню Git. Існують також опції меню для отримання змін з віддаленого репозиторію та для перегляду історії комітів:

Знімок екрана RStudio, що показує меню git з обраним пунктом "History"

Що робити, якщо команди Push/Pull виділені сірим кольором?

Якщо команди Push/Pull не активні, це зазвичай означає, що RStudio не знає місце знаходження вашого віддаленого репозиторію (наприклад, на GitHub). Щоб виправити це, відкрийте термінал у репозиторії і введіть команду git push -u origin main. Потім перезавантажте RStudio.

Якщо натиснути на “History”, ми побачимо графічну версію того, що нам сказав би git log:

RStudio створює ряд файлів, які використовуються для відстеження проєкту. Зазвичай ми не хочемо відстежувати їх у Git; в цьому випадку ми додаємо їх до нашого файлу .gitignore:

Знімок екрану RStudio, що показує .gitignore, відкритий у вікні редактора з файлами .Rproj.user, .Rhistory, .RData, та *.Rproj, доданими наприкінці

Порада: як виключити файли з контролю версій

Як правило, ви не хочете відстежувати версії похідних файлів, які можуть бути видалені та потім відтворені (наприклад, результатів аналізу), або даних, які використовуються лише для читання. У такому разі ви повинні змінити файл .gitignore, щоб повідомити Git, що треба ігнорувати ці файли та директорії.

Завдання

  1. Створіть у вашому проєкті новий каталог під назвою graphs.
  2. Змініть .gitignore, щоб graphs не відстежувався контролем версій.

Це можна зробити в Rstudio наступним чином:

R

dir.create("./graphs")

Потім відкрийте файл .gitignore з правої панелі Rstudio та додайте graphs/ до списку файлів, які слід ігнорувати.

У меню Git у RStudio є ще багато інших функцій, але цих має бути достатньо, щоб почати!

Ключові моменти

  • Використання інтеграції Git із RStudio дозволяє відстежувати еволюцію проєкту.