Перейти до основного вмісту

Git

Основні команди

# Ініціалізація git-репозиторію
git init

# Перегляд журналу коммітів
git log

# Переглянути історію виконання команди
git reflog

# Перегляд поточного статусу
git status

git restore

# Додавання вмісту робочого каталогу до індексної області
git add <name> # добавити конкретний файл
git add . # добавити всі змінені файли

git restore <name>
git restore .

# Якщо файл у робочому просторі було змінено і ці зміни є поетапними, ви можете скинути поетапні зміни за допомогою
# цієї команди
git restore --staged <name>
git restore --staged .

git commit

### git commit
git commit
git commit -m 'commit повідомлення'

# Ця команда може бути використана для переписування поточного вмісту та повідомлення комміту
git commit --amend
git commit --amend --reset-author

гілка git

# Показати всі гілки
git branch

# Показати всі віддалені гілки
git branch -r

# Створити гілку
git branch <назва_гілки>

# Видалити локальні гілки
git branch -D <branch_name>

# Змінити назву гілки
git branch -m <old_branch_name> <new_branch_name>

# Перемикання гілок
git checkout <branch_name>

# Перехід до попередньої гілки
git checkout -

# Створити гілку і переключитися
git checkout -b <name>

# Переглянути інформацію про трек гілки
git branch -vv

# Встановити висхідну гілку поточної гілки, еквівалентно --set-upstream
git branch -u origin/feature

git-тег

# Переглянути всі теґи
git tag

# позначити поточну фіксацію
git tag v1.0.1

# Позначити тегом комміт
git tag v1.0.1 <commit>

# Видалити тег
git tag --delete v1.0.1

git stash

# поетапне внесення змін до робочого простору
git stash

# переглянути вміст stash
git stash list

# відновити вміст останнього stash до робочого простору
git stash pop 0

# Видалити вміст stash
git stash clear

Злиття гілок

У git передбачено дві стратегії об'єднання гілок: git merge та git rebase. Рекомендую використовувати git rebase для керування гілками, оскільки це дуже проста стратегія і зберігає історію коммітів дуже чистою.

git merge

# об'єднати цільову гілку
git merge <name>

При використанні git merge існує два сценарії злиття, fast-forward і non-forward, залежно від гілки. Більшість часу при роботі з декількома людьми використовується сценарій non-fast-forward, коли об'єднана гілка створює новий комміт.

git rebase

### Об'єднати цільову гілку
git rebase <name>

конфлікти

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

Віддалені операції

git remote # Переглянути інформацію про віддалений репозиторій
git remote add origin <url> # Додати адрес віддаленого репозиторію
git remote remove origin # Видалити адрес віддаленого репозиторію

git clone <url> # Перетягнути віддалений репозиторій до локального

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

Поширеним сценарієм є ситуація, коли ми хочемо внести код до одного зі репозиторіїв Github, ми робимо fork і clone нашого репозиторію, де origin представляє наше власне віддалений репозиторій, зазвичай ми також вручну додаємо репозиторій за допомогою git remote add upstream <url>, щоб пов'язати оригінальний репозиторій з відкритим кодом з останніми оновленнями коду, де upstream представляє оригінальний репозиторій.

Гілка віддаленого відстеження

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

Коли ви використовуєте git clone для створення локального сховища, він не лише використовує origin для представлення віддаленого репозиторію за замовчуванням, але й автоматично створює зв'язок відстеження для локальної гілки, наприклад, гілка master автоматично відстежуватиме гілку origin/master, яка також називається гілкою master Tracking Branch, а гілка origin/master буде називатися Висхідна гілка. Насправді коли ви запускаєте git push або git pull безпосередньо без вказівки інформації про гілку, цільова гілка визначається на основі відносин відстеження поточної гілки.

git branch -vv

Використовуйте git branch -vv, щоб переглянути всю інформацію про відстеження

Створення висхідної гілки

# Чотири способи створення функціональної гілки, яку ви хочете відстежувати у гілці origin/master
git branch -u origin/master <branch_name>
git branch -u origin/master # за замовчуванням переходить до поточної гілки, якщо не вказано назву гілки

git branch --set-upstream-to=origin/master <branch_name>
git branch --set-upstream-to=origin/master

git fetch

# отримати всі віддалені коміти та гілки для віддаленого репозиторію
git fetch

# витягнути віддалені коміти та гілки для origin remote
git fetch origin

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

git fetch && git rebase origin/master

git pull

По суті, команда git pull виконує команду git fetch із заданими аргументами й за замовчуванням використовує стратегію git merge для злиття цільової гілки, тому git pull origin master еквівалентна git fetch origin master && git merge origin/master.

Ми також можемо налаштувати стратегію злиття гілок для git pull наступним чином:

git config pull.rebase false # git merge (за замовчуванням)
git config pull.rebase true # git rebase (особиста рекомендація)
git config pull.ff only # git merge

git push

git push використовується для відсилання вказаної гілки до цільового віддаленого репозиторію.

git push origin main # Перемістити головну гілку цього репозиторію до головної гілки оригіналу

git push origin test --delete # Видалити віддалену гілку

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

git push origin branchA:branchB

Відкат версій

Відкат версій виконується за допомогою git reset --hard, який по суті перемикає коміти, на які вказує вказівник HEAD, де HEAD^ позначає останній коміт HEAD, а HEAD~2 позначає два останні коміти HEAD.

# Відкотитися до попереднього коміту
git reset --hard HEAD^
git reset --hard HEAD^^
git reset --hard Head~3

# Відкат до попереднього коміту, але зміни поточного коміту не зникають, вони зберігаються в робочому просторі
git reset head^^ git reset --hard Head

На додаток до git reset, ми також можемо використовувати git revert для скасування коміту. git revert створить новий комміт.

# Відмінити поточну фіксацію
git revert HEAD

git rebase -i

git rebase -i origin/main 

Інтерактивний git rebase дозволяє стискати коміти, видаляти їх, змінювати порядок, редагувати конкретний історичний коміт тощо.

git cherry-pick

git cherry-pick <commit>

Основні принципи

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

Зазвичай, коли ми змінюємо файл у робочому каталозі, ми синхронізуємо оновлення з індексом за допомогою git add (тобто створюємо новий вузол object у сховищі git і оновлюємо індекс, що вказує на нього), а потім використовуємо git commit для створення нового вузла commit (тобто створюємо вузол tree на основі індексу, що вказує на нього, а потім у новому вузлі commit буде записано нову інформацію про файл.

Якщо припустити, що і в commitA, і в commitB записано файл test, то якщо ми перейдемо до commitB, перебуваючи у commitA, і змінимо файл у робочому каталозі, або синхронізуємо його з індексною областю, якщо він не був зафіксований, то наші локальні зміни буде синхронізовано до commitB.

Однак, якщо у нас є файл a, записаний у commitA, а файл a не існує у commitB, і ми змінюємо файл a, перебуваючи у commitA, перемикання безпосередньо до commitB не вдасться і нагадає нам, що спочатку слід зафіксувати наші зміни, або ми можемо скористатися git stash для того, щоб зберегти наші зміни у commitA.

Наприклад, ми можемо використати git stash для збереження змін, потім перейти до commitB і використати git stash pop для вилучення змін, коли ми повернемося до commitA у майбутньому.

Об'єкт git

### Показати всі об'єкти
ls .git/objects/
10/ ea/ 1c/ ... /info /pack

# Перегляд типів/значень об'єктів, поширені типи: blob (створюється після git add), tree та commit
# (створюється після git commit)
git cat-file -t 58c9
git cat-file -p 58c9 # 58c9 - значення об'єкта, який ви хочете знайти