Skip to content

Instantly share code, notes, and snippets.

@Artnoc1
Last active January 15, 2022 20:49
Show Gist options
  • Save Artnoc1/f1d564215d2aa04c8a3624fa9c2d6654 to your computer and use it in GitHub Desktop.
Save Artnoc1/f1d564215d2aa04c8a3624fa9c2d6654 to your computer and use it in GitHub Desktop.
GITHOWTO

"47. Добавление удаленного репозитория"


Добавить чистый репозиторий в качестве удаленного репозитория к нашему оригинальному репозиторию. Давайте добавим репозиторий hello.git к нашему оригинальному репозиторию.


cd hello
git remote add shared ../hello.git

Примечание: Сейчас мы находимся в репозитории hello.

"45. Добавление ветки наблюдения"


Научиться добавлять локальную ветку, которая отслеживает изменения удаленной ветки. Ветки, которые начинаются с remotes/origin являются ветками оригинального репозитория. Обратите внимание, что у вас больше нет ветки под названием style, но система контроля версий знает, что в оригинальном репозитории ветка style была.

01 Добавьте локальную ветку, которая отслеживает удаленную ветку.


git branch --track style origin/style
git branch -a
git hist --max-count=2

$ git branch --track style origin/style
Branch style set up to track remote branch style from origin.
$ git branch -a
  style
* master
  remotes/origin/HEAD -> origin/master
  remotes/origin/style
  remotes/origin/master
$ git hist --max-count=2
* 2faa4ea 2011-03-09 | Changed README in original repo (HEAD, origin/master, origin/HEAD, master) [Alexander Shvets]
* 6e6c76a 2011-03-09 | Updated index.html (origin/style, style) [Alexander Shvets]

Теперь мы можем видеть ветку style в списке веток и логе.

"11. Алиасы"


Научиться настраивать алиасы и шорткаты для команд git

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.

Попробуйте использовать новые команды.

02 Задайте алиас hist в файле .gitconfig

По большей части, я буду продолжать печатать полные команды в этом руководстве. Единственным исключением будет использование алиаса hist, указанного выше, когда мне понадобится посмотреть git лог. Если вы хотите повторять мои действия, убедитесь, что алиас hist установлен в вашем файле .gitconfig.

03 Type и Dump

Мы добавили несколько алиасов для команд, которых мы еще не рассматривали. С командой git branch разберемся чуть позже, а команда git cat-file используется для исследования git, в чем мы вскоре убедимся.

04 Алиасы команд (опционально)

Если ваша оболочка поддерживает алиасы или шорткаты, вы можете добавить алиасы и на этом уровне. Я использую:

Файл: .profile

alias gs='git status '
alias ga='git add '
alias gb='git branch '
alias gc='git commit'
alias gd='git diff'
alias gco='git checkout '
alias gk='gitk --all&'
alias gx='gitx --all'
#alias got='git '
#alias get='git '

Сокращение gco для команды git checkout особенно полезно. Оно позволяет мне вводить:

gco <branch> для переключения в отдельную ветку.

И да, я достаточно часто пишу вместо git get или got, поэтому создам алиасы и для них.

"19. Внесение изменений в коммиты"


Научиться изменять существующие коммиты

01 Измените страницу, а затем сделайте коммит

Добавьте в страницу комментарий автора.

Файл: hello.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"

02 Ой... необходим email

После совершения коммита вы понимаете, что любой хороший комментарий должен включать электронную почту автора. Обновите страницу hello, включив в нее email.

Файл: hello.html

<!-- Author: Alexander Shvets ([email protected]) -->
<html>
  <head>
  </head>
  <body>
    <h1>Hello, World!</h1>
  </body>
</html>

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(-)

04 Просмотр истории


git hist

$ 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». Этого же эффекта можно достичь путем сброса последнего коммита в ветке, и повторного коммита новых изменений.

"46. Чистые репозитории"


Научиться создавать чистые репозитории. Чистые репозитории (без рабочих каталогов) обычно используются для расшаривания.

Небольшое пояснение, что же все-таки означает «чистый репозиторий». Обычный git-репозиторий подразумевает, что вы будете использовать его как рабочую директорию, поэтому вместе с файлами проекта в актуальной версии, git хранит все служебные, «чисто-репозиториевские» файлы в поддиректории .git. В удаленных репозиториях нет смысла хранить рабочие файлы на диске (как это делается в рабочих копиях), а все что им действительно нужно — это дельты изменений и другие бинарные данные репозитория. Вот это и есть «чистый репозиторий».

01 Создайте чистый репозиторий


cd ..
git clone --bare hello hello.git
ls hello.git

Примечание: Сейчас мы находимся в рабочем каталоге


$ git clone --bare hello hello.git
Cloning into bare repository hello.git...
done.
$ ls hello.git
HEAD
config
description
hooks
info
objects
packed-refs
refs

Как правило, репозитории, оканчивающиеся на «.git» являются чистыми репозиториями. Мы видим, что в репозитории hello.git нет рабочего каталога. По сути, это есть не что иное, как каталог .git нечистого репозитория.

"26. Изменения в ветке master"


Научиться работать с несколькими ветками с различными (и, возможно, конфликтующими) изменениями. Пока вы меняли ветку «style», кто-то решил обновить ветку master. Они добавили README.

01 Создайте файл README в ветке master.


git checkout master

Файл: README This is the Hello World example from the git tutorial.

02 Сделайте коммит изменений README в ветку master.


git add README
git commit -m "Added README"

"9. Изменения, а не файлы"


Понять, что git работает с изменениями, а не файлами. Большинство систем версионного контроля работают с файлами. Вы добавляете файл в версионный контроль, а система отслеживает изменения файла с этого момента.

Git фокусируется на изменениях в файле, а не самом файле. Когда вы осуществляете команду git add file, вы не говорите git добавить файл в репозиторий. Скорее вы говорите, что git надо отметить текущее состояние файла, коммит которого будет произведен позже.

Мы попытаемся исследовать эту разницу в данном уроке.

01 Первое изменение: Добавьте стандартные теги страницы

Измените страницу «Hello, World», чтобы она содержала стандартные теги и .

Файл: hello.html

<html>
  <body>
    <h1>Hello, World!</h1>
  </body>
</html>

02 Добавьте это изменение

Теперь добавьте это изменение в индекс git.


git add hello.html

03 Второе изменение: Добавьте заголовки HTML

Теперь добавьте заголовки HTML (секцию ) к странице «Hello, World».

Файл: hello.html

<html>
  <head>
  </head>
  <body>
    <h1>Hello, World!</h1>
  </body>
</html>

04 Проверьте текущий статус


git status

Вы увидите…


$ git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#	modified:   hello.html
#
# 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
#

Обратите внимание на то, что hello.html указан дважды в состоянии. Первое изменение (добавление стандартных тегов) проиндексировано и готово к коммиту. Второе изменение (добавление заголовков HTML) является непроиндексированным. Если бы вы делали коммит сейчас, заголовки не были бы сохранены в репозиторий.

