Spec-Zone.ru › Git

gittutorial

Имя

gittutorial - Вводный учебник по Git

Синопсис

git *

Описание

Этот учебник объясняет, как импортировать новый проект в Git, вносить в него изменения и делиться изменениями с другими разработчиками.

Если вы преимущественно заинтересованы в использовании Git для получения проекта, например, для тестирования последней версии, вы можете начать с первых двух глав Руководства пользователя Git.

Во-первых, обратите внимание, что вы можете получить документацию для команды, такой как git log --graph с помощью:

$ man git-log

или:

$ git help log

В последнем случае вы можете использовать просмотрщик руководства по своему выбору; для получения дополнительной информации см. git-help[1].

Хорошо будет познакомить Git с вашим именем и публичным адресом электронной почты перед выполнением любых операций. Самый простой способ сделать это:

$ git config --global user.name "Your Name Comes Here"
$ git config --global user.email you@yourdomain.example.com

Импортирование нового проекта

Предположим, у вас есть архив project.tar.gz с вашей начальной работой. Вы можете поместить его под контроль версий Git следующим образом.

$ tar xzf project.tar.gz
$ cd project
$ git init

Git ответит

Initialized empty Git repository in .git/

Теперь вы инициализировали рабочую директорию — вы можете заметить, что создалась новая директория с именем .git.

Далее, сообщите Git о том, чтобы он сделал снимок содержимого всех файлов в текущей директории (обратите внимание на .), с помощью git add:

$ git add .

Этот снимок теперь хранится во временном области хранения, которую Git называет «индексом». Вы можете навсегда сохранить содержимое индекса в репозитории с помощью git commit:

$ git commit

Это потребует от вас сообщения об изменениях. Теперь вы сохранили первую версию своего проекта в Git.

Внесение изменений

Измените некоторые файлы, а затем добавьте их обновленное содержимое в индекс:

$ git add file1 file2 file3

Теперь вы готовы к коммиту. Вы можете увидеть, что собираетесь отправить на коммит, используя git diff с параметром --cached:

$ git diff --cached

(Без --cached, git diff покажет вам все внесенные вами изменения, но не добавленные в индекс.) Вы также можете получить краткий обзор ситуации с git status:

$ git status
On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)

        modified:   file1
        modified:   file2
        modified:   file3

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

$ git commit

Это снова потребует от вас сообщения, описывающего изменение, а затем запишет новую версию проекта.

В качестве альтернативы, вместо выполнения git add предварительно, вы можете использовать

$ git commit -a

который автоматически заметит любые измененные (но не новые) файлы, добавит их в индекс и выполнит коммит — все в одном шаге.

Примечание о сообщениях коммита: Хотя это необязательно, рекомендуется начинать сообщение коммита с одной короткой строки (не более 50 символов) в качестве резюме изменения, за которой следует пустая строка, а затем более подробное описание. Текст до первой пустой строки в сообщении коммита обрабатывается как заголовок коммита, и этот заголовок используется во всем Git. Например, git-format-patch[1] преобразует коммит в электронное письмо, и он использует заголовок в строке темы и остальную часть коммита в теле.

Git отслеживает содержимое, а не файлы

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

Просмотр истории проекта

В любой момент вы можете просмотреть историю своих изменений, используя

$ git log

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

$ git log -p

Часто полезно получить общее представление о каждом шаге.

$ git log --stat --summary

Управление ветками

Один репозиторий Git может поддерживать несколько веток разработки. Чтобы создать новую ветку с именем experimental, используйте

$ git branch experimental

Если вы теперь выполните

$ git branch

вы получите список всех существующих веток:

  experimental
* master

Ветка experimental — это та, которую вы только что создали, а ветка master — это стандартная ветка, которая была создана для вас автоматически. Звездочка отмечает ветку, на которой вы сейчас находитесь; введите

$ git switch experimental

чтобы перейти на ветку experimental. Теперь измените файл, выполните коммит изменения и вернитесь на ветку master:

(edit file)
$ git commit -a
$ git switch master

