Содержание:
Установка-Git
Настройка Git
Создание репозитория
Добавить новые файлы в репозиторий
Как проверить состояние репозитория
Добавление изменений
Расширенное исспользование git add
История коммитов
Алиасы
Получение предыдущих версий
Git — мощная и сложная распределенная система контроля версий. Понимание всех возможностей git открывает для разработчика новые горизонты в управлении исходным кодом. Самый верный способ обучиться владению Git — испытать его своими руками.
Основой интерфейс для работы с Git-ом является консоль/терминал.
Установка Git:
- Windows
Переходим по этой ссылке, выбираем под вашу ОС (32 или 64 битную), скачиваем и устанавливаем. - MacOS
- Linux (Ubuntu, ArchLinx)
Debian или Ubuntu
sudo apt install git
ArchLinux
sudo pacman -S git
Вы установили себе Git и можете им пользоваться. Давайте теперь его настроим, чтобы когда вы создавали commit, указывался автор, кто его создал. Выполните следующие команды, чтобы git узнал ваше имя и электронную почту. Если git уже установлен, можете переходить к разделу окончания строк.
Выполнить:
git config --global user.name "Your Name"
и
git config --global user.email "your_email@whatever.com"
Параметры установки окончания строк
- Для пользователей Unix/Mac
Выполнить:
git config --global core.autocrlf input
и
git config --global core.safecrlf warn
- Для пользователей Windows
Выполнить:
git config --global core.autocrlf input
и
git config --global core.safecrlf warn
Чтобы создать git репозиторий из каталога, выполните команду git init в этом каталоге.
Выполните:
git init
Теперь давайте добавим в репозиторий страницу «Hello, World» - hello.html.
Выполните:
git add hello.html
и
git commit -m "First Commit"
где "First commit" - Коммит - Название(Комментарий к) точки сохранения).
Используйте команду git status, чтобы проверить текущее состояние репозитория.
Выполните:
git status
Команда проверки состояния сообщит, что коммитить нечего. Это означает, что в репозитории хранится текущее состояние рабочего каталога, и нет никаких изменений, ожидающих записи.
Команда "git status", необходима, чтобы продолжать отслеживать состояние репозитория и рабочего каталога.
Если вы изменили файлы или добавили новые файлы, то набрав команду git status вы можете увидить следующий результат:
git status
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: hello.html
no changes added to commit (use "git add" and/or "git commit -a")"
Первое, что нужно заметить, это то, что git знает, что файл hello.html был изменен, но при этом эти изменения еще не зафиксированы в репозитории.
Также обратите внимание на то, что сообщение о состоянии дает вам подсказку о том, что нужно делать дальше. Если вы хотите добавить эти изменения в репозиторий, используйте команду "git add". В противном случае используйте команду "git сheckout" для отмены изменений.
Добавим изменения
Дадим команду git проиндексировать изменения.
Выполнить:
git add hello.html
Изменения файла hello.html были проиндексированы. Это означает, что git теперь знает об изменении, но изменение пока не перманентно (читай, навсегда) записано в репозиторий. Следующий коммит будет включать в себя проиндексированные изменения.
Если вы решили, что не хотите коммитить изменения, команда состояния напомнит вам о том, что с помощью команды "git reset" можно снять индексацию этих изменений.
Отдельный шаг индексации в git позволяет вам продолжать вносить изменения в рабочий каталог, а затем, в момент, когда вы захотите взаимодействовать с версионным контролем, git позволит записать изменения в малых коммитах, которые фиксируют то, что вы сделали.
Предположим, что вы отредактировали три файла (a.html, b.html, и c.html). Теперь вы хотите закоммитить все изменения, при этом чтобы изменения в "a.html" и "b.html" были одним коммитом, в то время как изменения в "c.html" логически не связаны с первыми двумя файлами и должны идти отдельным коммитом.
В теории, вы можете сделать следующее:
git add a.html
Затем
git add b.html
Затем
git commit -m "Changes for a and b"
Затем
git add c.html
И наконец
git commit -m "Unrelated change to c"
Разделяя индексацию и коммит, вы имеете возможность с легкостью настроить, что идет в какой коммит.
Давайте обозначим категории файлов, которые вообще можно добавлять. Будем использовать те же обозначения, что и в выводе команды git status -s:
M - (modified) отслеживаемые, изменились с прошлого коммита, еще не добавлены
D - (deleted) отслеживаемые, удалены после прошлого коммита, еще не добавлены
? - (untracked) неотслеживаемые, не запрещены к добавлению
! - (ignored) неотслеживаемые, запрещены к добавлению (например, в .gitignore)
Параметры и аргументы
Первое различие — в том, что . — это путь (аргумент), а всё остальное — параметры. Те и другие не исключают друг друга и возможны их сочетания. Использование абсолютных ":/" и относительных "." путей с командой add
Путь . обозначает текущую директорию, т.е. ту, в которой была запущена команда.
Начиная с Git версии 2.0, поведение команды add приведено в соответствие с поведением commit и других комманд. Теперь . обозначает не всю рабочую область (working tree), а текущий путь в этой области.
Таким образом, если вы выполняете команду add не в корневой директории проекта (той, где лежит .git/), то будет обработано содержимое только текущей директории.
Чтобы явным образом дать указание Git работать со всей рабочей областью, используйте ":/":
работает одинаково из любой директории, добавляет всю рабочую область
git add :/
путь относительно корневой директории
git add :/path/to/files/
работает только в текущей директории
cd test
git add .
эквивалентно этому:
git add :/test
путь относительно текущей директории
cd test
git add ./path
эквивалентно этому:
git add :/test/path
Если не указан никакой путь к добавляемым файлам, то большинство команд работает во всей рабочей области, а "git add" и "git add --no-all" просто не работают.
Сводная таблица
Changed | Untacked | Removed | Ignored | |
---|---|---|---|---|
Команды | Изменненые | Новые | Удаленные | Игнорируемые |
git add .(v 2.0+) | ✅ | ✅ | ✅ | ✖️ |
git add -u | ✅ | ✖️ | ✅ | ✖️ |
git add --all | ✅ | ✅ | ✅ | ✖️ |
git add -no-all | ✅ | ✅ | ✖️ | ✖️ |
git add -f . | ✅ | ✅ | ✅ | ✅ |
git add * | ✖️ | ⛔ |
О функционале команд подробнее
git add .
git add '*'
Git версии 2.0+ просматривает текущую папку и добавляет файлы M, D, ?. Git версии 1.х просматривает всю рабочую область и добавляет файлы M, D.
Если '*'
дается в кавычках, то обрабатывать его будет Git и это эквивалентно git add ..
Исключение: из-под cmd.exe git add '*'
не сработает, используйте git add
. или git add '*'
git add --no-all :/
git add --ignore-removal :/
Эта команда в Git v. 2.0+ работает как git add .
в Git v. 1.x, то есть добавляет измененные и новые файлы M, ? во всей рабочей области. Для этой команды обязательно указывать путь.
git add --no-all .
#добавляет измененные и новые файлы в текущей директории
git add --no-all path1/ path2/
# добавляет измененные и новые файлы в путях относительно текущей директории
git add -u
git add -update
Git обновляет (update) статус уже отслеживаемых файлов т.е. M, D.
git add -A
git add --all
git add --no-ignore-removal
Эти варианты эквивалентны и добавляют M, D, ?.
Без точки — из всей рабочей области:
git add -A = git add -A :/ = git add :/ + git add -u
С точкой — только текущий путь:
git add -A . = git add . + git add -u .
git add *
- Этот синтаксис лучше не использовать, и вот почему:
При этой команде shell (или bash или другая командная оболочка) просматривает рабочую область и отдает Git список файлов на добавление. Система сработает таким образом, что будут найдены абсолютно все не-скрытые файлы, находящиеся в заданном корне. Вы можете посмотреть на этот список, выполнив echo *
. ( Исключение: из-под cmd.exe git add *
работает так же как git add '*'
на shell/bash.)
Произойдет следующее (здесь мы видим сразу несколько причин не использовать add *):
Добавятся не изменившиеся с прошлого коммита файлы. Git спокойно и молча "прожует" этот запрос, не влияющий на индекс. Будут добавлены в индекс файлы в не-скрытых папках M,?. Не будут добавлены файлы в скрытых папках. .M, .? Не будут добавлены удаленные файлы D. Если будут захвачены игнорируемые файлы !, то будет попытка их добавить. Git отменит всю операцию и покажет сообщение об ошибке.
Зачем столько способов
Разнообразие параметров (-u, -A, --no-all) нужно для того, чтобы можно было добавлять разные группы файлов. Конкретно --no-all . было добавлено для того, чтобы реализовывать старое поведение add . в версиях 1.х.
Похоже, что несмотря на это, Git не позволяет добавлять конкретные группы файлов одной командой (см. сводную таблицу в начале).
Тонкости в использовании . и :/ нужны для того, чтобы каждую команду можно было выполнять как на всю рабочую область, так и на конкретную подпапку.
Git позволяет просматривать историю проекта.
Получение списка произведенных изменений — функция команды "git log". Выполните:
git log
Вы увидите…
Результат:
$ git log
commit fa3c1411aa09441695a9e645d4371e8d749da1dc
Author: Alexander Shvets <alex@githowto.com>
Date: Wed Mar 9 10:27:54 2011 -0500
Added HTML header
commit 8c3228730ed03116815a5cc682e8105e7d981928
Author: Alexander Shvets <alex@githowto.com>
Date: Wed Mar 9 10:27:54 2011 -0500
Added standard HTML page tags
commit 43628f779cb333dd30d78186499f93638107f70b
Author: Alexander Shvets <alex@githowto.com>
Date: Wed Mar 9 10:27:54 2011 -0500
Added h1 tag
commit 911e8c91caeab8d30ad16d56746cbd6eef72dc4c
Author: Alexander Shvets <alex@githowto.com>
Date: Wed Mar 9 10:27:54 2011 -0500
First Commit
Вот список всех четырех коммитов в репозиторий, которые мы успели совершить.
Вы полностью контролируете то, что отображает log, например, нравится однострочный формат: Выполните:
git log --pretty=oneline
Вы увидите… Результат:
$ git log --pretty=oneline
fa3c1411aa09441695a9e645d4371e8d749da1dc Added HTML header
8c3228730ed03116815a5cc682e8105e7d981928 Added standard HTML page tags
43628f779cb333dd30d78186499f93638107f70b Added h1 tag
911e8c91caeab8d30ad16d56746cbd6eef72dc4c First Commit
Контроль отображения записей
Есть много вариантов выбора, какие элементы отображаются в логе. Поиграйте со следующими параметрами:
git log --pretty=oneline --max-count=2
git log --pretty=oneline --since='5 minutes ago
git log --pretty=oneline --until='5 minutes ago
git log --pretty=oneline --author=<your name>
git log --pretty=oneline --all
В unix-системах доступна справочная страница man git log
.
Для просмотра изменений, сделанных за последнюю неделю, от автора "alex" --author=alex
git log --all --pretty=format:"%h %cd %s (%an)" --since='7 days ago'
Еще удобный вывод
git log --pretty=format:"%h %ad | %s%d [%an]" --graph --date=short
Результат:
$ git log --pretty=format:"%h %ad | %s%d [%an]" --graph --date=short
* fa3c141 2011-03-09 | Added HTML header (HEAD, master) [Alexander Shvets]
* 8c32287 2011-03-09 | Added standard HTML page tags [Alexander Shvets]
* 43628f7 2011-03-09 | Added h1 tag [Alexander Shvets]
* 911e8c9 2011-03-09 | First Commit [Alexander Shvets]
Давайте рассмотрим его в деталях:
--pretty="..." — определяет формат вывода.
%h — укороченный хэш коммита
%d — дополнения коммита («головы» веток или теги)
%ad — дата коммита
%s — комментарий
%an — имя автора
--graph — отображает дерево коммитов в виде ASCII-графика
--date=short — сохраняет формат даты коротким и симпатичным
Таким образом, каждый раз, когда вы захотите посмотреть лог, вам придется много печатать. К счастью, мы узнаем о git алиасах далее.
Как настраивать алиасы и шорткаты для команд git
** Общие алиасы**
Для пользователей Windows
Выполнить:
git config --global alias.co checkout
git config --global alias.ci commit
git config --global alias.st status
git config --global alias.br branch
git config --global alias.hist "log --pretty=format:'%h %ad | %s%d [%an]' --graph --date=short
git config --global alias.type 'cat-file -t
git config --global alias.dump 'cat-file -p
Также, для пользователей Unix/Mac:
git status, git add, git commit, git checkout — общие команды, для которых полезно иметь сокращения.
Добавьте следующее в файл .gitconfig в вашем $HOME каталоге. Файл: .gitconfig
[alias]
co = checkout
ci = commit
st = status
br = branch
hist = log --pretty=format:\"%h %ad | %s%d [%an]\" --graph --date=short
type = cat-file -t
dump = cat-file -p
Как возвращать рабочий каталог к любому предыдущему состоянию.
Возвращаться назад в историю очень просто. Команда checkout скопирует любой снимок из репозитория в рабочий каталог.
Получите хэши предыдущих версий
* fa3c141 2011-03-09 | Added HTML header (HEAD, master) [Alexander Shvets]
* 8c32287 2011-03-09 | Added standard HTML page tags [Alexander Shvets]
* 43628f7 2011-03-09 | Added h1 tag [Alexander Shvets]
* 911e8c9 2011-03-09 | First Commit [Alexander Shvets]
Изучите данные лога и найдите хэш для первого коммита. Он должен быть в последней строке данных. Используйте этот хэш-код (достаточно первых 7 знаков) в команде ниже. Затем проверьте содержимое файла hello.html.
Выполните:
git checkout <hash>
cat hello.html
Примечание: Многие команды зависят от хэшевых значений в репозитории. Поскольку ваши хеш-значения будут отличаться от представленных в примере, когда вы видите что-то вроде <hash>
или <treehash>
в команде, подставьте необходимое значение хэш для вашего репозитория.
Результат:
git checkout 911e8c9
Note: checking out '911e8c9'.
You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.
If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:
Выходные данные команды checkout очень хорошо объясняют ситуацию. Старые версии git будут ругаться, что не расположены в локальной ветке. В любом случае, сейчас об этом не беспокойтесь.
Обратите внимание на то, что содержимое файла hello.html является значением по умолчанию.
Вернитесь к последней версии в ветке master
Выполните:
git checkout master
cat hello.html
Результат:
$ git checkout master
Previous HEAD position was 911e8c9... First Commit
Switched to branch 'master'
$ cat hello.html
<html>
<head>
</head>
<body>
<h1>Hello, World!</h1>
</body>
</html>
«master» — имя ветки по умолчанию. Переключая имена веток, вы попадаете на последнюю версию выбранной ветки.