Давайте проверим.

05 Коммит

Произведите коммит проиндексированного изменения (значение по умолчанию), а затем еще раз проверьте состояние.


git commit -m "Added standard HTML page tags"
git status

Вы увидите…


$ git commit -m "Added standard HTML page tags"
[master 8c32287] Added standard HTML page tags
 1 files changed, 3 insertions(+), 1 deletions(-)
$ 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 имеет незафиксированные изменения, но уже не в буферной зоне.

06 Добавьте второе изменение

Теперь добавьте второе изменение в индекс, а затем проверьте состояние с помощью команды git status.


git add .
git status

Примечание: В качестве файла для добавления, мы использовали текущий каталог («.»). Это самый краткий и удобный способ добавления всех изменений в файлы текущего каталога и его подкаталоги. Но поскольку он добавляет все, не лишним будет проверить состояние перед запуском add, просто чтобы убедиться, что вы не добавили какой-то файл, который добавлять было не нужно.

Я хотел показать вам трюк с add, далее мы будем на всякий случай продолжать добавлять явные файлы.

Вы увидите…


$ git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#	modified:   hello.html
#

Второе изменение было проиндексировано и готово к коммиту.

07 Сделайте коммит второго изменения


git commit -m "Added HTML header"

"4. Проверка состояния"


Научиться проверять состояние репозитория

01 Проверьте состояние репозитория

Используйте команду git status, чтобы проверить текущее состояние репозитория.


git status

Вы увидите


$ git status
# On branch master
nothing to commit (working directory clean)

Команда проверки состояния сообщит, что коммитить нечего. Это означает, что в репозитории хранится текущее состояние рабочего каталога, и нет никаких изменений, ожидающих записи.

Мы будем использовать команду git status, чтобы продолжать отслеживать состояние репозитория и рабочего каталога.

"37. Клонирование репозиториев"


Научиться делать копии репозиториев. Если вы работаете в команде, последующие 12 глав довольно важны в понимании, т.к. вы почти всегда будете работать с клонированными репозиториями.

01 Перейдите в рабочий каталог

Перейдите в рабочий каталог и сделайте клон вашего репозитория hello.


cd ..
pwd
ls

Примечание: Сейчас мы находимся в рабочем каталоге.


$ cd ..
$ pwd
/Users/alex/Documents/Presentations/githowto/auto
$ ls
hello

В этот момент вы должны находиться в «рабочем» каталоге. Здесь должен быть единственный репозиторий под названием «hello».

02 Создайте клон репозитория hello

Давайте создадим клон репозитория.


git clone hello cloned_hello
ls

$ git clone hello cloned_hello
Cloning into cloned_hello...
done.
$ ls
cloned_hello
hello

В вашем рабочем каталоге теперь должно быть два репозитория: оригинальный репозиторий «hello» и клонированный репозиторий «cloned_hello»

"8. Коммит изменений"


Научиться коммитить изменения в репозиторий

01 Закоммитьте изменения

Достаточно об индексации. Давайте сделаем коммит того, что мы проиндексировали, в репозиторий.

Когда вы ранее использовали git commit для коммита первоначальной версии файла hello.html в репозиторий, вы включили метку -m, которая делает комментарий в командной строке. Команда commit позволит вам интерактивно редактировать комментарии для коммита. Теперь давайте это проверим.

Если вы опустите метку -m из командной строки, git перенесет вас в редактор по вашему выбору. Редактор выбирается из следующего списка (в порядке приоритета):

переменная среды GIT_EDITOR параметр конфигурации core.editor переменная среды VISUAL переменная среды EDITOR У меня переменная EDITOR установлена в emacsclient (доступен для Linux и Mac).

Сделайте коммит сейчас и проверьте состояние.


git commit

Вы увидите в вашем редакторе:


|
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#	modified:   hello.html
#

В первой строке введите комментарий: «Added h1 tag». Сохраните файл и выйдите из редактора (для этого в редакторе по умолчанию (Vim) вам нужно нажать клавишу ESC, ввести :wq и нажать Enter). Вы увидите…


git commit
Waiting for Emacs...
[master 569aa96] Added h1 tag
 1 files changed, 1 insertions(+), 1 deletions(-)

Строка «Waiting for Emacs…» получена из программы emacsclient, которая посылает файл в запущенную программу emacs и ждет его закрытия. Остальные выходные данные – стандартные коммит-сообщения.

02 Проверьте состояние

В конце давайте еще раз проверим состояние.


git status

Вы увидите…


$ git status
# On branch master
nothing to commit (working directory clean)

Рабочий каталог чистый, можете продолжить работу.

"3. Создание проекта"


Научиться создавать git репозиторий с нуля.

01 Создайте страницу «Hello, World»

Начните работу в пустом рабочем каталоге (например Work, если вы скачали архив с предыдущего шага) с создания пустого каталога с именем «hello», затем войдите в него и создайте там файл с именем hello.html с таким содержанием.


mkdir hello
cd hello
touch hello.html

Файл: hello.html

Hello, World

02 Создайте репозиторий

Теперь у вас есть каталог с одним файлом. Чтобы создать git репозиторий из этого каталога, выполните команду git init.


git init

$ git init
Initialized empty Git repository in /Users/alex/Documents/Presentations/githowto/auto/hello/.git/

03 Добавьте страницу в репозиторий

Теперь давайте добавим в репозиторий страницу «Hello, World».


git add hello.html
git commit -m "First Commit"

Вы увидите …


$ git add hello.html
$ git commit -m "First Commit"
[master (root-commit) 911e8c9] First Commit
 1 files changed, 1 insertions(+), 0 deletions(-)
 create mode 100644 hello.html

"24. Создание ветки"


Научиться создавать локальную ветку в репозитории Пора сделать наш hello world более выразительным. Так как это может занять некоторое время, лучше переместить эти изменения в отдельную ветку, чтобы изолировать их от изменений в ветке master.

01 Создайте ветку

Давайте назовем нашу новую ветку «style».


git checkout -b style
git status

Примечание: git checkout -b <имяветки> является шорткатом для git branch <имяветки> за которым идет git checkout <имяветки>.

Обратите внимание, что команда git status сообщает о том, что вы находитесь в ветке «style».

02 Добавьте файл стилей style.css


touch lib/style.css

Файл: lib/style.css

h1 {
  color: red;
}

git add lib/style.css
git commit -m "Added css stylesheet"

03 Измените основную страницу

Обновите файл hello.html, чтобы использовать стили style.css.

Файл: lib/hello.html

<!-- Author: Alexander Shvets ([email protected]) -->
<html>
  <head>
    <link type="text/css" rel="stylesheet" media="all" href="style.css" />
  </head>
  <body>
    <h1>Hello, World!</h1>
  </body>
</html>

git add lib/hello.html
git commit -m "Hello uses style.css"

04 Измените index.html

Обновите файл index.html, чтобы он тоже использовал style.css

Файл: index.html

