Skip to content

ifireice/git

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

12 Commits
 
 
 
 

Repository files navigation

Добавили изменения для ветки reset еще одна правка

Про Git

Существует несколько систем контроля версий: Git, Subversion, Team Foundation Server, Mercurial. Сегодня познакомимся и погорим о Git — самой популярной системой, ей пользуются более 90% разработчиков.

Git появился 7 апреля 2005 года и был создан для управления разработкой ядра Linux. Кстати, создал его тот самый Линусом Торвальдсом, а сегодня его развитием и поддержкой занимается Джунио Хамано.

Git — это распределённая система управления версиями.

Что такое распределенная система: есть один сервер, через который разработчики обмениваются кодом. Разработчик копирует (клолнирует) проект к себе на локальную машину, делает изменения и сохраняет их на удаленный сервер. При необходимости, другие разработчики могут скопировать эти изменения к себе.

Почти все разработка ведется локально, ведь история и копия проекта хранится локально и чаще всего не нужна никакая дополнительная информация с других клиентов. Вы можете работать с репозиторием и при отсутствии интернета (например, в самолете), а когда он появится, просто загрузить изменения в удаленный репозиторий (тот что на выделенном сервере).

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

Такой выделенный сервер, можно поднять и настроить самому, а можно использовать существующие сервисы.

GitHub - крупнейший веб-сервис, который позволяет заниматься совместной разработкой с использованием Git и сохранять изменения на своих серверах (на самом деле, функциональность GitHub намного больше, но сейчас нас интересует только совместная разработка).

Еще есть Gitlab, Bitbucket и другие, но мы будем использовать GitHub, как самый популярный в настоящее время.

Предварительная настройка

Для начала немного подготовительной настройки.

