Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save DuckJsus/4a501d59216e020545427d144e20dd06 to your computer and use it in GitHub Desktop.
Save DuckJsus/4a501d59216e020545427d144e20dd06 to your computer and use it in GitHub Desktop.
# Шпаргалка по консольным командам Git
## Общее
Git — система контроля версий (файлов). Что-то вроде возможности сохраняться в компьютерных играх (в Git эквивалент игрового сохранения — коммит).
Любой файл в папке существующего репозитория может находиться или не находиться под версионным контролем (отслеживаемые и неотслеживаемые).
Неотслеживаемые файлы можно в любой момент сделать отслеживаемыми и наоборот.
Отслеживаемые файлы могут быть в 3-х состояниях: неизменённые, изменённые, готовые к коммиту. Сразу после клонирования репозитория все файлы — отслеживаемые неизменённые.
После редактирования отслеживаемого файла он становится изменённым. Изменения файла (или нескольких) можно индексировать (подготовить к коммиту) и закоммитить. После коммита такие файлы становятся отслеживаемыми неизменёнными.
Проверить состояние репозитория можно командой `git status`. Она покажет ветку, изменённые файлы (если есть) с пометкой «modified», неотслеживаемые файлы в списке «Untracked files».
## Консольные команды
### Создать новый репозиторий
``` bash
git init # создать новый проект в текущей папке
git init folder-name # создать новый проект в указанной папке
```
### Клонирование репозитория
``` bash
git clone git@github.com:supervoron1/ruby.git # клонировать удаленный репозиторий в одноименную папку
# или
git clone git@github.com:supervoron1/ruby.git foldername # клонировать удаленный репозиторий в папку «foldername»
```
### Добавление файлов к отслеживанию, индексация отслеживаемых
``` bash
git add text.txt # добавить к отслеживанию этот существующий файл
git add . # добавить к отслеживанию все новые файлы из текущей папки и её подпапок, индексировать отслеживаемые файлы
git add -i # запуск оболочки интерактивного индексирования для добавления в индекс только выбранных файлов (см. [git-scm.com](http://git-scm.com/book/ru/v1/%D0%98%D0%BD%D1%81%D1%82%D1%80%D1%83%D0%BC%D0%B5%D0%BD%D1%82%D1%8B-Git-%D0%98%D0%BD%D1%82%D0%B5%D1%80%D0%B0%D0%BA%D1%82%D0%B8%D0%B2%D0%BD%D0%BE%D0%B5-%D0%B8%D0%BD%D0%B4%D0%B5%D0%BA%D1%81%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5))
```
### Отмена индексации
``` bash
git reset HEAD # убрать из индекса все индексированные файлы
git reset HEAD text.txt # убрать из индекса указанный файл
```
### Просмотр изменений
``` bash
git diff # посмотреть непроиндексированные изменения (если есть, иначе ничего не выведет)
git diff --staged # посмотреть проиндексированные изменения (если есть, иначе ничего не выведет)
```
### Отмена изменений
``` bash
git checkout -- text.txt # ОПАСНО: отменить все изменения, внесенные в файл со времени предыдущего коммита
git checkout text.txt # ОПАСНО: отменить изменения в непроиндексированном файле
```
### Коммиты
``` bash
git commit -m "Name of commit" # закоммитить отслеживаемые индексированные файлы (указано название коммита)
git commit -m -a "Name of commit" # закоммитить отслеживаемые индексированные файлы (указано название коммита, не требует git add, не добавит в коммит неотслеживаемые файлы)
git commit # закоммитить отслеживаемые индексированные файлы (откроется редактор для введения названия коммита)
git commit --amend # изменить последний коммит (Insert — режим ввода, : — командный режим; в командном режиме: :wq — сохранить и выйти)
```
### Отмена коммитов
``` bash
git revert HEAD --no-edit # создать новый коммит, отменяющий изменения последнего коммита (без запуска редактора сообщения)
git reset --hard 75e2d51 # вернуть репозиторий в состояние коммита с указанным хешем
```
### Удаление файла (просто удалить отслеживаемый файл из папки недостаточно, нужно сделать его неотслеживаемым и отправить коммит)
``` bash
git rm text.txt # удалить из отслеживаемых неиндексированный файл (файл будет удален из папки)
git rm -f text.txt # удалить из отслеживаемых индексированный файл (файл будет удален из папки)
git rm -r log/ # удалить из отслеживаемых всё содержимое папки log/ (папка будет удалена)
git rm ind* # удалить из отслеживаемых все файлы с именем, начинающимся на «ind» в текущей папке (файлы будут удалены из папки)
```
### Перемещение/переименование файлов (Git не отслеживает перемещения/переименование, но пытается его угадать)
``` bash
git mv text.txt test_new.txt # переименовать файл «text.txt» в «test_new.txt»
git mv readme_new.md folder/ # переместить файл readme_new.md в папку folder/ (должна существовать)
```
### История изменений
``` bash
git log -2 # показать последние 2 коммита
git log -2 --stat # показать последние 2 коммита и статистику внесенных ими изменений
git log -p -22 # показать последние 22 коммита и внесенную ими разницу на уровне строк (выход из длинного лога: Q)
git log --pretty=format:"%h - %an, %ar : %s" -4 # показать последние 4 коммита с форматированием выводимых данных
git log --graph -10 # показать последние 10 коммитов с ASCII-представлением ветвления
git log --since=2.weeks # показать коммиты за последние 2 недели
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 show 60d6582 # показать изменения из коммита с указанным хешем
git show HEAD^ # показать данные о предыдущем коммите
```
### Ветки
``` bash
git branch # показать список веток
git branch -v # показать список веток и последний коммит в каждой
git branch new_branch # создать новую ветку с указанным именем
git checkout new_branch # перейти в указанную ветку
git checkout -b new_branch # создать новую ветку с указанным именем и перейти в неё
git merge hotfix # влить в ветку, в которой находимся, данные из ветки hotfix
git branch -d hotfix # удалить ветку hotfix (если её изменения уже влиты в главную ветку)
git branch --merged # показать ветки, уже слитые с активной (их можно удалять)
git branch --no-merged # показать ветки, не слитые с активной
git branch -a # показать все имеющиеся ветки (в т.ч. на удаленных репозиториях)
```
### Удалённые репозитории
``` bash
git remote -v # показать список удалённых репозиториев, связанных с этим
git remote add origin git@github.com:nicothin/test.git # добавить удалённый репозиторий (с сокр. именем origin) с указанным URL
git remote show origin # получить данные об удалённом репозитории с сокращенным именем origin
git fetch origin # скачать все ветки с удаленного репозитория (с сокр. именем origin), но не сливать со своими ветками
git fetch origin master # то же, но скачивается только указанная ветка
git checkout origin/github_branch # посмотреть ветку, скачанную с удалённого репозитория (локальной редактируемой копии не создаётся! если нужно редактировать, придётся влить)
git checkout --track origin/github_branch # создать локальную ветку github_branch (данные взять из удалённого репозитория с сокр. именем origin, ветка github_branch) и переключиться на неё
git push origin master # отправить в удалённый репозиторий (с сокр. именем origin) данные своей ветки master
git pull origin # влить изменения с удалённого репозитория (все ветки)
git pull origin master # влить изменения с удалённого репозитория (только указанная ветка)
```
### Разное
``` bash
git clean -f # удалить из репозитория все неотслеживаемые файлы
```
## Примеры
Собираем коллекцию простых и сложных примеров работы
### Начало работы
Создание нового репозитория, первый коммит, привязка удалённого репозитория с gthub.com, отправка изменений в удалённый репозиторий.
``` bash
git init # инициируем гит в этой папке
touch readme.md # создаем файл readme.md
git add readme.md # делаем этот файл отслеживаемым
git commit -m "Первый коммит" # создаем первый коммит с вменяемым названием
git remote add origin git@github.com:nicothin/test.git # добавляем предварительно созданный пустой удаленный репозиторий
git push origin master # отправляем данные из локального репозитория в удаленный (в ветку master)
```
### Внесение изменений в коммит
``` bash
subl inc/header.html # редактируем и сохраняем разметку «шапки»
git add inc/header.html # индексируем измененный файл
git commit -m "Убрал телефон из шапки" # делаем коммит
# сознаём, что нужно было еще что-то сделать в этом коммите
git add inc/header.html # индексируем измененный файл
git commit --amend -m "«Шапка»: выполнена задача №34 (вставить-вынуть)" # заново делаем коммит
```
### Работа с ветками
``` bash
Есть master (публичная версия сайта), хотим масштабно что-то поменять (переверстать «шапку»), но по ходу работ возникает необходимость подправить критичный баг (неправильно указан контакт в «подвале»).
git checkout -b new_page_header # создадим новую ветку для задачи изменения «шапки» и перейдём в неё
subl inc/header.html # редактируем и сохраняем разметку «шапки»
git commit -a -m "Новая шапка: смена логотипа" # делаем первый коммит (работа еще не завершена)
# тут выясняется, что есть баг с контактом в «подвале»
git checkout master # возвращаемся к ветке master
git checkout -b footer_hotfix # создаём ветку (основанную на master) для решения проблемы
subl inc/footer.html # устраняем баг и сохраняем разметку «подвала»
git commit -a -m "Исправление контакта в подвале" # делаем коммит
git checkout master # переключаемся в ветку master
git merge footer_hotfix # вливаем в master изменения из ветки footer_hotfix
git branch -d footer_hotfix # удаляем ветку footer_hotfix
git checkout new_page_header # переключаемся в ветку new_page_header для продолжения работ над «шапкой»
subl inc/header.html # редактируем и сохраняем разметку «шапки»
git commit -a -m "Новая шапка: смена навигации" # делаем коммит (работа над «шапкой» завершена)
git checkout master # переключаемся в ветку master
git merge new_page_header # вливаем в master изменения из ветки new_page_header
git branch -d new_page_header # удаляем ветку new_page_header
```
### Работа с ветками, конфликт слияния
Есть master (публичная версия сайта), в двух параллельных ветках (branch_1 и branch_2) было отредактировано одно и то же место одного и того же файла, первую ветку (branch_1) влили в master, попытка влить вторую вызывает конфликт.
``` bash
git checkout master # переключаемся на ветку master
git checkout -b branch_1 # создаём ветку branch_1, основанную на ветке master
subl . # редактируем и сохраняем файлы
git commit -a -m "Правка 1" # коммитим (теперь имеем 1 коммит в ветке branch_1)
git checkout master # возвращаемся к ветке master
git checkout -b branch_2 # создаём ветку branch_2, основанную на ветке master
subl . # редактируем и сохраняем файлы
git commit -a -m "Правка 2" # коммитим (теперь имеем 1 коммит в ветке branch_2)
git checkout master # возвращаемся к ветке master
git merge branch_1 # вливаем изменения из ветки branch_1 в текущую ветку (master), удача (автослияние)
git merge branch_2 # вливаем изменения из ветки branch_2 в текущую ветку (master), КОНФЛИКТ автослияния
# Automatic merge failed; fix conflicts and then commit the result.
subl . # выбираем в конфликтных файлах те участки, которые нужно оставить, сохраняем
git commit -a -m "Устранение конфликта" # коммитим результат устранения конфликта
```
### Синхронизация репозитория-форка с мастер-репозиторием
Есть некий репозиторий на github.com, он него нами был сделан форк, добавлены какие-то изменения. Оригинальный (мастер-) репозиторий был как-то обновлён. Задача: стянуть с мастер-репозитория изменения (которые там внесены уже после того, как мы его форкнули).
``` bash
git remote add upstream git@github.com:address.git # добавляем удаленный репозиторий: сокр. имя — upstream, URL мастер-репозитория
git fetch upstream # качаем все ветки мастер-репозитория, но пока не сливаем со своими
git checkout master # переключаемся на ветку master своего репозитория
git merge upstream/master # вливаем ветку master удалённого репозитория upstream в свою ветку master
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment