Шаг 1-10 ..
Шаг 21-30
11. Алиасы
Цели: Научиться настраивать алиасы и шорткаты для команд git
11.01 Общие алиасы
Для пользователей 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
Мы уже успели рассмотреть команды commit и status, в предыдущем уроке рассмотрели команду log и совсем скоро познакомимся с checkout. Главное, что стоит запомнить из этого урока, так это то, что теперь вы можете вводить git st там, где раньше приходилось использовать git status. Аналогичным образом, пишем git co вместо git checkout и git ci вместо git commit. Что лучше всего, команда git hist позволит избежать ввода очень длинной команды log.
Попробуйте использовать новые команды.
11.02 Задайте алиас hist в файле .gitconfig
По большей части, я буду продолжать печатать полные команды в этом руководстве. Единственным исключением будет использование алиаса hist, указанного выше, когда мне понадобится посмотреть git лог. Если вы хотите повторять мои действия, убедитесь, что алиас hist установлен в вашем файле .gitconfig.
11.03 Type и Dump
Мы добавили несколько алиасов для команд, которых мы еще не рассматривали. С командой git branch разберемся чуть позже, а команда git cat-file используется для исследования git, в чем мы вскоре убедимся.
11.04 Алиасы команд (опционально)
Если ваша оболочка поддерживает алиасы или шорткаты, вы можете добавить алиасы и на этом уровне. Я использую:
ФАЙЛ: .PROFILE
alias gs='git status '
alias ga='git add '
alias gb='git branch '
alias gc='git commit'
alias gd='git diff'
alias go='git checkout '
alias gk='gitk --all&'
alias gx='gitx --all'
alias got='git '
alias get='git '
Сокращение go для команды git checkout особенно полезно. Оно позволяет мне вводить:
go <branch>
для переключения в отдельную ветку.
И да, я достаточно часто пишу вместо git get или got, поэтому создам алиасы и для них.
12. Получение старых версий
Цели:
Научиться возвращать рабочий каталог к любому предыдущему состоянию.
Возвращаться назад в историю очень просто. Команда checkout скопирует любой снимок из репозитория в рабочий каталог.
12.01 Получите хэши предыдущих версий
ВЫПОЛНИТЕ:
Примечание: Вы не забыли задать hist в вашем файле .gitconfig? Если забыли, посмотрите еще раз урок по алиасам.
РЕЗУЛЬТАТ:
$ git hist
* 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]
Изучите данные лога и найдите хэш для первого коммита. Он должен быть в последней строке данных git hist. Используйте этот хэш-код (достаточно первых 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:
git checkout -b new_branch_name
HEAD is now at 911e8c9... First Commit
$ cat hello.html
Hello, World
Выходные данные команды checkout очень хорошо объясняют ситуацию. Старые версии git будут ругаться, что не расположены в локальной ветке. В любом случае, сейчас об этом не беспокойтесь.
Обратите внимание на то, что содержимое файла hello.html является значением по умолчанию.
12.02 Вернитесь к последней версии в ветке 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» — имя ветки по умолчанию. Переключая имена веток, вы попадаете на последнюю версию выбранной ветки.
13. Создание тегов версий
Цели: Узнать, как создавать теги для коммитов для использования в будущем.
Давайте назовем текущую версию страницы hello первой (v1).
13.01 Создайте тег первой версии
ВЫПОЛНИТЕ:
Теперь текущая версия страницы называется v1.
13.02 Теги для предыдущих версий
Давайте создадим тег для версии, которая идет перед текущей версией и назовем его v1-beta. В первую очередь нам надо переключиться на предыдущую версию. Вместо поиска до хэш, мы будем использовать ^, обозначающее «родитель v1».
Если обозначение v1^ вызывает у вас какие-то проблемы, попробуйте также v1~1, указывающее на ту же версию. Это обозначение можно определить как «первую версию предшествующую v1».
ВЫПОЛНИТЕ:
git checkout v1^
cat hello.html
РЕЗУЛЬТАТ:
$ git checkout v1^
Note: checking out 'v1^'.
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:
git checkout -b new_branch_name
HEAD is now at 8c32287... Added standard HTML page tags
$ cat hello.html
<html>
<body>
<h1>Hello, World!</h1>
</body>
</html>
Это версия c тегами <html> и <body>, но еще пока без <head>. Давайте сделаем ее версией v1-beta.
ВЫПОЛНИТЕ:
13.03 Переключение по имени тега
Теперь попробуйте попереключаться между двумя отмеченными версиями.
ВЫПОЛНИТЕ:
git checkout v1
git checkout v1-beta
РЕЗУЛЬТАТ:
$ git checkout v1
Previous HEAD position was 8c32287... Added standard HTML page tags
HEAD is now at fa3c141... Added HTML header
$ git checkout v1-beta
Previous HEAD position was fa3c141... Added HTML header
HEAD is now at 8c32287... Added standard HTML page tags
13.04 Просмотр тегов с помощью команды tag
Вы можете увидеть, какие теги доступны, используя команду git tag.
ВЫПОЛНИТЕ:
РЕЗУЛЬТАТ:
13.05 Просмотр Тегов в логах
Вы также можете посмотреть теги в логе.
ВЫПОЛНИТЕ:
РЕЗУЛЬТАТ:
$ git hist master --all
* fa3c141 2011-03-09 | Added HTML header (v1, master) [Alexander Shvets]
* 8c32287 2011-03-09 | Added standard HTML page tags (HEAD, v1-beta) [Alexander Shvets]
* 43628f7 2011-03-09 | Added h1 tag [Alexander Shvets]
* 911e8c9 2011-03-09 | First Commit [Alexander Shvets]
Вы можете видеть теги (v1 и v1-beta) в логе вместе с именем ветки (master). Кроме того HEAD показывает коммит, на который вы переключились (на данный момент это v1-beta).
14. Отмена локальных изменений (до индексации)
Цели: Научиться отменять изменения в рабочем каталоге
14.01 Переключитесь на ветку Master
Убедитесь, что вы находитесь на последнем коммите ветки master, прежде чем продолжить работу.
ВЫПОЛНИТЕ:
14.02 Измените hello.html
Иногда случается, что вы изменили файл в рабочем каталоге, и хотите отменить последние коммиты. С этим справится команда checkout.
Внесите изменение в файл hello.html в виде нежелательного комментария.
ФАЙЛ: HTML
<html>
<head>
</head>
<body>
<h1>Hello, World!</h1>
<!-- This is a bad comment. We want to revert it. -->
</body>
</html>
14.03 Проверьте состояние
Сначала проверьте состояние рабочего каталога.
ВЫПОЛНИТЕ:
РЕЗУЛЬТАТ:
$ 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")
Мы видим, что файл hello.html был изменен, но еще не проиндексирован.
14.04 Отмена изменений в рабочем каталоге
Используйте команду checkout для переключения в версию файла hello.html в репозитории.
ВЫПОЛНИТЕ:
git checkout hello.html
git status
cat hello.html
РЕЗУЛЬТАТ:
$ git checkout hello.html
$ git status
# On branch master
nothing to commit (working directory clean)
$ cat hello.html
<html>
<head>
</head>
<body>
<h1>Hello, World!</h1>
</body>
</html>
Команда status показывает нам, что не было произведено никаких изменений, не зафиксированных в рабочем каталоге. И «нежелательный комментарий» больше не является частью содержимого файла.
15. Отмена проиндексированных изменений (перед коммитом)
Цели: Научиться отменять изменения, которые были проиндексированы
15.01 Измените файл и проиндексируйте изменения
Внесите изменение в файл hello.html в виде нежелательного комментария
ФАЙЛ: HTML
<html>
<head>
<!-- This is an unwanted but staged comment -->
</head>
<body>
<h1>Hello, World!</h1>
</body>
</html>
Проиндексируйте это изменение.
ВЫПОЛНИТЕ:
15.02 Проверьте состояние
Проверьте состояние нежелательного изменения.
ВЫПОЛНИТЕ:
РЕЗУЛЬТАТ:
$ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# modified: hello.html
#
Состояния показывает, что изменение было проиндексировано и готово к коммиту.
15.03 Выполните сброс буферной зоны
К счастью, вывод состояние показывает нам именно то, что мы должны сделать для отмены индексации изменения.
ВЫПОЛНИТЕ:
git reset HEAD hello.html
РЕЗУЛЬТАТ:
$ git reset HEAD hello.html
Unstaged changes after reset:
M hello.html
Команда reset сбрасывает буферную зону к HEAD. Это очищает буферную зону от изменений, которые мы только что проиндексировали.
Команда reset (по умолчанию) не изменяет рабочий каталог. Поэтому рабочий каталог все еще содержит нежелательный комментарий. Мы можем использовать команду checkout из предыдущего урока, чтобы удалить нежелательные изменения в рабочем каталоге.
15.04 Переключитесь на версию коммита
ВЫПОЛНИТЕ:
git checkout hello.html
git status
РЕЗУЛЬТАТ:
$ git status
# On branch master
nothing to commit (working directory clean)
Наш рабочий каталог опять чист.
16. Отмена коммитов
Цели: Научиться отменять коммиты в локальный репозиторий.
16.01 Отмена коммитов
Иногда вы понимаете, что новые коммиты являются неверными, и хотите их отменить. Есть несколько способов решения этого вопроса, здесь мы будем использовать самый безопасный.
Мы отменим коммит путем создания нового коммита, отменяющего нежелательные изменения.
16.02 Измените файл и сделайте коммит
Измените файл hello.html на следующий.
ФАЙЛ: HTML
<html>
<head>
</head>
<body>
<h1>Hello, World!</h1>
<!-- This is an unwanted but committed change -->
</body>
</html>
ВЫПОЛНИТЕ:
git add hello.html
git commit -m "Oops, we didnt want this commit"
16.03 Сделайте коммит с новыми изменениями, отменяющими предыдущие
Чтобы отменить коммит, нам необходимо сделать коммит, который удаляет изменения, сохраненные нежелательным коммитом.
ВЫПОЛНИТЕ:
Перейдите в редактор, где вы можете отредактировать коммит-сообщение по умолчанию или оставить все как есть. Сохраните и закройте файл. Вы увидите…
РЕЗУЛЬТАТ:
$ git revert HEAD --no-edit
[master 45fa96b] Revert "Oops, we didnt want this commit"
1 files changed, 1 insertions(+), 1 deletions(-)
Так как мы отменили самый последний произведенный коммит, мы смогли использовать HEAD в качестве аргумента для отмены. Мы можем отменить любой произвольной коммит в истории, указав его хэш-значение.
Примечание: Команду --no-edit можно проигнорировать. Она была необходима для генерации выходных данных без открытия редактора.
16.04 Проверьте лог
Проверка лога показывает нежелательные и отмененные коммиты в наш репозиторий.
ВЫПОЛНИТЕ:
РЕЗУЛЬТАТ:
$ git hist
* 45fa96b 2011-03-09 | Revert "Oops, we didnt want this commit" (HEAD, master) [Alexander Shvets]
* 846b90c 2011-03-09 | Oops, we didnt want this commit [Alexander Shvets]
* fa3c141 2011-03-09 | Added HTML header (v1) [Alexander Shvets]
* 8c32287 2011-03-09 | Added standard HTML page tags (v1-beta) [Alexander Shvets]
* 43628f7 2011-03-09 | Added h1 tag [Alexander Shvets]
* 911e8c9 2011-03-09 | First Commit [Alexander Shvets]
Эта техника будет работать с любым коммитом (хотя, возможно, возникнут конфликты). Она безопасна в использовании даже в публичных ветках удаленных репозиториев.
16.05 Далее
Далее давайте посмотрим на технику, которая может быть использована для удаления последних коммитов из истории репозитория.
17. Удаление коммиттов из ветки
Цели: Научиться удалять самые последние коммиты из ветки
Revert из предыдущего раздела является мощной командой, которая позволяет отменить любые коммиты в репозиторий. Однако, и оригинальный и «отмененный» коммиты видны в истории ветки (при использовании команды git log).
Часто мы делаем коммит, и сразу понимаем, что это была ошибка. Было бы неплохо иметь команду «возврата», которая позволила бы нам сделать вид, что неправильного коммита никогда и не было. Команда «возврата» даже предотвратила бы появление нежелательного коммита в истории git log.
17.01 Команда reset
Мы уже видели команду reset и использовали ее для согласования буферной зоны и выбранного коммита (мы использовали коммит HEAD в нашем предыдущем уроке).
При получении ссылки на коммит (т.е. хэш, ветка или имя тега), команда reset…
- Перепишет текущую ветку, чтобы она указывала на нужный коммит
- Опционально сбросит буферную зону для соответствия с указанным коммитом
- Опционально сбросит рабочий каталог для соответствия с указанным коммитом
17.02 Проверьте нашу историю
Давайте сделаем быструю проверку нашей истории коммитов.
ВЫПОЛНИТЕ:
РЕЗУЛЬТАТ:
$ git hist
* 45fa96b 2011-03-09 | Revert "Oops, we didn't want this commit" (HEAD, master) [Alexander Shvets]
* 846b90c 2011-03-09 | Oops, we didn't want this commit [Alexander Shvets]
* fa3c141 2011-03-09 | Added HTML header (v1) [Alexander Shvets]
* 8c32287 2011-03-09 | Added standard HTML page tags (v1-beta) [Alexander Shvets]
* 43628f7 2011-03-09 | Added h1 tag [Alexander Shvets]
* 911e8c9 2011-03-09 | First Commit [Alexander Shvets]
Мы видим, что два последних коммита в этой ветке - «Oops» и «Revert Oops». Давайте удалим их с помощью сброса.
17.03 Для начала отметьте эту ветку
Но прежде чем удалить коммиты, давайте отметим последний коммит тегом, чтобы потом можно было его найти.
ВЫПОЛНИТЕ:
17.04 Сброс коммитов к предшествующим коммиту Oops
Глядя на историю лога (см. выше), мы видим, что коммит с тегом «v1» является коммитом, предшествующим ошибочному коммиту. Давайте сбросим ветку до этой точки. Поскольку ветка имеет тег, мы можем использовать имя тега в команде сброса (если она не имеет тега, мы можем использовать хэш-значение).
ВЫПОЛНИТЕ:
git reset --hard v1
git hist
РЕЗУЛЬТАТ:
$ git reset --hard v1
HEAD is now at fa3c141 Added HTML header
$ git hist
* fa3c141 2011-03-09 | Added HTML header (HEAD, v1, master) [Alexander Shvets]
* 8c32287 2011-03-09 | Added standard HTML page tags (v1-beta) [Alexander Shvets]
* 43628f7 2011-03-09 | Added h1 tag [Alexander Shvets]
* 911e8c9 2011-03-09 | First Commit [Alexander Shvets]
Наша ветка master теперь указывает на коммит v1, а коммитов Oops и Revert Oops в ветке уже нет. Параметр --hard указывает, что рабочий каталог должен быть обновлен в соответствии с новым head ветки.
17.05 Ничего никогда не теряется
Что же случается с ошибочными коммитами? Оказывается, что коммиты все еще находятся в репозитории. На самом деле, мы все еще можем на них ссылаться. Помните, в начале этого урока мы создали для отмененного коммита тег «oops». Давайте посмотрим на все коммиты.
ВЫПОЛНИТЕ:
РЕЗУЛЬТАТ:
$ git hist --all
* 45fa96b 2011-03-09 | Revert "Oops, we didn't want this commit" (oops) [Alexander Shvets]
* 846b90c 2011-03-09 | Oops, we didn't want this commit [Alexander Shvets]
* fa3c141 2011-03-09 | Added HTML header (HEAD, v1, master) [Alexander Shvets]
* 8c32287 2011-03-09 | Added standard HTML page tags (v1-beta) [Alexander Shvets]
* 43628f7 2011-03-09 | Added h1 tag [Alexander Shvets]
* 911e8c9 2011-03-09 | First Commit [Alexander Shvets]
Мы видим, что ошибочные коммиты не исчезли. Они все еще находятся в репозитории. Просто они отсутствуют в ветке master. Если бы мы не отметили их тегами, они по-прежнему находились бы в репозитории, но не было бы никакой возможности ссылаться на них, кроме как при помощи их хэш имен. Коммиты, на которые нет ссылок, остаются в репозитории до тех пор, пока не будет запущен сборщик мусора.
17.06 Опасность сброса
Сброс в локальных ветках, как правило, безопасен. Последствия любой «аварии» как правило, можно восстановить простым сбросом с помощью нужного коммита.
Однако, если ветка «расшарена» на удаленных репозиториях, сброс может сбить с толку других пользователей ветки.
18. Удаление тега oops
Цели: Удаление тега oops (уборка)
18.01 Удаление тега oops
Тег oops свою функцию выполнил. Давайте удалим его и коммиты, на которые он ссылался, сборщиком мусора.
ВЫПОЛНИТЕ:
git tag -d oops
git hist --all
РЕЗУЛЬТАТ:
$ git tag -d oops
Deleted tag 'oops' (was 45fa96b)
$ git hist --all
* fa3c141 2011-03-09 | Added HTML header (HEAD, v1, master) [Alexander Shvets]
* 8c32287 2011-03-09 | Added standard HTML page tags (v1-beta) [Alexander Shvets]
* 43628f7 2011-03-09 | Added h1 tag [Alexander Shvets]
* 911e8c9 2011-03-09 | First Commit [Alexander Shvets]
Тег «oops» больше не будет отображаться в репозитории.
19. Внесение изменений в коммиты
Цели: Научиться изменять существующие коммиты
19.01 Измените страницу, а затем сделайте коммит
Добавьте в страницу комментарий автора.
ФАЙЛ: HTML
<!-- Author: Alexander Shvets -->
<html>
<head>
</head>
<body>
<h1>Hello, World!</h1>
</body>
</html>
ВЫПОЛНИТЕ:
git add hello.html
git commit -m "Add an author comment"
19.02 Ой... необходим email
После совершения коммита вы понимаете, что любой хороший комментарий должен включать электронную почту автора. Обновите страницу hello, включив в нее email.
ФАЙЛ: HTML
<!-- Author: Alexander Shvets (alex@githowto.com) -->
<html>
<head>
</head>
<body>
<h1>Hello, World!</h1>
</body>
</html>
19.03 Измените предыдущий коммит
Мы действительно не хотим создавать отдельный коммит только ради электронной почты. Давайте изменим предыдущий коммит, включив в него адрес электронной почты.
ВЫПОЛНИТЕ:
git add hello.html
git commit --amend -m "Add an author/email comment"
РЕЗУЛЬТАТ:
$ git add hello.html
$ git commit --amend -m "Add an author/email comment"
[master 6a78635] Add an author/email comment
1 files changed, 2 insertions(+), 1 deletions(-)
19.04 Просмотр истории
ВЫПОЛНИТЕ:
РЕЗУЛЬТАТ:
$ git hist
* 6a78635 2011-03-09 | Add an author/email comment (HEAD, master) [Alexander Shvets]
* fa3c141 2011-03-09 | Added HTML header (v1) [Alexander Shvets]
* 8c32287 2011-03-09 | Added standard HTML page tags (v1-beta) [Alexander Shvets]
* 43628f7 2011-03-09 | Added h1 tag [Alexander Shvets]
* 911e8c9 2011-03-09 | First Commit [Alexander Shvets]
Мы можем увидеть, что оригинальный коммит «автор» заменен коммитом «автор/email». Этого же эффекта можно достичь путем сброса последнего коммита в ветке, и повторного коммита новых изменений.
20. Перемещение файлов
Цели: Научиться перемещать файл в пределах репозитория.
20.01 Переместите файл hello.html в каталог lib
Сейчас мы собираемся создать структуру нашего репозитория. Давайте перенесем страницу в каталог lib.
ВЫПОЛНИТЕ:
mkdir lib
git mv hello.html lib
git status
РЕЗУЛЬТАТ:
$ mkdir lib
$ git mv hello.html lib
$ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# renamed: hello.html -> lib/hello.html
#
Перемещая файлы с помощью git, мы информируем git о 2 вещах
- Что файл hello.html был удален.
- Что файл lib/hello.html был создан.
Оба эти факта сразу же проиндексированы и готовы к коммиту. Команда git status сообщает, что файл был перемещен.
20.02 Второй способ перемещения файлов
Позитивной чертой git является то, что вы можете забыть о версионном контроле до того момента, когда вы готовы приступить к коммиту кода. Что бы случилось, если бы мы использовали командную строку операционной системы для перемещения файлов вместо команды git?
Оказывается, следующий набор команд идентичен нашим последним действиям. Работы здесь побольше, но результат тот же.
Мы могли бы выполнить:
mkdir lib
mv hello.html lib
git add lib/hello.html
git rm hello.html
20.03 Коммит в новый каталог
Давайте сделаем коммит этого перемещения.
ВЫПОЛНИТЕ:
git commit -m "Moved hello.html to lib"
Назад: Шаг 1-10 ..
Вперед: Шаг 21-30