> For the complete documentation index, see [llms.txt](https://olexsyn.gitbook.io/enote/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://olexsyn.gitbook.io/enote/dev/git.md).

# Git

* \[GitHub] - (github)
  * \[Jekyll конструктор] - (github/pages/jekyll)
* [Книга Pro Git](/enote/dev/git/git-scm-book.md)
* Git How To - <https://githowto.com/uk>
* [Робота з гілками](/enote/dev/git/branches.md)
  * `git fetch` - отримує зміни лише **з поточної гілки**.
  * `git fetch --all` - отримати всі зміни **з усіх гілок**.
  * `git fetch --all --prune` - якщо ви хочете очистити гілки, які більше не існують у віддаленому сховищі

### Клонувати репозиторій

Тобто зберегти на комп’ютері репозиторій з **github** :

```
git clone git@github.com:NICKNAME/REP.git
```

Ця команда створить в поточній дерикторії дерикторію 'REP', де і розмістить усі файли проекту.

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

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

А взагалі можна відразу клонувати в потрібну вам директорію, на кшталт

```
git clone https://github.com/NICKNAME/REP.git some_dir_name
```

Потім переходимо в неї і працюємо з git:

```
cd REP
# (або cd some_dir_name)
git status
...
```

### Перегляд віддалених репозиторіїв

```
git remote
origin
```

Если вы клонировали репозиторий, то увидите как минимум `origin` -- имя по умолчанию, которое Git дает серверу, с которого производилось клонирование. Можно также указать ключ `-v`, чтобы просмотреть адреса для чтения и записи, привязанные к репозиторию:

```
git remote -v

origin  git@github.com:olexsyn/e-note.git (fetch)
origin  git@github.com:olexsyn/e-note.git (push)
```

[подробнее...](https://git-scm.com/book/ru/v2/%D0%9E%D1%81%D0%BD%D0%BE%D0%B2%D1%8B-Git-%D0%A0%D0%B0%D0%B1%D0%BE%D1%82%D0%B0-%D1%81-%D1%83%D0%B4%D0%B0%D0%BB%D1%91%D0%BD%D0%BD%D1%8B%D0%BC%D0%B8-%D1%80%D0%B5%D0%BF%D0%BE%D0%B7%D0%B8%D1%82%D0%BE%D1%80%D0%B8%D1%8F%D0%BC%D0%B8)

### добавить отдаленный репозиторий и присвоить ему имя (shortname)

```
git remote add SHORTNAME URL
```

```
git remote add e-note git@github.com:olexsyn/e-note.git
```

Теперь вместо указания полного пути мы можем использовать 'e-note'.

### получение изменений с сервера

```
git fetch origin
```

Команда `git fetch` забирает данные в ваш локальный репозиторий, но не сливает их с какими-либо вашими наработками и не модифицирует то, над чем вы работаете в данный момент. Вам необходимо вручную слить эти данные с вашими, когда вы будете готовы.

```
git merge origin/branch_name
```

Команда `git pull`, как правило, извлекает (fetch) данные с сервера и автоматически пытается слить (merge) их с кодом, над которым вы в данный момент работаете.

## отправка изменений на сервер

Когда вы хотите поделиться своими наработками, вам необходимо отправить их в удаленный репозиторий.

```
git push REMOTE-NAME BRANCH-NAME
```

Чтобы отправить вашу ветку main на сервер origin (клонирование обычно настраивает оба этих имени автоматически), вы можете выполнить следующую команду для отправки ваших коммитов:

```
git push origin main
```

### Сокращенный вывод статуса

`-s` или `--short`

```
git status -s

 M README
MM Rakefile
A  lib/git.rb
M  lib/simplegit.rb
?? LICENSE.txt
```

В выводе два столбца: в левом - статус, в правом - (не)модифицирован

* `??` - новые неотслеживаемые файлы
* `A·` - файлы добавленные в отслеживаемые
* `·M` - модифицирован и НЕ проиндексирован
* `M·` - модифицирован и проиндексирован
* `MM` - модифицирован, проиндексирован и еще раз модифицирован, т.е. на данный момент у него есть изменения которые попадут в коммит и те которые не попадут

```
git add file1.ext file2.ext ...
```

```
git add --all
```

## Коммит

```
git commit -m 'Commit comment'
```

### Додати в останній коміт файли

Сначала добавляем в индекс файлы, которые необходимо присоединить к последнему коммиту, затем выполнить команду `commit`:

```
git add --all
git commit --amend --no-edit
```

* `--amend` - при использовании этого ключа, на самом деле удаляется последний коммит и создается новый. Поэтому нельзя выполнять `--amend` для коммитов, которые уже были отправлены на удаленный репозиторий (для которых был выполнен `git push`).
* `--no-edit` - позволяет оставить текущей комментарий к коммиту без изменений

Если необходимо также изменить и комментарий, то:

```
git commit -m 'New commit comment' --amend
```

### Просмотр истории коммитов

```
git log
git log --stat
```

### Побачити останні коміти по гілках

```
git branch -v
  atmo 2def2c2 atmo: end, to main brunch
  iss9 91bf676 iss9 process
* main ff22c5e add local icon
```

Опції `--merged` та `--no-merged` корисні для фільтрування списку гілок залежно від того чи вони були злиті з поточною гілкою.

```
git branch --merged:
  atmo
* main
```

Ви бачите `atmo` в цьому списку тому, що раніше її злили з `main`. Взагалі, гілки без \* із цього списку можна вже видаляти (за допомогою `git branch -d`), адже ми вже інтегрували ті зміни, тому не втратимо їх.

Наступна команда покаже гілки, які ви не зливали з поточною гілкою:

```
git branch --no-merged
  iss9
```

Тут ви бачите свою іншу гілку. Оскільки дана гілка містить роботу, що не зливалася, спроба видалити її за допомогою `git branch -d` не буде успішною.

```
git branch -d iss9
  error: The branch 'testing' is not fully merged.
  If you are sure you want to delete it, run 'git branch -D testing'.
```

Якщо ж ви дійсно впевнені в тому, що гілка вам не потрібна і всі зміни з неї можна втрачати, можна змусити Git це зробити за допомогою параметра `-D`

i Описані вище опції `--merged` і `--no-merged`, якщо не надати команді хеш коміту чи назву гілки як аргумент, покажуть, що, відповідно, було чи не було залите до **поточної** гілки. Завжди можна додати ще один аргумент, щоб дізнатися про стан злиття відносно якоїсь іншої гілки — немає потреби спочатку на неї переходити. Наприклад, з поточної гілки `testing` дивимося, що не було залите до гілки `main`?

```
git checkout testing
git branch --no-merged master
  topicA
  featureB
```

### [Возвращение файла к предыдущему состоянию](https://olexsyn.gitbook.io/enote/dev/pages/GmM1ir0sNh3NugFJhCZn#2.-vozvrashenie-faila-k-predydushemu-sostoyaniyu)

### TODO!

`git commit -m "description" filename.ext` - коммит только одного файла

### Примусово оновити віддалений репозиторій:

```
git push -f origin master
```

! Але слід розуміти, що на сервері затруться всі зміни в файлах, які були зроблені після останнього `git push`, навіть якщо відправляється лише один файл.

### Примусово оновити локальний репозиторій:

#### Якщо вам байдужі локальні зміни

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

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

```
git fetch
git reset --hard HEAD
git merge origin main
```

#### Якщо незафіксовані зміни важливі для вас

Є два варіанти. Ви можете закріпити їх, а потім виконати `git pull`, або ви можете приховати їх.

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

Щоб повернути зміни, збережені в останньому сховищі, скористайтеся `git stash pop` командою. Після успішного застосування схованих змін ця команда також видаляє сховану фіксацію, оскільки вона більше не потрібна.

Тоді робочий процес може виглядати так:

```
git fetch
git stash
git merge origin main
git stash pop
```

За замовчуванням зміни зі сховища стануть поетапними. Якщо ви хочете скасувати їх стадію, скористайтеся командою `git restore --staged` (якщо використовується Git, новіша за 2.25.0).

#### Ви просто хочете завантажити віддалені зміни

Останній сценарій трохи відрізняється від попередніх. Скажімо, ви перебуваєте в середині дуже заплутаного рефакторинга. Ані втрачати зміни, ані зберігати їх не можна. Тим не менш, ви все одно хочете мати віддалені зміни, доступні для `git diff` їх виконання.

Як ви, мабуть, зрозуміли, для завантаження віддалених змін зовсім не потрібен ~~`git pull`~~! `git fetch` буде достатньо.

* `git fetch` - отримує зміни лише **з поточної гілки**.
* `git fetch --all` - отримати всі зміни **з усіх гілок**.
* `git fetch --all --prune` - якщо ви хочете очистити гілки, які більше не існують у віддаленому сховищі

#### Але є і Git Pull Force

Допитливі уми, можливо, вже виявили, що існує така річ, як `git pull --force`. Однак це зовсім інший звір, ніж той, який представлений у цій статті.

Це може звучати як щось, що допоможе нам перезаписати локальні зміни. Натомість це дозволяє нам отримати зміни з однієї віддаленої гілки до іншої локальної гілки. `git pull --force` лише змінює поведінку частини, що отримується. Тому це еквівалентно `git fetch --force`.

Як і `git push`, `git fetch` дозволяє нам вказати, з якою локальною та віддаленою гілкою ми хочемо працювати. `git fetch origin/feature-1:my-feature` означатиме, що зміни у `feature-1` гілці з віддаленого сховища будуть видимі в локальній гілці `my-feature`. Коли така операція змінює існуючу історію, Git не дозволяє це робити без явного `--force` параметра.

Так само, як `git push --force` дозволяє перезаписувати віддалені гілки, `git fetch --force` (або `git pull --force`) дозволяє перезаписувати локальні гілки. Він завжди використовується з вихідними та кінцевими гілками, згаданими як параметри. Альтернативним підходом до перезапису локальних змін за допомогою `git --pull force`може бути `git pull --force "origin/$CURRENT_BRANCH:HEAD"`.

<https://www.freecodecamp.org/news/git-pull-force-how-to-overwrite-local-changes-with-git/>