Убедитесь, что внесенное вами изменение больше не видно, так как оно было сделано на ветке experimental , а вы вернулись на ветку master.

Вы можете внести другие изменения на ветке master:

(edit file)
$ git commit -a

на этом этапе две ветки разошлись, с разными изменениями, внесенными в каждую из них. Чтобы объединить изменения, внесённые в experimental в master, выполните

$ git merge experimental

Если конфликтов нет, вы закончили. Если есть конфликты, метки останутся в проблематичных файлах, показывая конфликт;

$ git diff

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

$ git commit -a

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

$ gitk

покажет красивую графическую репрезентацию полученной истории.

На этом этапе вы можете удалить ветку experimental с помощью

$ git branch -d experimental

Эта команда гарантирует, что изменения в ветке experimental уже находятся в текущей ветке.

Если вы разрабатываете на ветке crazy-idea, а потом передумаете, вы всегда можете удалить ветку с помощью

$ git branch -D crazy-idea

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

Использование Git для совместной работы

Предположим, что Алиса начала новый проект с репозиторием Git в /home/alice/project, а Боб, у которого домашний каталог на той же машине, хочет внести свой вклад.

Боб начинает с:

bob$ git clone /home/alice/project myrepo

Это создаёт новую директорию myrepo содержащую клон репозитория Алисы. Клон равноправен с оригинальным проектом, имея собственную копию истории оригинального проекта.

Затем Боб вносит некоторые изменения и коммитит их:

(edit files)
bob$ git commit -a
(repeat as necessary)

Когда он готов, он просит Алису получить изменения из репозитория в /home/bob/myrepo. Она делает это с помощью:

alice$ cd /home/alice/project
alice$ git pull /home/bob/myrepo master

Это объединяет изменения из ветки Боба master в текущую ветку Алисы. Если Алиса в это время внесла свои изменения, ей может потребоваться вручную разрешить конфликты.

Команда pull таким образом выполняет две операции: она получает изменения из удалённой ветки, затем объединяет их в текущую ветку.

Обратите внимание, что в общем случае Алисе следует закоммитить свои локальные изменения перед началом этого pull. Если работа Боба конфликтует с тем, что сделала Алиса после расхождения их истории, Алиса использует свою рабочую область и индекс для разрешения конфликтов, и существующие локальные изменения будут мешать процессу разрешения конфликтов (Git всё равно выполнит загрузку, но откажется от слияния — Алисе нужно будет как-то избавиться от своих локальных изменений и снова выполнить загрузку в таком случае).

Алиса может посмотреть, что сделал Боб, не сливая изменения сначала, используя команду fetch; это позволяет Алисе проверить, что сделал Боб, используя специальный символ FETCH_HEAD, для определения, есть ли у него что-то стоящее для получения, например так:

alice$ git fetch /home/bob/myrepo master
alice$ git log -p HEAD..FETCH_HEAD

Эта операция безопасна даже если у Алисы есть несохранённые локальные изменения. Запись HEAD..FETCH_HEAD означает "показать всё, что доступно от FETCH_HEAD, но исключить всё, что доступно от HEAD". Алиса уже знает всё, что ведёт к её текущему состоянию (HEAD), и проверяет, что у Боба есть в его состоянии (FETCH_HEAD), чего она ещё не видела с помощью этой команды.

Если Алиса хочет визуализировать, что сделал Боб после того, как их истории разошлись, она может выполнить следующую команду:

$ gitk HEAD..FETCH_HEAD

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

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

$ gitk HEAD...FETCH_HEAD

Это означает "показать всё, что доступно от любого из них, но исключить всё, что доступно от обоих из них".

Обратите внимание, что эти записи диапазонов могут использоваться как с gitk, так и с git log.

После проверки того, что сделал Боб, если нет ничего срочного, Алиса может продолжить работу без получения изменений от Боба. Если в истории Боба есть что-то, что Алисе нужно немедленно, Алиса может сохранить свою текущую работу с помощью операции stash, выполнить загрузку pull, и затем восстановить свою работу поверх полученной истории.

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

alice$ git remote add bob /home/bob/myrepo

С этим Алиса может выполнить первую часть операции pull самостоятельно с помощью команды git fetch без объединения с её собственной веткой, используя:

alice$ git fetch bob

В отличие от длинной формы, когда Алиса получает изменения от Боба, используя сокращение удалённого репозитория, настроенное с git remote, полученные данные сохраняются в ветке отслеживания удалённого репозитория, в данном случае bob/master. Поэтому после этого:

alice$ git log -p master..bob/master

отображает список всех изменений, внесённых Бобом с момента отделения его ветки от ветки Алисы master.

После изучения этих изменений Алиса может объединить изменения в свою ветку master:

alice$ git merge bob/master

Это merge также может быть выполнено с помощью pulling from her own remote-tracking branch, так:

alice$ git pull . remotes/bob/master

Обратите внимание, что git pull всегда объединяет в текущую ветку, независимо от того, что ещё указано в командной строке.

Позже Боб может обновить свой репозиторий с последними изменениями Алисы, используя

bob$ git pull

Обратите внимание, что ему не нужно указывать путь к репозиторию Алисы; когда Боб клонировал репозиторий Алисы, Git сохранил расположение её репозитория в конфигурации репозитория, и это расположение используется для загрузки:

bob$ git config --get remote.origin.url
/home/alice/project

(Полная конфигурация, созданная с помощью git clone, отображается с помощью git config -l, а страница справки git-config[1] объясняет значение каждого параметра.)

Git также хранит чистую копию ветки Алисы master под именем origin/master:

bob$ git branch -r
  origin/master

Если Боб позже решит работать с другого хоста, он по-прежнему может выполнять клонирование и загрузку, используя протокол ssh:

bob$ git clone alice.org:/home/alice/project myrepo

В качестве альтернативы, Git имеет собственный протокол или может использовать http; см. git-pull[1] для получения подробной информации.

Git также может использоваться в режиме CVS, с центральным репозиторием, в который различные пользователи загружают изменения; см. git-push[1] и gitcvs-migration[7].

Изучение истории

История Git представлена как серия взаимосвязанных коммитов. Мы уже видели, что команда git log может отображать эти коммиты. Обратите внимание, что первая строка каждого git log запися также даёт имя для коммита:

$ git log
commit c82a22c39cbc32576f64f5c6b3f24b99ea8149c7
Author: Junio C Hamano <junkio@cox.net>
Date:   Tue May 16 17:18:22 2006 -0700

    merge-base: Clarify the comments on post processing.

Мы можем дать это имя команде git show для просмотра деталей этого коммита.

$ git show c82a22c39cbc32576f64f5c6b3f24b99ea8149c7

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

$ git show c82a22c39c        # the first few characters of the name are
                        # usually enough
$ git show HEAD                # the tip of the current branch
$ git show experimental        # the tip of the "experimental" branch

Каждый коммит обычно имеет один "родительский" коммит, который указывает на предыдущее состояние проекта:

$ git show HEAD^  # to see the parent of HEAD
$ git show HEAD^^ # to see the grandparent of HEAD
$ git show HEAD~4 # to see the great-great grandparent of HEAD

Обратите внимание, что коммиты слияния могут иметь более одного родителя:

$ git show HEAD^1 # show the first parent of HEAD (same as HEAD^)
$ git show HEAD^2 # show the second parent of HEAD

Вы также можете давать коммитам свои собственные имена; после выполнения

$ git tag v2.5 1b2e1d63ff

вы можете ссылаться на 1b2e1d63ff по имени v2.5. Если вы хотите поделиться этим именем с другими людьми (например, для идентификации версии выпуска), вы должны создать объект "тега" и, возможно, подписать его; см. git-tag[1] для получения подробной информации.

Любая команда Git, которой нужно знать коммит, может принять любое из этих имён. Например:

$ git diff v2.5 HEAD         # compare the current HEAD to v2.5
$ git branch stable v2.5 # start a new branch named "stable" based
                         # at v2.5
$ git reset --hard HEAD^ # reset your current branch and working
                         # directory to its state at HEAD^

