Русский ▾ Topics ▾ Latest version ▾ git-worktree last updated in 2.54.0

НАЗВАНИЕ

git-worktree — управление несколькими рабочими каталогами

ОБЗОР

git worktree add [-f] [--detach] [--checkout] [--lock [--reason <строка>]]
		 [--orphan] [(-b | -B) <новая-ветка>] <путь> [<указатель-коммита>]
git worktree list [-v | --porcelain [-z]]
git worktree lock [--reason <строка>] <рабочий-каталог>
git worktree move <рабочий-каталог> <новый-путь>
git worktree prune [-n] [-v] [--expire <срок>]
git worktree remove [-f] <рабочий-каталог>
git worktree repair [<путь>…​]
git worktree unlock <рабочий-каталог>

ОПИСАНИЕ

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

Репозиторий git может поддерживать несколько рабочих каталогов, позволяя вам переключать более одной ветки одновременно. С помощью git worktree add с репозиторием связывается новый рабочий каталог вместе с дополнительными метаданными, которые отличают этот рабочий каталог от других в том же репозитории. Рабочий каталог вместе с этими метаданными называется "рабочим каталогом (worktree)".

Этот новый рабочий каталог называется "связанным рабочим каталогом" в отличие от "основного рабочего каталога", подготовленного git-init[1] или git-clone[1]. Репозиторий имеет один основной рабочий каталог (если это не голый репозиторий) и ноль или более связанных рабочих каталогов. Когда вы закончили работу со связанным рабочим каталогом, удалите его с помощью git worktree remove.

В своей простейшей форме git worktree add <путь> автоматически создаёт новую ветку, имя которой является последним компонентом <пути>, что удобно, если вы планируете работать над новой темой. Например, git worktree add ../hotfix создаёт новую ветку hotfix и переключает её по пути ../hotfix. Чтобы вместо этого работать над существующей веткой в новом рабочем каталоге, используйте git worktree add <путь> <ветка>. С другой стороны, если вы просто планируете внести некоторые экспериментальные изменения или выполнить тестирование, не нарушая существующую разработку, часто удобно создать "одноразовый" рабочий каталог, не связанный ни с какой веткой. Например, git worktree add -d <путь> создаёт новый рабочий каталог с отсоединённым HEAD в том же коммите, что и текущая ветка.

Если рабочий каталог удалён без использования git worktree remove, то его связанные служебные файлы, которые находятся в репозитории (см. "ПОДРОБНОСТИ" ниже), в конечном итоге будут удалены автоматически (см. gc.worktreePruneExpire в git-config[1]), или вы можете выполнить git worktree prune в основном или любом связанном рабочем каталоге, чтобы очистить устаревшие служебные файлы.

Если рабочий каталог для связанного рабочего каталога хранится на портативном устройстве или сетевом ресурсе, который подключён не всегда, вы можете предотвратить подчистку его служебных файлов, выполнив команду git worktree lock, опционально указав --reason, чтобы объяснить, почему рабочий каталог заблокирован.

КОМАНДЫ

add <путь> [<указатель-на-коммит>]

Создать рабочий каталог по пути <путь> и переключить в него <указатель-коммита>. Новый рабочий каталог связывается с текущим репозиторием, разделяя всё, кроме файлов, относящихся к рабочему каталогу, таких как HEAD, index и т.д. Для удобства <указатель-коммита> может быть просто "-", что является синонимом @{-1}.

Если <указатель-коммита> является именем ветки (назовём её <ветка>) и не найден, и не используются ни -b, ни -B, ни --detach, но существует отслеживаемая ветка ровно в одном внешнем репозитории (назовём его <внешний-репозиторий>) с совпадающим именем, обрабатывать как эквивалент:

$ git worktree add --track -b <ветка> <путь> <внешний-репозиторий>/<ветка>

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

Если <указатель-коммита> опущен и не используются ни -b, ни -B, ни --detach, то для удобства новый рабочий каталог связывается с веткой (назовём её <ветка>), названной в честь $(basename <путь>). Если <ветка> не существует, автоматически создаётся новая ветка на основе HEAD, как если бы было указано -b <ветка>. Если <ветка> существует, она будет переключена в новом рабочем каталоге, если она больше нигде не переключена, в противном случае команда откажется создавать рабочий каталог (если не используется --force).

