Основы Git

Кратко

Проверяем обстановку

git status

Добавляем файл который хотим закоммитить

git add index.html

Убираем файл который не хотим сейчас коммитить

git reset file.txt

Коммитим с комментарием

git commit -m 'Лучшие самоучители на сайте www.eth1.ru'

Стэйджим и коммитим с комментарием одной командой

git commit -am 'Наш любимый сайт www.HeiHei.ru'

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

git push origin master

Пользователь

Задать имя активного глобавльного пользовотеля

git config --global user.name "Andrei"

Проверить имя активного пользовотеля

git config user.name

Andrei

Задать email активного пользовотеля

git config --global user.email "andrei@devhops.site"

git config --global --list

credential.helper=cache user.name=Andrei user.email=andrei@devhops.site

Изменить имя дефолтной ветки

git config --global init.defaultBranch main

git config --global --list | grep branch

init.defaultbranch=main

Удалить настройку

Было:

git config --global --list | grep user

user.name=Andrei user.email=andrei@devhops.site

Удалим user.name

git config --global --unset user.name

Стало:

git config --global --list | grep user

user.email=andrei@devhops.site

Локальный пользователь

Если нужно пушить от другого пользователя можно использовать user.local для конкретного репозитория

Сперва нужно создать пару ключей и публичный ключ добавить в репозиторий.

Дадим ключу имя aogithub и будем действовать по этой инструкции

ssh-keygen

Generating public/private rsa key pair. Enter file in which to save the key (/c/Users/Andrei/.ssh/id_rsa): aogithub Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in aogithub Your public key has been saved in aogithub.pub The key fingerprint is: SHA256:cvv+vna9oR1T9tueN9pPKzS6VzINYAiYGKcUZ2uo7Ok Andrei@urnsulab The key's randomart image is: +---[RSA 3072]----+ | ==oo.. . | | ..=o. . o | | o o . . | |. . . . | | o . S . o| |. . o . = +o| | o . o ==o| |. . ..o=o@| | E .o=*=oOO| +----[SHA256]-----+

eval `ssh-agent -s`

Agent pid 2261

ssh-add ~/.ssh/aogithub

Identity added: /c/Users/Andrei/.ssh/aogithub (Andrei@urnsulab)

git clone git@github.com:AndreiOlegovich/robot_web_ui_test.git

Cloning into 'robot_web_ui_test'… warning: You appear to have cloned an empty repository.

cd robot_web_ui_test/ git config --local user.name "AndreiOlegovich" git config --local user.email "info@eth1.ru" git config --local core.sshcommand 'ssh -i ~/.ssh/aogithub -F /dev/null' git status

On branch main No commits yet nothing to commit (create/copy files and use "git add" to track)

echo "# robot_web_ui_test" >> README.md
git add README.md

warning: in the working copy of 'README.md', LF will be replaced by CRLF the next time Git touches it

git commit -m "first commit"

[main (root-commit) 05fe1fe] first commit 1 file changed, 1 insertion(+) create mode 100644 README.md

git push -u origin main

Enumerating objects: 3, done. Counting objects: 100% (3/3), done. Writing objects: 100% (3/3), 245 bytes | 245.00 KiB/s, done. Total 3 (delta 0), reused 0 (delta 0), pack-reused 0 To github.com:AndreiOlegovich/robot_web_ui_test.git * [new branch] main -> main branch 'main' set up to track 'origin/main'.

init

Начать отслеживать изменения - инициализаци или начало работы Git

git init

Initialized empty Git repository in C:/Users/aolegovich/Desktop/Sites/hello-world/.git/

По умолчанию репозиторий хранится в скрытой директории под названием .git в корневом каталоге рабочей копии дерева файлов, хранящегося в репозитории.

ls .git

config description fsmonitor--daemon/ HEAD hooks/ info/ objects/ refs/

Любое файловое дерево в системе можно превратить в репозиторий git, отдав команду создания репозитория из корневого каталога этого дерева (или указав корневой каталог в параметрах программы)

Важно понимать, что инициализировать репозиторий нужно в директории с проектом.

На одном компьютере могут быть десятки проектов и каждый из них может иметь свой репозиторий, который, в свою очередь может быть подлючён к github , gitlab , bitbucket или куда-то ещё.

Перейдя из одной директории в другую вы перемещаетесь между этими репозиториями. Благодаря файлам .gitinit git автоматически понимает, что вы уже в другом месте и работаете с другим проектом.

Можно настроить ваш терминал bash или zsh так, чтобы он показывал вам с каким именно репозиторием вы работаете и какая ветка активна.

status

Посмотреть свежие изменения в репозитории

git status

Если команда выполнена в директории, которая не является частью репозитория, появится сообщение об ошибке.

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

Чтобы сделать директорию частью репозитория нужно выполнить git init либо в ней, либо в одной из родительских директории.

В пустом репозитории команда git status вернёт следующий результат:

On branch main No commits yet nothing to commit (create/copy files and use "git add" to track)