Для начала ааарегистрируйтесь на GitHub](https://github.com/join?source=header-home) при регистрации задайте логин, почту и придумайте пароль. После “Создать аккаунт” не забудьте проверить почту и подтвердить ее (опрос от Github после подтверждения почты можно пропустить).

если все ок, экран GitHub будет выглядеть вот так

Untitled

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

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

Для безопасной работы GitHub поддерживает два сетевых протокола HTTPS и SSH и вся работа с сервисом происходит через один из них.

Работать с GitHub будем через терминал по SSH. Для этого мы один раз сгенирируем специальный ключи, добавим один из них в наш аккаунт на GitHub.

Можно работать и через HTTPS, но нужно будет каждый раз вводить пароль и специальный token.

Пара слов про SSH и как он работает.

SSH - это сетевой протокол для зашифрованного соединения между клиентом и сервером → данные по такому соединения можно передавать безопасно.

При установлении соединения используется пара ключей: открытый (публичный, public) и закрытый (приватный, private). Пользователь создает пару ключей при помощи специальной команды и сохраняет закрытый ключ у себя, а открытый “кладет” на сервер (в нашем случае на GitHub). А работает это все благодаря ассиметричному шифрованию.

Алгоритм работает так: отправитель (GitHub) шифрует сообщение публичным ключом и передает сообщение клиенту (нам), а мы его расшифровываем при помощи приватного ключа, который предусмотрительно сохранили у себя. То что зашифровано публичным ключом, расшифровать сможет только приватный ключ.

Давай-те создадим пару ключей и добавим открытый ключ на GitHub

Что-бы создать пару ключей, в терминале нужно ввести команду, задать путь где сохранить ключи и задать пароль к ключу (не обязательно).

Будем дальше в статье основываться на том, что путь для ключей дефолтный и пароль на ключи не установлен.

Пароль для ключей нужен, как дополнительная мера безопасности, если вдруг ваш приватный ключ попадёт не в те руки.

$ ssh-keygen
Generating public/private rsa key pair.
# путь до ключей, в скобках путь по умолчанию
Enter file in which to save the key (/Users/ifireice/.ssh/id_rsa):  
# пароль для ключей, при задании пароля в консоли не отображается ничего, даже звездочки
# если нажать Enter ничего не вводя, пароль будет пустым
Enter passphrase (empty for no passphrase):
# повторите пароль
Enter same passphrase again:
# после появится сообщение такого вида
Your identification has been saved in /Users/ifireice/.ssh/id_rsa
Your public key has been saved in /Users/ifireice/.ssh/id_rsa.pub
The key fingerprint is:
SHA256:Zu+HkZPC4ZP0veRmVjuKgylVvljHBNO8mHs+ieFFPvs ifireice@ifireice-osx
The key's randomart image is:
+---[RSA 3072]----+
|           o     |
|          o o    |
|           = .   |
|        o + +    |
|       +S* X     |
|       oB.@ X .  |
|       . O.# * . |
|      . +.*.% o  |
|       .  o*.+E. |
+----[SHA256]-----+

Вуаля, ключи сгенирированы (в заданной директории появится 2 файла id_rsa и id_rsa.pub).

Теперь надо добавить публичный ключ в аккаунт на GitHub.

# выведите содержимое публичного ключа в консоль
$ cat ~/.ssh/id_rsa.pub 
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDDJfHIi73sKd6cqm3RwKuY1zl46aAaE6X9Gp
/6zJiY3BiJj95oJjPdpfpPhVFWLIbmT8zFAtOLbX9N4C3b0enHUzgMacP/Kl4AbrAkhLqaua9iD
VNxxiTVxADG1M5525oc/eAvx7y0pXIb9ouWdYJSKa8/TUYFhWlCzV2quY9SA0FaMs7eY41+KWYpG.....
tA0oGxv+7WmXQmQzleLIRG13KQ+VAbL2vabdPcRoGuZavh0smOr/GtVSnLdspZ5RgONMSPWlF2I1YHMR
Q7CIKPs= ifireice@ifireice-osx
$

Скопируйте ключ от символов ssh-rsa и до конца файла и вставьте его в ваш аккаунт на GitHub. Идем в иконка пользователя (1) → Settings (2)

Untitled

→ SSH and GPG keys (3) → New SSH key (4)

Untitled

→ в Title дайте имя ключу, что бы понимать откуда он (мб в будущем, у вас будет несколько ключей) (5) → в Key вставляем скопированный из консоли ключ (6) → жмяк кнопку Add SSH key (7)

Untitled

После этого в ваших SSH ключах появится новый ключ и с компьютера где лежит приватный ключ сможете работать с GitHub

Untitled

Ну что, с настройкой GitHub пока закончили, осталось установить git на компьютер. Сделать это можно по официальной инструкции (выберете пункт для вашей ОС).

======

Терминология

Немного терминологии, прежде чем начнем создадим первый PR.

Репозиторий (repository)- директория проекта, который отслеживается Git. В директории хранится проект, история изменений и мета информация проекта (в скрытой директории .git)

Индекс - такая хранилка, в которой содержатся имена файлов и изменения в них, которые должны быть в следующем коммите. По факту индекс просто файл. В индекс файлы сами не попадают, их нужно явно добавлять при помощи git add

Коммит (commit) - это фиксация изменений в истории проекта (изменения, которые внесены в индекс). Коммит хранит измененные файлы, имя автора коммита и время, в которое был сделан коммит + каждый коммит имеет уникальный идентификатор, который позволяет в любое время к нему откатиться.

Ветка (branch) - последовательность коммитов. По сути это ссылка на последний коммит в этой ветке. Ветки не зависят друг от друга, можно вносить изменения в одну ветки и они не повлияют на другую ветку (если вы явно этого не попросите). Изначально одну ветка - main, чуть позже увидим.

Пул реквест - pull request PR (пиар) (он же merge request MR(мр)) -

Форк (Fork) -

====

Начало работы

Начнем с простого - создадим свой репозиторий и сделаем наш первый коммит.

Открываем repositories (1) и создаем новый (2).

Untitled

Зададим параметры:

  • (1) Repository name: имя нашего репозитория
  • (2) Description: описание репозитория
  • (3) Тип репозитория: Public (публичный) или Private (приватный). Сейчас выберем публичный - кто угодно может видеть содержимое репозитория.
  • (4) Ставим галку создать README файл. В этом файле в формате MarkDown описывают проект или различную документацию. Именно содержимое этого файла можно увидеть, когда заходим на главную страницу репозитория. Пример 1, 2, 3.
  • (5) Если мы знаем на каком языке наш проект, можем добавить шаблон .gitignore для этого языка. Сейчас у нас нет какого то языка, мы не будем создавать .gitignore.
  • (6) Выбираем тип лизенции для нашего кода. В лицензии оговариваются права на проект. Стоит обратить внимание на BSD 3 или MIT, тк они предоставляют хороший баланс прав и ответственности.
  • (7) По умолчанию имя основной ветки в GitHub носит имя main, но до недавнего времени имя было master .

Untitled

И нажимаем кнопку “Create repository”. Успех, у нас есть первый репозиторий!

Untitled

А что будет, если не добавим README и .gitignore?

На самом деле ничего страшного не произойдет, но придется выполнить еще ряд шагов, что бы проинициализировать git-репозиторий, прежде чем начать с ним работать.

Не переживайте, Git очень дружелюбный и расскажет как это сделать.

Untitled

Ну что, мы создали репозиторий на удаленном сервере, самое время “забрать” его к себе на локальную машину и внести какие-то изменения.

Что бы “забрать” репозиторий его надо склонировать к себе при помощи команды git clone и пути до репозитория.

Для начала получим путь до репозитория.

Для этого заходим в созданный репозиторий и находим кнопочку “Code” (1) → нажимаем ее → выбираем SSH (2) → и копируем строку (3)

Untitled

Теперь идем в консоль, переходим в директорию где хотим хранить проекты и выполним (git@github.com:ifireiceya/MyFirstRepo.git - путь который мы скопировали ранее)

$ git clone git@github.com:ifireiceya/MyFirstRepo.git
Cloning into 'MyFirstRepo'...
remote: Enumerating objects: 4, done.
remote: Counting objects: 100% (4/4), done.
remote: Compressing objects: 100% (4/4), done.
remote: Total 4 (delta 0), reused 0 (delta 0), pack-reused 0
Receiving objects: 100% (4/4), done.

Переходим в новый каталог, в котором теперь лежит копия нашего проекта с GitHub

$ cd MyFirstRepo

Можем посмотреть, что у нас в этой директории уже есть

$ ls -a
.git      LICENSE   README.md

Мы видим два знакомых нам файла LICENSE и README.md, а так же одну скрытую директорию .git

В .git хранится мета информация проекта и вся история для проекта. На каждый проект есть только одна директория .git и лежит она в корне проекта.

$ ls .git
HEAD                 # указатель на вашу активную ветку
config               # персональные настройки для проекта
description          # описание проекта
hooks                # pre/post action hooks
index                # индексный файл
logs                 # история веток проекта (где они располагались)        
objects              # ваши объекты (коммиты, теги и тд)
packed-refs refs     # указатели на ваши ветки разработки

Давайте немного поднастроим git под себя - делаем только один раз, потом настройки сохраняться, но при необходимости их можно изменить.

При установке Git была установлена утилита git config , которая позволяет просматривать и изменять большинство параметров работы Git’а

Будь-то данные пользователя или способ работы репозитория – это самый удобный способ настройки.

Настроим имя пользователя и адрес электронной почты. Эта информация важна, потому что она включается в каждый коммит.

Для этого в терминале переходим в git репозиторий для которого задаем настройки и выполняем:

$ git config user.name "Дарья Меленцова"
$ git config user.email ifireice@example.com

# Если добавить опцию --global, то эти настройки запишутся в настройки пользователя и будут действовать на все проекты. 
# Мы выполняем эту команду без параметра --global, чтобы настройки касались только вашего проекта.

Что еще можно настроить с помощью git config читать тут.

Вносим изменения

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

Но перед этим посмотрим 2 полезных команды:

  • git status - показывает текущее состояние файлов в репозитории (какие файлы изменились, удалились, добавились)
  • git log - показывает историю изменений ( это про зафиксированные изменения - коммиты (commit))

Выполним эти команды и посмотрим, что они выведут для нашего репозитория.

git status видим, что у нас нет изменений - коммитов в репозитории ( мы ведь только его склонировали и еще ничего не делали)

$ git status                                  
On branch main
Your branch is up to date with 'origin/main'.

nothing to commit, working tree clean

а git log покажет нам, что в проекте был только один Initial commit - когда мы создавали репозиторий с README.md

$ git log
commit 9ae1cbcc77f3b64d604612d4a599bdbb8b1cf204 (HEAD -> main, origin/main, origin/HEAD)
Author: ifireiceya <117034707+ifireiceya@users.noreply.github.com>
Date:   Mon Oct 31 00:01:05 2022 +0300

    Initial commit
(END)

Убедились, что у нас нет неучтенных изменений, пора бы уже что-то сделать.

Открывайте любимый текстовый редактор и создаем новый файл с именем hw.py.

Это будет небольшая программа на Python, которая при запуске печатает “Hello World!”

$ vi hw.py
print("Hello World!")

Отлично, код написан и даже в есть локально в нашем репозитории (мы же в директории проекта все делали)

Итак наша задача сохранить наши изменения в “оригинальный”(удаленный) репозиторий. Для этого нам нужно:

  1. Познакомить Git с новым файлом - добавить файл в индекс - git add
  2. Зафиксировать изменения “закоммитить” - git commit
  3. Синхронизировать наши изменения с серверов - git push
  4. Посмотреть в репозиторий и убедится, что все сработало

Делаем:

Мы уже создали файл, посмотрим в каком теперь у нас статусе Git

Untitled

Мы видим, что появился файл hw.py, но он красный. Паника! Все сломалось?!

Все в порядке, но прежде чем продолжить, стоит обсудить состояние файлов с точки зрения Git’а.

По мнению Git’а файл может в одним из четырех состояний:

  1. Неотслеживаемый (untracked)

  2. измененный (modified) - файл, в котором есть изменения, но он еще не добавлен в коммит (не зафиксирован)

  3. отслеживаемый (staged) - файл, который добавили в индекс

  4. зафиксированный (committed) - файл уже сохранен в локальной базе и в нем не было изменений с последнего коммита.

Untitled

В связке с состоянием файлов есть три основных секции проекта.

  • рабочая директория (working directory) - это директория которая содержит в себе то с чем вы работаете или то что вы извлекли из истории проекта в данный момент. рабочая директория это просто временное место где вы можете модифицировать файлы, а затем выполнить коммит.
  • область индексирования (staging area) - индекс - файл, в каталоге Git, который содержит информацию о том, что попадет в следующий коммит.
  • каталог Git - место, где Git хранит метаданные и базу объектов вашего проекта, помните еще про .git?

На практике:

Мы добавили новый файл hw.py и видим, что у него состояние untracked, т.е. не важно что мы делаем с файлом, Git проигнорирует любые изменения в нем.

Для того, что бы Git начал “следить” за изменениям в файле, его нужно добавить в индекс.

Для этого используем команду git add <имя файла>

Кстати, заметили, что Git довольно дружелюбный и часто подсказывает команды, который нужно выполнить

$ git add hw.py
# если нужно добавить много файлов и не хочется описывать, можно использовать команду
# git add .
# но стоит точно понимать, что добавляем, иначе придется удалять потом файлы из индекса
# кстати, для удаления используется команда git rm ,но стоит почитать доку перед использованием

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

.gitignore то же файл, который надо добавить в индекс.

Если файл попадает в “правила” .gitignore, то он не появится в git status

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

Посмотрим как изменилось состояние нашего файла

$ git status

Untitled

О, наш файл стал зеленым и сообщение от Git изменилось. Кстати, файл теперь имеет состояние staged.

Хотим зафиксировать изменения, тк наша задача сейчас решена - мы написали программку на Python и хотим сказать Git, что вот сейчас мы закончили работать с файлом и надо запомнить текущее состояние.

Для этого на нужно закомитить файл и поможет команда git commit

При создании принято писать описание коммита и делается это с помощью ключа -m

$ git commit -m "add python hello world"     
[main 6d8a5c3] add python hello world
 1 file changed, 1 insertion(+)
 create mode 100644 hw.py

Пара слов про то как писать сообщения для коммитов:

  • максимум 50 символов
  • осознано и понятно, как будто пишете для человека, который по описанию должен понять, что происходит внутри коммита, ведь этим человеком через какое то время можете стать вы, а о себе надо заботиться
  • сообщение стоит начинать с заглавной буквы
  • если меняли код пишите исходный код в сообщении
$ git log

Untitled

Осталось отправить наши изменения на “удаленный” сервер. Используем git push

$ git push
Counting objects: 100% (4/4), done.
Delta compression using up to 12 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 341 bytes | 341.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
To github.com:ifireiceya/MyFirstRepo.git
   9ae1cbc..6d8a5c3  main -> main

Предлагаю проверить, что наши изменения есть на GitHub. Идем в репозиторий и смотрим на него → видим, что появился наш файл и даже видим нам commit message, которы задали.

Untitled

Задача немного посложнее

Все здорово, но мы не всегда создаем репозитории и часто нам нужно добавлять новые фичи или исправления в уже существующий репозиторий, да еще и не наш.

Например, есть у нас наш любимый опенсорсный проект, в который мы хотим причинить добро и закрыть им какой нибудь Issue.

В учебных целях у нас есть репозиторий этой статьи на GitHub и мы хотим исправить опечатку, которую нашли в статье.

Но будем делать это как будто не наш репозиторий, а мы внешние пользователи.

Репозиторий хранится в ifireice/git , а изменения у нас делает пользователь ifireiceya

#TODO Дописать

  • squash - схлапывание коммитов в один
  • revert
  • rebase
  • cherry-pick