From 40c3f86262223539e9f1c7456e7164be3bbeac08 Mon Sep 17 00:00:00 2001 From: ILYA Date: Mon, 21 Feb 2022 07:17:15 +0300 Subject: [PATCH] added file homewerk1 --- homework1.md | 439 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 439 insertions(+) create mode 100644 homework1.md diff --git a/homework1.md b/homework1.md new file mode 100644 index 0000000..1e2cb35 --- /dev/null +++ b/homework1.md @@ -0,0 +1,439 @@ +# **Шпаргалка по консольным командам Git** +## **Общее** + +***Git*** — система контроля версий (файлов). Что-то вроде возможности сохраняться в компьютерных играх (в Git эквивалент игрового сохранения — коммит). Важно: добавление файлов к «сохранению» двухступенчатое: сначала добавляем файл в индекс (git add), потом «сохраняем» (git commit). + +Любой файл в директории существующего репозитория может находиться или не находиться под версионным контролем (отслеживаемые и неотслеживаемые). + +Отслеживаемые файлы могут быть в 3-х состояниях: неизменённые, изменённые, проиндексированные (готовые к коммиту). + +## **Ключ к пониманию** + +Ключ к пониманию концепции *git* — знание о «***трех деревьях***»: + +1. ***Рабочая директория*** — файловая система проекта (те файлы, с которыми вы работаете). + +2. ***Индекс*** — список отслеживаемых git-ом файлов и директорий, промежуточное хранилище изменений (редактирование, удаление отслеживаемых файлов). + +3. ***Директория*** _.git/_ — все данные контроля версий этого проекта (вся история разработки: коммиты, ветки, теги и пр.). + +***Коммит*** — «сохранение» (хранит набор изменений, сделанный в рабочей директории с момента предыдущего коммита). Коммит неизменен, его нельзя отредактировать. + +У всех коммитов (кроме самого первого) есть один или более родительских коммитов, поскольку коммиты хранят изменения от предыдущих состояний. + +## **Простейший цикл работ** + +* Редактирование, добавление, удаление файлов (собственно, работа). + +* Индексация/добавление файлов в индекс (указание для git какие изменения нужно будет закоммитить). + +* Коммит (фиксация изменений). + +* Возврат к шагу 1 или отход ко сну. + +## **Указатели** + +* _HEAD_ — указатель на текущий коммит или на текущую ветку (то есть, в любом случае, на коммит). Указывает на родителя коммита, который будет создан следующим. + +* _ORIG_HEAD_ — указатель на коммит, с которого вы только что переместили HEAD (командой git reset ..., например). + +* Ветка (_master, develop etc._) — указатель на коммит. При добавлении коммита, указатель ветки перемещается с родительского коммита на новый. + +* Теги — простые указатели на коммиты. Не перемещаются. + +## **Настройки** +Перед началом работы нужно выполнить некоторые настройки: + +_git config --global user.name "Your Name" # указать имя, которым будут подписаны коммиты_ + +_git config --global user.email "e@w.com" # указать электропочту, которая будет в описании коммитера_ + +Если вы в Windows: + +_git config --global core.autocrlf true # включить преобразование окончаний строк из CRLF в LF_ + +## **Указание неотслеживаемых файлов** + +Файлы и директории, которые не нужно включать в репозиторий, указываются в файле _.gitignore._ Обычно это устанавливаемые зависимости (node_modules/, bower_components/), готовая сборка build/ или dist/ и подобные, создаваемые при установке или запуске. Каждый файл или директория указываются с новой строки. + +### ***Консоль*** + +***Длинный вывод в консоли: Vim*** + +Вызов некоторых консольных команд приводит к необходимости очень длинного вывода в консоль (пример: вывод истории всех изменений в файле командой _git log -p fileName.txt_). При этом прямо в консоли запускается редактор Vim. Он работает в нескольких режимах, из которых Вас заинтересуют режим вставки (редактирование текста) и нормальный (командный) режим. Чтобы попасть из Vim обратно в консоль, нужно в командном режиме ввести _:q_. Переход в командный режим из любого другого: _Esc_. + +Если нужно что-то написать, нажмите _i_ — это переход в режим вставки текста. Если нужно сохранить изменения, перейдите в командный режим и наберите _:w_. + +# **Vim (некоторые команды)** +* **Нажатия кнопок** + + ESC — переход в командный режим + + i — переход в режим редактирования текста + + ZQ (зажат Shift, поочередное нажатие) — выход без сохранения + + ZZ (зажат Shift, поочередное нажатие) — сохранить и выйти + + +* **Ввод в командном режиме** + + :q! — выйти без сохранения + + :wq — сохранить файл и выйти + + :w filename.txt — сохранить файл как filename.txt + +## **Консольные команды** + +**Создать новый репозиторий** + + git init # создать новый проект в текущей директории + + git init folder-name # создать новый проект в указанной директории + +**Клонирование репозитория** + +* клонировать удаленный репозиторий в одноименную директорию +git clone https://github.com/cyberspacedk/Git-commands.git + +* клонировать удаленный репозиторий в директорию «FolderName» +git clone https://github.com/cyberspacedk/Git-commands.git FolderName + +* клонировать репозиторий в текущую директорию +git clone https://github.com:nicothin/web-design.git . + +**Просмотр изменений** + + git status # показать состояние репозитория (отслеживаемые, изменённые, новые файлы и пр.) + + git diff # сравнить рабочую директорию и индекс (неотслеживаемые файлы ИГНОРИРУЮТСЯ) + + git diff --color-words # сравнить рабочую директорию и индекс, показать отличия в словах (неотслеживаемые файлы ИГНОРИРУЮТСЯ) + + git diff index.html # сравнить файл из рабочей директории и индекс + + git diff HEAD # сравнить рабочую директорию и коммит, на который указывает HEAD (неотслеживаемые файлы ИГНОРИРУЮТСЯ) + + git diff --staged # сравнить индекс и коммит с HEAD + + git diff master feature # посмотреть что сделано в ветке feature по сравнению с веткой master + + git diff --name-only master feature # посмотреть что сделано в ветке feature по сравнению с веткой master, показать только имена файлов + + git diff master...feature # посмотреть что сделано в ветке feature с момента (коммита) расхождения с master + +**Добавление изменений в индекс** + + git add . # добавить в индекс все новые, изменённые, удалённые файлы из текущей директории и её поддиректорий + + git add text.txt # добавить в индекс указанный файл (был изменён, был удалён или это новый файл) + + git add -i # запустить интерактивную оболочку для добавления в индекс только выбранных файлов + + git add -p # показать новые/изменённые файлы по очереди с указанием их изменений и вопросом об отслеживании/индексировании + +**Удаление изменений из индекса** + + git reset # убрать из индекса все добавленные в него изменения (в рабочей директории все изменения сохранятся), антипод git add + + git reset readme.txt # убрать из индекса изменения указанного файла (в рабочей директории изменения сохранятся) + +**Отмена изменений** + + git checkout text.txt # ОПАСНО: отменить изменения в файле, вернуть состояние файла, имеющееся в индексе + + git reset --hard # ОПАСНО: отменить изменения; вернуть то, что в коммите, на который указывает HEAD (незакомиченные изменения удалены из индекса и из рабочей директории, неотслеживаемые файлы останутся на месте) + + git clean -df # удалить неотслеживаемые файлы и директории + +**Коммиты** + + git commit -m "Name of commit" # зафиксировать в коммите проиндексированные изменения (закоммитить), добавить сообщение + + git commit -a -m "Name of commit" # проиндексировать отслеживаемые файлы (ТОЛЬКО отслеживаемые, но НЕ новые файлы) и закоммитить, добавить сообщение + +**Отмена коммитов и перемещение по истории** + +Все коммиты, которые уже были отправлены в удалённый репозиторий, должны отменяться новыми коммитами (git revert), дабы избежать проблем с историей разработки у других участников проекта. + + git revert HEAD --no-edit # создать новый коммит, отменяющий изменения последнего коммита без запуска редактора сообщения + + git revert b9533bb --no-edit # то же, но отменяются изменения, внесённые коммитом с указанным хешем (b9533bb) + +Все команды, приведённые ниже можно выполнять ТОЛЬКО если коммиты еще не были отправлены в удалённый репозиторий. + +***ВНИМАНИЕ! Опасные команды, можно потерять незакоммиченные изменения*** + + git commit --amend -m "Название" # «перекоммитить» изменения последнего коммита, заменить его новым коммитом с другим сообщением (сдвинуть текущую ветку на один коммит назад, сохранив рабочую директорию и индекс «как есть», создать новый коммит с данными из «отменяемого» коммита, но новым сообщением) + + git reset --hard @~ # передвинуть HEAD (и ветку) на предыдущий коммит, рабочую директорию и индекс сделать такими, какими они были в момент предыдущего коммита + + git reset --hard 75e2d51 # передвинуть HEAD (и ветку) на коммит с указанным хешем, рабочую директорию и индекс сделать такими, какими они были в момент указанного коммита + + git reset --soft @~ # передвинуть HEAD (и ветку) на предыдущий коммит, но в рабочей директории и индексе оставить все изменения + + git reset --soft @~2 # то же, но передвинуть HEAD (и ветку) на 2 коммита назад + + git reset @~ # передвинуть HEAD (и ветку) на предыдущий коммит, рабочую директорию оставить как есть, индекс сделать таким, каким он был в момент предыдущего коммита (удобнее, чем git reset --soft @~, если индекс нужно задать заново) + + Почти как git reset --hard, но безопаснее: не получится потерять изменения в рабочей директории + + git reset --keep @~ # передвинуть HEAD (и ветку) на предыдущий коммит, сбросить индекс, но в рабочей директории оставить изменения, если возможно (если файл с изменениями между коммитами менялся, будет выдана ошибка и переключение не произойдёт) + +**Временно переключиться на другой коммит** + + git checkout b9533bb # переключиться на коммит с указанным хешем (переместить HEAD на указанный коммит, рабочую директорию вернуть к состоянию, на момент этого коммита) + + git checkout master # переключиться на коммит, на который указывает master (переместить HEAD на коммит, на который указывает master, рабочую директорию вернуть к состоянию на момент этого коммита) + +**Переключиться на другой коммит и продолжить работу с него** + +Потребуется создание новой ветки, начинающейся с указанного коммита. + + git checkout -b new-branch 5589877 # создать ветку new-branch, начинающуюся с коммита c хешем 5589877 (переместить HEAD на указанный коммит, рабочую директорию вернуть к состоянию, на момент этого коммита, создать указатель на этот коммит (ветку) с указанным именем) + +**Восстановление изменений** + + git checkout 5589877 index.html # восстановить в рабочей директории указанный файл на момент указанного коммита (и добавить это изменение в индекс) (git reset index.html для удаления из индекса, но сохранения изменений в файле) + +**Копирование коммита (перенос коммитов)** + + git cherry-pick 5589877 # скопировать на активную ветку изменения из указанного коммита, закоммитить эти изменения + + git cherry-pick master~2..master # скопировать на активную ветку изменения из master (2 последних коммита) + + git cherry-pick -n 5589877 # скопировать на активную ветку изменения из указанного коммита, но НЕ КОММИТИТЬ (подразумевается, что мы сами потом закоммитим) + + git cherry-pick master..feature # скопировать на активную ветку изменения из всех коммитов ветки feature с момента её расхождения с master (похоже на слияние веток, но это копирование изменений, а не слияние), закоммитить эти изменения; это может вызвать конфликт + + git cherry-pick --abort # прервать конфликтный перенос коммитов + + git cherry-pick --continue # продолжить конфликтный перенос коммитов (сработает только после решения конфликта) + +**Удаление файла** + + git rm text.txt # удалить отслеживаемый неизменённый файл и проиндексировать это изменение + + git rm -f text.txt # удалить отслеживаемый изменённый файл и проиндексировать это изменение + + git rm -r log/ # удалить всё содержимое отслеживаемой директории log/ и проиндексировать это изменение + + git rm ind* # удалить все отслеживаемые файлы с именем, начинающимся на «ind» в текущей директории и проиндексировать это изменение + + git rm --cached readme.txt # удалить из отслеживаемых индексированный файл (ФАЙЛ ОСТАНЕТСЯ НА МЕСТЕ) (часто используется для нечаянно добавленных в отслеживаемые файлов) + +**Перемещение/переименование файлов** + +Для git не существует переименования. Переименование воспринимается как удаление старого файла и создание нового. Факт переименования может быть определен только после индексации изменения. + + git mv text.txt test_new.txt # переименовать файл «text.txt» в «test_new.txt» и проиндексировать это изменение + + git mv readme_new.md folder/ # переместить файл readme_new.md в директорию folder/ (должна существовать) и проиндексировать это изменение + +**История коммитов** + +Выход из длинного лога вывода: q. + + git log master # показать коммиты в указанной ветке + + git log -2 # показать последние 2 коммита в активной ветке + + git log -2 --stat # показать последние 2 коммита и статистику внесенных ими изменений + + git log -p -22 # показать последние 22 коммита и внесенную ими разницу на уровне строк + + git log --graph -10 # показать последние 10 коммитов с ASCII-представлением ветвления + + git log --since=2.weeks # показать коммиты за последние 2 недели + + git log --after '2018-06-30' # показать коммиты, сделанные после указанной даты + + git log index.html # показать историю изменений файла index.html (только коммиты) + + git log -5 index.html # показать историю изменений файла index.html, последние 5 коммитов (только коммиты) + + git log -p index.html # показать историю изменений файла index.html (коммиты и изменения) + + git log -G'myFunction' -p # показать все коммиты, в которых менялись строки с myFunction (в кавычках регулярное выражение) + + git log -L '//','/<\/head>/':index.html # показать изменения от указанного до указанного регулярных выражений в указанном файле + + git log --grep fix # показать коммиты, в описании которых есть буквосочетание fix (регистрозависимо, только коммиты текущей ветки) + + git log --grep fix -i # показать коммиты, в описании которых есть буквосочетание fix (регистроНЕзависимо, только коммиты текущей ветки) + + git log --grep 'fix(ing|me)' -P # показать коммиты, в описании которых есть совпадения для регулярного выражения (только коммиты текущей ветки) + + git log --pretty=format:"%h - %an, %ar : %s" -4 # показать последние 4 коммита с форматированием выводимых данных + + git log --pretty=format:"%h %ad | %s%d [%an]" --graph --date=short # мой формат вывода, висящий на алиасе оболочки + + git log master..branch_99 # показать коммиты из ветки branch_99, которые не влиты в master + + git log branch_99..master # показать коммиты из ветки master, которые не влиты в branch_99 + + git log master...branch_99 --boundary -- graph # показать коммиты из указанных веток, начиная с их расхождения (коммит расхождения будет показан) + + git show 60d6582 # показать изменения из коммита с указанным хешем + + git show HEAD~ # показать данные о предыдущем коммите в активной ветке + + git show @~ # аналогично предыдущему + + git show HEAD~3 # показать данные о коммите, который был 3 коммита назад + + git show my_branch~2 # показать данные о коммите, который был 2 коммита назад в указанной ветке + + git show @~:index.html # показать контент указанного файла на момент предыдущего (от HEAD) коммита + + git show :/"подвал" # показать самый новый коммит, в описании которого есть указанное слово (из любой ветки) + +**Кто написал строку** + + git blame README.md --date=short -L 5,8 # показать строки 5-8 указанного файла и коммиты, в которых строки были добавлены + + История изменений указателей (веток, HEAD) + + git reflog -20 # показать последние 20 изменений положения указателя HEAD + + git reflog --format='%C(auto)%h %<|(20)%gd %C(blue)%cr%C(reset) %gs (%s)' -20 # то же, но с указанием давности действий + +**Ветки** + + git branch # показать список веток + + git branch -v # показать список веток и последний коммит в каждой + + git branch new_branch # создать новую ветку с указанным именем на текущем коммите + + git branch new_branch 5589877 # создать новую ветку с указанным именем на указанном коммите + + git branch -f master 5589877 # переместить ветку master на указанный коммит + + git branch -f master master~2 # переместить ветку master на 2 коммита назад + + git checkout new_branch # перейти в указанную ветку + + git checkout -b new_branch # создать новую ветку с указанным именем и перейти в неё + + git checkout -B master 5589877 # переместить ветку с указанным именем на указанный коммит и перейти в неё + + git merge hotfix # влить в ветку, в которой находимся, данные из ветки hotfix + + git merge hotfix -m "Горячая правка" # влить в ветку, в которой находимся, данные из ветки hotfix (указано сообщение коммита слияния) + + git merge hotfix --log # влить в ветку, в которой находимся, данные из ветки hotfix, показать редактор описания коммита, добавить в него сообщения вливаемых коммитов + + git merge hotfix --no-ff # влить в ветку, в которой находимся, данные из ветки hotfix, запретить простой сдвиг указателя, изменения из hotfix «останутся» в ней, а в активной ветке появится только коммит слияния + + git branch -d hotfix # удалить ветку hotfix (используется, если её изменения уже влиты в главную ветку) + + git branch --merged # показать ветки, уже слитые с активной + + git branch --no-merged # показать ветки, не слитые с активной + + git branch -a # показать все имеющиеся ветки (в т.ч. на удаленных репозиториях) + + git branch -m old_branch_name new_branch_name # переименовать локально ветку old_branch_name в new_branch_name + + git branch -m new_branch_name # переименовать локально ТЕКУЩУЮ ветку в new_branch_name + + git push origin :old_branch_name new_branch_name # применить переименование в удаленном репозитории + + git branch --unset-upstream # завершить процесс переименования + +**Теги** + + git tag v1.0.0 # создать тег с указанным именем на коммите, на который указывает HEAD + + git tag -a -m 'В продакшен!' v1.0.1 master # создать тег с описанием на том коммите, на который смотрит ветка master + + git tag -d v1.0.0 # удалить тег с указанным именем(ами) + + git tag -n # показать все теги, и по 1 строке сообщения коммитов, на которые они указывают + + git tag -n -l 'v1.*' # показать все теги, которые начинаются с 'v1.*' + +**Временное сохранение изменений без коммита** + + git stash # временно сохранить незакоммиченные изменения и убрать их из рабочей д + иректории + + git stash pop # вернуть сохраненные командой git stash изменения в рабочую директорию + +**Удалённые репозитории** + +*Есть два распространённых способа привязать удалённый репозиторий к локальному: по HTTPS и по SSH. Если SSH у вас не настроен (или вы не знаете что это), привязывайте удалённый репозиторий по HTTPS (адрес привязываемого репозитория должен начинаться с https://).* + + git remote -v # показать список удалённых репозиториев, связанных с локальным + + git remote remove origin # убрать привязку удалённого репозитория с сокр. именем origin + + git remote add origin https://github.com:nicothin/test.git # добавить удалённый репозиторий (с сокр. именем origin) с указанным URL + + git remote rm origin # удалить привязку удалённого репозитория + + git remote show origin # получить данные об удалённом репозитории с сокращенным именем origin + + git fetch origin # скачать все ветки с удаленного репозитория (с сокр. именем origin), но не сливать со своими ветками + + git fetch origin master # то же, но скачивается только указанная ветка + + git checkout --track origin/github_branch # создать локальную ветку github_branch (данные взять из удалённого репозитория с сокр. именем origin, ветка github_branch) и переключиться на неё + + git push origin master # отправить в удалённый репозиторий (с сокр. именем origin) данные своей ветки master + + git pull origin # влить изменения с удалённого репозитория (все ветки) + + git pull origin master # влить изменения с удалённого репозитория (только указанная ветка) + +**Конфликт слияния** + +*Предполагается ситуация: есть ветка master и есть ветка feature. В обеих ветках есть коммиты, сделанные после расхождения веток. В ветку master пытаемся влить ветку feature (git merge feature), получаем конфликт, т.к. в обеих ветках есть изменения одной и той же строки в файле index.html.* + +*При возникновении конфликта, репозиторий находится в состоянии прерванного слияния. Нужно оставить в конфликтующих местах файлов только нужный код, проиндексировать изменения и закоммитить.* + + git merge feature # влить в активную ветку изменения из ветки feature + + git merge-base master feature # показать хеш последнего общего коммита для двух указанных веток + + git checkout --ours index.html # оставить в конфликтном файле (index.html) состояние ветки, В КОТОРУЮ мы вливаем (в примере — из ветки master) + + git checkout --theirs index.html # оставить в конфликтном файле (index.html) состояние ветки, ИЗ КОТОРОЙ мы вливаем (в примере — из ветки feature) + + git checkout --merge index.html # показать в конфликтном файле (index.html) сравнение содержимого сливаемых веток (для ручного редактирования) + + git checkout --conflict=diff3 --merge index.html # показать в конфликтном файле (index.html) сравнение содержимого сливаемых веток плюс то, что было в месте конфликта в коммите, на котором разошлись сливаемые ветки + + git reset --hard # прекратить это прерванное слияние, вернуть рабочую директорию и индекс как было в момент коммита, на который указывает HEAD, а я пойду немного поплачу + + git reset --merge # прекратить это прерванное слияние, но оставить изменения, не закоммиченные до слияния (для случая, когда слияние делается не на чистом статусе) + + git reset --abort # то же, что и строкой выше + +**«Перенос» ветки** + +*Можно «переместить» ответвление какой-либо ветки от основной на произвольный коммит. Это нужно для того, чтобы в «переносимой» ветке появились какие-либо изменения, внесённые в основной ветке (уже после ответвления переносимой).* + +*Нельзя «переносить» ветку, если она уже отправлена на удалённый репозиторий.* + + git rebase master # перенести все коммиты (создать их копии) активной ветки так, будто активная ветка ответвилась от master на нынешней вершине master (часто вызывает конфликты) + + git rebase --onto master feature # перенести коммиты активной ветки на master, начиная с того места, в котором активная ветка отделилась от ветки feature + + git rebase --abort # прервать конфликтный rebase, вернуть рабочую директорию и индекс к состоянию до начала rebase + + git rebase --continue # продолжить конфликтный rebase (сработает только после разрешения конфликта и индексации такого разрешения) + +**Как отменить rebase** + + git reflog feature -2 # смотрим лог перемещений ветки, которой делали rebase (в этом примере — feature), видим последний коммит ПЕРЕД rebase, на него и нужно перенести указатель ветки + + git reset --hard feature@{1} # переместить указатель ветки feature на один коммит назад, обновить рабочую директорию и индекс + +**Разное** + + git archive -o ./project.zip HEAD # создать архив с файловой структурой проекта по указанному пути (состояние репозитория, соответствующее указателю HEAD) + +## **КОНЕЦ**