Если <указатель-коммита> опущен, не используются ни --detach, ни --orphan, и нет допустимых локальных веток (или внешних веток, если указан --guess-remote), то для удобства новый рабочий каталог связывается с новой нерождённой веткой с именем <ветка> (по $(basename <путь>), если не используются ни -b, ни -B), как если бы команде был передан --orphan. В случае, если у репозитория есть внешний репозиторий и используется --guess-remote, но не существует ни внешних, ни локальных веток, команда завершается ошибкой с предупреждением, напоминающим пользователю о необходимости сначала выполнить получение из внешнего репозитория (или переопределить, используя -f/--force).

list

Выводит список подробностей о каждом рабочем каталоге. Сначала указывается основной рабочий каталог, за ним каждый из связанных рабочих каталогов. Подробности вывода включают, является ли рабочий каталог голым, какая редакция в данный момент переключена, какая ветка в данный момент переключена (или "отсоединённый HEAD", если никакая), "locked", если рабочий каталог заблокирован, "prunable", если рабочий каталог может быть подчищён командой prune.

lock

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

move

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

prune

Удаляет информацию о рабочем каталоге в $GIT_DIR/worktrees для рабочих каталогов, чьи рабочие деревья отсутствуют. Полезно после ручного удаления рабочего каталога, который больше не нужен (но в следующий раз, когда вы захотите это сделать, используйте "git worktree remove"). Кроме того, если вы переместили рабочий каталог в другое место, в результате чего информация о рабочем каталоге стала болтающейся, обратитесь к "git worktree repair", чтобы восстановить связь рабочего каталога с новым местоположением рабочего дерева.

remove

Удаляет рабочий каталог. Могут быть удалены только чистые рабочие каталоги (без неотслеживаемых файлов и без изменений в отслеживаемых файлах). Нечистые рабочие каталоги или содержащие подмодули могут быть удалены с помощью --force. Основной рабочий каталог не может быть удалён.

repair [<путь>...]

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

Например, если основной рабочий каталог (или голый репозиторий) перемещён, связанные рабочие каталоги не смогут его найти. Выполнение repair в основном рабочем каталоге восстановит связь от связанных рабочих каталогов обратно к основному рабочему каталогу.

Аналогично, если рабочий каталог для связанного рабочего каталога перемещён без использования git worktree move, основной рабочий каталог (или голый репозиторий) не сможет его найти. Выполнение repair в недавно перемещённом рабочем каталоге восстановит связь. Если перемещено несколько связанных рабочих каталогов, выполнение repair из любого рабочего каталога с новым <путь> каждого дерева в качестве аргумента восстановит связь со всеми указанными путями.

Если и основной рабочий каталог, и связанные рабочие каталоги были перемещены или скопированы вручную, то выполнение repair в основном рабочем каталоге и указание нового <пути> каждого связанного рабочего каталога восстановит все связи в обоих направлениях.

unlock

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

ПАРАМЕТРЫ

-f
--force

По умолчанию add отказывается создавать новый рабочий каталог, когда <указатель-коммита> является именем ветки и уже переключён другим рабочим каталогом, или если <путь> уже назначен какому-то рабочему каталогу, но отсутствует (например, если <путь> был удалён вручную). Этот параметр переопределяет эти защиты. Чтобы добавить отсутствующий, но заблокированный путь рабочего каталога, укажите --force дважды.

move отказывается перемещать заблокированный рабочий каталог, если --force не указан дважды. Если место назначения уже назначено какому-то другому рабочему каталогу, но отсутствует (например, если <новый-путь> был удалён вручную), то --force разрешает перемещение; используйте --force дважды, если место назначения заблокировано.

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

-b <новая-ветка>
-B <новая-ветка>

С add создаёт новую ветку с именем <новая-ветка>, начинающуюся с <указатель-коммита>, и переключает <новую-ветку> в новый рабочий каталог. Если <указатель-коммита> опущен, по умолчанию используется HEAD. По умолчанию -b отказывается создавать новую ветку, если она уже существует. -B переопределяет эту защиту, сбрасывая <новую-ветку> на <указатель-коммита>.

-d
--detach

С add отсоединяет HEAD в новом рабочем каталоге. См. "ОТСОЕДИНЁННЫЙ HEAD" в git-checkout[1].

--checkout
--no-checkout

По умолчанию add переключает <указатель-коммита>, однако --no-checkout можно использовать для отмены переключения, чтобы выполнить настройки, такие как настройка частичного переключения. См. "Частичное переключение" в git-read-tree[1].

--guess-remote
--no-guess-remote

С worktree add <путь>, без <указатель-коммита>, вместо создания новой ветки из HEAD, если существует отслеживаемая ветка ровно в одном внешнем репозитории, совпадающая с базовым именем <пути>, основать новую ветку на отслеживаемой внешней ветке и пометить отслеживаемую внешнюю ветку как "вышестоящую" для новой ветки.