<html>
  <head>
    <link type="text/css" rel="stylesheet" media="all" href="lib/style.css" />
  </head>
  <body>
    <iframe src="lib/hello.html" width="200" height="200" />
  </body>
</html>

git add index.html
git commit -m "Updated index.html"

05 Далее

Теперь у нас есть новая ветка под названием style с 3 новыми коммитами. Далее мы узнаем, как осуществлять навигацию и переключаться между ветками.

"29. Создание конфликта"


Создание конфликтующих изменений в ветке master.

01 Вернитесь в master и создайте конфликт

Вернитесь в ветку master и внесите следующие изменения:

git checkout master

Файл: lib/hello.html

<!-- Author: Alexander Shvets ([email protected]) -->
<html>
  <head>
    <!-- no style -->
  </head>
  <body>
    <h1>Hello, World! Life is great!</h1>
  </body>
</html>

git add lib/hello.html
git commit -m 'Life is great!'

Внимание: используйте для этого коммита одинарные кавычки, дабы избежать проблем с символом !. В bash он считается служебным.

02 Просмотр веток


git hist --all

$ git hist --all
* 454ec68 2011-03-09 | Life is great! (HEAD, master) [Alexander Shvets]
| * 5813a3f 2011-03-09 | Merge branch 'master' into style (style) [Alexander Shvets]
| |\  
| |/  
|/| 
* | 6c0f848 2011-03-09 | Added README [Alexander Shvets]
| * 07a2a46 2011-03-09 | Updated index.html [Alexander Shvets]
| * 649d26c 2011-03-09 | Hello uses style.css [Alexander Shvets]
| * 1f3cbd2 2011-03-09 | Added css stylesheet [Alexander Shvets]
|/  
* 8029c07 2011-03-09 | Added index.html. [Alexander Shvets]
* 567948a 2011-03-09 | Moved hello.html to lib [Alexander Shvets]
* 6a78635 2011-03-09 | Add an author/email comment [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]

После коммита «Added README» ветка master была объединена с веткой style, но в настоящее время в master есть дополнительный коммит, который не был слит с style.

03 Далее

Последнее изменение в master конфликтует с некоторыми изменениями в style. На следующем шаге мы решим этот конфликт.

"42. Извлечение изменений"


Научиться извлекать изменения из удаленного репозитория.


cd ../cloned_hello
git fetch
git hist --all

Примечание: Сейчас мы находимся в репозитории cloned_hello


$ git fetch
From /Users/alex/Documents/Presentations/githowto/auto/hello
   6e6c76a..2faa4ea  master     -> origin/master
$ git hist --all
* 2faa4ea 2011-03-09 | Changed README in original repo (origin/master, origin/HEAD) [Alexander Shvets]
* 6e6c76a 2011-03-09 | Updated index.html (HEAD, origin/style, master) [Alexander Shvets]
* 1436f13 2011-03-09 | Hello uses style.css [Alexander Shvets]
* 59da9a7 2011-03-09 | Added css stylesheet [Alexander Shvets]
* 6c0f848 2011-03-09 | Added README [Alexander Shvets]
* 8029c07 2011-03-09 | Added index.html. [Alexander Shvets]
* 567948a 2011-03-09 | Moved hello.html to lib [Alexander Shvets]
* 6a78635 2011-03-09 | Add an author/email comment [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]

На данный момент в репозитории есть все коммиты из оригинального репозитория, но они не интегрированы в локальные ветки клонированного репозитория.

В истории выше найдите коммит «Changed README in original repo». Обратите внимание, что коммит включает в себя коммиты «origin/master» и «origin/HEAD».

Теперь давайте посмотрим на коммит «Updated index.html». Вы увидите, что локальная ветка master указывает на этот коммит, а не на новый коммит, который мы только что извлекли.

Выводом является то, что команда «git fetch» будет извлекать новые коммиты из удаленного репозитория, но не будет сливать их с вашими наработками в локальных ветках.

01 Проверьте README

Мы можем продемонстрировать, что клонированный файл README не изменился.


cat README

$ cat README
This is the Hello World example from the git tutorial.

Как видите, никаких изменений.

"12. Получение старых версий"


Научиться возвращать рабочий каталог к любому предыдущему состоянию. Возвращаться назад в историю очень просто. Команда checkout скопирует любой снимок из репозитория в рабочий каталог.

01 Получите хэши предыдущих версий


git hist

Примечание: Вы не забыли задать 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

Примечание: Многие команды зависят от хэшевых значений в репозитории. Поскольку ваши хеш-значения будут отличаться от моих, когда вы видите что-то вроде или в команде, подставьте необходимое значение хэш для вашего репозитория.

Вы увидите…


$ 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 является значением по умолчанию.

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» — имя ветки по умолчанию. Переключая имена веток, вы попадаете на последнюю версию выбранной ветки.

"22. Git внутри: Каталог .git"


Узнать о структуре каталога .git

01 Каталог .git

Настало время провести небольшое исследование. Для начала, из корневого каталога вашего проекта…


ls -C .git

$ ls -C .git
COMMIT_EDITMSG	MERGE_RR	config		hooks		info		objects		rr-cache
HEAD		ORIG_HEAD	description	index		logs		refs

Это магический каталог, в котором хранятся все «материалы» git. Давайте заглянем в каталог объектов.

02 База данных объектов


ls -C .git/objects

$ ls -C .git/objects
09	24	28	45	59	6a	77	80	8c	97	af	c4	e7	info
11	27	43	56	69	6b	78	84	91	9c	b5	e4	fa	pack

Вы должны увидеть кучу каталогов, имена которых состоят из 2 символов. Имена каталогов являются первыми двумя буквами хэша sha1 объекта, хранящегося в git.

03 Углубляемся в базу данных объектов


ls -C .git/objects/<dir>

$ ls -C .git/objects/09
6b74c56bfc6b40e754fc0725b8c70b2038b91e	9fb6f9d3a104feb32fcac22354c4d0e8a182c1

Смотрим в один из каталогов с именем из 2 букв. Вы увидите файлы с именами из 38 символов. Это файлы, содержащие объекты, хранящиеся в git. Они сжаты и закодированы, поэтому просмотр их содержимого нам мало чем поможет. Рассмотрим далее каталог .git внимательно

04 Config File


cat .git/config

$ cat .git/config
[core]
	repositoryformatversion = 0
	filemode = true
	bare = false
	logallrefupdates = true
	ignorecase = true
[user]
	name = Alexander Shvets
	email = [email protected]

Это файл конфигурации, создающийся для каждого конкретного проекта. Записи в этом файле будут перезаписывать записи в файле .gitconfig вашего главного каталога, по крайней мере в рамках этого проекта.

05 Ветки и теги


ls .git/refs
ls .git/refs/heads
ls .git/refs/tags
cat .git/refs/tags/v1

$ ls .git/refs
heads
tags
$ ls .git/refs/heads
master
$ ls .git/refs/tags
v1
v1-beta
$ cat .git/refs/tags/v1
fa3c1411aa09441695a9e645d4371e8d749da1dc

Вы должны узнавать файлы в подкаталоге тегов. Каждый файл соответствует тегу, ранее созданному с помощью команды git tag. Его содержание – это всего лишь хэш коммита, привязанный к тегу.

Каталог heads практически аналогичен, но используется для веток, а не тегов. На данный момент у нас есть только одна ветка, так что все, что вы увидите в этом каталоге – это ветка master.

06 Файл HEAD


cat .git/HEAD

$ cat .git/HEAD
ref: refs/heads/master

Файл HEAD содержит ссылку на текущую ветку, в данный момент это должна быть ветка master.

"10. История"


Научиться просматривать историю проекта. Получение списка произведенных изменений — функция команды git log.


git log

Вы увидите…


$ git log
commit fa3c1411aa09441695a9e645d4371e8d749da1dc
Author: Alexander Shvets <[email protected]>
Date:   Wed Mar 9 10:27:54 2011 -0500

    Added HTML header

commit 8c3228730ed03116815a5cc682e8105e7d981928
Author: Alexander Shvets <[email protected]>
Date:   Wed Mar 9 10:27:54 2011 -0500

    Added standard HTML page tags

commit 43628f779cb333dd30d78186499f93638107f70b
Author: Alexander Shvets <[email protected]>
Date:   Wed Mar 9 10:27:54 2011 -0500

    Added h1 tag

commit 911e8c91caeab8d30ad16d56746cbd6eef72dc4c
Author: Alexander Shvets <[email protected]>
Date:   Wed Mar 9 10:27:54 2011 -0500

    First Commit

Вот список всех четырех коммитов в репозиторий, которые мы успели совершить.

01 Однострочная история

Вы полностью контролируете то, что отображает 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

02 Контроль отображения записей

Есть много вариантов выбора, какие элементы отображаются в логе. Поиграйте со следующими параметрами:

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.

03 Изощряемся

Вот что я использую для просмотра изменений, сделанных за последнюю неделю. Я добавлю --author=alex, если я хочу увидеть только изменения, которые сделал я.

git log --all --pretty=format:"%h %cd %s (%an)" --since='7 days ago'

04 Конечный формат лога

Со временем, я решил, что для большей части моей работы мне подходит следующий формат лога.


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 алиасах в следующем уроке.

05 Другие инструменты

Оба gitx (для Mac) и gitk (для любой платформы) полезны в изучении истории изменений.

"50. Размещение ваших git репозиториев"


Научиться настраивать git сервер для совместного использования репозиториев. Есть много способов расшаривать git репозитории по сети. Вот быстрый способ.

01 Запуск git сервера


# (From the work directory)
git daemon --verbose --export-all --base-path=.

Теперь в отдельном окне терминала перейдите в ваш рабочий каталог


# (From the work directory)
git clone git://localhost/hello.git network_hello
cd network_hello
ls

Вы увидите копию проекта hello.

02 Отправка в Git Daemon

Если вы хотите разрешить отправку (push) в репозиторий Git Daemon, добавьте метку --enable=receive-pack к команде git daemon. Будьте осторожны, этот сервер не производит аутентификацию, поэтому любой сможет отправлять изменения в ваш репозиторий.

"Git How To: курс обучения Git на русском" description: "Git How To — это интерактивный тур, который познакомит вас с основами Git. Тур создан с пониманием того, что лучший способ научиться использовать Git — попробовать его своими руками." blade: true


Что это? Git How To — это интерактивный тур, который познакомит вас с основами Git. Тур создан с пониманием того, что лучшим способом научиться чему-нибудь — сделать это своими руками.

Кстати, если вы знаете английский и Ruby, вам может быть удобней пройти курс на Git Immersion.

Git? Git — мощная и сложная распределенная система контроля версий. Понимание всех возможностей git открывает для разработчика новые горизонты в управлении исходным кодом. Самый верный способ обучиться владению Git — испытать его своими руками.

Для начала установите Git-клиент Linux yum install git apt-get install git zypper in git Mac Git for Mac OS X brew install git Windows git for windows Поехали! @if (config('app.ads_ru') == 'Google')

@elseif (config('app.ads_ru') == 'CarbonAds')

@endif

"5. Внесение изменений"


Научиться отслеживать состояние рабочего каталога

01 Измените страницу «Hello, World»

Добавим кое-какие HTML-теги к нашему приветствию. Измените содержимое файла на:

Файл: hello.html

<h1>Hello, World!</h1>

02 Проверьте состояние

Теперь проверьте состояние рабочего каталога.


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 для отмены изменений.

03 А далее...

Давайте проиндексируем изменения.

"35. Слияние в ветку master"


Мы поддерживали соответствие ветки style с веткой master (с помощью rebase), теперь давайте сольем изменения style в ветку master.

01 Слияние style в master


git checkout master
git merge style

$ git checkout master
Switched to branch 'master'
$
$ git merge style
Updating 6c0f848..6e6c76a
Fast-forward
 index.html       |    2 +-
 lib/style.css |    8 ++++++++
 lib/hello.html   |    6 ++++--
 3 files changed, 13 insertions(+), 3 deletions(-)
 create mode 100644 lib/style.css

Поскольку последний коммит ветки master прямо предшествует последнему коммиту ветки style, git может выполнить ускоренное слияние-перемотку. При быстрой перемотке вперед, git просто передвигает указатель вперед, таким образом указывая на тот же коммит, что и ветка style.

При быстрой перемотке конфликтов быть не может.

02 Просмотрите логи


git hist

$ git hist
* 6e6c76a 2011-03-09 | Updated index.html (HEAD, master, style) [Alexander Shvets]
* 1436f13 2011-03-09 | Hello uses style.css [Alexander Shvets]
* 59da9a7 2011-03-09 | Added css stylesheet [Alexander Shvets]
* 6c0f848 2011-03-09 | Added README [Alexander Shvets]
* 8029c07 2011-03-09 | Added index.html. [Alexander Shvets]
* 567948a 2011-03-09 | Moved hello.html to lib [Alexander Shvets]
* 6a78635 2011-03-09 | Add an author/email comment [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]

Теперь ветки style и master идентичны.

"28. Слияние"


Научиться сливать две отличающиеся ветки для переноса изменений обратно в одну ветку.

01 Слияние веток

Слияние переносит изменения из двух веток в одну. Давайте вернемся к ветке style и сольем master с style.


git checkout style
git merge master
git hist --all

$ git checkout style
Switched to branch 'style'
$ git merge master
Merge made by recursive.
 README |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)
 create mode 100644 README
$ git hist --all
*   5813a3f 2011-03-09 | Merge branch 'master' into style (HEAD, style) [Alexander Shvets]
|\  
| * 6c0f848 2011-03-09 | Added README (master) [Alexander Shvets]
* | 07a2a46 2011-03-09 | Updated index.html [Alexander Shvets]
* | 649d26c 2011-03-09 | Hello uses style.css [Alexander Shvets]
* | 1f3cbd2 2011-03-09 | Added css stylesheet [Alexander Shvets]
|/  
* 8029c07 2011-03-09 | Added index.html. [Alexander Shvets]
* 567948a 2011-03-09 | Moved hello.html to lib [Alexander Shvets]
* 6a78635 2011-03-09 | Add an author/email comment [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]

Путем периодического слияния ветки master с веткой style вы можете переносить из master любые изменения и поддерживать совместимость изменений style с изменениями в основной ветке.

Однако, это делает графики коммитов действительно уродливыми. Позже мы рассмотрим возможность перебазирования, как альтернативы слиянию.

02 Далее

Но что если изменения в ветке master конфликтуют с изменениями в style?

"43. Слияние извлеченных изменений"


Научиться перемещать извлеченные изменения в текущую ветку и рабочий каталог.

01 Слейте извлеченные изменения в локальную ветку master


git merge origin/master

$ git merge origin/master
Updating 6e6c76a..2faa4ea
Fast-forward
 README |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

02 Еще раз проверьте файл README

Сейчас мы должны увидеть изменения.


cat README

$ cat README
This is the Hello World example from the git tutorial.
(changed in original)

Вот и изменения. Хотя команда «git fetch» не сливает изменения, мы можем вручную слить изменения из удаленного репозитория.

03 Далее

Теперь давайте рассмотрим объединение fetch & merge в одну команду.

"2. Финальные приготовления"


Установить материалы учебника и подготовить их к работе.

01 Скачайте учебные материалы

Скачайте учебные материалы здесь:

http://githowto.com/git_tutorial.zip

02 Распакуйте учебные материалы

Пакет учебных материалов должен иметь главную папку «git_tutorial» с двумя подпапками:

work — пустой рабочий каталог. Здесь будут лежать ваши репозитории. files — заранее упакованные файлы для того, чтобы вы могли продолжить работать с учебными материалами на любом этапе. Если вы застрянете, просто скопируйте нужный урок в свою рабочую папку.

"21. Подробнее о структуре"


Добавить еще один файл в наш репозиторий

01 Добавление index.html

Давайте добавим файл index.html в наш репозиторий. Следующий файл отлично подойдет для этой .

Файл: index.html

<html>
  <body>
    <iframe src="lib/hello.html" width="200" height="200" />
  </body>
</html>

Добавьте файл и сделайте коммит.


git add index.html
git commit -m "Added index.html."

Теперь при открытии index.html, вы должны увидеть кусок страницы hello в маленьком окошке.

"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 сообщает, что файл был перемещен.

02 Второй способ перемещения файлов

Позитивной чертой git является то, что вы можете забыть о версионном контроле до того момента, когда вы готовы приступить к коммиту кода. Что бы случилось, если бы мы использовали командную строку операционной системы для перемещения файлов вместо команды git?

Оказывается, следующий набор команд идентичен нашим последним действиям. Работы здесь побольше, но результат тот же.

Мы могли бы выполнить:

mkdir lib
mv hello.html lib
git add lib/hello.html
git rm hello.html

03 Коммит в новый каталог

Давайте сделаем коммит этого перемещения.


git commit -m "Moved hello.html to lib"

"36. Несколько репозиториев"


До сих пор мы работали с одним git репозиторием. Однако, git удается отлично работать с несколькими репозиториями. Эти дополнительные репозитории могут храниться локально, или доступ к ним может осуществляться через сетевое подключение.

В следующем разделе мы создадим новый репозиторий с именем «cloned_hello». Мы покажем, как перемещать изменения из одного репозитория в другой и как разрешать конфликты, возникающие в результате работы с двумя репозиториями.

git_clone А пока что поработаем с локальными репозиториями (т.е. репозиториями, хранящимися на вашем локальном жестком диске), однако практически все, что вы узнаете в этом разделе, будет применяться к нескольким репозиториям, несмотря на то, хранятся ли они локально или являются публичными.

Примечание: Мы будем вносить изменения в обе копии наших репозиториев. Обращайте внимание на то, в каком репозитории вы находитесь на каждом шаге в следующих уроках.

"25. Навигация по веткам"


Научиться перемещаться между ветками репозитория Теперь в вашем проекте есть две ветки:


git hist --all

$ git hist --all
* 07a2a46 2011-03-09 | Updated index.html (HEAD, style) [Alexander Shvets]
* 649d26c 2011-03-09 | Hello uses style.css [Alexander Shvets]
* 1f3cbd2 2011-03-09 | Added css stylesheet [Alexander Shvets]
* 8029c07 2011-03-09 | Added index.html. (master) [Alexander Shvets]
* 567948a 2011-03-09 | Moved hello.html to lib [Alexander Shvets]
* 6a78635 2011-03-09 | Add an author/email comment [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]

01 Переключение на ветку Master

Просто используйте команду git checkout для переключения между ветками.


git checkout master
cat lib/hello.html

$ git checkout master
Switched to branch 'master'
$ cat lib/hello.html
<!-- Author: Alexander Shvets ([email protected]) -->
<html>
  <head>
  </head>
  <body>
    <h1>Hello, World!</h1>
  </body>
</html>

Сейчас мы находимся на ветке Master. Это заметно по тому, что файл hello.html не использует стили style.css.

02 Вернемся к ветке «style».


git checkout style
cat lib/hello.html

$ git checkout style
Switched to branch 'style'
$ cat lib/hello.html
<!-- Author: Alexander Shvets ([email protected]) -->
<html>
  <head>
    <link type="text/css" rel="stylesheet" media="all" href="style.css" />
  </head>
  <body>
    <h1>Hello, World!</h1>
  </body>
</html>

Содержимое lib/hello.html подтверждает, что мы вернулись в ветку style.

"44. Извлечение и слияние изменений"


Узнать о том, что команда git pull эквивалентна комбинации git fetch и git merge. Обсуждение Мы не собираемся опять проходить весь процесс создания нового изменения и его извлечения, но мы хотим, чтобы вы знали, что выполнение:

git pull

действительно эквивалентно двум следующим шагам:

git fetch
git merge origin/master

"49. Извлечение общих изменений"


Научиться извлекать изменения из общего репозитория. Быстро переключитесь в клонированный репозиторий и извлеките изменения, только что отправленные в общий репозиторий.


cd ../cloned_hello

Примечание: Сейчас мы находимся в репозитории cloned_hello.

Продолжите с…


git remote add shared ../hello.git
git branch --track shared master
git pull shared master
cat README

"48. Отправка изменений"


Научиться отправлять изменения в удаленный репозиторий. Так как чистые репозитории, как правило, расшариваются на каком-нибудь сетевом сервере, нам необходимо отправить наши изменения в другие репозитории.

Начнем с создания изменения для отправки. Отредактируйте файл README и сделайте коммит

Файл: README

This is the Hello World example from the git tutorial.
(Changed in the original and pushed to shared)

git checkout master
git add README
git commit -m "Added shared comment to readme"

Теперь отправьте изменения в общий репозиторий.


git push shared master

Общим называется репозиторий, получающий отправленные нами изменения. (Помните, мы добавили его в качестве удаленного репозитория в предыдущем уроке.)


$ git push shared master
To ../hello.git
   2faa4ea..79f507c  master -> master

Примечание: Мы должны были явно указать ветку master для отправки изменений. Это можно настроить автоматически, но я все время забываю нужные команды. Для более простого управления удаленными ветками переключитесь в «Git Remote Branch».

"34. Перебазирование"


Использовать команду rebase вместо команды merge. Итак, мы вернулись в точку до первого слияния и хотим перенести изменения из ветки master в нашу ветку style.

На этот раз для переноса изменений из ветки master мы будем использовать команду rebase вместо слияния.


git checkout style
git rebase master
git hist

$ go style
Switched to branch 'style'
$
$ git rebase master
First, rewinding head to replay your work on top of it...
Applying: Added css stylesheet
Applying: Hello uses style.css
Applying: Updated index.html
$
$ git hist
* 6e6c76a 2011-03-09 | Updated index.html (HEAD, style) [Alexander Shvets]
* 1436f13 2011-03-09 | Hello uses style.css [Alexander Shvets]
* 59da9a7 2011-03-09 | Added css stylesheet [Alexander Shvets]
* 6c0f848 2011-03-09 | Added README (master) [Alexander Shvets]
* 8029c07 2011-03-09 | Added index.html. [Alexander Shvets]
* 567948a 2011-03-09 | Moved hello.html to lib [Alexander Shvets]
* 6a78635 2011-03-09 | Add an author/email comment [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]

01 Слияние VS перебазирование

Конечный результат перебазирования очень похож на результат слияния. Ветка style в настоящее время содержит все свои изменения, а также все изменения ветки master. Однако, дерево коммитов значительно отличается. Дерево коммитов ветки style было переписано таким образом, что ветка master является частью истории коммитов. Это делает цепь коммитов линейной и гораздо более читабельной.

02 Когда использовать перебазирование, а когда слияние?

Не используйте перебазирование …

Если ветка является публичной и расшаренной. Переписывание общих веток будет мешать работе других членов команды. Когда важна точная история коммитов ветки (так как команда rebase переписывает историю коммитов). Учитывая приведенные выше рекомендации, я предпочитаю использовать rebase для кратковременных, локальных веток, а слияние для веток в публичном репозитории.

"31. Перебазирование как альтернатива слиянию"


Узнать различия между перебазированием и слиянием. Обсуждение Давайте рассмотрим различия между слиянием и перебазированием. Для того, чтобы это сделать, нам нужно вернуться в репозиторий в момент до первого слияния, а затем повторить те же действия, но с использованием перебазирования вместо слияния.

Мы будем использовать команду reset для возврата веток к предыдущему состоянию.

"40. Удаленные ветки"


Узнать о локальных и удаленных ветках Давайте посмотрим на ветки, доступные в нашем клонированном репозитории.


git branch

$ git branch
* master

Как мы видим, в списке только ветка master. Где ветка style? Команда git branch выводит только список локальных веток по умолчанию.

01 Список удаленных веток

Для того, чтобы увидеть все ветки, попробуйте следующую команду:


git branch -a

$ git branch -a
* master
  remotes/origin/HEAD -> origin/master
  remotes/origin/style
  remotes/origin/master

Git выводит все коммиты в оригинальный репозиторий, но ветки в удаленном репозитории не рассматриваются как локальные. Если мы хотим иметь собственную ветку style, мы должны сами ее создать. Через минуту вы увидите, как это делается.

"18. Удаление тега oops"


Удаление тега oops (уборка)

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» больше не будет отображаться в репозитории.

"32. Сброс ветки style"


Сброс ветки style до точки перед первым слиянием.

01 Сброс ветки style

Давайте вернемся во времени на ветке style к точке перед тем, как мы слили ее с веткой master. Мы можем сбросить ветку к любому коммиту. По сути, это изменение указателя ветки на любую точку дерева коммитов.

В этом случае мы хотим вернуться в ветке style в точку перед слиянием с master. Нам необходимо найти последний коммит перед слиянием.


git checkout style
git hist

$ git checkout style
Already on 'style'
$ git hist
*   645c4e6 2011-03-09 | Merged master fixed conflict. (HEAD, style) [Alexander Shvets]
|\  
| * 454ec68 2011-03-09 | Life is great! (master) [Alexander Shvets]
* |   5813a3f 2011-03-09 | Merge branch 'master' into style [Alexander Shvets]
|\ \  
| |/  
| * 6c0f848 2011-03-09 | Added README [Alexander Shvets]
* | 07a2a46 2011-03-09 | Updated index.html [Alexander Shvets]
* | 649d26c 2011-03-09 | Hello uses style.css [Alexander Shvets]
* | 1f3cbd2 2011-03-09 | Added css stylesheet [Alexander Shvets]
|/  
* 8029c07 2011-03-09 | Added index.html. [Alexander Shvets]
* 567948a 2011-03-09 | Moved hello.html to lib [Alexander Shvets]
* 6a78635 2011-03-09 | Add an author/email comment [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]

Это немного трудно читать, но, глядя на данные, мы видим, что коммит «Updated index.html» был последним на ветке style перед слиянием. Давайте сбросим ветку style к этому коммиту.


git reset --hard <hash>

$ git reset --hard 07a2a46
HEAD is now at 07a2a46 Updated index.html

02 Проверьте ветку.

Поищите лог ветки style. У нас в истории больше нет коммитов слияний.


git hist --all

$ git hist --all
* 454ec68 2011-03-09 | Life is great! (master) [Alexander Shvets]
* 6c0f848 2011-03-09 | Added README [Alexander Shvets]
| * 07a2a46 2011-03-09 | Updated index.html (HEAD, style) [Alexander Shvets]
| * 649d26c 2011-03-09 | Hello uses style.css [Alexander Shvets]
| * 1f3cbd2 2011-03-09 | Added css stylesheet [Alexander Shvets]
|/  
* 8029c07 2011-03-09 | Added index.html. [Alexander Shvets]
* 567948a 2011-03-09 | Moved hello.html to lib [Alexander Shvets]
* 6a78635 2011-03-09 | Add an author/email comment [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]

"33. Сброс ветки master"


Сбросить ветку master в точку до конфликтующего коммита.

01 Сброс ветки master

Добавив интерактивный режим в ветку master, мы внесли изменения, конфликтующие с изменениями в ветке style. Давайте вернемся в ветке master в точку перед внесением конфликтующих изменений. Это позволяет нам продемонстрировать работу команды rebase, не беспокоясь о конфликтах.


git checkout master
git hist

$ git hist
* 454ec68 2011-03-09 | Life is great! (HEAD, master) [Alexander Shvets]
* 6c0f848 2011-03-09 | Added README [Alexander Shvets]
* 8029c07 2011-03-09 | Added index.html. [Alexander Shvets]
* 567948a 2011-03-09 | Moved hello.html to lib [Alexander Shvets]
* 6a78635 2011-03-09 | Add an author/email comment [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]

Коммит «Added README» идет непосредственно перед коммитом конфликтующего интерактивного режима. Мы сбросим ветку master к коммиту «Added README».


git reset --hard <hash>
git hist --all

Просмотрите лог. Он должен выглядеть, как будто репозиторий был перемотан назад во времени к точке до какого-либо слияния.


$ git reset --hard 6c0f848
$ git hist --all
* 6c0f848 2011-03-09 | Added README (HEAD, master) [Alexander Shvets]
| * 07a2a46 2011-03-09 | Updated index.html (style) [Alexander Shvets]
| * 649d26c 2011-03-09 | Hello uses style.css [Alexander Shvets]
| * 1f3cbd2 2011-03-09 | Added css stylesheet [Alexander Shvets]
|/  
* 8029c07 2011-03-09 | Added index.html. [Alexander Shvets]
* 567948a 2011-03-09 | Moved hello.html to lib [Alexander Shvets]
* 6a78635 2011-03-09 | Add an author/email comment [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]

"30. Разрешение конфликтов"


Научиться разрешать конфликты во время слияния

01 Слияние master с веткой style

Теперь вернемся к ветке style и попытаемся объединить ее с новой веткой master.


git checkout style
git merge master

$ git checkout style
Switched to branch 'style'
$ git merge master
Auto-merging lib/hello.html
CONFLICT (content): Merge conflict in lib/hello.html
Automatic merge failed; fix conflicts and then commit the result.

Если вы откроете lib/hello.html, вы увидите:

Файл: lib/hello.html

<!-- Author: Alexander Shvets ([email protected]) -->
<html>
  <head>
<<<<<<< HEAD
    <link type="text/css" rel="stylesheet" media="all" href="style.css" />
=======
    <!-- no style -->
>>>>>>> master
  </head>
  <body>
    <h1>Hello,World! Life is great!</h1>
  </body>
</html>

Первый раздел - версия во главе текущей ветки (style). Второй раздел - версия ветки master.

02 Решение конфликта

Вам необходимо вручную разрешить конфликт. Внесите изменения в lib/hello.html для достижения следующего результата.

Файл: lib/hello.html

<!-- Author: Alexander Shvets ([email protected]) -->
<html>
  <head>
    <link type="text/css" rel="stylesheet" media="all" href="style.css" />
  </head>
  <body>
    <h1>Hello, World! Life is great!</h1>
  </body>
</html>

03 Сделайте коммит решения конфликта


git add lib/hello.html
git commit -m "Merged master fixed conflict."

$ git add lib/hello.html
$ git commit -m "Merged master fixed conflict."
Recorded resolution for 'lib/hello.html'.
[style 645c4e6] Merged master fixed conflict.

04 Расширенные возможности слияния

Git не предоставляет никаких графических инструментов слияния, но будет с удовольствием работать с любыми сторонними инструментами слияния, которые вы хотите использовать (обсуждение таких инструментов на StackOverflow).

"38. Просмотр клонированного репозитория"


Узнать о ветках в удаленных репозиториях.

01 Посмотрите на клонированный репозиторий

Давайте взглянем на клонированный репозиторий.


cd cloned_hello
ls

$ cd cloned_hello
$ ls
README
index.html
lib

Вы увидите список всех файлов на верхнем уровне оригинального репозитория README, index.html и lib).

02 Просмотрите историю репозитория


git hist --all

$ git hist --all
* 6e6c76a 2011-03-09 | Updated index.html (HEAD, origin/master, origin/style, origin/HEAD, master) [Alexander Shvets]
* 1436f13 2011-03-09 | Hello uses style.css [Alexander Shvets]
* 59da9a7 2011-03-09 | Added css stylesheet [Alexander Shvets]
* 6c0f848 2011-03-09 | Added README [Alexander Shvets]
* 8029c07 2011-03-09 | Added index.html. [Alexander Shvets]
* 567948a 2011-03-09 | Moved hello.html to lib [Alexander Shvets]
* 6a78635 2011-03-09 | Add an author/email comment [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]

Вы увидите список всех коммитов в новый репозиторий, и он должен (более или менее) совпадать с историей коммитов в оригинальном репозитории. Единственная разница должна быть в названиях веток.

03 Удаленные ветки

Вы увидите ветку master (HEAD) в списке истории. Вы также увидите ветки со странными именами (origin/master, origin/style и origin/HEAD). Мы поговорим о них чуть позже.

"1. Подготовка"


Полная готовность к работе с Git.

01 Установка имени и электронной почты

Если вы никогда ранее не использовали git, для начала вам необходимо осуществить установку. Выполните следующие команды, чтобы git узнал ваше имя и электронную почту. Если git уже установлен, можете переходить к разделу окончания строк.

Выполнить:

git config --global user.name "Your Name"
git config --global user.email "[email protected]"

02 Параметры установки окончаний строк

Для пользователей Unix/Mac:

Выполнить:

git config --global core.autocrlf input
git config --global core.safecrlf warn

Для пользователей Windows:

Выполнить:

git config --global core.autocrlf true
git config --global core.safecrlf warn

03 Установка отображения unicode

По умолчанию, git будет печатать не-ASCII символы в именах файлов в виде восьмеричных последовательностей \nnn. Чтобы избежать нечитаемых строк, установите соответствующий флаг:

git config --global core.quotepath off

"51. Расшаривание репозиториев"


Научиться расшаривать репозитории по WIFI. Посмотрите, запущен ли git daemon у вашего соседа. Обменяйтесь IP-адресами и проверьте, сможете ли вы извлекать изменения из репозиториев друг друга.

"7. Индексация и коммит"


Отдельный шаг индексации в 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"

Разделяя индексацию и коммит, вы имеете возможность с легкостью настроить, что идет в какой коммит.

"6. Индексация изменений"


Научиться индексировать изменения для последующих коммитов

01 Добавьте изменения

Теперь дайте команду git проиндексировать изменения. Проверьте состояние


git add hello.html
git status

Вы увидите…


$ git add hello.html
$ git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#	modified:   hello.html
#

Изменения файла hello.html были проиндексированы. Это означает, что git теперь знает об изменении, но изменение пока не перманентно (читай, навсегда) записано в репозиторий. Следующий коммит будет включать в себя проиндексированные изменения.

Если вы решили, что не хотите коммитить изменения, команда состояния напомнит вам о том, что с помощью команды git reset можно снять индексацию этих изменений.

"13. Создание тегов версий"


Узнать, как создавать теги для коммитов для использования в будущем Давайте назовем текущую версию страницы hello первой (v1).

01 Создайте тег первой версии


git tag v1

Теперь текущая версия страницы называется v1.

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 тегами и , но еще пока без . Давайте сделаем ее версией v1-beta.


git tag v1-beta

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

04 Просмотр тегов с помощью команды tag

Вы можете увидеть, какие теги доступны, используя команду git tag.


git tag

$ git tag
v1
v1-beta

05 Просмотр Тегов в логах

Вы также можете посмотреть теги в логе.


git hist master --all

$ 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).

"Спасибо!"


Спасибо за использование GitHowTo! Надеюсь, вам было интересно.

Отзывы и пожелания Если у вас есть вопросы, отзывы или пожелания, присылайте их мне на email:

Александр Швец [email protected]

Лицензия Содержимое этого сайта находится под лицензией Creative Commons, Attribution-NonCommercial-ShareAlike.

Содержимое сайта доступно на Github. Если вы нашли ошибку или хотите сделать правку, можете создать Pull Request с вашим исправлением, либо просто создать новую Issue.--- ## "16. Отмена коммитов"

Научиться отменять коммиты в локальный репозиторий.

01 Отмена коммитов

Иногда вы понимаете, что новые коммиты являются неверными, и хотите их отменить. Есть несколько способов решения этого вопроса, здесь мы будем использовать самый безопасный.

Мы отменим коммит путем создания нового коммита, отменяющего нежелательные изменения.

02 Измените файл и сделайте коммит

Измените файл hello.html на следующий.

Файл: hello.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 didn't want this commit"

03 Сделайте коммит с новыми изменениями, отменяющими предыдущие

Чтобы отменить коммит, нам необходимо сделать коммит, который удаляет изменения, сохраненные нежелательным коммитом.


git revert HEAD

Перейдите в редактор, где вы можете отредактировать коммит-сообщение по умолчанию или оставить все как есть. Сохраните и закройте файл. Вы увидите…


$ git revert HEAD --no-edit
[master 45fa96b] Revert "Oops, we didn't want this commit"
 1 files changed, 1 insertions(+), 1 deletions(-)

Так как мы отменили самый последний произведенный коммит, мы смогли использовать HEAD в качестве аргумента для отмены. Мы можем отменить любой произвольной коммит в истории, указав его хэш-значение.

Примечание: Команду --no-edit можно проигнорировать. Она была необходима для генерации выходных данных без открытия редактора.

04 Проверьте лог

Проверка лога показывает нежелательные и отмененные коммиты в наш репозиторий.


git hist

$ 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]

Эта техника будет работать с любым коммитом (хотя, возможно, возникнут конфликты). Она безопасна в использовании даже в публичных ветках удаленных репозиториев.

05 Далее

Далее давайте посмотрим на технику, которая может быть использована для удаления последних коммитов из истории репозитория.

"14. Отмена локальных изменений (до индексации)"


Научиться отменять изменения в рабочем каталоге

01 Переключитесь на ветку Master

Убедитесь, что вы находитесь на последнем коммите ветки master, прежде чем продолжить работу.


git checkout master

02 Измените hello.html

Иногда случается, что вы изменили файл в рабочем каталоге, и хотите отменить последние коммиты. С этим справится команда checkout.

Внесите изменение в файл hello.html в виде нежелательного комментария.

Файл: hello.html

<html>
  <head>
  </head>
  <body>
    <h1>Hello, World!</h1>
    <!-- This is a bad comment.  We want to revert it. -->
  </body>
</html>

03 Проверьте состояние

Сначала проверьте состояние рабочего каталога.


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")

Мы видим, что файл hello.html был изменен, но еще не проиндексирован.

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. Отмена проиндексированных изменений (перед коммитом)"


Научиться отменять изменения, которые были проиндексированы

01 Измените файл и проиндексируйте изменения

Внесите изменение в файл hello.html в виде нежелательного комментария

Файл: hello.html

<html>
  <head>
    <!-- This is an unwanted but staged comment -->
  </head>
  <body>
    <h1>Hello, World!</h1>
  </body>
</html>

Проиндексируйте это изменение.


git add hello.html

02 Проверьте состояние

Проверьте состояние нежелательного изменения.


git status

$ git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#	modified:   hello.html
#

Состояние показывает, что изменение было проиндексировано и готово к коммиту.

03 Выполните сброс буферной зоны

К счастью, вывод состояния показывает нам именно то, что мы должны сделать для отмены индексации изменения.


git reset HEAD hello.html

$ git reset HEAD hello.html
Unstaged changes after reset:
M	hello.html

Команда reset сбрасывает буферную зону к HEAD. Это очищает буферную зону от изменений, которые мы только что проиндексировали.

Команда reset (по умолчанию) не изменяет рабочий каталог. Поэтому рабочий каталог все еще содержит нежелательный комментарий. Мы можем использовать команду checkout из предыдущего урока, чтобы удалить нежелательные изменения в рабочем каталоге.

04 Переключитесь на версию коммита


git checkout hello.html
git status

$ git status
# On branch master
nothing to commit (working directory clean)

Наш рабочий каталог опять чист.

"27. Просмотр отличающихся веток"


Научиться просматривать отличающиеся ветки в репозитории.

01 Просмотрите текущие ветки

Теперь у нас в репозитории есть две отличающиеся ветки. Используйте следующую лог-команду для просмотра веток и их отличий.


git hist --all

$ git hist --all
* 6c0f848 2011-03-09 | Added README (HEAD, master) [Alexander Shvets]
| * 07a2a46 2011-03-09 | Updated index.html (style) [Alexander Shvets]
| * 649d26c 2011-03-09 | Hello uses style.css [Alexander Shvets]
| * 1f3cbd2 2011-03-09 | Added css stylesheet [Alexander Shvets]
|/
* 8029c07 2011-03-09 | Added index.html. [Alexander Shvets]
* 567948a 2011-03-09 | Moved hello.html to lib [Alexander Shvets]
* 6a78635 2011-03-09 | Add an author/email comment [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]

Это наша первая возможность увидеть в действии --graph в git hist. Добавление опции --graph в git log вызывает построение дерева коммитов с помощью простых ASCII символов. Мы видим обе ветки (style и master), и то, что ветка master является текущей HEAD. Общим предшественником обеих веток является коммит «Added index.html».

Метка --all гарантированно означает, что мы видим все ветки. По умолчанию показывается только текущая ветка.

"39. Что такое origin?"


Узнать об именах удаленных репозиториев.


git remote

$ git remote
origin

Мы видим, что клонированный репозиторий знает об имени по умолчанию удаленного репозитория. Давайте посмотрим, можем ли мы получить более подробную информацию об имени по умолчанию:


git remote show origin

$ git remote show origin
* remote origin
  Fetch URL: /Users/alex/Documents/Presentations/githowto/auto/hello
  Push  URL: /Users/alex/Documents/Presentations/githowto/auto/hello
  HEAD branch (remote HEAD is ambiguous, may be one of the following):
    style
    master
  Remote branches:
    style  tracked
    master tracked
  Local branch configured for 'git pull':
    master merges with remote master
  Local ref configured for 'git push':
    master pushes to master (up to date)

Мы видим, что «имя по умолчанию»(«origin») удаленного репозитория – оригинальное hello. Удаленные репозитории обычно размещаются на отдельной машине, возможно, централизованном сервере. Однако, как мы видим здесь, они могут с тем же успехом указывать на репозиторий на той же машине. Нет ничего особенного в имени «origin», однако существует традиция использовать «origin» в качестве имени первичного централизованного репозитория (если таковой имеется).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment