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