Skip to content

Latest commit

 

History

History
472 lines (344 loc) · 35.6 KB

File metadata and controls

472 lines (344 loc) · 35.6 KB

Задание 1. Init Repo (optional)

  1. Создай папку my-project

  2. Создай внутри файл hello.txt

  3. Открой терминал (Git Bash для Windows). Выполни команду cd путь_до_папки_my-project

Убедись что путь введен правильно: команда pwd должна вывести правильный путь до папки my-project

  1. Выполни команду git init

  2. Убедись, что появилась скрытая папка .git

Для Windows: чтобы отображались скрытые файлы и папки, в проводнике нужно отметить галочку Вид - Скрытые элементы. Лучше рядом также отметить галочку Расширения имен файлов

Для Mac: чтобы отображались скрытые файлы и папки, нужно в Finder нажать Cmd + Shift + .

Также можно просмотреть список файлов и папок в текущей директории из консоли с помощью команды ls -la

Задание 2. Commits

  1. Найди в GitHub репозиторий https://github.com/kontur-courses/git-sheet, сделай его fork в свой профиль, а затем склонируй форкнутый репозиторий.
    НЕ СПУТАЙ: это НЕ репозиторий с презентацией и текстом этого задания!

Склонировать репозиторий можно с помощью команды git clone Не забудь после этого открыть папку с репозиторем в терминале: cd git-sheet

  1. Открой папку git-sheet в VS Code (File - Open Folder).

  2. Открой Git Graph (кнопка в нижней панели VS Code). Убедись, что в нем есть коммит с названием Initial commit

  3. Через VS Code создай файл init.md со следующим содержимым (здесь и далее копировать надо то, что между тройных бэктиков как этот текст, но не сами «бэктики»):

## S1. Everything Is Local
### Все работает локально
1. `git init` — создать пустой репозиторий
2. `git clone <url>` — склонировать репозиторий в новую директорию

  1. Выполни команду git status. В секции Untracked files должен появиться init.md.

  2. Выполни команду git add init.md Теперь init.md находится в Commit Index

  3. Сделай коммит с сообщением Add init.md. Для этого выполни команду git commit -m "Add init.md"

  4. Открой Git Graph и убедись, что коммит появился в истории коммитов

  5. Создай файл commit.md со следующим содержимым:

## S2. Tree Of Commits
### Хранится последовательность состояний некоторой директории

  1. Выполни git status и убедись что commit.md находится в секции Untracked files

  2. Добавь commit.md в Commit Index: git add commit.md

  3. Выполни git status и убедись что commit.md находится в секции Changes to be commited

  4. Замени содержимое commit.md на следующее:

## S2. Tree Of Commits
### Хранится последовательность состояний некоторой директории
1. `git add .` — добавить все измененные файлы в индекс
2. `git commit -m <msg>` — записать изменения из индекс в репозиторий
3. `git status -sb` — вывести состояние директории и индекса кратко с указанием текущей ветки
4. `git log --oneline` — вывести список коммитов, связанных с HEAD, в кратком виде
5. `git log --oneline --graph` — вывести историю коммитов, связанных с HEAD, в виде дерева
6. `git log --oneline --graph --all` — вывести историю всех коммитов в виде дерева
  1. Выполни git status. Убедись, что commit.md находится как в Working Directory (секция Changes not staged for commit), так и в Commit Index (секция Changes to be commited)
  2. Открой в VS Code вкладку Source Control (Ctrl + Shift + G) и убедись, что commit.md находится как в верхней части окна, так и в нижней, причем содержимое у файлов разное и при выборе commit.md в нижней части показывается отличия от Commit Index, а не предыдущего от коммита
  3. Выполни коммит с сообщением Add commit.md header
  4. В истории коммитов (Git Graph) найди только что созданный коммит и убедись, что в него попали только изменения из Commit Index
  5. Закоммить изменения с сообщением Change commit.md

Задание 3. Tag (optional)

  1. Создай тег с именем v0.1 с помощью команды git tag "v0.1"

Теги также можно создавать в Git Graph с помощью контекстного меню

  1. Найди в Git Graph начальный коммит Initial commit, выбери его и с помощью контекстного меню выполни Checkout...
  2. Выполни команду git checkout v0.1, чтобы вернуться обратно на помеченный тегом коммит.

Задание 4. Feature Branches

  1. Создай новую ветку branch-feature и перейди на нее: git checkout -b branch-feature

Команда git checkout -b branch-name создает новую ветку и сразу выполняет checkout на нее. Это эквивалентно паре команд git branch branch-name и git checkout branch-name

  1. С помощью VS Code создай новый файл branch.md со следующим содержимым:
## S3. Refer To Branch
### Используются именованные ссылки
1. `git tag` — вывести список тегов
2. `git tag <tagname>` — создать тег
3. `git branch` — вывести список локальных веток
4. `git branch -av` - вывести список локальных и удаленных веток
5. `git branch <branchname>` — создать ветку
6. `git branch -d <branchname>` — удалить ветку
7. `git checkout <commit>` — переместить HEAD на коммит
8. `git checkout <branch>` — переместить HEAD на ветку
9. `git checkout -m <branch>` — переместить HEAD, объединить текущие изменения с состоянием ветки
10. `git checkout -b <new_branch>` — создать новую ветку и перейти на нее

  1. Закоммить изменения с сообщением Add branch.md

  2. Перейди назад на ветку master: git checkout master

  3. Создай ветку bullet-feature и перейди на нее.

  4. Во всех доступных md-файлах замени нумерованные списки на ненумерованные списки. На примере init.md это выглядит следующим образом.

Было:

## S1. Everything Is Local
### Все работает локально
1. `git init` — создать пустой репозиторий
2. `git clone <url>` — склонировать репозиторий в новую директорию

Стало:

## S1. Everything Is Local
### Все работает локально
- `git init` — создать пустой репозиторий
- `git clone <url>` — склонировать репозиторий в новую директорию

Аналогично сделай для commit.md.

  1. Закоммить изменения с сообщением Replace with bullets

  2. Перейди назад на ветку master

  3. Замени содержимое commit.md на следующее:

## S2. Tree Of Commits
### Хранится последовательность состояний некоторой директории
1. `git add .` — добавить все измененные файлы в индекс
2. `git commit -m <msg>` — записать изменения из индекс в репозиторий
3. `git status -sb` — вывести состояние директории и индекса кратко с указанием текущей ветки
4. `git show <commit>` — показать содержимое коммита
5. `git log --oneline` — вывести список коммитов, связанных с HEAD, в кратком виде
6. `git log --oneline --graph` — вывести историю коммитов, связанных с HEAD, в виде дерева
7. `git log --oneline --graph --all` — вывести историю всех коммитов в виде дерева

  1. Закоммить изменения с сообщением show command for commit.md
  2. Открой Git Graph. Обрати внимание, что история коммитов стала похожа на дерево, а на концах веток этого дерева расположены метки master, branch-feature, bullet-feature. А вот тег v0.1, остался на своем месте.

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

Задание 5. Merge Conflict

  1. Начни вливать bullet-feature в master: Убедись что HEAD находится на master и выполни команду git merge bullet-feature.

Эта команда вливает указанную ветку в текущую (в ту, на которой сейчас находится HEAD).

Выполнение Merge закончится конфликтом. Конфликт произошел, потому что в этот файл вносились изменения и в bullet-feature и в master.

  1. В VS Code открой вкладку Source Control. В списке Merge Changes будет файл — commit.md. Выбери его.

Часто конфликты разрешаются выбором варианта из одной из веток, но это не тот случай. В VS Code нажми Compare Changes и убедись, что поменялось все. Придется объединять изменения аккуратно вручную. Сначала выбери Accept Both Changes — теперь текст обоих изменений станет доступен для редактирования. Затем напиши правильную версию блока. В ней должна быть команда git show и перед каждой командой должны быть дефисы. Когда закончишь редактирование, сохрани изменения и добавь commit.md в Commit Index: git add commit.md

  1. Выполни git status. Вывод сообщит, что все конфликты разрешены. Можно коммитить: выполни команду git commit (без опции -m). В VS Code откроется редактор сообщения коммита. Будет указано хорошее подробное сообщение: его можно не менять. Чтобы завершить коммит, достаточно закрыть в редакторе открывшийся файл COMMIT_EDITMSG (Ctrl + F4 на Windows, Ctrl + W на Linux, Cmd + W на Mac).

  2. Убедись, что в результате твоих действий был создан новый коммит, объединяющий две ветви изменений. HEAD сдвинулся на него, а master сдвинулся за HEAD.

Задание 6. Hidden Conflict

  1. Начни вливать branch-feature в master, как и в прошлый раз. Конфликтов в этот раз не будет, поэтому шаг разрешения конфликтов будет пропущен. Таким образом слияние будет выполнено.

  2. Хоть «настоящих» конфликтов нет, после слияния появился «логический» конфликт. Дело в том, что файл branch.md до сих пор содержит нумерованный список. Замени числа в нем на дефисы, аналогично другим файлам.

  3. Теперь пришло время добавить в историю эти изменения. Простой способ это сделать — коммит с сообщением вида Fix after merge. Прекрасно работает. Но можно воспользоваться Ammend Commit. Эта команда позволяет дополнить последний коммит дополнительными изменениями: git commit --amend Добавь изменения файла branch.md в Commit index и выполни Amend commit.

Задание 7. Fast-Forward Merge

  1. Создай ветку merge-feature и перейди на нее
  2. Создай файл merge.md со следующим содержимым:
## A1. Merge Them All
### Два состояния можно объединить через merge, mergetool и commit
- `git merge <commit>` — объединить текущую ветку с другой
- `git mergetool` — разрешить имеющиеся конфликты

  1. Закоммить изменения с сообщением Add merge.md
  2. Перейди назад на ветку master
  3. Влей merge-feature в master
  4. Заметь, что в этот раз не только конфликтов не было, но и новый коммит не был создан. Потому что в master не было изменений и для объединения двух веток было достаточно передвинуть master на коммит, на который ссылалась merge-feature.

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

Задание 8. Hot Rebase

  1. Создай ветку rebase-feature и перейди на нее.
  2. Создай файл rebase.md со следующим содержимым:
## A2. Immutable History
### Нельзя переписать историю — можно создать новую
- `git commit --ammend` — заменить последний коммит ветки на отредактированный с дополнительными изменениями
- `git rebase <upstream>` — применить все коммиты от общего родителя до текущего к `<upstream>`
- `git rebase -i <upstream>` — применить заново все коммиты, указав действие с каждым коммитом
- `git cherry-pick <commit>` — применить указанный коммит к HEAD

  1. Закоммить изменения с сообщением Add rebase.md
  2. Создай файл reflog.md со следующим содержимым:
## A4. Hide The Garbage
### Видно только то, на что есть ссылки
- `git gc` — удалить ненужные файлы и оптимизировать локальный репозиторий
- `git clean` — удалить неотслеживаемые файлы из директории
- `git reflog show <ref>` — показать лог действий со ссылкой
- `git reflog` = `git reflog show HEAD` — показать лог действий с HEAD

  1. Закоммить изменения с сообщением Add reflog.md.

  2. Перейди на ветку master.

  3. Создай файл reflog.md со следующим содержимым:

## A4. Hide The Garbage
### Lorem ipsum dolor sit amet, consectetur adipiscing elit

  1. Закоммить изменения с сообщением Add stub for reflog.md.

  2. Установи тег old-rebase-feature на коммит, на который ссылается rebase-feature:

git tag old-rebase-feature rebase-feature

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

  1. Перейди на ветку rebase-feature

  2. Выполни rebase rebase-feature на master: убедись что HEAD уже находится на rebase-feature и выполни команду git rebase master. При rebase возникнет конфликт.

  3. Первый коммит Add rebase.md успешно скопирован, а вот Add reflog.md по понятным причинам порождает конфликты. Открой вкладку Source Control в VS Code. Несмотря на то, что файлы были созданы в разных ветках, Git видит, что первые строчки совпадают и по ним конфликта нет. А вот оставшиеся строчки конфликтуют. Так как в ветке rebase-feature был правильный текст, нажми Accept Incoming Change. Добавь reflog.md в Commit Index и выполни команду git rebase --continue. Раз оба коммита были успешно скопированы, rebase на этом будет закончен.

  4. Обрати внимание, что в результате rebase были созданы коммиты Add rebase.md и Add reflog.md. Хоть они похожи на исходные, все же это новые коммиты с новыми ревизиями. Ветка rebase-feature была перемещена и теперь ссылается на новый коммит. Старые коммиты остались в репозитории и на последний из них все еще ссылается тег old-rebase-feature.

  5. Перейди на ветку master и влей в него изменения из rebase-feature. Это будет fast-forward merge.

Задание 9. Reflog (optional)

  1. Удали тег old-rebase-feature с помощью команды git tag -d old-rebase-feature. Коммит, на который он ссылался будет скрыт, но продолжит существовать в репозитории.

  2. Выполни команду git reflog -15

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

  1. В результате ты увидишь список коммитов, по которым передвигался HEAD. Найди в списке действие commit: Add reflog.md и скопируй хэш коммита.
  2. Перейди на этот коммит: git checkout COMMIT_HASH
  3. Убедись, что скрытый коммит найден и снова виден. По крайней мере пока на него ссылается HEAD.
  4. Перейди на master

Задание 10. Fetch From Remote

  1. Добавь новый репозиторий для синхронизации: https://github.com/kontur-courses/git-sheet-ext git remote add ext https://github.com/kontur-courses/git-sheet-ext Убедись, что удаленный репозиторий был добавлен: git remote -v
  2. Выполни fetch репозитория: git fetch ext
  3. Убедись, что в истории появилась ветка ext/sheet-feature из удаленного репозитория, а также несколько новых коммитов.

Задание 11. Interactive Rebase

  1. Выполни checkout на ветку ext/sheet-feature: git checkout sheet-feature

Git автоматически создаст локальную ветку с именем sheet-feature, которая будет указывать на тот же коммит, что и ext/sheet-feature.

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

  1. Выполни интерактивный rebase sheet-feature на master: git rebase -i master
  2. В текстовом редакторе описан сценарий действий для rebase. Сейчас он заключается в том, что надо взять и переместить на новое место все коммиты последовательно: сначала первый, затем второй и т.д. Все как обычно. Ниже сценария приведены комментарии по возможным действиям с коммитами. Прочитай, что делает reword, squash и fixup.
  3. В первой строчке файла замени pick на reword, а последующих строчках замени pick на fixup. Сохрани изменения и закрой открывшийся файл (Ctrl + F4 на Windows, Ctrl + W на Linux, Cmd + W на Mac). Редактор откроется снова и в нем надо будет ввести новое сообщение для Sheet markup. Введи в качестве сообщения Extension и закрой файл.
  4. Убедись, что ветка sheet-feature теперь ссылается на новый коммит с названием Extension. А внутри этого коммита объединены все изменения скопированных коммитов.
  5. Перейди на ветку master и влей в него изменения из sheet-feature. Это будет fast-forward merge.
  6. Удали ветку sheet-feature: git branch -D sheet-feature

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

Задание 12. Push Force

  1. Создай новый файл push.md со следующим содержимым:
## R2. Will Push Force Be With You
### Изменить удаленный репозиторий — это push
- `git push <remote> <local_branch>:<remote_branch>` — добавить изменения из локальной ветки `<local_branch>` и переместить ветку `<remote_branch>` удаленного репозитория
- `git push` = `git push origin HEAD` — добавить изменения из текущей локальной ветки и переместить соответствующую ветку удаленного репозитория

  1. Закоммить изменения с сообщением Add push.md

  2. Сделай push локальной ветки master в master из origin с помощью git push

  3. Замени содержимое push.md на следующее:

## R2. Will Push Force Be With You
### Изменить удаленный репозиторий — это push
- `git push <remote> <local_branch>:<remote_branch>` — добавить изменения из локальной ветки `<local_branch>` и переместить ветку `<remote_branch>` удаленного репозитория
- `git push` = `git push origin HEAD` — добавить изменения из текущей локальной ветки и переместить соответствующую ветку удаленного репозитория
- `git push -f` — выполнить `push`, даже если удаленная ветка находится в другом поддереве
- `git push <remote> -d <branch>` — удалить ветку в удаленном репозитории

  1. Закоммить изменения с опцией --amend (Amend commit), чтобы не создавать лишний коммит.
  2. Обрати внимание, что старый коммит остался видимым, ведь на него ссылается origin/master.
  3. Если сейчас выполнить push, то он завешится ошибкой, т.к. навозможно продвинуть origin/master вперед по истории так, чтобы он стал ссылаться на коммит, на который ссылается master. Поэтому выполни push с опцией --force: git push --force

Задание 13. Upstream

  1. Создай ветку upstream-feature и перейди на нее
  2. Создай новый файл upstream.md со следующим содержимым:
## R3. Upstream Mapping
### Связь локальных и удаленных веток устанавливается явно
- `git branch -vv` — вывести список локальных веток с указанием привязанных к ним upstream-веток
- `git branch -u <upstream> [<branchname>]` — задать upstream-ветку для указанной или текущей ветки
- `git push -u origin HEAD` — создать удаленную ветку, соответствующую локальной и установить между ними upstream-связь, затем добавить изменения из локальной ветки в удаленный репозиторий
- `git checkout <remote_branchname>` — создать локальную ветку, соответствующую удаленной и установить между ними upstream-связь, затем переместить HEAD на нее
- `git pull` = `git pull origin` — получить содержимое основного удаленного репозитория и влить изменения из удаленной ветки в соответствующую локальную ветку
- `git pull --ff-only` — получить содержимое, а затем влить, если возможен fast-forward merge
- `git pull --rebase` — получить содержимое и выполнить rebase локальной ветки на удаленную ветку
- `git config --global push.default simple` — задать simple-режим действий с upstream-связями при push. Это режим по умолчанию в Git 2.0 и выше

  1. Закоммить изменения с сообщением Add upstream.md
  2. Начни делать push этой ветки. git push не сработает потому что ветки в удаленном репозитории еще нет. Чтобы она появилась, нужно выполнить команду git push -u origin upstream-feature:upstream-feature. Но Git поймет и более краткие варианты: git push -u origin upstream-feature, git push -u origin HEAD. Выполни push любым из этих способов.

Задание 14. Stash

  1. Перейди на ветку master.
  2. Создай ветку reset-feature и перейди на нее
  3. Создай новый файл reset.md со следующим содержимым:
## A3. Reset The Difference
### Хранятся файлы, разница вычисляется на лету

  1. Закоммить изменения с сообщением Add reset.md

  2. Замени содержимое reset.md на следующее:

## A3. Reset The Difference
### Хранятся файлы, разница вычисляется на лету
- `git reset --hard <commit>` — переместить текущую ветку на `<commit>`, задать индекс и директорию согласно коммиту, устранив всю разницу
- `git reset --mixed <commit>` — переместить текущую ветку на `<commit>`, задать индекс согласно коммиту, оставить разницу между исходным и новым состоянием в директории
- `git reset --soft <commit>` — переместить текущую ветку на `<commit>`, не задавать индекс и директорию согласно коммиту, а оставить разницу между исходным и новым состоянием в индексе и директории
- `git reset --hard HEAD~1` — отменить последний коммит
- `git stash` — сохранить все модифицированные файлы в виде набора изменений
- `git stash pop` — восстановить последний сохраненный набор изменений и удалить его из списка
- `git stash list` — показать список сохраненных наборов изменений

  1. Ты не влил upstream-feature в master, поэтому придется прервать работу. Выполни команду git stash Обрати внимание, что в Working Directory изменения пропали.

  2. Перейди на ветку master, влей в нее ветку upstream-feature, сделай push.

  3. Перейди назад на ветку reset-feature.

  4. Верни изменения из stash. Для этого выполни команду git stash apply.

Apply не удаляет сохраненные изменения из stash. Если хочется применить изменения и тут же их удалить, то вместо apply надо использовать команду git stash pop

  1. Закоммить изменения с сообщением Change reset.md
  2. Похоже разработка закончена, поэтому можно влить в нее master и отдать в тестирование. Влей master.

Задание 15. Hard Reset

  1. К сожалению ты забыл добавить некоторые изменения в reset-feature. Придется отменить merge. Хорошо, что еще reset-feature не запушен.

  2. В Git Graph найди коммит Change reset.md, выбери его и с помощью контекстного меню выполни Copy commit hash to clipboard. Хэш коммита будет скопирован в буфер обмена. После этого выполни git reset --hard COPIED_COMMIT_HASH

  3. Замени содержимое reset.md на следующее:

## A3. Reset The Difference
### Хранятся файлы, разница вычисляется на лету
- `git reset --hard <commit>` — переместить текущую ветку на `<commit>`, задать индекс и директорию согласно коммиту, устранив всю разницу
- `git reset --mixed <commit>` — переместить текущую ветку на `<commit>`, задать индекс согласно коммиту, оставить разницу между исходным и новым состоянием в директории
- `git reset --soft <commit>` — переместить текущую ветку на `<commit>`, не задавать индекс и директорию согласно коммиту, а оставить разницу между исходным и новым состоянием в индексе и директории
- `git reset --hard HEAD~1` — отменить последний коммит
- `git stash` — сохранить все модифицированные файлы в виде набора изменений
- `git stash pop` — восстановить последний сохраненный набор изменений и удалить его из списка
- `git stash list` — показать список сохраненных наборов изменений
- `git revert <commit>` — создать коммит, отменяющий изменения из коммита
- `git diff <from_commit> [<to_commit>]` — вывести разницу между двумя коммитами
- `git diff --name-status <from_commit> [<to_commit>]` — список измененных файлов
- `git difftool <from_commit> [<to_commit>]` - вывести разницу с помощью difftool из настроек

  1. Закоммить изменения с сообщением Change reset.md again
  2. Снова влей master в reset-feature, чтобы в ней были все актуальные изменения.
  3. Перейди в master. Пришло время запушить последнуюю версию. Для этого влей reset-feature в master и сделай push. Так как в master не произошло изменений с последнего влития master в reset-feature, это будет fast-forward merge.

Задание 16. Soft Reset (optional)

  1. Найди в Git Graph начальный коммит Initial commit, выбери его и с помощью контекстного меню выполни Reset current branch to this Commit. В открывшемся диалоговом окне выбери вариант Soft и выполни reset.
  2. Создай ветку solved и перейди на нее
  3. Закоммить изменения с сообщением Solved
  4. Сделай push

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