Что такое коммит?
Коммит - очередное зафиксированное состояние проекта, "единица" версии.Все коммиты (кроме первого) должны наследоваться от предыдущего коммита, образуя таким образом древовидную структуру, как изображено на рисунке ниже (кружки - коммиты).
Как видно из иллюстрации, проект может разветвляться, например если два разработчика параллельно работают и каждый создаёт свои коммиты. Чтобы не возникало полного хаоса и можно было ориентироваться в происходящем вводят понятие ветки
Ветка - по большому счёту просто именованная ссылка на некий коммит, указывающая на конец очередного ответвления от главной центральной ветки (по умолчанию она зовётся master). Как правило, репозиторий работает в привязке к какой-то ветке и при создании нового коммита, он присоединяется к тому, на который ссылается ветка, и ветка начинает указывать на новый коммит. На картинке выше помимо master есть ветки Little Feature и Big Feature.
Установка
Linux — нужно просто открыть терминал и установить приложение при помощи пакетного менеджера вашего дистрибутива. Для Ubuntu команда будет выглядеть следующим образом:sudo apt-get install gitWindows — мы рекомендуем git for windows, так как он содержит и клиент с графическим интерфейсом, и эмулятор bash.
Настройка
Первым делом до начала работы, нужно внести глобальные настройки:git config --global user.name "My Name"
git config --global user.email myEmail@example.com
Репозиторий
Итак, вот у вас уже есть git. Теперь нужно создать хранилище версий для него. Запомните, это хранилище называется репозиторий (англ. repository) — при случае можете вставить где-нибудь это словечко. В зависимости от того, какая у вас оболочка, соответствующей командой создайте новую директорию, откройте ее (в командной строке, она же оболочка, а не проводником или чем-то подобным) и выполните:git initВсе, локальный репозиторий в этой папке создан. То, что здесь сейчас хранится, будет бекапом, поэтому, чтобы его не испортить, создадим рабочую копию (англ. check out)локальной версии:
git clone [url]Где [url] — это путь до клонируемого репозитория. Мы разбираем сейчас случай, когда вы создаете рабочую копию собственного репозитория, поэтому в качестве [url] здесь вам нужно указать путь до директории, для которой мы выполняли git init.
git clone username@host:/path/to/repositoryИногда нужно склонировать только конкретную ветку, тогда:
git clone --branch=branch-name http://whatever.gitЕще иногда может потребоваться склонировать репозиторий без многолетней истории его коммитов, тогда нужно использовать параметр --depth=5, где 5 - количество коммитов от последнего:
git clone --depth=1 --branch=branch-name http://whatever.gitЕсть несколько условных этапов работы с репозиторием (с файлами в нём):
- Создание репозитория (git init) или (git clone адресс_репозитория ), если копируем удалённый
- Делаем изменения
- Помещаем файлы под VCS-отслеживание (git add)
- Фиксируем (коммитим) изменения (git commit)
- Заливаем (пушим) их на удалённое хранилище (git push)
Создание коммита
Получение статуса репозитория:git statusДобавление файлов в коммит:
git add [имя_файла]Добавление всех файлов в коммит:
git add *Создание коммита:
git commit -m "Commit message"Файл(-ы) находятся в HEAD вашей рабочей локальной копии. В вашем удаленном репозитории их все еще нет.
Пуш в репозиторий:
git push origin masterРабота с удалёнными репозиториями:
git remote add origin [сервер]
Ветвление
Создание новой веткиЕсть разные принципы модели ветвления в git. Одна из них: Новая задача - новая ветка. О другой поговорим далее.
Создание новой ветки:
git checkout -b [новая_ветка]Переключение между ветками
Выбор ветки:
git checkout [репозиторий]/[ветка]Удаление ветки:
git branch -d [ветка]Обязательно нужно делать пуш изменений в общий репозиторий:
git push origin [ветка]Запрос изменений с сервера
Чтобы обновить локальный репозиторий до последнего коммита, нужно сделать “пулл”:
git pull [ветка] - например origin masterЗагрузить изменения с конкретной ветки:
git fetch <remote_name> <branch_name>
Слияние веток
Чтобы слить ветку в ту, с которой вы сейчас работаете, используйте:git merge [ветка]Ветки можно сравнить:
git diff [одна_ветка] [другая_ветка]Обновить локальный репозиторий до нового коммита:
git pullТеги:
git tag [tag] [первые_десять_символов_соответствующего_коммита]Историю репозитория — его лог:
git logОткат мерджа
Если проблема только в одном файле, то вот вам Ctrl Z для HEAD’a:
git checkout -- [имя_файла]Но если проблема находится в локальном репозитории, то зачистите там все и верните версию с сервера:
git fetch origin git reset --hard origin/master
Разрешение конфликтов при слиянии
Мы попытаемся слить две ветки под названием 1_branch и 1_branch.Где есть изменения в одних и тех же файлах. Если попытаться слить две ветки, они получат сообщение об ошибке:
git merge 1_branchСистема не смогла разрешить конфликт автоматически, значит, это придется сделать разработчикам. Приложение отметило строки, содержащие конфликт:
Auto-merging print_array.js
CONFLICT (content): Merge conflict in print_array.js
Automatic merge failed; fix conflicts and then commit the result.
Над разделителем ======= мы видим последний (HEAD) коммит, а под ним — конфликтующий. Таким образом, мы можем увидеть, чем они отличаются и решать, какая версия лучше. Или вовсе написать новую. В этой ситуации мы так и поступим, перепишем все, удалив разделители, и дадим git понять, что закончили.Когда все готово, нужно закоммитить изменения, чтобы закончить процесс:
git add -A
git commit -m "Array printing conflict resolved."
Пример:
Короткая и простая история коммитов.
git checkout -b iss53
Создание новой ветки / указателя.
Сделали новый коммит:
Ветка iss53 передвинулась вперёд во время работы.
Создание хот-фикса:
git checkout master
git checkout -b hotfix
Ветка для решения срочной проблемы базируется на ветке master.
Слияние веток:
git checkout master
git merge hotfix
git merge iss53
Git автоматически создаёт новый коммит, содержащий результаты слияния.
Настройка .gitignore
В большинстве проектов есть файлы или целые директории, в которые мы не хотим (и, скорее всего, не захотим) коммитить. Мы можем удостовериться, что они случайно не попадут в git add -A при помощи файла .gitignore- Создайте вручную файл под названием .gitignore и сохраните его в директорию проекта.
- Внутри файла перечислите названия файлов/папок, которые нужно игнорировать, каждый с новой строки.
- Файл .gitignore должен быть добавлен, закоммичен и отправлен на сервер, как любой другой файл в проекте.
- Логи
- Артефакты систем сборки
- Папки node_modules в проектах node.js
- Папки, созданные IDE, например, Netbeans или IntelliJ
- Разнообразные заметки разработчика.
*.log
build/
node_modules/
.idea/
my_notes.txt
Удачная модель ветвления для Git
Главные ветви
Ядро модели разработки не отличается от большинства существующих моделей. Центральный репозиторий содержит две главные ветки, существующие всё время.
- master - создаётся при инициализации репозитория, считаем ветку origin/master главной.
- develop - ветвь origin/develop мы считаем главной ветвью для разработки.
- Ветви функциональностей (Feature branches)
- Ветви релизов (Release branches)
- Ветви исправлений (Hotfix branches)
Должны вливаться в: develop
Соглашение о наименовании: всё, за исключением master, develop, release-* или hotfix-*
При начале работы над новой функциональностью делается ответвление от ветви разработки (develop).
git checkout -b myfeature develop
Ветви релизов (release branches)
Могут порождаться от: develop
Должны вливаться в: develop и master
Соглашение о наименовании: release-*
Ветвь релиза создаётся из ветви разработки (develop).
Закрытие ветви релиза
Когда мы решаем, что ветвь релиза (release branch) окончательно готова для выпуска, нужно проделать несколько действий. В первую очередь ветвь релиза вливается в главную ветвь (напоминаю, каждый коммит в master — это по определению новый релиз). Далее, этот коммит в master должен быть помечен тегом, чтобы в дальнейшем можно было легко обратиться к любой существовавшей версии продукта. И наконец, изменения, сделанные в ветви релиза (release branch), должны быть добавлены обратно в разработку (ветвь develop), чтобы будущие релизы также содержали внесённые исправления багов.
Теперь релиз издан и помечен тегом.
git checkout master
Switched to branch 'master'
git merge --no-ff release-1.2
Merge made by recursive.
(Отчёт об изменениях)
git tag -a 1.2
Чтобы сохранить изменения и в последующих релизах, мы должны влить эти изменения обратно в разработку. Делаем это так:
Этот шаг, в принципе, может привести к конфликту слияния (нередко бывает, что к причиной конфликта является изменение номера версии проекта). Если это произошло, исправьте их и издайте коммит.
git checkout develop
Switched to branch 'develop'
git merge --no-ff release-1.2
Merge made by recursive.
(Отчёт об изменениях)
Теперь мы окончательно разделались с веткой релиза. Можно её удалять, потому что она нам больше не понадобится:
git branch -d release-1.2Ветви исправлений (hotfix branches)
Deleted branch release-1.2 (was ff452fe).
Могут порождаться от: master
Должны вливаться в: develop и master
Соглашение о наименовании: hotfix-*
Ветви исправлений (hotfix branches) создаются из главной (master) ветви.
Заключение
Можно сказать есть такие пути работы с гит:
1) разбить деятельность на задачи, и каждой задаче создать свою ветку, а потом мерджить
2) работать в одной ветке, и обновлять свой локальный репозиторий, с последующим его залитием
Краткая справка команд:
git pull - обновить данные из серверного репозитория
git add - добавить в список "на коммит"
git commit - создание пакета (коммита) с изменениями
git push - залить за серверный (удалённый) репозиторий
git merge BRANCH - слияние ветки в который ты находишься, с веткой BRANCH
ПО
http://git-scm.com/downloads консольный клиентhttps://desktop.github.com/ github
https://www.gitkraken.com/ https://www.gitkraken.com/
Вопросы:
Есть репозиторий, над ним работают два человека: первый клонирует репозиторий, вносит правки и пушит; второй в это же время тоже начал работу, склонировал, но запушить не может, так как 1й уже внес правки. Как быть?
Ответ:
Ты делаешь комит и когда пытается сделать пуш, гит говорит, что надо сначала стянуть изменения. Когда стягиваешь изменения, они автоматом мержатся со своими изменениями и потом уже можешь сделать свой пуш.
Если правите разные файлы или разные строчки в одном и том же файле, то гит смержит изменения автоматически.
Теперь случай посложнее, когда вы правили одни и те же строчки в одних и тех же файлах:
Тут гит сам не справится. сценарий такой. 1й делает изменения и пушит их в репозиторий. 2й делает изменения и пытается сделать пуш, но гит говорит стянуть сначала новые изменения. Когда он стягивает изменения, гит говорит ему что есть конфликты и надо бы их поправить; пишет в каких файлах; нужно зайти в эти файлы, там будут специальные метки:
<================
изменения_друга
===============>
твои_изменения
==========
В тех местах, где гит не смог сам смержить 2му придется выбирать что оставить или переписать эти куски так, чтобы работало правильно.
Потом сделать:
git add .
git commit
(в комите можно написать комментарий типа "фикс конфликтов")
git push
После этого ваши изменения будут залиты.
13.04.20
06.06.20
git cherry-pick test
08.06.21