Добавляйте свои команды и остальные полезности через Pull request.
Общее
Git — система контроля версий (файлов). Что-то вроде возможности сохраняться в компьютерных играх (в Git эквивалент игрового сохранения — коммит). Важно: добавление файлов к «сохранению» двухступенчатое: сначала добавляем файл в индекс (git add), потом «сохраняем» (git commit).
Любой файл в директории существующего репозитория может находиться или не находиться под версионным контролем (отслеживаемые и неотслеживаемые).
Отслеживаемые файлы могут быть в 3-х состояниях: неизменённые, изменённые, проиндексированные (готовые к коммиту).
Ключ к пониманию
Ключ к пониманию концепции git — знание о «трех деревьях»:
Рабочая директория — файловая система проекта (те файлы, с которыми вы работаете).
Индекс — список отслеживаемых git-ом файлов и директорий, промежуточное хранилище изменений (редактирование, удаление отслеживаемых файлов).
Директория .git/ — все данные контроля версий этого проекта (вся история разработки: коммиты, ветки, теги и пр.).
Коммит — «сохранение» (хранит набор изменений, сделанный в рабочей директории с момента предыдущего коммита). Коммит неизменен, его нельзя отредактировать.
У всех коммитов (кроме самого первого) есть один или более родительских коммитов, поскольку коммиты хранят изменения от предыдущих состояний.
Индексация/добавление файлов в индекс (указание для git какие изменения нужно будет закоммитить).
Коммит (фиксация изменений).
Возврат к шагу 1 или отход ко сну.
Указатели
HEAD — указатель на текущий коммит или на текущую ветку (то есть, в любом случае, на коммит). Указывает на родителя коммита, который будет создан следующим.
ORIG_HEAD — указатель на коммит, с которого вы только что переместили HEAD (командой git reset ..., например).
Ветка (master, develop etc.) — указатель на коммит. При добавлении коммита, указатель ветки перемещается с родительского коммита на новый.
Теги — простые указатели на коммиты. Не перемещаются.
Настройки
Перед началом работы нужно выполнить некоторые настройки:
git config --global user.name "Your Name" # указать имя, которым будут подписаны коммиты
git config --global user.email "[email protected]" # указать электропочту, которая будет в описании коммитера
Если вы в Windows:
git config --global core.autocrlf true # включить преобразование окончаний строк из CRLF в LF
Указание неотслеживаемых файлов
Файлы и директории, которые не нужно включать в репозиторий, указываются в файле .gitignore. Обычно это устанавливаемые зависимости (node_modules/, bower_components/), готовая сборка build/ или dist/ и подобные, создаваемые при установке или запуске. Каждый файл или директория указываются с новой строки, возможно использование шаблонов.
Вызов некоторых консольных команд приводит к необходимости очень длинного вывода в консоль (пример: вывод истории всех изменений в файле командой git log -p fileName.txt). При этом прямо в консоли запускается редактор Vim. Он работает в нескольких режимах, из которых Вас заинтересуют режим вставки (редактирование текста) и нормальный (командный) режим. Чтобы попасть из Vim обратно в консоль, нужно в командном режиме ввести :q. Переход в командный режим из любого другого: Esc.
Если нужно что-то написать, нажмите i — это переход в режим вставки текста. Если нужно сохранить изменения, перейдите в командный режим и наберите :w.
Vim (некоторые команды)
# Нажатия кнопок
ESC — переход в командный режим
i — переход в режим редактирования текста
ZQ (зажат Shift, поочередное нажатие) — выход без сохранения
ZZ (зажат Shift, поочередное нажатие) — сохранить и выйти
```bash# Нажатия кнопокESC — переход в командный режимi — переход в режим редактирования текстаZQ (зажат Shift, поочередное нажатие) — выход без сохраненияZZ (зажат Shift, поочередное нажатие) — сохранить и выйти# Ввод в командном режиме:q! — выйти без сохранения:wq — сохранить файл и выйти:w filename.txt — сохранить файл как filename.txt
Консольные команды
Создать новый репозиторий
git init # создать новый проект в текущей директории
git init folder-name # создать новый проект в указанной директории
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 #
请发表评论