Будьте осторожны с последней командой: помимо потери всех изменений в рабочей директории, она также удалит все последующие коммиты из этой ветки. Если эта ветка — единственная ветка, содержащая эти коммиты, они будут потеряны. Кроме того, не используйте git reset в общедоступной ветке, из которой другие разработчики выполняют загрузку, так как это приведёт к ненужным слияниям для других разработчиков при очистке истории. Если вам нужно отменить изменения, которые вы отправили, используйте git revert вместо этого.

Команда git grep может искать строки в любой версии вашего проекта, поэтому

$ git grep "hello" v2.5

ищет все вхождения "hello" в v2.5.

Если вы опустите имя коммита, git grep будет искать любые из файлов, которые она управляет, в вашей текущей директории. Поэтому

$ git grep "hello"

— это быстрый способ поиска только тех файлов, которые отслеживаются Git.

Многие команды Git также принимают наборы коммитов, которые могут быть указаны различными способами. Вот некоторые примеры с git log:

$ git log v2.5..v2.6            # commits between v2.5 and v2.6
$ git log v2.5..                # commits since v2.5
$ git log --since="2 weeks ago" # commits from the last 2 weeks
$ git log v2.5.. Makefile       # commits since v2.5 which modify
                                # Makefile

Вы также можете дать git log "диапазон" коммитов, где первый не обязательно является предком второго; например, если концы веток stable и master разошлись от общего коммита некоторое время назад, то

$ git log stable..master

отобразит коммиты, сделанные в ветке master, но не в стабильной ветке, а

$ git log master..stable

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

У команды git log есть слабое место: она должна представлять коммиты в виде списка. Когда в истории есть линии развития, которые разошлись, а затем вновь объединились, порядок, в котором git log представляет эти коммиты, не имеет значения.

В большинстве проектов с несколькими участниками (например, ядро Linux или сам Git) часто происходят слияния, и gitk лучше визуализирует их историю. Например,

$ gitk --since="2 weeks ago" drivers/

позволяет просматривать любые коммиты из последних 2 недель, которые изменяли файлы в каталоге drivers. (Примечание: вы можете настроить шрифты gitk, удерживая клавишу Control и нажимая "-" или "+").

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

$ git diff v2.5:Makefile HEAD:Makefile.in

Вы также можете использовать git show для просмотра таких файлов:

$ git show v2.5:Makefile

Следующие шаги

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

  • База данных объектов — это довольно элегантная система, используемая для хранения истории вашего проекта — файлов, каталогов и коммитов.

  • Файл индекса — это кэш состояния дерева каталогов, используемый для создания коммитов, проверки каталогов, а также хранения различных деревьев, участвующих в слиянии.

Во второй части этого учебника объясняются база данных объектов, файл индекса и несколько других нюансов, которые вам понадобятся для эффективного использования Git. Вы можете найти его по адресу gittutorial-2[7].

Если вы не хотите сразу переходить к этому, несколько других интересных в данный момент отступлений:

  • git-format-patch[1], git-am[1]: Эти команды преобразуют серию коммитов Git в электронные патчи и наоборот, что полезно для таких проектов, как ядро Linux, которые сильно полагаются на электронные патчи.

  • git-bisect[1]: Когда в вашем проекте происходит регрессия, один из способов отследить ошибку — это поиск в истории, чтобы найти точный коммит, который виновен. git bisect может помочь вам выполнить двоичный поиск этого коммита. Он достаточно умён, чтобы выполнять поиск, близкий к оптимальному, даже в случае сложной нелинейной истории с множеством слитых ветвей.

  • gitworkflows[7]: Предоставляет обзор рекомендуемых рабочих процессов.

  • giteveryday[7]: Ежедневное использование Git с 20-ю командами.

  • gitcvs-migration[7]: Git для пользователей CVS.

См. также

gittutorial-2[7], gitcvs-migration[7], gitcore-tutorial[7], gitglossary[7], git-help[1], gitworkflows[7], giteveryday[7], Руководство пользователя Git

gittutorial

© 2005–2026 Linus Torvalds and others
Licensed under the GNU General Public License version 2.
https://git-scm.com/docs/gittutorial

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API