├── .gitignore ├── Git-Commands.md ├── Hub. Git-Hub.md ├── init-text-on-rep.txt ├── Шпаргалка по bash.md └── Шпаргалка по консольным командам Git.md /.gitignore: -------------------------------------------------------------------------------- 1 | .vscode -------------------------------------------------------------------------------- /Git-Commands.md: -------------------------------------------------------------------------------- 1 | # git-help-2 2 | # Шпаргалка по консольным командам Git 3 | 4 | * [Общее](https://github.com/nicothin/web-development/tree/master/git#Общее) 5 | * [Консольные команды](https://github.com/nicothin/web-development/tree/master/git#Консольные-команды) 6 | * [Примеры реальной работы](https://github.com/nicothin/web-development/tree/master/git#Примеры) 7 | 8 | 9 | 10 | ## Общее 11 | 12 | Git — система контроля версий (файлов). Что-то вроде возможности сохраняться в компьютерных играх (в Git эквивалент игрового сохранения — коммит). **Важно**: добавление файлов к «сохранению» двухступенчатое: сначала добавляем файл в индекс (`git add`), потом «сохраняем» (`git commit`). 13 | 14 | Любой файл в директории существующего репозитория может находиться или не находиться под версионным контролем (отслеживаемые и неотслеживаемые). 15 | 16 | Отслеживаемые файлы могут быть в 3-х состояниях: неизменённые, изменённые, проиндексированные (готовые к коммиту). 17 | 18 | ### Ключ к пониманию 19 | 20 | Ключ к пониманию концепции git — знание о «трех деревьях»: 21 | 22 | - Рабочая директория — файловая система проекта (те файлы, с которыми вы работаете). 23 | - Индекс — список отслеживаемых git-ом файлов и директорий, промежуточное хранилище изменений (редактирование, удаление отслеживаемых файлов). 24 | - Директория `.git/` — все данные контроля версий этого проекта (вся история разработки: коммиты, ветки, теги и пр.). 25 | 26 | Коммит — «сохранение» (хранит набор изменений, сделанный в рабочей директории с момента предыдущего коммита). Коммит неизменен, его нельзя отредактировать. 27 | 28 | У всех коммитов (кроме самого первого) есть один или более родительских коммитов, поскольку коммиты хранят изменения от предыдущих состояний. 29 | 30 | ### Простейший цикл работ 31 | 32 | - Редактирование, добавление, удаление файлов (собственно, работа). 33 | - Индексация/добавление файлов в индекс (указание для git какие изменения нужно будет закоммитить). 34 | - Коммит (фиксация изменений). 35 | - Возврат к шагу 1 или отход ко сну. 36 | 37 | ### Указатели 38 | 39 | - `HEAD` — указатель на текущий коммит или на текущую ветку (то есть, в любом случае, на коммит). Указывает на родителя коммита, который будет создан следующим. 40 | - `ORIG_HEAD` — указатель на коммит, с которого вы только что переместили `HEAD` (командой `git reset ...`, например). 41 | - Ветка (`master`, `develop` etc.) — указатель на коммит. При добавлении коммита, указатель ветки перемещается с родительского коммита на новый. 42 | - Теги — простые указатели на коммиты. Не перемещаются. 43 | 44 | 45 | 46 | ### Настройки 47 | 48 | Перед началом работы нужно выполнить некоторые настройки: 49 | 50 | ``` 51 | git config --global user.name "Your Name" # указать имя, которым будут подписаны коммиты 52 | git config --global user.email "e@w.com" # указать электропочту, которая будет в описании коммитера 53 | ``` 54 | 55 | Если вы в Windows: 56 | 57 | ``` 58 | git config --global core.autocrlf true # включить преобразование окончаний строк из CRLF в LF 59 | ``` 60 | 61 | 62 | ### Указание неотслеживаемых файлов 63 | 64 | Файлы и директории, которые не нужно включать в репозиторий, указываются в файле `.gitignore`. Обычно это устанавливаемые зависимости (`node_modules/`, `bower_components/`), готовая сборка `build/` или `dist/` и подобные, создаваемые при установке или запуске. Каждый файл или директория указываются с новой строки, [возможно использование шаблонов](http://git-scm.com/book/ru/v2/%D0%9E%D1%81%D0%BD%D0%BE%D0%B2%D1%8B-Git-%D0%97%D0%B0%D0%BF%D0%B8%D1%81%D1%8C-%D0%B8%D0%B7%D0%BC%D0%B5%D0%BD%D0%B5%D0%BD%D0%B8%D0%B9-%D0%B2-%D1%80%D0%B5%D0%BF%D0%BE%D0%B7%D0%B8%D1%82%D0%BE%D1%80%D0%B8%D0%B9#Игнорирование-файлов). 65 | 66 | 67 | ### Консоль 68 | 69 | [Как использовать консоль в Windows](http://nicothin.pro/page/console-windows) (на OSX и Linux сразу есть хорошая консоль (терминал)). [Как комфортно работать с GitHub в консоли Windows](http://nicothin.pro/page/kak-komfortno-rabotat-s-github-v-konsoli-windows). 70 | 71 | 72 | ### Длинный вывод в консоли: Vim 73 | 74 | Вызов некоторых консольных команд приводит к необходимости очень длинного вывода в консоль (пример: вывод истории всех изменений в файле командой `git log -p fileName.txt`). При этом прямо в консоли запускается редактор [Vim](https://ru.wikipedia.org/wiki/Vim). Он работает в нескольких режимах, из которых Вас заинтересуют режим вставки (редактирование текста) и нормальный (командный) режим. Чтобы попасть из Vim обратно в консоль, нужно в командном режиме ввести :q. Переход в командный режим из любого другого: Esc. 75 | 76 | Если нужно что-то написать, нажмите i — это переход в режим вставки текста. Если нужно сохранить изменения, перейдите в командный режим и наберите :w. 77 | 78 | [Чуть-чуть больше команд](vim.md). 79 | 80 | 81 | 82 | 83 | 84 | ## Консольные команды 85 | 86 | ### Создать новый репозиторий 87 | 88 | ``` bash 89 | git init # создать новый проект в текущей директории 90 | git init folder-name # создать новый проект в указанной директории 91 | ``` 92 | 93 | 94 | ### Клонирование репозитория 95 | 96 | ``` bash 97 | git clone https://github.com:nicothin/web-design.git # клонировать удаленный репозиторий в одноименную директорию 98 | git clone https://github.com:nicothin/web-design.git FolderName # клонировать удаленный репозиторий в директорию «FolderName» 99 | git clone https://github.com:nicothin/web-design.git . # клонировать репозиторий в текущую директорию 100 | ``` 101 | 102 | 103 | ### Просмотр изменений 104 | 105 | ``` bash 106 | git status # показать состояние репозитория (отслеживаемые, изменённые, новые файлы и пр.) 107 | git diff # сравнить рабочую директорию и индекс (неотслеживаемые файлы ИГНОРИРУЮТСЯ) 108 | git diff --color-words # сравнить рабочую директорию и индекс, показать отличия в словах (неотслеживаемые файлы ИГНОРИРУЮТСЯ) 109 | git diff index.html # сравнить файл из рабочей директории и индекс 110 | git diff HEAD # сравнить рабочую директорию и коммит, на который указывает HEAD (неотслеживаемые файлы ИГНОРИРУЮТСЯ) 111 | git diff --staged # сравнить индекс и коммит с HEAD 112 | git diff master feature # посмотреть что сделано в ветке feature по сравнению с веткой master 113 | git diff --name-only master feature # посмотреть что сделано в ветке feature по сравнению с веткой master, показать только имена файлов 114 | git diff master...feature # посмотреть что сделано в ветке feature с момента (коммита) расхождения с master 115 | ``` 116 | 117 | 118 | ### Добавление изменений в индекс 119 | 120 | ``` bash 121 | git add . # добавить в индекс все новые, изменённые, удалённые файлы из текущей директории и её поддиректорий 122 | git add text.txt # добавить в индекс указанный файл (был изменён, был удалён или это новый файл) 123 | git add -i # запустить интерактивную оболочку для добавления в индекс только выбранных файлов 124 | git add -p # показать новые/изменённые файлы по очереди с указанием их изменений и вопросом об отслеживании/индексировании 125 | ``` 126 | 127 | 128 | ### Удаление изменений из индекса 129 | 130 | ``` bash 131 | git reset # убрать из индекса все добавленные в него изменения (в рабочей директории все изменения сохранятся), антипод git add 132 | git reset readme.txt # убрать из индекса изменения указанного файла (в рабочей директории изменения сохранятся) 133 | ``` 134 | 135 | 136 | ### Отмена изменений 137 | 138 | ``` bash 139 | git checkout text.txt # ОПАСНО: отменить изменения в файле, вернуть состояние файла, имеющееся в индексе 140 | git reset --hard # ОПАСНО: отменить изменения; вернуть то, что в коммите, на который указывает HEAD (незакомиченные изменения удалены из индекса и из рабочей директории, неотслеживаемые файлы останутся на месте) 141 | git clean -df # удалить неотслеживаемые файлы и директории 142 | ``` 143 | 144 | 145 | ### Коммиты 146 | 147 | ``` bash 148 | git commit -m "Name of commit" # зафиксировать в коммите проиндексированные изменения (закоммитить), добавить сообщение 149 | git commit -a -m "Name of commit" # проиндексировать отслеживаемые файлы (ТОЛЬКО отслеживаемые, но НЕ новые файлы) и закоммитить, добавить сообщение 150 | ``` 151 | 152 | 153 | ### Отмена коммитов и перемещение по истории 154 | 155 | Все коммиты, которые уже были отправлены в удалённый репозиторий, должны отменяться новыми коммитами (`git revert`), дабы избежать проблем с историей разработки у других участников проекта. 156 | 157 | ``` bash 158 | git revert HEAD --no-edit # создать новый коммит, отменяющий изменения последнего коммита без запуска редактора сообщения 159 | git revert b9533bb --no-edit # то же, но отменяются изменения, внесённые коммитом с указанным хешем (b9533bb) 160 | ``` 161 | 162 | **Все команды, приведённые ниже можно выполнять ТОЛЬКО если коммиты еще не были отправлены в удалённый репозиторий.** 163 | 164 | ``` bash 165 | # ВНИМАНИЕ! Опасные команды, можно потерять незакоммиченные изменения 166 | git commit --amend -m "Название" # «перекоммитить» изменения последнего коммита, заменить его новым коммитом с другим сообщением (сдвинуть текущую ветку на один коммит назад, сохранив рабочую директорию и индекс «как есть», создать новый коммит с данными из «отменяемого» коммита, но новым сообщением) 167 | git reset --hard @~ # передвинуть HEAD (и ветку) на предыдущий коммит, рабочую директорию и индекс сделать такими, какими они были в момент предыдущего коммита 168 | git reset --hard 75e2d51 # передвинуть HEAD (и ветку) на коммит с указанным хешем, рабочую директорию и индекс сделать такими, какими они были в момент указанного коммита 169 | git reset --soft @~ # передвинуть HEAD (и ветку) на предыдущий коммит, но в рабочей директории и индексе оставить все изменения 170 | git reset --soft @~2 # то же, но передвинуть HEAD (и ветку) на 2 коммита назад 171 | git reset @~ # передвинуть HEAD (и ветку) на предыдущий коммит, рабочую директорию оставить как есть, индекс сделать таким, каким он был в момент предыдущего коммита (удобнее, чем git reset --soft @~, если индекс нужно задать заново) 172 | # Почти как git reset --hard, но безопаснее: не получится потерять изменения в рабочей директории 173 | git reset --keep @~ # передвинуть HEAD (и ветку) на предыдущий коммит, сбросить индекс, но в рабочей директории оставить изменения, если возможно (если файл с изменениями между коммитами менялся, будет выдана ошибка и переключение не произойдёт) 174 | ``` 175 | 176 | 177 | ### Временно переключиться на другой коммит 178 | 179 | ``` bash 180 | git checkout b9533bb # переключиться на коммит с указанным хешем (переместить HEAD на указанный коммит, рабочую директорию вернуть к состоянию, на момент этого коммита) 181 | git checkout master # переключиться на коммит, на который указывает master (переместить HEAD на коммит, на который указывает master, рабочую директорию вернуть к состоянию на момент этого коммита) 182 | ``` 183 | 184 | 185 | ### Переключиться на другой коммит и продолжить работу с него 186 | 187 | Потребуется создание новой ветки, начинающейся с указанного коммита. 188 | 189 | ``` bash 190 | git checkout -b new-branch 5589877 # создать ветку new-branch, начинающуюся с коммита c хешем 5589877 (переместить HEAD на указанный коммит, рабочую директорию вернуть к состоянию, на момент этого коммита, создать указатель на этот коммит (ветку) с указанным именем) 191 | ``` 192 | 193 | 194 | ### Восстановление изменений 195 | 196 | ``` bash 197 | git checkout 5589877 index.html # восстановить в рабочей директории указанный файл на момент указанного коммита (и добавить это изменение в индекс) (git reset index.html для удаления из индекса, но сохранения изменений в файле) 198 | ``` 199 | 200 | 201 | ### Копирование коммита (перенос коммитов) 202 | 203 | ``` bash 204 | git cherry-pick 5589877 # скопировать на активную ветку изменения из указанного коммита, закоммитить эти изменения 205 | git cherry-pick master~2..master # скопировать на активную ветку изменения из master (2 последних коммита) 206 | git cherry-pick -n 5589877 # скопировать на активную ветку изменения из указанного коммита, но НЕ КОММИТИТЬ (подразумевается, что мы сами потом закоммитим) 207 | git cherry-pick master..feature # скопировать на активную ветку изменения из всех коммитов ветки feature с момента её расхождения с master (похоже на слияние веток, но это копирование изменений, а не слияние), закоммитить эти изменения; это может вызвать конфликт 208 | git cherry-pick --abort # прервать конфликтный перенос коммитов 209 | git cherry-pick --continue # продолжить конфликтный перенос коммитов (сработает только после решения конфликта) 210 | ``` 211 | 212 | 213 | ### Удаление файла 214 | 215 | ``` bash 216 | git rm text.txt # удалить отслеживаемый неизменённый файл и проиндексировать это изменение 217 | git rm -f text.txt # удалить отслеживаемый изменённый файл и проиндексировать это изменение 218 | git rm -r log/ # удалить всё содержимое отслеживаемой директории log/ и проиндексировать это изменение 219 | git rm ind* # удалить все отслеживаемые файлы с именем, начинающимся на «ind» в текущей директории и проиндексировать это изменение 220 | git rm --cached readme.txt # удалить из отслеживаемых индексированный файл (ФАЙЛ ОСТАНЕТСЯ НА МЕСТЕ) (часто используется для нечаянно добавленных в отслеживаемые файлов) 221 | ``` 222 | 223 | 224 | ### Перемещение/переименование файлов 225 | 226 | Для git не существует переименования. Переименование воспринимается как удаление старого файла и создание нового. Факт переименования может быть определен только после индексации изменения. 227 | 228 | ``` bash 229 | git mv text.txt test_new.txt # переименовать файл «text.txt» в «test_new.txt» и проиндексировать это изменение 230 | git mv readme_new.md folder/ # переместить файл readme_new.md в директорию folder/ (должна существовать) и проиндексировать это изменение 231 | ``` 232 | 233 | 234 | ### История коммитов 235 | 236 | Выход из длинного лога вывода: `q`. 237 | 238 | ``` bash 239 | git log master # показать коммиты в указанной ветке 240 | git log -2 # показать последние 2 коммита в активной ветке 241 | git log -2 --stat # показать последние 2 коммита и статистику внесенных ими изменений 242 | git log -p -22 # показать последние 22 коммита и внесенную ими разницу на уровне строк 243 | git log --graph -10 # показать последние 10 коммитов с ASCII-представлением ветвления 244 | git log --since=2.weeks # показать коммиты за последние 2 недели 245 | git log --after '2018-06-30' # показать коммиты, сделанные после указанной даты 246 | git log index.html # показать историю изменений файла index.html (только коммиты) 247 | git log -5 index.html # показать историю изменений файла index.html, последние 5 коммитов (только коммиты) 248 | git log -p index.html # показать историю изменений файла index.html (коммиты и изменения) 249 | git log -G'myFunction' -p # показать все коммиты, в которых менялись строки с myFunction (в кавычках регулярное выражение) 250 | git log -L '/
/','/<\/head>/':index.html # показать изменения от указанного до указанного регулярных выражений в указанном файле 251 | git log --grep fix # показать коммиты, в описании которых есть буквосочетание fix (регистрозависимо, только коммиты текущей ветки) 252 | git log --grep fix -i # показать коммиты, в описании которых есть буквосочетание fix (регистроНЕзависимо, только коммиты текущей ветки) 253 | git log --grep 'fix(ing|me)' -P # показать коммиты, в описании которых есть совпадения для регулярного выражения (только коммиты текущей ветки) 254 | git log --pretty=format:"%h - %an, %ar : %s" -4 # показать последние 4 коммита с форматированием выводимых данных 255 | git log --pretty=format:"%h %ad | %s%d [%an]" --graph --date=short # мой формат вывода, висящий на алиасе оболочки 256 | git log master..branch_99 # показать коммиты из ветки branch_99, которые не влиты в master 257 | git log branch_99..master # показать коммиты из ветки master, которые не влиты в branch_99 258 | git log master...branch_99 --boundary -- graph # показать коммиты из указанных веток, начиная с их расхождения (коммит расхождения будет показан) 259 | ``` 260 | 261 | ``` bash 262 | git show 60d6582 # показать изменения из коммита с указанным хешем 263 | git show HEAD~ # показать данные о предыдущем коммите в активной ветке 264 | git show @~ # аналогично предыдущему 265 | git show HEAD~3 # показать данные о коммите, который был 3 коммита назад 266 | git show my_branch~2 # показать данные о коммите, который был 2 коммита назад в указанной ветке 267 | git show @~:index.html # показать контент указанного файла на момент предыдущего (от HEAD) коммита 268 | git show :/"подвал" # показать самый новый коммит, в описании которого есть указанное слово (из любой ветки) 269 | ``` 270 | 271 | 272 | ### Кто написал строку 273 | 274 | ``` bash 275 | git blame README.md --date=short -L 5,8 # показать строки 5-8 указанного файла и коммиты, в которых строки были добавлены 276 | ``` 277 | 278 | 279 | ### История изменений указателей (веток, HEAD) 280 | 281 | ``` 282 | git reflog -20 # показать последние 20 изменений положения указателя HEAD 283 | git reflog --format='%C(auto)%h %<|(20)%gd %C(blue)%cr%C(reset) %gs (%s)' -20 # то же, но с указанием давности действий 284 | ``` 285 | 286 | 287 | ### Ветки 288 | 289 | ``` bash 290 | git branch # показать список веток 291 | git branch -v # показать список веток и последний коммит в каждой 292 | git branch new_branch # создать новую ветку с указанным именем на текущем коммите 293 | git branch new_branch 5589877 # создать новую ветку с указанным именем на указанном коммите 294 | git branch -f master 5589877 # переместить ветку master на указанный коммит 295 | git branch -f master master~2 # переместить ветку master на 2 коммита назад 296 | git checkout new_branch # перейти в указанную ветку 297 | git checkout -b new_branch # создать новую ветку с указанным именем и перейти в неё 298 | git checkout -B master 5589877 # переместить ветку с указанным именем на указанный коммит и перейти в неё 299 | git merge hotfix # влить в ветку, в которой находимся, данные из ветки hotfix 300 | git merge hotfix -m "Горячая правка" # влить в ветку, в которой находимся, данные из ветки hotfix (указано сообщение коммита слияния) 301 | git merge hotfix --log # влить в ветку, в которой находимся, данные из ветки hotfix, показать редактор описания коммита, добавить в него сообщения вливаемых коммитов 302 | git merge hotfix --no-ff # влить в ветку, в которой находимся, данные из ветки hotfix, запретить простой сдвиг указателя, изменения из hotfix «останутся» в ней, а в активной ветке появится только коммит слияния 303 | git branch -d hotfix # удалить ветку hotfix (используется, если её изменения уже влиты в главную ветку) 304 | git branch --merged # показать ветки, уже слитые с активной 305 | git branch --no-merged # показать ветки, не слитые с активной 306 | git branch -a # показать все имеющиеся ветки (в т.ч. на удаленных репозиториях) 307 | git branch -m old_branch_name new_branch_name # переименовать локально ветку old_branch_name в new_branch_name 308 | git branch -m new_branch_name # переименовать локально ТЕКУЩУЮ ветку в new_branch_name 309 | git push origin :old_branch_name new_branch_name # применить переименование в удаленном репозитории 310 | git branch --unset-upstream # завершить процесс переименования 311 | ``` 312 | 313 | 314 | ### Теги 315 | 316 | ``` bash 317 | git tag v1.0.0 # создать тег с указанным именем на коммите, на который указывает HEAD 318 | git tag -a -m 'В продакшен!' v1.0.1 master # создать тег с описанием на том коммите, на который смотрит ветка master 319 | git tag -d v1.0.0 # удалить тег с указанным именем(ами) 320 | git tag -n # показать все теги, и по 1 строке сообщения коммитов, на которые они указывают 321 | git tag -n -l 'v1.*' # показать все теги, которые начинаются с 'v1.*' 322 | ``` 323 | 324 | 325 | ### Временное сохранение изменений без коммита 326 | 327 | ``` bash 328 | git stash # временно сохранить незакоммиченные изменения и убрать их из рабочей директории 329 | git stash pop # вернуть сохраненные командой git stash изменения в рабочую директорию 330 | ``` 331 | 332 | 333 | ### Удалённые репозитории 334 | 335 | Есть два распространённых способа привязать удалённый репозиторий к локальному: по HTTPS и по SSH. Если SSH у вас не настроен (или вы не знаете что это), привязывайте удалённый репозиторий по HTTPS (адрес привязываемого репозитория должен начинаться с https://). 336 | 337 | ``` bash 338 | git remote -v # показать список удалённых репозиториев, связанных с локальным 339 | git remote remove origin # убрать привязку удалённого репозитория с сокр. именем origin 340 | git remote add origin https://github.com:nicothin/test.git # добавить удалённый репозиторий (с сокр. именем origin) с указанным URL 341 | git remote rm origin # удалить привязку удалённого репозитория 342 | git remote show origin # получить данные об удалённом репозитории с сокращенным именем origin 343 | git fetch origin # скачать все ветки с удаленного репозитория (с сокр. именем origin), но не сливать со своими ветками 344 | git fetch origin master # то же, но скачивается только указанная ветка 345 | git checkout --track origin/github_branch # создать локальную ветку github_branch (данные взять из удалённого репозитория с сокр. именем origin, ветка github_branch) и переключиться на неё 346 | git push origin master # отправить в удалённый репозиторий (с сокр. именем origin) данные своей ветки master 347 | git pull origin # влить изменения с удалённого репозитория (все ветки) 348 | git pull origin master # влить изменения с удалённого репозитория (только указанная ветка) 349 | ``` 350 | 351 | 352 | ### Конфликт слияния 353 | 354 | Предполагается ситуация: есть ветка `master` и есть ветка `feature`. В обеих ветках есть коммиты, сделанные после расхождения веток. В ветку `master` пытаемся влить ветку `feature` (`git merge feature`), получаем конфликт, т.к. в обеих ветках есть изменения одной и той же строки в файле `index.html`. 355 | 356 | При возникновении конфликта, репозиторий находится в состоянии прерванного слияния. Нужно оставить в конфликтующих местах файлов только нужный код, проиндексировать изменения и закоммитить. 357 | 358 | ``` bash 359 | git merge feature # влить в активную ветку изменения из ветки feature 360 | git merge-base master feature # показать хеш последнего общего коммита для двух указанных веток 361 | git checkout --ours index.html # оставить в конфликтном файле (index.html) состояние ветки, В КОТОРУЮ мы вливаем (в примере — из ветки master) 362 | git checkout --theirs index.html # оставить в конфликтном файле (index.html) состояние ветки, ИЗ КОТОРОЙ мы вливаем (в примере — из ветки feature) 363 | git checkout --merge index.html # показать в конфликтном файле (index.html) сравнение содержимого сливаемых веток (для ручного редактирования) 364 | git checkout --conflict=diff3 --merge index.html # показать в конфликтном файле (index.html) сравнение содержимого сливаемых веток плюс то, что было в месте конфликта в коммите, на котором разошлись сливаемые ветки 365 | ``` 366 | 367 | ``` bash 368 | git reset --hard # прекратить это прерванное слияние, вернуть рабочую директорию и индекс как было в момент коммита, на который указывает HEAD, а я пойду немного поплачу 369 | git reset --merge # прекратить это прерванное слияние, но оставить изменения, не закоммиченные до слияния (для случая, когда слияние делается не на чистом статусе) 370 | git reset --abort # то же, что и строкой выше 371 | ``` 372 | 373 | 374 | ### «Перенос» ветки 375 | 376 | Можно «переместить» ответвление какой-либо ветки от основной на произвольный коммит. Это нужно для того, чтобы в «переносимой» ветке появились какие-либо изменения, внесённые в основной ветке (уже после ответвления переносимой). 377 | 378 | Нельзя «переносить» ветку, если она уже отправлена на удалённый репозиторий. 379 | 380 | ``` bash 381 | git rebase master # перенести все коммиты (создать их копии) активной ветки так, будто активная ветка ответвилась от master на нынешней вершине master (часто вызывает конфликты) 382 | git rebase --onto master feature # перенести коммиты активной ветки на master, начиная с того места, в котором активная ветка отделилась от ветки feature 383 | git rebase --abort # прервать конфликтный rebase, вернуть рабочую директорию и индекс к состоянию до начала rebase 384 | git rebase --continue # продолжить конфликтный rebase (сработает только после разрешения конфликта и индексации такого разрешения) 385 | ``` 386 | 387 | #### Как отменить rebase 388 | 389 | ``` bash 390 | git reflog feature -2 # смотрим лог перемещений ветки, которой делали rebase (в этом примере — feature), видим последний коммит ПЕРЕД rebase, на него и нужно перенести указатель ветки 391 | git reset --hard feature@{1} # переместить указатель ветки feature на один коммит назад, обновить рабочую директорию и индекс 392 | ``` 393 | 394 | 395 | ### Разное 396 | 397 | ``` bash 398 | git archive -o ./project.zip HEAD # создать архив с файловой структурой проекта по указанному пути (состояние репозитория, соответствующее указателю HEAD) 399 | ``` 400 | 401 | 402 | 403 | 404 | 405 | ## Примеры 406 | 407 | Собираем коллекцию простых и сложных примеров работы. 408 | 409 | 410 | ### Начало работы 411 | 412 | Создание нового репозитория, первый коммит, привязка удалённого репозитория с github.com, отправка изменений в удалённый репозиторий. 413 | 414 | ``` bash 415 | # указана последовательность действий: 416 | # создана директория проекта, мы в ней 417 | git init # создаём репозиторий в этой директории 418 | touch readme.md # создаем файл readme.md 419 | git add readme.md # добавляем файл в индекс 420 | git commit -m "Старт" # создаем коммит 421 | git remote add origin https://github.com:nicothin/test.git # добавляем предварительно созданный пустой удаленный репозиторий 422 | git push -u origin master # отправляем данные из локального репозитория в удаленный (в ветку master) 423 | ``` 424 | 425 | 426 | ### «Внесение изменений» в коммит 427 | 428 | Только если коммит ещё не был отправлен в удалённый репозиторий. 429 | 430 | ``` bash 431 | # указана последовательность действий: 432 | subl inc/header.html # редактируем и сохраняем разметку «шапки» 433 | git add inc/header.html # индексируем измененный файл 434 | git commit -m "Убрал телефон из шапки" # делаем коммит 435 | # ВНИМАНИЕ: коммит пока не был отправлен в удалённый репозиторий 436 | # сознаём, что нужно было еще что-то сделать в этом коммите. 437 | subl inc/header.html # вносим изменения 438 | git add inc/header.html # индексируем измененный файл (можно git add .) 439 | git commit --amend -m "«Шапка»: выполнена задача №34" # заново делаем коммит 440 | ``` 441 | 442 | 443 | ### Работа с ветками 444 | 445 | Есть master (публичная версия сайта), выполняем масштабную задачу (переверстать «шапку»), но по ходу работ возникает необходимость подправить критичный баг (неправильно указан контакт в «подвале»). 446 | 447 | ``` bash 448 | # указана последовательность действий: 449 | git checkout -b new-page-header # создадим новую ветку для задачи изменения «шапки» и перейдём в неё 450 | subl inc/header.html # редактируем разметку «шапки» 451 | git commit -a -m "Новая шапка: смена логотипа" # делаем коммит (работа еще не завершена) 452 | # тут выясняется, что есть баг с контактом в «подвале» 453 | git checkout master # возвращаемся к ветке master 454 | subl inc/footer.html # устраняем баг и сохраняем разметку «подвала» 455 | git commit -a -m "Исправление контакта в подвале" # делаем коммит 456 | git push # отправляем коммит с быстрым критическим изменением в master в удалённом репозитории 457 | git checkout new-page-header # переключаемся обратно в ветку new-page-header для продолжения работ над «шапкой» 458 | subl inc/header.html # редактируем и сохраняем разметку «шапки» 459 | git commit -a -m "Новая шапка: смена навигации" # делаем коммит (работа над «шапкой» завершена) 460 | git checkout master # переключаемся в ветку master 461 | git merge new-page-header # вливаем в master изменения из ветки new-page-header 462 | git branch -d new-page-header # удаляем ветку new_page_header 463 | ``` 464 | 465 | 466 | ### Работа с ветками, слияние и откат к состоянию до слияния 467 | 468 | Была ветка `fix`, в которой исправляли баг. Исправили, влили `fix` в `master`. но тут выяснилось, что это исправление ломает какую-то функциональность, Нужно откатить `master` к состоянию без слияния (наличие бага менее критично, чем порча функциональности). 469 | 470 | ``` bash 471 | # находимся в ветке fix, баг уже «исправлен» 472 | git checkout master # переключаемся на master 473 | git merge fix # вливаем изменения из fix в master 474 | # видим проблему: часть функциональности сломалась 475 | git checkout fix # переключаемся на fix (пока мы в master, git не даст ее двигать) 476 | git branch -f master ORIG_HEAD # передвигаем ветку master на коммит, указанный в ORIG_HEAD (тот, на который указывала master до вливания fix) 477 | ``` 478 | 479 | 480 | 481 | ### Работа с ветками, конфликт слияния 482 | 483 | Есть ветка `master` (публичная версия сайта), в двух параллельных ветках (`branch-1` и `branch-2`) было отредактировано одно и то же место одного и того же файла, первую ветку (`branch-1`) влили в master, попытка влить вторую вызывает конфликт. 484 | 485 | ``` bash 486 | # указана последовательность действий: 487 | git checkout master # переключаемся на ветку master 488 | git checkout -b branch-1 # создаём ветку branch-1, основанную на ветке master 489 | subl . # редактируем и сохраняем файлы 490 | git commit -a -m "Правка 1" # коммитим 491 | git checkout master # возвращаемся к ветке master 492 | git checkout -b branch-2 # создаём ветку branch-2, основанную на ветке master 493 | subl . # редактируем и сохраняем файлы 494 | git commit -a -m "Правка 2" # коммитим 495 | git checkout master # возвращаемся к ветке master 496 | git merge branch-1 # вливаем изменения из ветки branch-1 в текущую ветку (master), удача (автослияние) 497 | git merge branch-2 # вливаем изменения из ветки branch-2 в текущую ветку (master), КОНФЛИКТ автослияния 498 | # Automatic merge failed; fix conflicts and then commit the result. 499 | subl . # выбираем в конфликтных файлах те участки, которые нужно оставить, сохраняем 500 | git commit -a -m "Устранение конфликта" # коммитим результат устранения конфликта 501 | ``` 502 | 503 | 504 | 505 | ### Синхронизация репозитория-форка с мастер-репозиторием 506 | 507 | Есть некий репозиторий на github.com, от него нами был сделан форк, добавлены какие-то изменения. Оригинальный (мастер-)репозиторий был как-то обновлён. Задача: стянуть с мастер-репозитория изменения (которые там внесены уже после того, как мы его форкнули). 508 | 509 | ``` bash 510 | # указана последовательность действий: 511 | git remote add upstream https://github.com:address.git # добавляем удаленный репозиторий: сокр. имя — upstream, URL мастер-репозитория 512 | git fetch upstream # стягиваем все ветки мастер-репозитория, но пока не сливаем со своими 513 | git checkout master # переключаемся на ветку master своего репозитория 514 | git merge upstream/master # вливаем стянутую ветку master удалённого репозитория upstream в свою ветку master 515 | ``` 516 | 517 | 518 | 519 | ### Ошибка в работе: закоммитили в мастер, но поняли, что нужно было коммитить в новую ветку 520 | 521 | **ВАЖНО: это сработает только если коммит еще не отправлен в удалённый репозиторий.** 522 | 523 | ``` bash 524 | # указана последовательность действий: 525 | # сделали изменения, проиндексировали их, закоммитили в master, но ЕЩЁ НЕ ОТПРАВИЛИ (не делали git push) 526 | git checkout -b new-branch # создаём новую ветку из master 527 | git checkout master # переключаемся на master 528 | git reset HEAD~ --hard # сдвигаем указатель (ветку) master на 1 коммит назад 529 | git checkout new-branch # переключаемся обратно на новую ветку для продолжения работы 530 | ``` 531 | 532 | 533 | 534 | ### Нужно вернуть содержимое файла к состоянию, бывшему в каком-либо коммите (известен хеш коммита) 535 | 536 | ``` bash 537 | # указана последовательность действий: 538 | git checkout f26ed88 -- index.html # восстановить в рабочей директории состояние указанного файла на момент указанного коммита, добавить это изменение в индекс 539 | git commit -am "Navigation fixs" # сделать коммит 540 | ``` 541 | 542 | 543 | 544 | ### При любом действии с github (или другим удалённым сервисом) запрашивается логин и пароль 545 | 546 | Речь именно о запросе пары логин + пароль, а не ключевой фразы. Происходит это потому, что git по умолчанию не сохранит пароль для доступа к репозиторию по HTTPS. 547 | 548 | Простое решение: [указать git кешировать ваш пароль](https://help.github.com/articles/caching-your-github-password-in-git/). 549 | 550 | 551 | 552 | ## `.gitattributes` 553 | 554 | ``` 555 | * text=auto 556 | 557 | *.html diff=html 558 | *.css diff=css 559 | *.scss diff=css 560 | ``` 561 | -------------------------------------------------------------------------------- /Hub. Git-Hub.md: -------------------------------------------------------------------------------- 1 | # git-help-3-hub 2 | Создание репозитория на github на компьюторе, удаленно из командной строки терминала, используя команды консольного приложения hub. 3 | 4 | ## Демонстрация 5 | Создаём, используя Git Bash, репозиторий с именем KristinitaTest.github.io в Windows. 6 | 7 | SashaChernykh@DESKTOP-0G54NVG MINGW32 /e 8 | $ mkdir KristinitaTest.github.io 9 | #### Имя папки станет и именем Вашего удалённого репозитория. 10 | SashaChernykh@DESKTOP-0G54NVG MINGW32 /e 11 | $ cd KristinitaTest.github.io 12 | 13 | SashaChernykh@DESKTOP-0G54NVG MINGW32 /e/KristinitaTest.github.io 14 | $ touch README.MD 15 | 16 | SashaChernykh@DESKTOP-0G54NVG MINGW32 /e/KristinitaTest.github.io 17 | $ start README.MD 18 | #### Пишем «Repository for test GitHub features and demonstrations.» в файл README.MD. 19 | SashaChernykh@DESKTOP-0G54NVG MINGW32 /e/KristinitaTest.github.io 20 | $ hub init 21 | Initialized empty Git repository in E:/KristinitaTest.github.io/.git/ 22 | 23 | SashaChernykh@DESKTOP-0G54NVG MINGW32 /e/KristinitaTest.github.io (master) 24 | $ hub add . && git commit -m "Repository for Sasha tests" 25 | [master (root-commit) b56f811] Repository for Sasha tests 26 | 1 file changed, 1 insertion(+) 27 | create mode 100644 README.MD 28 | 29 | SashaChernykh@DESKTOP-0G54NVG MINGW32 /e/KristinitaTest.github.io (master) 30 | $ hub create -d "Create test repository" -h "Kristinita.ru" 31 | Updating origin 32 | created repository: Kristinita/KristinitaTest.github.io 33 | #### Протокол «http://» будет добавлен автоматически в имя сайта. 34 | SashaChernykh@DESKTOP-0G54NVG MINGW32 /e/KristinitaTest.github.io (master) 35 | $ hub push -u origin master 36 | Counting objects: 3, done. 37 | Delta compression using up to 4 threads. 38 | Compressing objects: 100% (2/2), done. 39 | Writing objects: 100% (3/3), 296 bytes | 0 bytes/s, done. 40 | Total 3 (delta 0), reused 0 (delta 0) 41 | To https://github.com/Kristinita/KristinitaTest.github.io.git 42 | * [new branch] master -> master 43 | 44 | *Ссылка на статью:* 45 | https://ru.stackoverflow.com/questions/504578/%D0%9A%D0%B0%D0%BA-%D1%81%D0%BE%D0%B7%D0%B4%D0%B0%D1%82%D1%8C-%D1%80%D0%B5%D0%BF%D0%BE%D0%B7%D0%B8%D1%82%D0%BE%D1%80%D0%B8%D0%B9-%D0%BD%D0%B0-github-%D1%87%D0%B5%D1%80%D0%B5%D0%B7-%D0%BA%D0%BE%D0%BC%D0%B0%D0%BD%D0%B4%D0%BD%D1%83%D1%8E-%D1%81%D1%82%D1%80%D0%BE%D0%BA%D1%83 46 | -------------------------------------------------------------------------------- /init-text-on-rep.txt: -------------------------------------------------------------------------------- 1 | Quick setup — if you’ve done this kind of thing before 2 | 3 | or 4 | git@github.com:Oxana-S/git.git 5 | Get started by creating a new file or uploading an existing file. We recommend every repository include a README, LICENSE, and .gitignore. 6 | 7 | …or create a new repository on the command line 8 | echo "# git" >> README.md 9 | git init 10 | git add README.md 11 | git commit -m "first commit" 12 | git branch -M main 13 | git remote add origin git@github.com:Oxana-S/git.git 14 | git push -u origin main 15 | 16 | …or push an existing repository from the command line 17 | git remote add origin git@github.com:Oxana-S/git.git 18 | git branch -M main 19 | git push -u origin main 20 | 21 | …or import code from another repository 22 | You can initialize this repository with code from a Subversion, Mercurial, or TFS project. -------------------------------------------------------------------------------- /Шпаргалка по bash.md: -------------------------------------------------------------------------------- 1 | # Шпаргалка по bash 2 | 3 | Шпаргалка для начинающих пользователей консоли Git Bash, терминала OSX, терминала linux. См. так же: [Как использовать консоль в Windows](http://nicothin.pro/page/console-windows) 4 | 5 | В этой папке 2 файла: 6 | 7 | - `.bashrc` - для Windows. 8 | - `.bash_profile` - для maxOS. 9 | 10 | ## Суть 11 | 12 | Консоль — удобный и быстрый инструмент управления компьютером. Вводим команду текстом, получаем результат или сообщение об ошибке с указанием в чём ошибка. 13 | 14 | Ввод начинается с указания программы (которую вызываем) и может быть дополнен аргументами и ключами, указывающими программе что именно нужно сделать или как нужно работать. Пример с аргументом: `ls build/css` — вызываем утилиту `ls`, указываем ключ `build/css` — будет показано содержимое указанной в аргументе папки. Пример с ключом: `git --version` — взвываем программу `git`, передаем ключ `--version` — будет показана версия программы (если установлена). 15 | 16 | Работая с консолью, мы всегда «находимся» в какой-то папке (она указана в приглашении командной строки). Если там написано `~`, то мы в папке пользователя (зависит от настроек Windows, чаще всего это `C:/Users/ВАШЕИМЯПОЛЬЗОВАТЕЛЯ/`), если там `/d/projects`, мы в папке `D:/projects`. 17 | 18 | ## Файловая система 19 | 20 | ### Просмотр содержимого папки 21 | 22 | ```bash 23 | ls # показать содержимое папки 24 | ls -a # то же, но показывать и скрытые файлы и папки 25 | ls -a -1 # то же, но в один столбец 26 | ls -hF -1 --sort=extension # показать содержимое папки «красиво, в один столбец» 27 | ls build/css # показать содержимое папки ТЕКУЩАЯ_ПАПКА/build/css 28 | ls /d/projects # показать содержимое папки D:/projects 29 | ``` 30 | 31 | ### Переход по папкам 32 | 33 | Пользователь всегда находится в какой-то папке, она (или полный путь) всегда показана до области ввода команд. 34 | 35 | ```bash 36 | cd projects # переход в папку projects, которая есть в текущей папке 37 | cd /d/projects # windows: переход в папку projects, расположенную по адресу D:/projects 38 | cd /c/Program\ Files # windows: переход в C/:Program Files 39 | cd .. # переход к родительской папке 40 | cd - # переход к последней рабочей папке 41 | cd !$ # переход в новосозданную папку (после mkdir) 42 | ``` 43 | 44 | Чтобы не набирать имя папки целиком, наберите первые пару символов и нажмите Tab — произойдет автодополнение (если нет двух папок, начинающихся с введенных символов, иначе будут показаны сами эти папки). Справедливо для любой команды. 45 | 46 | ### Создание папок и файлов 47 | 48 | ```bash 49 | mkdir project # создать папку с именем «project» 50 | mkdir project project/css project/js # создать несколько папок 51 | mkdir -p project/{css,js} # то же, что выше 52 | touch index.html # создать файл 53 | touch index.html css/style.css js/script.js # создать файлы (папки css/ и js/ должны уже существовать) 54 | ``` 55 | 56 | ### Копирование файлов 57 | 58 | ```bash 59 | cp index.html catalog.html # копирование файла index.html в тот же каталог с переименованием в catalog.html 60 | cp index.html old/ # копирование файла index.html в папку old/ (все произойдет в текущей папке) 61 | cp temp/ temp2/ -r # дублирование каталога 62 | ``` 63 | 64 | 65 | ### Переименование или перемещение файлов 66 | 67 | ```bash 68 | mv index.html old # перемещение файла в папку 69 | mv index.html old/new_name.txt # перемещение файла в папку с переименованием файла 70 | mv order.txt orderNew.txt # переименовать файл 71 | ``` 72 | 73 | 74 | ### Удаление папок и файлов 75 | 76 | ```bash 77 | rm ghost.png # удалить файл 78 | rm -rf old # удалить папку и всё из нее 79 | ``` 80 | 81 | ### Разные мелочи 82 | 83 | Подборка команд, показывающих бОльшую скорость работы с консолью, чем с GUI или просто удобных команд. Многие из них могут быть реализованы различными путями с GUI, что ничуть не умаляет удобства консоли. 84 | 85 | ```bash 86 | rm -rf node_modules && npm i # выполнение первой части команды (до &&) и, при отсутствии ошибок, второй части (после &&) 87 | pwd # «где я?» 88 | cat ~/.bash_profile # вывести в консоль содержимое файла 89 | ls -a >> file.txt # записать в file.txt результат вывода команды ls -a 90 | echo 'some text' >> readme.md # дописать строку в конец файла 91 | df -h # показать статистику использования пространства на дисках 92 | grep -i -n --color 'carousel' index.html css/style.css # найти слово carousel в двух указанных файлах (с игнором регистра), вывести строки с этим словом и номера строк (искомое слово подсветить) 93 | grep word -r project # найти слово word во всех файлах в папке project 94 | find . -iname '*ind*' # найти в текущей папке (и подпапках) все файлы, имена которых содержат ind и показать списком 95 | ``` 96 | 97 | ## Алиасы 98 | 99 | Для команд можно создавать алиасы (короткие синонимы команд). Для этого в папке пользователя (OSX: `/Users/ИМЯ_ПОЛЬЗОВАТЕЛЯ/.bash_profile`, Windows: `C:/Users/ИМЯ_ПОЛЬЗОВАТЕЛЯ/.bash_profile`) нужно вписать строки, наподобие `alias pro='cd /d/projects'` (одна строка в файле — один алиас). Если файла `.bash_profile` нет, его можно создать. Это обычный текстовой файл. 100 | 101 | После добавления алиасов нужно перезапустить терминал. 102 | -------------------------------------------------------------------------------- /Шпаргалка по консольным командам Git.md: -------------------------------------------------------------------------------- 1 | # Шпаргалка по консольным командам Git 2 | 3 | * [Общее](https://github.com/nicothin/web-development/tree/master/git#Общее) 4 | * [Консольные команды](https://github.com/nicothin/web-development/tree/master/git#Консольные-команды) 5 | * [Примеры реальной работы](https://github.com/nicothin/web-development/tree/master/git#Примеры) 6 | 7 | 8 | 9 | ## Общее 10 | 11 | Git — система контроля версий (файлов). Что-то вроде возможности сохраняться в компьютерных играх (в Git эквивалент игрового сохранения — коммит). **Важно**: добавление файлов к «сохранению» двухступенчатое: сначала добавляем файл в индекс (`git add`), потом «сохраняем» (`git commit`). 12 | 13 | Любой файл в директории существующего репозитория может находиться или не находиться под версионным контролем (отслеживаемые и неотслеживаемые). 14 | 15 | Отслеживаемые файлы могут быть в 3-х состояниях: неизменённые, изменённые, проиндексированные (готовые к коммиту). 16 | 17 | ### Ключ к пониманию 18 | 19 | Ключ к пониманию концепции git — знание о «трех деревьях»: 20 | 21 | - Рабочая директория — файловая система проекта (те файлы, с которыми вы работаете). 22 | - Индекс — список отслеживаемых git-ом файлов и директорий, промежуточное хранилище изменений (редактирование, удаление отслеживаемых файлов). 23 | - Директория `.git/` — все данные контроля версий этого проекта (вся история разработки: коммиты, ветки, теги и пр.). 24 | 25 | Коммит — «сохранение» (хранит набор изменений, сделанный в рабочей директории с момента предыдущего коммита). Коммит неизменен, его нельзя отредактировать. 26 | 27 | У всех коммитов (кроме самого первого) есть один или более родительских коммитов, поскольку коммиты хранят изменения от предыдущих состояний. 28 | 29 | ### Простейший цикл работ 30 | 31 | - Редактирование, добавление, удаление файлов (собственно, работа). 32 | - Индексация/добавление файлов в индекс (указание для git какие изменения нужно будет закоммитить). 33 | - Коммит (фиксация изменений). 34 | - Возврат к шагу 1 или отход ко сну. 35 | 36 | ### Указатели 37 | 38 | - `HEAD` — указатель на текущий коммит или на текущую ветку (то есть, в любом случае, на коммит). Указывает на родителя коммита, который будет создан следующим. 39 | - `ORIG_HEAD` — указатель на коммит, с которого вы только что переместили `HEAD` (командой `git reset ...`, например). 40 | - Ветка (`master`, `develop` etc.) — указатель на коммит. При добавлении коммита, указатель ветки перемещается с родительского коммита на новый. 41 | - Теги — простые указатели на коммиты. Не перемещаются. 42 | 43 | 44 | 45 | ### Настройки 46 | 47 | Перед началом работы нужно выполнить некоторые настройки: 48 | 49 | ``` 50 | git config --global user.name "Your Name" # указать имя, которым будут подписаны коммиты 51 | git config --global user.email "e@w.com" # указать электропочту, которая будет в описании коммитера 52 | ``` 53 | 54 | Если вы в Windows: 55 | 56 | ``` 57 | git config --global core.autocrlf true # включить преобразование окончаний строк из CRLF в LF 58 | ``` 59 | 60 | 61 | ### Указание неотслеживаемых файлов 62 | 63 | Файлы и директории, которые не нужно включать в репозиторий, указываются в файле `.gitignore`. Обычно это устанавливаемые зависимости (`node_modules/`, `bower_components/`), готовая сборка `build/` или `dist/` и подобные, создаваемые при установке или запуске. Каждый файл или директория указываются с новой строки, [возможно использование шаблонов](http://git-scm.com/book/ru/v2/%D0%9E%D1%81%D0%BD%D0%BE%D0%B2%D1%8B-Git-%D0%97%D0%B0%D0%BF%D0%B8%D1%81%D1%8C-%D0%B8%D0%B7%D0%BC%D0%B5%D0%BD%D0%B5%D0%BD%D0%B8%D0%B9-%D0%B2-%D1%80%D0%B5%D0%BF%D0%BE%D0%B7%D0%B8%D1%82%D0%BE%D1%80%D0%B8%D0%B9#Игнорирование-файлов). 64 | 65 | 66 | ### Консоль 67 | 68 | [Как использовать консоль в Windows](http://nicothin.pro/page/console-windows) (на OSX и Linux сразу есть хорошая консоль (терминал)). [Как комфортно работать с GitHub в консоли Windows](http://nicothin.pro/page/kak-komfortno-rabotat-s-github-v-konsoli-windows). 69 | 70 | 71 | ### Длинный вывод в консоли: Vim 72 | 73 | Вызов некоторых консольных команд приводит к необходимости очень длинного вывода в консоль (пример: вывод истории всех изменений в файле командой `git log -p fileName.txt`). При этом прямо в консоли запускается редактор [Vim](https://ru.wikipedia.org/wiki/Vim). Он работает в нескольких режимах, из которых Вас заинтересуют режим вставки (редактирование текста) и нормальный (командный) режим. Чтобы попасть из Vim обратно в консоль, нужно в командном режиме ввести :q. Переход в командный режим из любого другого: Esc. 74 | 75 | Если нужно что-то написать, нажмите i — это переход в режим вставки текста. Если нужно сохранить изменения, перейдите в командный режим и наберите :w. 76 | 77 | [Чуть-чуть больше команд](vim.md). 78 | 79 | 80 | 81 | 82 | 83 | ## Консольные команды 84 | 85 | ### Создать новый репозиторий 86 | 87 | ``` bash 88 | git init # создать новый проект в текущей директории 89 | git init folder-name # создать новый проект в указанной директории 90 | ``` 91 | 92 | 93 | ### Клонирование репозитория 94 | 95 | ``` bash 96 | git clone https://github.com:nicothin/web-design.git # клонировать удаленный репозиторий в одноименную директорию 97 | git clone https://github.com:nicothin/web-design.git FolderName # клонировать удаленный репозиторий в директорию «FolderName» 98 | git clone https://github.com:nicothin/web-design.git . # клонировать репозиторий в текущую директорию 99 | ``` 100 | 101 | 102 | ### Просмотр изменений 103 | 104 | ``` bash 105 | git status # показать состояние репозитория (отслеживаемые, изменённые, новые файлы и пр.) 106 | git diff # сравнить рабочую директорию и индекс (неотслеживаемые файлы ИГНОРИРУЮТСЯ) 107 | git diff --color-words # сравнить рабочую директорию и индекс, показать отличия в словах (неотслеживаемые файлы ИГНОРИРУЮТСЯ) 108 | git diff index.html # сравнить файл из рабочей директории и индекс 109 | git diff HEAD # сравнить рабочую директорию и коммит, на который указывает HEAD (неотслеживаемые файлы ИГНОРИРУЮТСЯ) 110 | git diff --staged # сравнить индекс и коммит с HEAD 111 | git diff master feature # посмотреть что сделано в ветке feature по сравнению с веткой master 112 | git diff --name-only master feature # посмотреть что сделано в ветке feature по сравнению с веткой master, показать только имена файлов 113 | git diff master...feature # посмотреть что сделано в ветке feature с момента (коммита) расхождения с master 114 | ``` 115 | 116 | 117 | ### Добавление изменений в индекс 118 | 119 | ``` bash 120 | git add . # добавить в индекс все новые, изменённые, удалённые файлы из текущей директории и её поддиректорий 121 | git add text.txt # добавить в индекс указанный файл (был изменён, был удалён или это новый файл) 122 | git add -i # запустить интерактивную оболочку для добавления в индекс только выбранных файлов 123 | git add -p # показать новые/изменённые файлы по очереди с указанием их изменений и вопросом об отслеживании/индексировании 124 | ``` 125 | 126 | 127 | ### Удаление изменений из индекса 128 | 129 | ``` bash 130 | git reset # убрать из индекса все добавленные в него изменения (в рабочей директории все изменения сохранятся), антипод git add 131 | git reset readme.txt # убрать из индекса изменения указанного файла (в рабочей директории изменения сохранятся) 132 | ``` 133 | 134 | 135 | ### Отмена изменений 136 | 137 | ``` bash 138 | git checkout text.txt # ОПАСНО: отменить изменения в файле, вернуть состояние файла, имеющееся в индексе 139 | git reset --hard # ОПАСНО: отменить изменения; вернуть то, что в коммите, на который указывает HEAD (незакомиченные изменения удалены из индекса и из рабочей директории, неотслеживаемые файлы останутся на месте) 140 | git clean -df # удалить неотслеживаемые файлы и директории 141 | ``` 142 | 143 | 144 | ### Коммиты 145 | 146 | ``` bash 147 | git commit -m "Name of commit" # зафиксировать в коммите проиндексированные изменения (закоммитить), добавить сообщение 148 | git commit -a -m "Name of commit" # проиндексировать отслеживаемые файлы (ТОЛЬКО отслеживаемые, но НЕ новые файлы) и закоммитить, добавить сообщение 149 | ``` 150 | 151 | 152 | ### Отмена коммитов и перемещение по истории 153 | 154 | Все коммиты, которые уже были отправлены в удалённый репозиторий, должны отменяться новыми коммитами (`git revert`), дабы избежать проблем с историей разработки у других участников проекта. 155 | 156 | ``` bash 157 | git revert HEAD --no-edit # создать новый коммит, отменяющий изменения последнего коммита без запуска редактора сообщения 158 | git revert b9533bb --no-edit # то же, но отменяются изменения, внесённые коммитом с указанным хешем (b9533bb) 159 | ``` 160 | 161 | **Все команды, приведённые ниже можно выполнять ТОЛЬКО если коммиты еще не были отправлены в удалённый репозиторий.** 162 | 163 | ``` bash 164 | # ВНИМАНИЕ! Опасные команды, можно потерять незакоммиченные изменения 165 | git commit --amend -m "Название" # «перекоммитить» изменения последнего коммита, заменить его новым коммитом с другим сообщением (сдвинуть текущую ветку на один коммит назад, сохранив рабочую директорию и индекс «как есть», создать новый коммит с данными из «отменяемого» коммита, но новым сообщением) 166 | git reset --hard @~ # передвинуть HEAD (и ветку) на предыдущий коммит, рабочую директорию и индекс сделать такими, какими они были в момент предыдущего коммита 167 | git reset --hard 75e2d51 # передвинуть HEAD (и ветку) на коммит с указанным хешем, рабочую директорию и индекс сделать такими, какими они были в момент указанного коммита 168 | git reset --soft @~ # передвинуть HEAD (и ветку) на предыдущий коммит, но в рабочей директории и индексе оставить все изменения 169 | git reset --soft @~2 # то же, но передвинуть HEAD (и ветку) на 2 коммита назад 170 | git reset @~ # передвинуть HEAD (и ветку) на предыдущий коммит, рабочую директорию оставить как есть, индекс сделать таким, каким он был в момент предыдущего коммита (удобнее, чем git reset --soft @~, если индекс нужно задать заново) 171 | # Почти как git reset --hard, но безопаснее: не получится потерять изменения в рабочей директории 172 | git reset --keep @~ # передвинуть HEAD (и ветку) на предыдущий коммит, сбросить индекс, но в рабочей директории оставить изменения, если возможно (если файл с изменениями между коммитами менялся, будет выдана ошибка и переключение не произойдёт) 173 | ``` 174 | 175 | 176 | ### Временно переключиться на другой коммит 177 | 178 | ``` bash 179 | git checkout b9533bb # переключиться на коммит с указанным хешем (переместить HEAD на указанный коммит, рабочую директорию вернуть к состоянию, на момент этого коммита) 180 | git checkout master # переключиться на коммит, на который указывает master (переместить HEAD на коммит, на который указывает master, рабочую директорию вернуть к состоянию на момент этого коммита) 181 | ``` 182 | 183 | 184 | ### Переключиться на другой коммит и продолжить работу с него 185 | 186 | Потребуется создание новой ветки, начинающейся с указанного коммита. 187 | 188 | ``` bash 189 | git checkout -b new-branch 5589877 # создать ветку new-branch, начинающуюся с коммита c хешем 5589877 (переместить HEAD на указанный коммит, рабочую директорию вернуть к состоянию, на момент этого коммита, создать указатель на этот коммит (ветку) с указанным именем) 190 | ``` 191 | 192 | 193 | ### Восстановление изменений 194 | 195 | ``` bash 196 | git checkout 5589877 index.html # восстановить в рабочей директории указанный файл на момент указанного коммита (и добавить это изменение в индекс) (git reset index.html для удаления из индекса, но сохранения изменений в файле) 197 | ``` 198 | 199 | 200 | ### Копирование коммита (перенос коммитов) 201 | 202 | ``` bash 203 | git cherry-pick 5589877 # скопировать на активную ветку изменения из указанного коммита, закоммитить эти изменения 204 | git cherry-pick master~2..master # скопировать на активную ветку изменения из master (2 последних коммита) 205 | git cherry-pick -n 5589877 # скопировать на активную ветку изменения из указанного коммита, но НЕ КОММИТИТЬ (подразумевается, что мы сами потом закоммитим) 206 | git cherry-pick master..feature # скопировать на активную ветку изменения из всех коммитов ветки feature с момента её расхождения с master (похоже на слияние веток, но это копирование изменений, а не слияние), закоммитить эти изменения; это может вызвать конфликт 207 | git cherry-pick --abort # прервать конфликтный перенос коммитов 208 | git cherry-pick --continue # продолжить конфликтный перенос коммитов (сработает только после решения конфликта) 209 | ``` 210 | 211 | 212 | ### Удаление файла 213 | 214 | ``` bash 215 | git rm text.txt # удалить отслеживаемый неизменённый файл и проиндексировать это изменение 216 | git rm -f text.txt # удалить отслеживаемый изменённый файл и проиндексировать это изменение 217 | git rm -r log/ # удалить всё содержимое отслеживаемой директории log/ и проиндексировать это изменение 218 | git rm ind* # удалить все отслеживаемые файлы с именем, начинающимся на «ind» в текущей директории и проиндексировать это изменение 219 | git rm --cached readme.txt # удалить из отслеживаемых индексированный файл (ФАЙЛ ОСТАНЕТСЯ НА МЕСТЕ) (часто используется для нечаянно добавленных в отслеживаемые файлов) 220 | ``` 221 | 222 | 223 | ### Перемещение/переименование файлов 224 | 225 | Для git не существует переименования. Переименование воспринимается как удаление старого файла и создание нового. Факт переименования может быть определен только после индексации изменения. 226 | 227 | ``` bash 228 | git mv text.txt test_new.txt # переименовать файл «text.txt» в «test_new.txt» и проиндексировать это изменение 229 | git mv readme_new.md folder/ # переместить файл readme_new.md в директорию folder/ (должна существовать) и проиндексировать это изменение 230 | ``` 231 | 232 | 233 | ### История коммитов 234 | 235 | Выход из длинного лога вывода: `q`. 236 | 237 | ``` bash 238 | git log master # показать коммиты в указанной ветке 239 | git log -2 # показать последние 2 коммита в активной ветке 240 | git log -2 --stat # показать последние 2 коммита и статистику внесенных ими изменений 241 | git log -p -22 # показать последние 22 коммита и внесенную ими разницу на уровне строк 242 | git log --graph -10 # показать последние 10 коммитов с ASCII-представлением ветвления 243 | git log --since=2.weeks # показать коммиты за последние 2 недели 244 | git log --after '2018-06-30' # показать коммиты, сделанные после указанной даты 245 | git log index.html # показать историю изменений файла index.html (только коммиты) 246 | git log -5 index.html # показать историю изменений файла index.html, последние 5 коммитов (только коммиты) 247 | git log -p index.html # показать историю изменений файла index.html (коммиты и изменения) 248 | git log -G'myFunction' -p # показать все коммиты, в которых менялись строки с myFunction (в кавычках регулярное выражение) 249 | git log -L '//','/<\/head>/':index.html # показать изменения от указанного до указанного регулярных выражений в указанном файле 250 | git log --grep fix # показать коммиты, в описании которых есть буквосочетание fix (регистрозависимо, только коммиты текущей ветки) 251 | git log --grep fix -i # показать коммиты, в описании которых есть буквосочетание fix (регистроНЕзависимо, только коммиты текущей ветки) 252 | git log --grep 'fix(ing|me)' -P # показать коммиты, в описании которых есть совпадения для регулярного выражения (только коммиты текущей ветки) 253 | git log --pretty=format:"%h - %an, %ar : %s" -4 # показать последние 4 коммита с форматированием выводимых данных 254 | git log --pretty=format:"%h %ad | %s%d [%an]" --graph --date=short # мой формат вывода, висящий на алиасе оболочки 255 | git log master..branch_99 # показать коммиты из ветки branch_99, которые не влиты в master 256 | git log branch_99..master # показать коммиты из ветки master, которые не влиты в branch_99 257 | git log master...branch_99 --boundary -- graph # показать коммиты из указанных веток, начиная с их расхождения (коммит расхождения будет показан) 258 | ``` 259 | 260 | ``` bash 261 | git show 60d6582 # показать изменения из коммита с указанным хешем 262 | git show HEAD~ # показать данные о предыдущем коммите в активной ветке 263 | git show @~ # аналогично предыдущему 264 | git show HEAD~3 # показать данные о коммите, который был 3 коммита назад 265 | git show my_branch~2 # показать данные о коммите, который был 2 коммита назад в указанной ветке 266 | git show @~:index.html # показать контент указанного файла на момент предыдущего (от HEAD) коммита 267 | git show :/"подвал" # показать самый новый коммит, в описании которого есть указанное слово (из любой ветки) 268 | ``` 269 | 270 | 271 | ### Кто написал строку 272 | 273 | ``` bash 274 | git blame README.md --date=short -L 5,8 # показать строки 5-8 указанного файла и коммиты, в которых строки были добавлены 275 | ``` 276 | 277 | 278 | ### История изменений указателей (веток, HEAD) 279 | 280 | ``` 281 | git reflog -20 # показать последние 20 изменений положения указателя HEAD 282 | git reflog --format='%C(auto)%h %<|(20)%gd %C(blue)%cr%C(reset) %gs (%s)' -20 # то же, но с указанием давности действий 283 | ``` 284 | 285 | 286 | ### Ветки 287 | 288 | ``` bash 289 | git branch # показать список веток 290 | git branch -v # показать список веток и последний коммит в каждой 291 | git branch new_branch # создать новую ветку с указанным именем на текущем коммите 292 | git branch new_branch 5589877 # создать новую ветку с указанным именем на указанном коммите 293 | git branch -f master 5589877 # переместить ветку master на указанный коммит 294 | git branch -f master master~2 # переместить ветку master на 2 коммита назад 295 | git checkout new_branch # перейти в указанную ветку 296 | git checkout -b new_branch # создать новую ветку с указанным именем и перейти в неё 297 | git checkout -B master 5589877 # переместить ветку с указанным именем на указанный коммит и перейти в неё 298 | git merge hotfix # влить в ветку, в которой находимся, данные из ветки hotfix 299 | git merge hotfix -m "Горячая правка" # влить в ветку, в которой находимся, данные из ветки hotfix (указано сообщение коммита слияния) 300 | git merge hotfix --log # влить в ветку, в которой находимся, данные из ветки hotfix, показать редактор описания коммита, добавить в него сообщения вливаемых коммитов 301 | git merge hotfix --no-ff # влить в ветку, в которой находимся, данные из ветки hotfix, запретить простой сдвиг указателя, изменения из hotfix «останутся» в ней, а в активной ветке появится только коммит слияния 302 | git branch -d hotfix # удалить ветку hotfix (используется, если её изменения уже влиты в главную ветку) 303 | git branch --merged # показать ветки, уже слитые с активной 304 | git branch --no-merged # показать ветки, не слитые с активной 305 | git branch -a # показать все имеющиеся ветки (в т.ч. на удаленных репозиториях) 306 | git branch -m old_branch_name new_branch_name # переименовать локально ветку old_branch_name в new_branch_name 307 | git branch -m new_branch_name # переименовать локально ТЕКУЩУЮ ветку в new_branch_name 308 | git push origin :old_branch_name new_branch_name # применить переименование в удаленном репозитории 309 | git branch --unset-upstream # завершить процесс переименования 310 | ``` 311 | 312 | 313 | ### Теги 314 | 315 | ``` bash 316 | git tag v1.0.0 # создать тег с указанным именем на коммите, на который указывает HEAD 317 | git tag -a -m 'В продакшен!' v1.0.1 master # создать тег с описанием на том коммите, на который смотрит ветка master 318 | git tag -d v1.0.0 # удалить тег с указанным именем(ами) 319 | git tag -n # показать все теги, и по 1 строке сообщения коммитов, на которые они указывают 320 | git tag -n -l 'v1.*' # показать все теги, которые начинаются с 'v1.*' 321 | ``` 322 | 323 | 324 | ### Временное сохранение изменений без коммита 325 | 326 | ``` bash 327 | git stash # временно сохранить незакоммиченные изменения и убрать их из рабочей директории 328 | git stash pop # вернуть сохраненные командой git stash изменения в рабочую директорию 329 | ``` 330 | 331 | 332 | ### Удалённые репозитории 333 | 334 | Есть два распространённых способа привязать удалённый репозиторий к локальному: по HTTPS и по SSH. Если SSH у вас не настроен (или вы не знаете что это), привязывайте удалённый репозиторий по HTTPS (адрес привязываемого репозитория должен начинаться с https://). 335 | 336 | ``` bash 337 | git remote -v # показать список удалённых репозиториев, связанных с локальным 338 | git remote remove origin # убрать привязку удалённого репозитория с сокр. именем origin 339 | git remote add origin https://github.com:nicothin/test.git # добавить удалённый репозиторий (с сокр. именем origin) с указанным URL 340 | git remote rm origin # удалить привязку удалённого репозитория 341 | git remote show origin # получить данные об удалённом репозитории с сокращенным именем origin 342 | git fetch origin # скачать все ветки с удаленного репозитория (с сокр. именем origin), но не сливать со своими ветками 343 | git fetch origin master # то же, но скачивается только указанная ветка 344 | git checkout --track origin/github_branch # создать локальную ветку github_branch (данные взять из удалённого репозитория с сокр. именем origin, ветка github_branch) и переключиться на неё 345 | git push origin master # отправить в удалённый репозиторий (с сокр. именем origin) данные своей ветки master 346 | git pull origin # влить изменения с удалённого репозитория (все ветки) 347 | git pull origin master # влить изменения с удалённого репозитория (только указанная ветка) 348 | ``` 349 | 350 | 351 | ### Конфликт слияния 352 | 353 | Предполагается ситуация: есть ветка `master` и есть ветка `feature`. В обеих ветках есть коммиты, сделанные после расхождения веток. В ветку `master` пытаемся влить ветку `feature` (`git merge feature`), получаем конфликт, т.к. в обеих ветках есть изменения одной и той же строки в файле `index.html`. 354 | 355 | При возникновении конфликта, репозиторий находится в состоянии прерванного слияния. Нужно оставить в конфликтующих местах файлов только нужный код, проиндексировать изменения и закоммитить. 356 | 357 | ``` bash 358 | git merge feature # влить в активную ветку изменения из ветки feature 359 | git merge-base master feature # показать хеш последнего общего коммита для двух указанных веток 360 | git checkout --ours index.html # оставить в конфликтном файле (index.html) состояние ветки, В КОТОРУЮ мы вливаем (в примере — из ветки master) 361 | git checkout --theirs index.html # оставить в конфликтном файле (index.html) состояние ветки, ИЗ КОТОРОЙ мы вливаем (в примере — из ветки feature) 362 | git checkout --merge index.html # показать в конфликтном файле (index.html) сравнение содержимого сливаемых веток (для ручного редактирования) 363 | git checkout --conflict=diff3 --merge index.html # показать в конфликтном файле (index.html) сравнение содержимого сливаемых веток плюс то, что было в месте конфликта в коммите, на котором разошлись сливаемые ветки 364 | ``` 365 | 366 | ``` bash 367 | git reset --hard # прекратить это прерванное слияние, вернуть рабочую директорию и индекс как было в момент коммита, на который указывает HEAD, а я пойду немного поплачу 368 | git reset --merge # прекратить это прерванное слияние, но оставить изменения, не закоммиченные до слияния (для случая, когда слияние делается не на чистом статусе) 369 | git reset --abort # то же, что и строкой выше 370 | ``` 371 | 372 | 373 | ### «Перенос» ветки 374 | 375 | Можно «переместить» ответвление какой-либо ветки от основной на произвольный коммит. Это нужно для того, чтобы в «переносимой» ветке появились какие-либо изменения, внесённые в основной ветке (уже после ответвления переносимой). 376 | 377 | Нельзя «переносить» ветку, если она уже отправлена на удалённый репозиторий. 378 | 379 | ``` bash 380 | git rebase master # перенести все коммиты (создать их копии) активной ветки так, будто активная ветка ответвилась от master на нынешней вершине master (часто вызывает конфликты) 381 | git rebase --onto master feature # перенести коммиты активной ветки на master, начиная с того места, в котором активная ветка отделилась от ветки feature 382 | git rebase --abort # прервать конфликтный rebase, вернуть рабочую директорию и индекс к состоянию до начала rebase 383 | git rebase --continue # продолжить конфликтный rebase (сработает только после разрешения конфликта и индексации такого разрешения) 384 | ``` 385 | 386 | #### Как отменить rebase 387 | 388 | ``` bash 389 | git reflog feature -2 # смотрим лог перемещений ветки, которой делали rebase (в этом примере — feature), видим последний коммит ПЕРЕД rebase, на него и нужно перенести указатель ветки 390 | git reset --hard feature@{1} # переместить указатель ветки feature на один коммит назад, обновить рабочую директорию и индекс 391 | ``` 392 | 393 | 394 | ### Разное 395 | 396 | ``` bash 397 | git archive -o ./project.zip HEAD # создать архив с файловой структурой проекта по указанному пути (состояние репозитория, соответствующее указателю HEAD) 398 | ``` 399 | 400 | 401 | 402 | 403 | 404 | ## Примеры 405 | 406 | Собираем коллекцию простых и сложных примеров работы. 407 | 408 | 409 | ### Начало работы 410 | 411 | Создание нового репозитория, первый коммит, привязка удалённого репозитория с github.com, отправка изменений в удалённый репозиторий. 412 | 413 | ``` bash 414 | # указана последовательность действий: 415 | # создана директория проекта, мы в ней 416 | git init # создаём репозиторий в этой директории 417 | touch readme.md # создаем файл readme.md 418 | git add readme.md # добавляем файл в индекс 419 | git commit -m "Старт" # создаем коммит 420 | git remote add origin https://github.com:nicothin/test.git # добавляем предварительно созданный пустой удаленный репозиторий 421 | git push -u origin master # отправляем данные из локального репозитория в удаленный (в ветку master) 422 | ``` 423 | 424 | 425 | ### «Внесение изменений» в коммит 426 | 427 | Только если коммит ещё не был отправлен в удалённый репозиторий. 428 | 429 | ``` bash 430 | # указана последовательность действий: 431 | subl inc/header.html # редактируем и сохраняем разметку «шапки» 432 | git add inc/header.html # индексируем измененный файл 433 | git commit -m "Убрал телефон из шапки" # делаем коммит 434 | # ВНИМАНИЕ: коммит пока не был отправлен в удалённый репозиторий 435 | # сознаём, что нужно было еще что-то сделать в этом коммите. 436 | subl inc/header.html # вносим изменения 437 | git add inc/header.html # индексируем измененный файл (можно git add .) 438 | git commit --amend -m "«Шапка»: выполнена задача №34" # заново делаем коммит 439 | ``` 440 | 441 | 442 | ### Работа с ветками 443 | 444 | Есть master (публичная версия сайта), выполняем масштабную задачу (переверстать «шапку»), но по ходу работ возникает необходимость подправить критичный баг (неправильно указан контакт в «подвале»). 445 | 446 | ``` bash 447 | # указана последовательность действий: 448 | git checkout -b new-page-header # создадим новую ветку для задачи изменения «шапки» и перейдём в неё 449 | subl inc/header.html # редактируем разметку «шапки» 450 | git commit -a -m "Новая шапка: смена логотипа" # делаем коммит (работа еще не завершена) 451 | # тут выясняется, что есть баг с контактом в «подвале» 452 | git checkout master # возвращаемся к ветке master 453 | subl inc/footer.html # устраняем баг и сохраняем разметку «подвала» 454 | git commit -a -m "Исправление контакта в подвале" # делаем коммит 455 | git push # отправляем коммит с быстрым критическим изменением в master в удалённом репозитории 456 | git checkout new-page-header # переключаемся обратно в ветку new-page-header для продолжения работ над «шапкой» 457 | subl inc/header.html # редактируем и сохраняем разметку «шапки» 458 | git commit -a -m "Новая шапка: смена навигации" # делаем коммит (работа над «шапкой» завершена) 459 | git checkout master # переключаемся в ветку master 460 | git merge new-page-header # вливаем в master изменения из ветки new-page-header 461 | git branch -d new-page-header # удаляем ветку new_page_header 462 | ``` 463 | 464 | 465 | ### Работа с ветками, слияние и откат к состоянию до слияния 466 | 467 | Была ветка `fix`, в которой исправляли баг. Исправили, влили `fix` в `master`. но тут выяснилось, что это исправление ломает какую-то функциональность, Нужно откатить `master` к состоянию без слияния (наличие бага менее критично, чем порча функциональности). 468 | 469 | ``` bash 470 | # находимся в ветке fix, баг уже «исправлен» 471 | git checkout master # переключаемся на master 472 | git merge fix # вливаем изменения из fix в master 473 | # видим проблему: часть функциональности сломалась 474 | git checkout fix # переключаемся на fix (пока мы в master, git не даст ее двигать) 475 | git branch -f master ORIG_HEAD # передвигаем ветку master на коммит, указанный в ORIG_HEAD (тот, на который указывала master до вливания fix) 476 | ``` 477 | 478 | 479 | 480 | ### Работа с ветками, конфликт слияния 481 | 482 | Есть ветка `master` (публичная версия сайта), в двух параллельных ветках (`branch-1` и `branch-2`) было отредактировано одно и то же место одного и того же файла, первую ветку (`branch-1`) влили в master, попытка влить вторую вызывает конфликт. 483 | 484 | ``` bash 485 | # указана последовательность действий: 486 | git checkout master # переключаемся на ветку master 487 | git checkout -b branch-1 # создаём ветку branch-1, основанную на ветке master 488 | subl . # редактируем и сохраняем файлы 489 | git commit -a -m "Правка 1" # коммитим 490 | git checkout master # возвращаемся к ветке master 491 | git checkout -b branch-2 # создаём ветку branch-2, основанную на ветке master 492 | subl . # редактируем и сохраняем файлы 493 | git commit -a -m "Правка 2" # коммитим 494 | git checkout master # возвращаемся к ветке master 495 | git merge branch-1 # вливаем изменения из ветки branch-1 в текущую ветку (master), удача (автослияние) 496 | git merge branch-2 # вливаем изменения из ветки branch-2 в текущую ветку (master), КОНФЛИКТ автослияния 497 | # Automatic merge failed; fix conflicts and then commit the result. 498 | subl . # выбираем в конфликтных файлах те участки, которые нужно оставить, сохраняем 499 | git commit -a -m "Устранение конфликта" # коммитим результат устранения конфликта 500 | ``` 501 | 502 | 503 | 504 | ### Синхронизация репозитория-форка с мастер-репозиторием 505 | 506 | Есть некий репозиторий на github.com, от него нами был сделан форк, добавлены какие-то изменения. Оригинальный (мастер-)репозиторий был как-то обновлён. Задача: стянуть с мастер-репозитория изменения (которые там внесены уже после того, как мы его форкнули). 507 | 508 | ``` bash 509 | # указана последовательность действий: 510 | git remote add upstream https://github.com:address.git # добавляем удаленный репозиторий: сокр. имя — upstream, URL мастер-репозитория 511 | git fetch upstream # стягиваем все ветки мастер-репозитория, но пока не сливаем со своими 512 | git checkout master # переключаемся на ветку master своего репозитория 513 | git merge upstream/master # вливаем стянутую ветку master удалённого репозитория upstream в свою ветку master 514 | ``` 515 | 516 | 517 | 518 | ### Ошибка в работе: закоммитили в мастер, но поняли, что нужно было коммитить в новую ветку 519 | 520 | **ВАЖНО: это сработает только если коммит еще не отправлен в удалённый репозиторий.** 521 | 522 | ``` bash 523 | # указана последовательность действий: 524 | # сделали изменения, проиндексировали их, закоммитили в master, но ЕЩЁ НЕ ОТПРАВИЛИ (не делали git push) 525 | git checkout -b new-branch # создаём новую ветку из master 526 | git checkout master # переключаемся на master 527 | git reset HEAD~ --hard # сдвигаем указатель (ветку) master на 1 коммит назад 528 | git checkout new-branch # переключаемся обратно на новую ветку для продолжения работы 529 | ``` 530 | 531 | 532 | 533 | ### Нужно вернуть содержимое файла к состоянию, бывшему в каком-либо коммите (известен хеш коммита) 534 | 535 | ``` bash 536 | # указана последовательность действий: 537 | git checkout f26ed88 -- index.html # восстановить в рабочей директории состояние указанного файла на момент указанного коммита, добавить это изменение в индекс 538 | git commit -am "Navigation fixs" # сделать коммит 539 | ``` 540 | 541 | 542 | 543 | ### При любом действии с github (или другим удалённым сервисом) запрашивается логин и пароль 544 | 545 | Речь именно о запросе пары логин + пароль, а не ключевой фразы. Происходит это потому, что git по умолчанию не сохранит пароль для доступа к репозиторию по HTTPS. 546 | 547 | Простое решение: [указать git кешировать ваш пароль](https://help.github.com/articles/caching-your-github-password-in-git/). 548 | 549 | 550 | 551 | ## `.gitattributes` 552 | 553 | ``` 554 | * text=auto 555 | 556 | *.html diff=html 557 | *.css diff=css 558 | *.scss diff=css 559 | ``` --------------------------------------------------------------------------------