Spec-Zone.ru › Git

git-checkout

Название

git-checkout — переключение веток или восстановление файлов рабочего дерева

Краткое описание

git checkout [-q] [-f] [-m] [<branch>]
git checkout [-q] [-f] [-m] --detach [<branch>]
git checkout [-q] [-f] [-m] [--detach] <commit>
git checkout [-q] [-f] [-m] [[-b|-B|--orphan] <new-branch>] [<start-point>]
git checkout <tree-ish> [--] <pathspec>…​
git checkout <tree-ish> --pathspec-from-file=<file> [--pathspec-file-nul]
git checkout [-f|--ours|--theirs|-m|--conflict=<style>] [--] <pathspec>…​
git checkout [-f|--ours|--theirs|-m|--conflict=<style>] --pathspec-from-file=<file> [--pathspec-file-nul]
git checkout (-p|--patch) [<tree-ish>] [--] [<pathspec>…​]

Описание

git checkout имеет два основных режима:

  1. Переключение веток с помощью git checkout <branch>

  2. Восстановление другой версии файла, например, с помощью git checkout <commit> <filename> или git checkout <filename>

О том, как Git определяет, какое действие выполнить, см. раздел «РАЗБОР АРГУМЕНТОВ» ниже.

git checkout [<branch>]

Переключиться на <branch>. Текущей веткой становится <branch>, а файлы в вашем рабочем каталоге обновляются. Переключение не будет выполнено, если в каких-либо файлах есть незафиксированные изменения и содержимое этих файлов в <branch> отличается от содержимого в текущей фиксации. В остальных случаях незафиксированные изменения сохраняются.

Если <branch> не найдена, но в единственном удалённом репозитории существует отслеживаемая ветка (обозначим её <remote>) с таким же именем, а параметр --no-guess не указан, это равносильно выполнению команды

$ git checkout -b <branch> --track <remote>/<branch>

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

git checkout -b <new-branch> [<start-point>]

Создать ветку с именем <new-branch>, указать в качестве её начальной точки <start-point> (по умолчанию — текущая фиксация) и переключиться на новую ветку. Параметры --track или --no-track позволяют настроить информацию об отслеживании вышестоящей ветки.

Операция завершится ошибкой, если не удастся переключиться на <new-branch>, например, если переключение на фиксацию <start-point> приведёт к перезаписи ваших незафиксированных изменений.

git checkout -B <branch> [<start-point>]

То же, что и -b, но если ветка уже существует, команда сбрасывает <branch> к начальной точке, а не завершает работу с ошибкой.

git checkout --detach [<branch>]
git checkout [--detach] <commit>

То же, что и git checkout <branch>, за исключением того, что вместо указания HEAD на ветку команда указывает HEAD на идентификатор фиксации. Подробнее см. раздел «ОТДЕЛЁННЫЙ HEAD» ниже.

Если не указывать <branch>, HEAD будет отсоединён на вершине текущей ветки.

git checkout <tree-ish> [--] <pathspec>...
git checkout <tree-ish> --pathspec-from-file=<file> [--pathspec-file-nul]

Заменить указанные файлы и/или каталоги версиями из заданной фиксации или дерева и добавить их в индекс (также известный как «область подготовки»).

Например, команда git checkout main file.txt заменит file.txt версией из main.

git checkout [-f|--ours|--theirs|-m|--conflict=<style>] [--] <pathspec>...
git checkout [-f|--ours|--theirs|-m|--conflict=<style>] --pathspec-from-file=<file> [--pathspec-file-nul]

Заменить указанные файлы и/или каталоги версиями из индекса.

Например, если вы переключились на фиксацию, отредактировали file.txt, а затем решили, что эти изменения были ошибкой, команда git checkout file.txt отменит все изменения в file.txt, ещё не добавленные в индекс.

Команда завершится ошибкой, если файл содержит конфликт слияния, а вы ещё не выполнили git add file.txt (или эквивалентную команду), чтобы отметить его как разрешённый. Чтобы вместо завершения с ошибкой игнорировать файлы с неразрешёнными конфликтами, можно использовать -f; чтобы заменить их версией с определённой стороны слияния — --ours или --theirs; а чтобы заменить их исходным результатом слияния с конфликтами — -m.

git checkout (-p|--patch) [<tree-ish>] [--] [<pathspec>...]

Этот режим похож на два предыдущих, но позволяет использовать интерактивный интерфейс, чтобы просмотреть вывод команды «diff» и выбрать блоки изменений для включения в результат. Описание параметра --patch см. ниже.

Параметры

-q
--quiet

Не выводить сообщения обратной связи.

--progress
--no-progress

По умолчанию сведения о ходе выполнения передаются в стандартный поток ошибок, если он подключён к терминалу, если не указан параметр --quiet. Этот флаг включает вывод сведений о ходе выполнения, даже если поток не подключён к терминалу, независимо от --quiet.

-f
--force

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

При извлечении путей из индекса не завершать операцию с ошибкой при наличии неслитых записей; вместо этого игнорировать их.

--ours
--theirs

При извлечении путей из индекса извлечь для неслитых путей вариант из этапа № 2 (ours) или № 3 (theirs).

Обратите внимание: во время git rebase и git pull --rebase значения ours и theirs могут поменяться местами; --ours указывает версию из ветки, на которую перемещаются изменения при перебазировании, а --theirs — версию из ветки с вашими изменениями, которые перебазируются.

Это объясняется тем, что rebase используется в рабочем процессе, где история на удалённом репозитории считается общей канонической историей, а работа, выполненная в перебазируемой ветке, рассматривается как сторонняя работа, которую нужно интегрировать. Во время перебазирования вы временно принимаете на себя роль хранителя канонической истории. Как хранитель канонической истории, вы должны рассматривать историю удалённого репозитория как ours (то есть «нашу общую каноническую историю»), а сделанное вами в отдельной ветке — как theirs (то есть «работу одного из участников поверх неё»).

-b <new-branch>

Создать ветку с именем <new-branch>, начать её с <start-point> и переключиться на неё; подробности см. в git-branch[1].

-B <new-branch>

То же, что и -b, за исключением того, что если ветка уже существует, <branch> сбрасывается к исходной точке вместо завершения с ошибкой.

-t
--track[=(direct|inherit)]

При создании новой ветки настроить конфигурацию «вышестоящей» ветки. Подробности см. в разделе --track на странице git-branch[1]. Для удобства параметр --track без -b подразумевает создание ветки.

Если параметр -b не задан, имя новой ветки будет определено на основе ветки отслеживания удалённого репозитория: будет взята локальная часть refspec, настроенного для соответствующего удалённого репозитория, после чего начальная часть до «*» будет удалена. Например, при создании ветки от origin/hack это укажет использовать hack в качестве локальной ветки (или remotes/origin/hack, или даже refs/remotes/origin/hack). Если в указанном имени нет косой черты или в результате такого определения получится пустое имя, определение прерывается. В этом случае можно явно задать имя с помощью -b.

--no-track

Не настраивать конфигурацию «вышестоящей» ветки, даже если переменная конфигурации branch.autoSetupMerge имеет значение true.

--guess
--no-guess

Если <branch> не найдена, но в единственном удалённом репозитории существует ветка отслеживания с таким же именем (назовём её <remote>), считать параметр эквивалентным

$ git checkout -b <branch> --track <remote>/<branch>

Если ветка существует в нескольких удалённых репозиториях и один из них указан переменной конфигурации checkout.defaultRemote, для устранения неоднозначности будет выбран именно он, даже если <branch> не является уникальным среди всех удалённых репозиториев. Например, задайте checkout.defaultRemote=origin, чтобы всегда переключаться на удалённые ветки из этого репозитория, если <branch> неоднозначно, но существует в удалённом репозитории origin. См. также checkout.defaultRemote на странице git-config[1].

--guess — поведение по умолчанию. Чтобы отключить его, используйте --no-guess.

Поведение по умолчанию можно задать с помощью переменной конфигурации checkout.guess.

-l

Создать журнал ссылок новой ветки; подробности см. в git-branch[1].

-d
--detach

Вместо переключения на ветку для работы с ней переключиться на коммит для просмотра и экспериментов, которые можно отбросить. Это поведение по умолчанию для git checkout <commit>, если <commit> не является именем ветки. Подробности см. в разделе «ОТДЕЛЁННЫЙ HEAD» ниже.

--orphan <new-branch>

Создать новую ветку без коммитов с именем <new-branch>, начав её с <start-point>, и переключиться на неё. Первый коммит в этой новой ветке не будет иметь родителей и станет корнем новой истории, полностью не связанной с другими ветками и коммитами.

Индекс и рабочее дерево будут приведены в состояние, как если бы ранее была выполнена команда git checkout <start-point>. Это позволяет начать новую историю, в которой будет записан набор путей, похожий на <start-point>, выполнив команду git commit -a для создания корневого коммита.

Это может быть полезно, если нужно опубликовать дерево из коммита, не раскрывая всю его историю. Например, так можно опубликовать ветку проекта с открытым исходным кодом, дерево которой сейчас «чистое», но полная история содержит проприетарные или иным образом обременённые фрагменты кода.

Если нужно начать несвязанную историю, в которой будет записан набор путей, полностью отличный от набора в <start-point>, после создания ветки без предков следует очистить индекс и рабочее дерево, выполнив команду git rm -rf . из корневого каталога рабочего дерева. После этого можно подготовить новые файлы, заполнив рабочее дерево копированием из других мест, распаковкой tar-архива и т. п.

--ignore-skip-worktree-bits

В режиме разреженного извлечения команда git checkout -- <path>... обновляет только записи, соответствующие <paths> и шаблонам разреженного извлечения в $GIT_DIR/info/sparse-checkout. Этот параметр игнорирует шаблоны разреженного извлечения и добавляет обратно все файлы из <path>....

-m
--merge

При переключении веток, если у вас есть локальные изменения в одном или нескольких файлах, отличающихся между текущей веткой и веткой, на которую вы переключаетесь, команда откажется переключать ветки, чтобы сохранить изменения в контексте. С этим параметром конфликтующие локальные изменения автоматически сохраняются во временное хранилище перед переключением и применяются повторно после него. Если локальные изменения не пересекаются с различиями между ветками, переключение происходит без временного сохранения. Если при повторном применении временно сохранённых изменений возникают конфликты, запись сохраняется в списке временного хранилища. Устраните конфликты и по завершении выполните git stash drop либо очистите рабочее дерево (например, с помощью git reset --hard), а затем позднее выполните git stash pop, чтобы повторно применить изменения.

При извлечении путей из индекса этот параметр позволяет восстановить конфликтное слияние для указанных путей. Его нельзя использовать при извлечении путей из дерева.

--conflict=<style>

То же, что и описанный выше параметр --merge, но изменяет способ отображения конфликтующих фрагментов, переопределяя переменную конфигурации merge.conflictStyle. Возможные значения: merge (по умолчанию), diff3 и zdiff3.

-p
--patch

Интерактивно выбрать фрагменты различий между <tree-ish> (или индексом, если он не указан) и рабочим деревом. Выбранные фрагменты затем применяются к рабочему дереву в обратном направлении (а если указан <tree-ish>, то и к индексу).

Это означает, что с помощью git checkout -p можно выборочно отменять изменения в текущем рабочем дереве. О том, как работать в режиме --patch, см. раздел «Интерактивный режим» на странице git-add[1].

Обратите внимание: по умолчанию этот параметр использует режим без наложения (см. также --overlay); режим с наложением сейчас не поддерживается.

-U<n>
--unified=<n>

Создавать различия с <n> строками контекста. Количество строк контекста по умолчанию равно diff.context или 3, если переменная конфигурации не задана. (-U без <n> принимается без предупреждения как синоним -p из-за исторической особенности).

--inter-hunk-context=<n>

Показывать контекст между фрагментами различий, до указанного <number> строк, объединяя тем самым близко расположенные фрагменты. По умолчанию используется diff.interHunkContext или 0, если параметр конфигурации не задан.