В репозитории, в котом все изменения уже закоммичены результат будет таким:

On branch main nothing to commit, working tree clean

Если интересует только текущая директория после status нужно поставить пробел и точку.

git status .

Создать файл можно командой touch в Linux и UNIX или командой NewItem в PowerShell

touch index.html

New-Item -Path . -Name "index.html" -ItemType "file"

git status

On branch master

No commits yet

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

        index.html

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

Файлы могут быть как отслеживаемыми (Tracked) так и не отслеживаемыми (Untracked)

Неотслеживаемые файлы выделены красным - как файл index.html в примере выше.

Отслеживаемые файлы могут находится в трёх состояниях: Unmodified, Modified, Staged. Итого, получаем четыре возможных состояния

Состояние Eng Описание Выделение
Неотслеживаемое Untracked Гит знает о существовании этих файлов, но не следит за их изменениями. Красным
Неизменённое Unmodified Файл не изменялся по сравнению с последним известным состоянием Не виден
Изменённое Modified Файл, в котором уже произошли изменения, но ещё не добавленный в область подготовки Красным
В области подготовки Staged Файл, в котором уже произошли изменения и который уже добавлен в область подготовки Зелёным

Пример:

git status

On branch andrei/PROJECT-12345_acceptance_test_automation Changes to be committed: (use "git restore --staged <file>..." to unstage) modified: app/Tests/Acceptance/NewItemCreation.robot Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git restore <file>..." to discard changes in working directory) modified: app/Resources/shared_keywords.resource modified: app/page_object/page_steps/DashBoardPageSteps.py Untracked files: (use "git add <file>..." to include in what will be committed) get_all_attrs.py

Файл, который уже добавлен в staging area выделен зелёным.

Изменения, в известный файлах выделены красным.

Если появились файлы, ещё не отслеживаемые гитом, они тоже будут выделены красным в разделе Untracked fiies.

Чтобы git не отслеживал какие-то файлы, директории или определённые типы файлов их перечисляют в специальном скрытом файле .gitignore

add

Командой add можно показать гиту, что новый файл нужно отслеживать. Основное применение - добавление в staging area

Рассмотрим пример

git status

On branch master No commits yet Untracked files: (use "git add <file>..." to include in what will be committed) README.md index.html nothing added to commit but untracked files present (use "git add" to track)

git пока что не отлеживает файлы README.md и index.html

Чтобы начать отслеживание но не добавлять в staging area нужно использовать опцию -N

git add -N README.md

On branch master No commits yet Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git restore <file>..." to discard changes in working directory) new file: README.md Untracked files: (use "git add <file>..." to include in what will be committed) index.html no changes added to commit (use "git add" and/or "git commit -a")

Добавить файл в группу файлов, которые Вы планируете зафиксировать (staging area)

git add index.html

Чтобы добавить несколько файлов - перечислите их

git add index.html about.html contacts.html parser.py

Если файлов много и Вы хотите добавить все используйте

git add -A

Добавить все файлы из текущей директории

git add .

Посмотреть свежие изменения в репозитории

git status

On branch andrei/PROJECT-12345_acceptance_test_automation Changes to be committed: (use "git restore --staged <file>..." to unstage) modified: app/Tests/Acceptance/NewItemCreation.robot Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git restore <file>..." to discard changes in working directory) modified: app/Resources/shared_keywords.resource modified: app/page_object/page_steps/DashBoardPageSteps.py Untracked files: (use "git add <file>..." to include in what will be committed) get_all_attrs.py

Файл, который уже добавлен в staging area выделен зелёным.

Изменения, в известный файлах выделены красным.

Если появились файлы, ещё не отслеживаемые гитом, они тоже будут выделены красным в разделе Untracked fiies.

Чтобы добавить в staging area все уже известные гиту файлы, но не добавлять Untracked files используйте флаг -u

git add -u

Чтобы добавить в staging area не весь файл, а только часть изменений в файле используется флаг -p

git add -p

Добавить только удалённые файлы

git ls-files --deleted | xargs git add

Удалить файл из staging area

Если вы добавили что-то лишнее

git reset имя_файла

restore: удалить незаписанные изменения

Если файл добавлен в staging area, и при этом все незаписанные изменения нужно отменить подойдёт команда restore

git restore имя_файла

Пример

touch test.txt git add test.txt echo "abc" >> test.txt cat test.txt

abc

git restore test.txt
cat test.txt

Файл вернулся в исходное состояние - стал пустым.

Если нужно вернуть в исходное состояние несколько файлов одновременно - можно использовать wildcard.

Пример восстановления всех .py файлов:

git restore *.py

commit

Зафиксировать изменения - записать изменения файла в репозиторий.

git commit -m '[PROJECT-12345] - Чинит всё'

[master (root-commit) e2d3195] My first commit.
1 file changed, 1 insertion(+)
create mode 100644 index.html

В данном случае права доступа 100644 — означают обычный файл .

Другие возможные варианты: 100755 — исполняемый файл, 120000 — символическая ссылка.