Это также может быть настроено как поведение по умолчанию с помощью параметра конфигурации worktree.guessRemote.

--relative-paths
--no-relative-paths

Связывать рабочие каталоги, используя относительные пути или абсолютные пути (по умолчанию). Переопределяет параметр конфигурации worktree.useRelativePaths, см. git-config[1].

С repair файлы связей будут обновлены, если есть несоответствие абсолютного/относительного пути, даже если связи верны.

--track
--no-track

При создании новой ветки, если <указатель-коммита> является веткой, пометить её как "вышестоящую" для новой ветки. Это поведение по умолчанию, если <указатель-коммита> является отслеживаемой внешней веткой. Подробности см. в описании --track в git-branch[1].

--lock

Оставить рабочий каталог заблокированным после создания. Это эквивалентно выполнению git worktree lock после git worktree add, но без состояния гонки.

-n
--dry-run

С prune ничего не удалять; просто сообщить, что было бы удалено.

--orphan

С add сделать новый рабочий каталог и индекс пустыми, связывая рабочий каталог с новой нерождённой веткой с именем <новая-ветка>.

--porcelain

С list выводить в формате, удобном для анализа сценариями. Этот формат останется стабильным во всех версиях Git и независимо от конфигурации пользователя. Рекомендуется комбинировать это с -z. Подробности см. ниже.

-z

Завершать каждую строку символом NUL вместо символа новой строки, когда с list указан --porcelain. Это позволяет анализировать вывод, когда путь рабочего каталога содержит символ новой строки.

-q
--quiet

С add подавлять информационные сообщения.

-v
--verbose

С prune сообщать обо всех удалениях.

С list выводить дополнительную информацию о рабочих каталогах (см. ниже).

--expire <время>

С prune подчищать (prune) отсутствующие рабочие копии, только если они старше <время>.

С list помечать отсутствующие рабочие каталоги как подлежащие подчистке, если они старше <времени>.

--reason <строка>

С lock или с add --lock указывает причину, по которой рабочий каталог заблокирован.

<рабочий-каталог>

Рабочие каталоги могут быть идентифицированы по пути, относительному или абсолютному.

Если последние компоненты пути рабочего каталога уникальны среди рабочих каталогов, их можно использовать для идентификации рабочего каталога. Например, если у вас есть только два рабочих каталога, /abc/def/ghi и /abc/def/ggg, то ghi или def/ghi достаточно, чтобы указать на первый рабочий каталог.

ССЫЛКИ

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

В общем, все псевдоссылки относятся к рабочему каталогу, а все ссылки, начинающиеся с refs/, являются общими. Псевдоссылки — это такие ссылки, как HEAD, которые находятся непосредственно в $GIT_DIR, а не внутри $GIT_DIR/refs. Однако есть исключения: ссылки внутри refs/bisect, refs/worktree и refs/rewritten не являются общими.

К ссылкам, относящимся к рабочему каталогу, всё равно можно получить доступ из другого рабочего каталога через два специальных пути: main-worktree и worktrees. Первый предоставляет доступ к ссылкам основного рабочего каталога, а второй — ко всем связанным рабочим каталогам.

Например, main-worktree/HEAD или main-worktree/refs/bisect/good преобразуются в то же значение, что и HEAD основного рабочего каталога и refs/bisect/good соответственно. Аналогично, worktrees/foo/HEAD или worktrees/bar/refs/bisect/bad совпадают с $GIT_COMMON_DIR/worktrees/foo/HEAD и $GIT_COMMON_DIR/worktrees/bar/refs/bisect/bad.

Для доступа к ссылкам лучше не заглядывать внутрь $GIT_DIR напрямую. Вместо этого используйте такие команды, как git-rev-parse[1] или git-update-ref[1], которые будут правильно обрабатывать ссылки.

ФАЙЛ КОНФИГУРАЦИИ

По умолчанию файл config репозитория является общим для всех рабочих каталогов. Если переменные конфигурации core.bare или core.worktree присутствуют в общем файле конфигурации и extensions.worktreeConfig отключён, то они будут применяться только к основному рабочему каталогу.

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

$ git config extensions.worktreeConfig true

В этом режиме специфическая конфигурация хранится по пути, на который указывает git rev-parse --git-path config.worktree. Вы можете добавлять или обновлять конфигурацию в этом файле с помощью git config --worktree. Более старые версии Git откажутся от доступа к репозиториям с этим расширением.

Обратите внимание, что в этом файле исключение для core.bare и core.worktree отсутствует. Если они существуют в $GIT_DIR/config, вы должны переместить их в config.worktree основного рабочего каталога. Вы также можете воспользоваться этой возможностью, чтобы просмотреть и переместить другую конфигурацию, которую вы не хотите распространять на все рабочие каталоги:

  • core.worktree никогда не должен быть общим.

  • core.bare не должен быть общим, если значение равно core.bare=true.

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

Более подробную информацию см. в документации по extensions.worktreeConfig в git-config[1].

ОПИСАНИЕ

Каждый связанный рабочий каталог имеет частный подкаталог в каталоге $GIT_DIR/worktrees репозитория. Имя частного подкаталога обычно является базовым именем пути связанного рабочего каталога, возможно, с добавленным номером для обеспечения уникальности. Например, когда $GIT_DIR=/path/main/.git, команда git worktree add /path/other/test-next next создаёт связанный рабочий каталог в /path/other/test-next, а также создаёт каталог $GIT_DIR/worktrees/test-next (или $GIT_DIR/worktrees/test-next1, если test-next уже занято).

Внутри связанного рабочего каталога $GIT_DIR устанавливается так, чтобы указывать на этот частный каталог (например, /path/main/.git/worktrees/test-next в примере), а $GIT_COMMON_DIR устанавливается так, чтобы указывать обратно на $GIT_DIR основного рабочего каталога (например, /path/main/.git). Эти настройки производятся в файле .git, расположенном в верхнем каталоге связанного рабочего каталога.

Разрешение пути с помощью git rev-parse --git-path использует либо $GIT_DIR, либо $GIT_COMMON_DIR в зависимости от пути. Например, в связанном рабочем каталоге git rev-parse --git-path HEAD возвращает /path/main/.git/worktrees/test-next/HEAD (не /path/other/test-next/.git/HEAD или /path/main/.git/HEAD), в то время как git rev-parse --git-path refs/heads/master использует $GIT_COMMON_DIR и возвращает /path/main/.git/refs/heads/master, поскольку ссылки являются общими для всех рабочих каталогов, за исключением refs/bisect, refs/worktree и refs/rewritten.

Дополнительную информацию см. в gitrepository-layout[5]. Эмпирическое правило: не делайте никаких предположений о том, принадлежит ли путь $GIT_DIR или $GIT_COMMON_DIR, когда вам нужно напрямую получить доступ к чему-либо внутри $GIT_DIR. Используйте git rev-parse --git-path, чтобы получить окончательный путь.

Если вы вручную перемещаете связанный рабочий каталог, вам нужно обновить файл gitdir в каталоге записи. Например, если связанный рабочий каталог перемещён в /newpath/test-next, и его файл .git указывает на /path/main/.git/worktrees/test-next, то обновите /path/main/.git/worktrees/test-next/gitdir, чтобы он ссылался на /newpath/test-next. Ещё лучше выполните git worktree repair, чтобы автоматически восстановить связь.

Чтобы предотвратить подчистку записи $GIT_DIR/worktrees (что может быть полезно в некоторых ситуациях, например, когда рабочий каталог записи хранится на портативном устройстве), используйте команду git worktree lock, которая добавляет файл с именем locked в каталог записи. Файл содержит причину в обычном тексте. Например, если файл .git связанного рабочего каталога указывает на /path/main/.git/worktrees/test-next, то файл с именем /path/main/.git/worktrees/test-next/locked предотвратит подчистку записи test-next. Подробности см. в gitrepository-layout[5].

Когда extensions.worktreeConfig включён, файл конфигурации .git/worktrees/<id>/config.worktree читается после .git/config.

ФОРМАТ ВЫВОДА СПИСКА

Команда worktree list имеет два формата вывода. Формат по умолчанию показывает подробности в одной строке с колонками. Например:

$ git worktree list
/путь/к/голому-источнику            (bare)
/путь/к/связанному-рабочему-каталогу        abcd1234 [master]
/путь/к/другому-связанному-рабочему-каталогу  1234abc  (detached HEAD)

Команда также показывает аннотации для каждого рабочего каталога в соответствии с его состоянием. Эти аннотации:

  • locked, если рабочая копия заблокирована.

  • prunable, если рабочий каталог может быть подчищён с помощью git worktree prune.

$ git worktree list
/путь/к/связанному-рабочему-каталогу    abcd1234 [master]
/путь/к/заблокированному-рабочему-каталогу    acbd5678 (brancha) locked
/путь/к/подлежащему-подчистке-рабочему-каталогу  5678abc  (detached HEAD) prunable

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

$ git worktree list --verbose
/путь/к/связанному-рабочему-каталогу              abcd1234 [master]
/путь/к/заблокированному-рабочему-каталогу-без-причины    abcd5678 (detached HEAD) locked
/путь/к/заблокированному-рабочему-каталогу-с-причиной  1234abcd (brancha)
	locked: путь рабочего каталога смонтирован на портативном устройстве
/путь/к/подлежащему-подчистке-рабочему-каталогу            5678abc1 (detached HEAD)
	prunable: файл gitdir указывает на несуществующее местоположение

Обратите внимание, что аннотация перемещается на следующую строку, если доступна дополнительная информация, в противном случае она остаётся на той же строке, что и сам рабочий каталог.

Фарфоровый формат

Фарфоровый формат имеет одну строку на атрибут. Если указан -z, строки завершаются NUL вместо символа новой строки. Атрибуты перечисляются с меткой и значением, разделёнными одним пробелом. Булевы атрибуты (например, bare и detached) перечисляются только как метка и присутствуют только в том случае, если значение истинно. Некоторые атрибуты (например, locked) могут перечисляться только как метка или со значением в зависимости от того, доступна ли причина. Первым атрибутом рабочего каталога всегда является worktree, пустая строка указывает на конец записи. Например:

$ git worktree list --porcelain
worktree /путь/к/голому-источнику
bare

worktree /путь/к/связанному-рабочему-каталогу
HEAD abcd1234abcd1234abcd1234abcd1234abcd1234
branch refs/heads/master

worktree /путь/к/другому-связанному-рабочему-каталогу
HEAD 1234abc1234abc1234abc1234abc1234abc1234a
detached

worktree /путь/к/связанному-рабочему-каталогу-заблокированному-без-причины
HEAD 5678abc5678abc5678abc5678abc5678abc5678c
branch refs/heads/locked-no-reason
locked

worktree /путь/к/связанному-рабочему-каталогу-заблокированному-с-причиной
HEAD 3456def3456def3456def3456def3456def3456b
branch refs/heads/locked-with-reason
locked причина почему заблокирован

worktree /путь/к/связанному-рабочему-каталогу-подлежащему-подчистке
HEAD 1233def1234def1234def1234def1234def1234b
detached
prunable файл gitdir указывает на несуществующее местоположение

Если не используется -z, любые "необычные" символы в причине блокировки, такие как переводы строк, экранируются, и вся причина заключается в кавычки, как объяснено для переменной конфигурации core.quotePath (см. git-config[1]). Например:

$ git worktree list --porcelain
...
locked "причина\nпочему заблокирован"
...

ПРИМЕРЫ

Вы находитесь в середине сеанса рефакторинга, и ваш начальник входит и требует, чтобы вы немедленно что-то исправили. Обычно вы можете использовать git-stash[1], чтобы временно сохранить ваши изменения, однако ваш рабочий каталог находится в таком состоянии беспорядка (с новыми, перемещёнными и удалёнными файлами, а также другими разбросанными частями), что вы не хотите рисковать, нарушая что-либо. Вместо этого вы создаёте временный связанный рабочий каталог, чтобы сделать срочное исправление, удаляете его, когда закончите, а затем возобновляете предыдущий сеанс рефакторинга.

$ git worktree add -b emergency-fix ../temp master
$ pushd ../temp
# ... вносим экстренные правки ...
$ git commit -a -m 'emergency fix for boss'
$ popd
$ git worktree remove ../temp

КОНФИГУРАЦИЯ

Дальнейшее содержание этого раздела, повторяет то, что может быть найдено в git-config[1]:

worktree.guessRemote

Если ветка не указана и не используются ни -b, ни -B, ни --detach, то git worktree add по умолчанию создаёт новую ветку из HEAD. Если worktree.guessRemote установлено в true, worktree add пытается найти отслеживаемую внешнюю ветку, имя которой однозначно соответствует имени новой ветки. Если такая ветка существует, она переключается (checkout) и устанавливается как «вышестоящая» (upstream) для новой ветки. Если такого соответствия найти не удаётся, возвращается к созданию новой ветки из текущего HEAD.

worktree.useRelativePaths

Связывать рабочие копии (worktrees), используя относительные пути (когда «true») или абсолютные пути (когда «false»). Это особенно полезно для конфигураций, где репозиторий и рабочие копии могут перемещаться между разными местами или средами. По умолчанию «false».

Обратите внимание, что установка worktree.useRelativePaths в «true» подразумевает включение конфигурации extensions.relativeWorktrees (см. git-config[1]), что делает её несовместимой со старыми версиями Git.

ОШИБКИ

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

GIT

Является частью пакета git[1]