--ignore-other-worktrees

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

--overwrite-ignore
--no-overwrite-ignore

При переключении веток без предупреждения перезаписывать игнорируемые файлы. Это поведение по умолчанию. Используйте --no-overwrite-ignore, чтобы прервать операцию, если в новой ветке есть игнорируемые файлы.

--recurse-submodules
--no-recurse-submodules

Использование --recurse-submodules обновит содержимое всех активных подмодулей в соответствии с коммитом, записанным в суперпроекте. Если локальные изменения в подмодуле будут перезаписаны, извлечение завершится ошибкой, если не использовать -f. Если не задано ничего (или задано --no-recurse-submodules), рабочие деревья подмодулей не обновляются. Как и git-submodule[1], эта команда отсоединит HEAD подмодуля.

--overlay
--no-overlay

В режиме наложения, используемом по умолчанию, команда git checkout никогда не удаляет файлы из индекса или рабочего дерева. При указании --no-overlay файлы, присутствующие в индексе и рабочем дереве, но отсутствующие в <tree-ish>, удаляются, чтобы точно привести их в соответствие с <tree-ish>.

--pathspec-from-file=<file>

Спецификация путей передаётся в <file> вместо аргументов командной строки. Если <file> равно в точности -, используется стандартный ввод. Элементы спецификации путей разделяются символом LF или CR/LF. Элементы спецификации путей можно заключать в кавычки, как описано для переменной конфигурации core.quotePath (см. git-config[1]). См. также --pathspec-file-nul и глобальный параметр --literal-pathspecs.

--pathspec-file-nul

Имеет смысл только вместе с --pathspec-from-file. Элементы спецификации путей разделяются символом NUL, все остальные символы воспринимаются буквально (включая символы новой строки и кавычки).

<branch>

Ветка для переключения; если параметр указывает на ветку (то есть имя, которое после добавления префикса «refs/heads/» является допустимой ссылкой), будет извлечена эта ветка. В противном случае, если он указывает на допустимый коммит, ваш HEAD станет «отделённым», и вы перестанете находиться в какой-либо ветке (подробности см. ниже).

Можно использовать синтаксис @{-N}, чтобы обратиться к N-й последней ветке или коммиту, на которые переключались с помощью команды «git checkout». Также можно указать -, что является синонимом @{-1}.

В особом случае можно использовать <rev-a>...<rev-b> как сокращённую запись базового коммита слияния для <rev-a> и <rev-b>, если такой базовый коммит ровно один. Можно опустить не более одного из <rev-a> и <rev-b>; в таком случае вместо него используется HEAD.

<new-branch>

Имя новой ветки.

<start-point>

Имя коммита, с которого начинается новая ветка; подробности см. в git-branch[1]. По умолчанию используется HEAD.

В особом случае можно использовать <rev-a>...<rev-b> как сокращённую запись базового коммита слияния для <rev-a> и <rev-b>, если такой базовый коммит ровно один. Можно опустить не более одного из <rev-a> и <rev-b>; в таком случае вместо него используется HEAD.

<tree-ish>

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

В особом случае можно использовать <rev-a>...<rev-b> как сокращённую запись базового коммита слияния для <rev-a> и <rev-b>, если такой базовый коммит ровно один. Можно опустить не более одного из <rev-a> и <rev-b>; в таком случае вместо него используется HEAD.

--

Не интерпретировать следующие аргументы как параметры.

<pathspec>...

Ограничивает набор путей, затрагиваемых операцией.

Подробности см. в записи pathspec глоссария gitglossary[7].

Отделённый HEAD

HEAD обычно указывает на именованную ветку (например, master). При этом каждая ветка указывает на определённый коммит. Рассмотрим репозиторий с тремя коммитами, один из которых помечен тегом, и с извлечённой веткой master:

           HEAD (refers to branch 'master')
            |
            v
a---b---c  branch 'master' (refers to commit 'c')
    ^
    |
  tag 'v2.0' (refers to commit 'b')

Когда в таком состоянии создаётся коммит, ветка обновляется и начинает указывать на новый коммит. В частности, команда git commit создаёт новый коммит d, родителем которого является коммит c, а затем обновляет ветку master, чтобы она указывала на новый коммит d. HEAD по-прежнему указывает на ветку master и поэтому теперь косвенно указывает на коммит d:

$ edit; git add; git commit

               HEAD (refers to branch 'master')
                |
                v
a---b---c---d  branch 'master' (refers to commit 'd')
    ^
    |
  tag 'v2.0' (refers to commit 'b')

Иногда бывает полезно переключиться на коммит, не являющийся вершиной какой-либо именованной ветки, или даже создать коммит, на который не указывает ни одна именованная ветка. Посмотрим, что произойдёт при переключении на коммит b (здесь показаны два способа сделать это):

$ git checkout v2.0  # or
$ git checkout master^^

   HEAD (refers to commit 'b')
    |
    v
a---b---c---d  branch 'master' (refers to commit 'd')
    ^
    |
  tag 'v2.0' (refers to commit 'b')

Обратите внимание: независимо от используемой команды переключения HEAD теперь указывает непосредственно на коммит b. Это называется состоянием с отделённым HEAD. Это просто означает, что HEAD указывает на определённый коммит, а не на именованную ветку. Посмотрим, что произойдёт при создании коммита:

$ edit; git add; git commit

     HEAD (refers to commit 'e')
      |
      v
      e
     /
a---b---c---d  branch 'master' (refers to commit 'd')
    ^
    |
  tag 'v2.0' (refers to commit 'b')

Теперь есть новый коммит e, на который указывает только HEAD. Разумеется, в этом состоянии можно создать ещё один коммит:

$ edit; git add; git commit

         HEAD (refers to commit 'f')
          |
          v
      e---f
     /
a---b---c---d  branch 'master' (refers to commit 'd')
    ^
    |
  tag 'v2.0' (refers to commit 'b')

Фактически можно выполнять все обычные операции Git. Но посмотрим, что произойдёт, если затем переключиться на master:

$ git checkout master

               HEAD (refers to branch 'master')
      e---f     |
     /          v
a---b---c---d  branch 'master' (refers to commit 'd')
    ^
    |
  tag 'v2.0' (refers to commit 'b')

Важно понимать, что теперь на коммит f ничто не указывает. В конечном итоге коммит f (и, соответственно, коммит e) будет удалён в ходе обычной сборки мусора Git, если до этого не создать ссылку. Если мы ещё не ушли с коммита f, ссылку на него создаст любая из следующих команд:

$ git checkout -b foo  # or "git switch -c foo"  (1)
$ git branch foo                                 (2)
$ git tag foo                                    (3)
  1. создаёт новую ветку foo, которая указывает на коммит f, а затем переключает HEAD на ветку foo. Иными словами, после этой команды состояние с отделённым HEAD завершится.

  2. аналогичным образом создаёт новую ветку foo, которая указывает на коммит f, но оставляет HEAD отделённым.

  3. создаёт новый тег foo, который указывает на коммит f, оставляя HEAD отделённым.

Если мы уже ушли с коммита f, сначала нужно восстановить имя его объекта (обычно с помощью git reflog), после чего можно создать на него ссылку. Например, чтобы увидеть два последних коммита, на которые указывал HEAD, можно выполнить одну из следующих команд:

$ git reflog -2 HEAD # or
$ git log -g -2 HEAD

Разрешение неоднозначности аргументов

При выполнении команды git checkout <something> Git пытается определить, означает ли <something> ветку, коммит или набор файлов, а затем либо переключается на эту ветку или коммит, либо восстанавливает указанные файлы.

Если возможны разные трактовки, Git считает, что <something> — это ветка или коммит. Чтобы принудительно указать Git трактовать параметр как список файлов и/или каталогов, можно использовать двойной дефис --, например:

git checkout -- file.txt

Примеры

1. Пути

Следующая последовательность переключается на ветку master, возвращает Makefile на две ревизии назад, по ошибке удаляет hello.c, а затем восстанавливает его из индекса.