Права доступа в Git сделаны по аналогии с правами доступа в UNIX , но они гораздо менее гибки: указанные три режима — единственные доступные для файлов (блобов) в Git (хотя существуют и другие режимы, используемые для каталогов и подмодулей).

Вернуть файл к последнему закоммиченному состоянию

git checkout -- .

Восстановить удалённый файл, если он не закоммичен можно выполнив

git checkout .

Если нужно вернуться к какому-то коммиту и удалить всё, что появилось после

git log

commit b662b06badbbddf3b6a824ff2f360e2d4ae32734 (HEAD -> master) Author: andrei <andrei@aredel.com> Date: Tue Oct 16 20:41:27 2023 +0300 Adds all files created with new empty project

Находим нужный коммит. В данном примере он всего один - b662b06badbbddf3b6a824ff2f360e2d4ae32734

Делаем жёсткий ресет.

git reset --hard b662b06badbbddf3b6a824ff2f360e2d4ae32734

HEAD is now at b662b06 Adds all files created with new empty project

diff

Если вы внесли изменения можно изучить их командой git diff

Рассмотрим файлы sites.md и partners.txt

vi sites.md

## sites.md andreyolegovich.ru aredel.com

Добавим пустую строку в конце и выполним

git diff

diff --git a/sites.md b/sites.md index 05780b3..0333fd4 100644 --- a/sites.md +++ b/sites.md @@ -2,3 +2,4 @@ andreyolegovich.ru aredel.com +

Добавим www. ко второму домену

diff --git a/sites.md b/sites.md index 093ea8c..12153af 100644 --- a/sites.md +++ b/sites.md @@ -1,4 +1,5 @@ ## sites.md andreyolegovich.ru -aredel.com +www.aredel.com +

Добавим файл в область подготовки

git add sites.md

Теперь git diff не вернёт ничего

git diff

Чтобы увидеть изменения в файлах из области подготовки нужно добавить флаг --cached или --staged

git diff --cached
git diff --staged

diff --git a/sites.md b/sites.md index 093ea8c..12153af 100644 --- a/sites.md +++ b/sites.md @@ -1,4 +1,5 @@ ## sites.md andreyolegovich.ru -aredel.com +www.aredel.com +

Рассмотрим файл partners.txt из той же директории

## partners.txt aviasales.com beget.com

Добавим ещё один домен

git diff

diff --git a/partners.txt b/partners.txt index fbe9f56..9567887 100644 --- a/partners.txt +++ b/partners.txt @@ -2,3 +2,4 @@ aviasales.com beget.com +ostrovok.ru

Один файл уже в области подготовки а другой нет.

Чтобы увидеть изменения в обоих файлах нужно выполнить

git diff head

diff --git a/partners.txt b/partners.txt index fbe9f56..9567887 100644 --- a/partners.txt +++ b/partners.txt @@ -2,3 +2,4 @@ aviasales.com beget.com +ostrovok.ru diff --git a/sites.md b/sites.md index 093ea8c..12153af 100644 --- a/sites.md +++ b/sites.md @@ -1,4 +1,5 @@ ## sites.md andreyolegovich.ru -aredel.com +www.aredel.com +

git hash-object

echo "HeiHei.ru" | git hash-object --stdin

0bdb2c54a9617d62b661102a4862b417d7bdde9b

config

Для локальной настройки определённого репозитория используется файл config который находится в корне директории .git

[core] repositoryformatversion = 0 filemode = false bare = false logallrefupdates = true ignorecase = true [remote "origin"] url = git@github.com:AndreiOlegovich/mkdocs-demo-project.git fetch = +refs/heads/*:refs/remotes/origin/* puttykeyfile = C:\Users\Andrei\.ssh\putty [branch "main"] remote = origin merge = refs/heads/main [branch "topic/dev2"] remote = origin merge = refs/heads/topic/dev2

Предположим у вас в общих настройках git выставлен пользователь user0 с почтой user0@eth1.ru

Первым делом нужно проверить эти значения

git config user.name

user0

git config user.email

user0@eth1.ru

git config --list

… user.name=user0 user.email=user0@eth1.ru …

Эти настройки находятся в секции user файла gitconfig

vi ~/.gitconfig

… [user] name = user0 email = user0@eth1.ru

Чтобы поменять их например на user1, можно скопировать эту секцию в файл config из директории .git и заменить значения на нужные

[user] name = user1 email = user1@eth1.ru [core] repositoryformatversion = 0 filemode = false bare = false logallrefupdates = true ignorecase = true [remote "origin"] url = git@github.com:AndreiOlegovich/mkdocs-demo-project.git fetch = +refs/heads/*:refs/remotes/origin/* puttykeyfile = C:\Users\Andrei\.ssh\putty [branch "main"] remote = origin merge = refs/heads/main [branch "topic/dev2"] remote = origin merge = refs/heads/topic/dev2

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

Пример поиска слова value в истории файла README.md

git grep value $(git rev-list --all -- README.md) -- README.md

Автор статьи: Андрей Олегович