$ git checkout master             (1)
$ git checkout master~2 Makefile  (2)
$ rm -f hello.c
$ git checkout hello.c            (3)
  1. переключиться на ветку

  2. взять файл из другого коммита

  3. восстановить hello.c из индекса

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

$ git checkout -- '*.c'

Обратите внимание на кавычки вокруг *.c. Файл hello.c также будет извлечён, хотя его уже нет в рабочем дереве, потому что шаблон подстановки файлов используется для поиска записей в индексе (а не в рабочем дереве оболочкой).

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

$ git checkout -- hello.c

2. Слияние

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

$ git checkout mytopic

Однако «неправильная» ветка и нужная ветка mytopic могут различаться файлами, которые вы изменили локально. В этом случае выполнение приведённой выше команды checkout завершится ошибкой, например, так:

$ git checkout mytopic
error: You have local changes to 'frotz'; not switching branches.

К команде можно добавить флаг -m, который перенесёт ваши локальные изменения в новую ветку:

$ git checkout -m mytopic
Applied autostash.
Switched to branch 'mytopic'
The following paths have local changes:
M        frotz

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

3. Конфликт слияния

Если указан параметр --merge (-m) и локальные изменения пересекаются с изменениями в ветке, на которую выполняется переключение, изменения сохраняются в stash и повторно применяются после переключения. Если в результате этого процесса возникают конфликты, запись stash сохраняется и выводится сообщение:

$ git checkout -m mytopic
Your local changes are stashed, however applying them
resulted in conflicts.  You can either resolve the conflicts
and then discard the stash with "git stash drop", or, if you
do not want to resolve them now, run "git reset --hard" and
apply the local changes later by running "git stash pop".

Настройка

Всё содержимое этого раздела после данной строки выборочно включено из документации git-config[1]. Содержимое совпадает с приведённым там:

checkout.defaultRemote

Если выполнить команду git checkout <something> или git switch <something> и у вас есть только один удалённый репозиторий, Git может неявно переключиться на ветку и отслеживать, например, origin/<something>. Это перестаёт работать, если у вас есть более одного удалённого репозитория с ссылкой <something>. Эта настройка позволяет указать имя предпочтительного удалённого репозитория, который всегда будет выбираться при разрешении неоднозначности. Обычно в этом качестве указывают origin.

В настоящее время эта настройка используется командами git-switch[1] и git-checkout[1], когда команды git checkout <something> или git switch <something> переключаются на ветку <something> в другом удалённом репозитории, а также командой git-worktree[1], когда git worktree add указывает на удалённую ветку. В будущем эта настройка может использоваться другими командами или функциями, подобными checkout.

checkout.guess

Задаёт значение по умолчанию для параметра --guess или --no-guess в командах git checkout и git switch. См. git-switch[1] и git-checkout[1].

checkout.workers

Количество параллельных рабочих процессов, используемых при обновлении рабочего дерева. По умолчанию используется один рабочий процесс, то есть выполнение происходит последовательно. Если задано значение меньше единицы, Git использует столько рабочих процессов, сколько доступно логических ядер. Эта настройка и checkout.thresholdForParallelism влияют на все команды, выполняющие checkout, например checkout, clone, reset, sparse-checkout и т. д.

Примечание
Параллельный checkout обычно обеспечивает более высокую производительность для репозиториев, расположенных на SSD или доступных через NFS. Для репозиториев на обычных жёстких дисках и/или машин с небольшим числом ядер последовательный checkout по умолчанию часто работает быстрее. На производительность параллельной версии также могут влиять размер репозитория и степень сжатия.
checkout.thresholdForParallelism

При выполнении параллельного checkout с небольшим количеством файлов затраты на запуск подпроцессов и межпроцессное взаимодействие могут превысить выигрыш от распараллеливания. Эта настройка позволяет определить минимальное количество файлов, при котором следует пытаться выполнить параллельный checkout. По умолчанию используется значение 100.

См. также

git-switch[1], git-restore[1]

checkout

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

Spec-Zone.ru

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