Skip to content

Commit 68a2e6a

Browse files
committed
Merge branch 'nd/multiple-work-trees'
A replacement for contrib/workdir/git-new-workdir that does not rely on symbolic links and make sharing of objects and refs safer by making the borrowee and borrowers aware of each other. * nd/multiple-work-trees: (41 commits) prune --worktrees: fix expire vs worktree existence condition t1501: fix test with split index t2026: fix broken &&-chain t2026 needs procondition SANITY git-checkout.txt: a note about multiple checkout support for submodules checkout: add --ignore-other-wortrees checkout: pass whole struct to parse_branchname_arg instead of individual flags git-common-dir: make "modules/" per-working-directory directory checkout: do not fail if target is an empty directory t2025: add a test to make sure grafts is working from a linked checkout checkout: don't require a work tree when checking out into a new one git_path(): keep "info/sparse-checkout" per work-tree count-objects: report unused files in $GIT_DIR/worktrees/... gc: support prune --worktrees gc: factor out gc.pruneexpire parsing code gc: style change -- no SP before closing parenthesis checkout: clean up half-prepared directories in --to mode checkout: reject if the branch is already checked out elsewhere prune: strategies for linked checkouts checkout: support checking out into a new working directory ...
2 parents 17c7f4d + 562bc08 commit 68a2e6a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+1391
-250
lines changed

Documentation/config.txt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -453,6 +453,8 @@ false), while all other repositories are assumed to be bare (bare
453453

454454
core.worktree::
455455
Set the path to the root of the working tree.
456+
If GIT_COMMON_DIR environment variable is set, core.worktree
457+
is ignored and not used for determining the root of working tree.
456458
This can be overridden by the GIT_WORK_TREE environment
457459
variable and the '--work-tree' command-line option.
458460
The value can be an absolute path or relative to the path to
@@ -1274,6 +1276,13 @@ gc.pruneExpire::
12741276
"now" may be used to disable this grace period and always prune
12751277
unreachable objects immediately.
12761278

1279+
gc.pruneWorktreesExpire::
1280+
When 'git gc' is run, it will call
1281+
'prune --worktrees --expire 3.months.ago'.
1282+
Override the grace period with this config variable. The value
1283+
"now" may be used to disable the grace period and prune
1284+
$GIT_DIR/worktrees immediately.
1285+
12771286
gc.reflogExpire::
12781287
gc.<pattern>.reflogExpire::
12791288
'git reflog expire' removes reflog entries older than

Documentation/git-checkout.txt

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,19 @@ This means that you can use `git checkout -p` to selectively discard
225225
edits from your current working tree. See the ``Interactive Mode''
226226
section of linkgit:git-add[1] to learn how to operate the `--patch` mode.
227227

228+
--to=<path>::
229+
Check out a branch in a separate working directory at
230+
`<path>`. A new working directory is linked to the current
231+
repository, sharing everything except working directory
232+
specific files such as HEAD, index... See "MULTIPLE WORKING
233+
TREES" section for more information.
234+
235+
--ignore-other-worktrees::
236+
`git checkout` refuses when the wanted ref is already checked
237+
out by another worktree. This option makes it check the ref
238+
out anyway. In other words, the ref can be held by more than one
239+
worktree.
240+
228241
<branch>::
229242
Branch to checkout; if it refers to a branch (i.e., a name that,
230243
when prepended with "refs/heads/", is a valid ref), then that
@@ -388,6 +401,71 @@ $ git reflog -2 HEAD # or
388401
$ git log -g -2 HEAD
389402
------------
390403

404+
MULTIPLE WORKING TREES
405+
----------------------
406+
407+
A git repository can support multiple working trees, allowing you to check
408+
out more than one branch at a time. With `git checkout --to` a new working
409+
tree is associated with the repository. This new working tree is called a
410+
"linked working tree" as opposed to the "main working tree" prepared by "git
411+
init" or "git clone". A repository has one main working tree (if it's not a
412+
bare repository) and zero or more linked working trees.
413+
414+
Each linked working tree has a private sub-directory in the repository's
415+
$GIT_DIR/worktrees directory. The private sub-directory's name is usually
416+
the base name of the linked working tree's path, possibly appended with a
417+
number to make it unique. For example, when `$GIT_DIR=/path/main/.git` the
418+
command `git checkout --to /path/other/test-next next` creates the linked
419+
working tree in `/path/other/test-next` and also creates a
420+
`$GIT_DIR/worktrees/test-next` directory (or `$GIT_DIR/worktrees/test-next1`
421+
if `test-next` is already taken).
422+
423+
Within a linked working tree, $GIT_DIR is set to point to this private
424+
directory (e.g. `/path/main/.git/worktrees/test-next` in the example) and
425+
$GIT_COMMON_DIR is set to point back to the main working tree's $GIT_DIR
426+
(e.g. `/path/main/.git`). These settings are made in a `.git` file located at
427+
the top directory of the linked working tree.
428+
429+
Path resolution via `git rev-parse --git-path` uses either
430+
$GIT_DIR or $GIT_COMMON_DIR depending on the path. For example, in the
431+
linked working tree `git rev-parse --git-path HEAD` returns
432+
`/path/main/.git/worktrees/test-next/HEAD` (not
433+
`/path/other/test-next/.git/HEAD` or `/path/main/.git/HEAD`) while `git
434+
rev-parse --git-path refs/heads/master` uses
435+
$GIT_COMMON_DIR and returns `/path/main/.git/refs/heads/master`,
436+
since refs are shared across all working trees.
437+
438+
See linkgit:gitrepository-layout[5] for more information. The rule of
439+
thumb is do not make any assumption about whether a path belongs to
440+
$GIT_DIR or $GIT_COMMON_DIR when you need to directly access something
441+
inside $GIT_DIR. Use `git rev-parse --git-path` to get the final path.
442+
443+
When you are done with a linked working tree you can simply delete it.
444+
The working tree's entry in the repository's $GIT_DIR/worktrees
445+
directory will eventually be removed automatically (see
446+
`gc.pruneworktreesexpire` in linkgit::git-config[1]), or you can run
447+
`git prune --worktrees` in the main or any linked working tree to
448+
clean up any stale entries in $GIT_DIR/worktrees.
449+
450+
If you move a linked working directory to another file system, or
451+
within a file system that does not support hard links, you need to run
452+
at least one git command inside the linked working directory
453+
(e.g. `git status`) in order to update its entry in $GIT_DIR/worktrees
454+
so that it does not get automatically removed.
455+
456+
To prevent a $GIT_DIR/worktrees entry from from being pruned (which
457+
can be useful in some situations, such as when the
458+
entry's working tree is stored on a portable device), add a file named
459+
'locked' to the entry's directory. The file contains the reason in
460+
plain text. For example, if a linked working tree's `.git` file points
461+
to `/path/main/.git/worktrees/test-next` then a file named
462+
`/path/main/.git/worktrees/test-next/locked` will prevent the
463+
`test-next` entry from being pruned. See
464+
linkgit:gitrepository-layout[5] for details.
465+
466+
Multiple checkout support for submodules is incomplete. It is NOT
467+
recommended to make multiple checkouts of a superproject.
468+
391469
EXAMPLES
392470
--------
393471

Documentation/git-prune.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@ OPTIONS
4848
--expire <time>::
4949
Only expire loose objects older than <time>.
5050

51+
--worktrees::
52+
Prune dead working tree information in $GIT_DIR/worktrees.
53+
5154
<head>...::
5255
In addition to objects
5356
reachable from any of our references, keep objects

Documentation/git-rev-parse.txt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,9 @@ If `$GIT_DIR` is not defined and the current directory
216216
is not detected to lie in a Git repository or work tree
217217
print a message to stderr and exit with nonzero status.
218218

219+
--git-common-dir::
220+
Show `$GIT_COMMON_DIR` if defined, else `$GIT_DIR`.
221+
219222
--is-inside-git-dir::
220223
When the current working directory is below the repository
221224
directory print "true", otherwise "false".
@@ -233,6 +236,13 @@ print a message to stderr and exit with nonzero status.
233236
repository. If <path> is a gitfile then the resolved path
234237
to the real repository is printed.
235238

239+
--git-path <path>::
240+
Resolve "$GIT_DIR/<path>" and takes other path relocation
241+
variables such as $GIT_OBJECT_DIRECTORY,
242+
$GIT_INDEX_FILE... into account. For example, if
243+
$GIT_OBJECT_DIRECTORY is set to /foo/bar then "git rev-parse
244+
--git-path objects/abc" returns /foo/bar/abc.
245+
236246
--show-cdup::
237247
When the command is invoked from a subdirectory, show the
238248
path of the top-level directory relative to the current

Documentation/git.txt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -833,6 +833,15 @@ Git so take care if using Cogito etc.
833833
an explicit repository directory set via 'GIT_DIR' or on the
834834
command line.
835835

836+
'GIT_COMMON_DIR'::
837+
If this variable is set to a path, non-worktree files that are
838+
normally in $GIT_DIR will be taken from this path
839+
instead. Worktree-specific files such as HEAD or index are
840+
taken from $GIT_DIR. See linkgit:gitrepository-layout[5] and
841+
the section 'MULTIPLE CHECKOUT MODE' in linkgit:checkout[1]
842+
details. This variable has lower precedence than other path
843+
variables such as GIT_INDEX_FILE, GIT_OBJECT_DIRECTORY...
844+
836845
Git Commits
837846
~~~~~~~~~~~
838847
'GIT_AUTHOR_NAME'::

Documentation/gitrepository-layout.txt

Lines changed: 64 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ of incomplete object store is not suitable to be published for
4646
use with dumb transports but otherwise is OK as long as
4747
`objects/info/alternates` points at the object stores it
4848
borrows from.
49+
+
50+
This directory is ignored if $GIT_COMMON_DIR is set and
51+
"$GIT_COMMON_DIR/objects" will be used instead.
4952

5053
objects/[0-9a-f][0-9a-f]::
5154
A newly created object is stored in its own file.
@@ -92,7 +95,8 @@ refs::
9295
References are stored in subdirectories of this
9396
directory. The 'git prune' command knows to preserve
9497
objects reachable from refs found in this directory and
95-
its subdirectories.
98+
its subdirectories. This directory is ignored if $GIT_COMMON_DIR
99+
is set and "$GIT_COMMON_DIR/refs" will be used instead.
96100

97101
refs/heads/`name`::
98102
records tip-of-the-tree commit objects of branch `name`
@@ -114,7 +118,8 @@ refs/replace/`<obj-sha1>`::
114118
packed-refs::
115119
records the same information as refs/heads/, refs/tags/,
116120
and friends record in a more efficient way. See
117-
linkgit:git-pack-refs[1].
121+
linkgit:git-pack-refs[1]. This file is ignored if $GIT_COMMON_DIR
122+
is set and "$GIT_COMMON_DIR/packed-refs" will be used instead.
118123

119124
HEAD::
120125
A symref (see glossary) to the `refs/heads/` namespace
@@ -133,14 +138,22 @@ being a symref to point at the current branch. Such a state
133138
is often called 'detached HEAD.' See linkgit:git-checkout[1]
134139
for details.
135140

141+
config::
142+
Repository specific configuration file. This file is ignored
143+
if $GIT_COMMON_DIR is set and "$GIT_COMMON_DIR/config" will be
144+
used instead.
145+
136146
branches::
137147
A slightly deprecated way to store shorthands to be used
138148
to specify a URL to 'git fetch', 'git pull' and 'git push'.
139149
A file can be stored as `branches/<name>` and then
140150
'name' can be given to these commands in place of
141151
'repository' argument. See the REMOTES section in
142152
linkgit:git-fetch[1] for details. This mechanism is legacy
143-
and not likely to be found in modern repositories.
153+
and not likely to be found in modern repositories. This
154+
directory is ignored if $GIT_COMMON_DIR is set and
155+
"$GIT_COMMON_DIR/branches" will be used instead.
156+
144157

145158
hooks::
146159
Hooks are customization scripts used by various Git
@@ -149,7 +162,9 @@ hooks::
149162
default. To enable, the `.sample` suffix has to be
150163
removed from the filename by renaming.
151164
Read linkgit:githooks[5] for more details about
152-
each hook.
165+
each hook. This directory is ignored if $GIT_COMMON_DIR is set
166+
and "$GIT_COMMON_DIR/hooks" will be used instead.
167+
153168

154169
index::
155170
The current index file for the repository. It is
@@ -161,7 +176,8 @@ sharedindex.<SHA-1>::
161176

162177
info::
163178
Additional information about the repository is recorded
164-
in this directory.
179+
in this directory. This directory is ignored if $GIT_COMMON_DIR
180+
is set and "$GIT_COMMON_DIR/index" will be used instead.
165181

166182
info/refs::
167183
This file helps dumb transports discover what refs are
@@ -201,12 +217,15 @@ remotes::
201217
when interacting with remote repositories via 'git fetch',
202218
'git pull' and 'git push' commands. See the REMOTES section
203219
in linkgit:git-fetch[1] for details. This mechanism is legacy
204-
and not likely to be found in modern repositories.
220+
and not likely to be found in modern repositories. This
221+
directory is ignored if $GIT_COMMON_DIR is set and
222+
"$GIT_COMMON_DIR/remotes" will be used instead.
205223

206224
logs::
207-
Records of changes made to refs are stored in this
208-
directory. See linkgit:git-update-ref[1]
209-
for more information.
225+
Records of changes made to refs are stored in this directory.
226+
See linkgit:git-update-ref[1] for more information. This
227+
directory is ignored if $GIT_COMMON_DIR is set and
228+
"$GIT_COMMON_DIR/logs" will be used instead.
210229

211230
logs/refs/heads/`name`::
212231
Records all changes made to the branch tip named `name`.
@@ -217,11 +236,46 @@ logs/refs/tags/`name`::
217236
shallow::
218237
This is similar to `info/grafts` but is internally used
219238
and maintained by shallow clone mechanism. See `--depth`
220-
option to linkgit:git-clone[1] and linkgit:git-fetch[1].
239+
option to linkgit:git-clone[1] and linkgit:git-fetch[1]. This
240+
file is ignored if $GIT_COMMON_DIR is set and
241+
"$GIT_COMMON_DIR/shallow" will be used instead.
242+
243+
commondir::
244+
If this file exists, $GIT_COMMON_DIR (see linkgit:git[1]) will
245+
be set to the path specified in this file if it is not
246+
explicitly set. If the specified path is relative, it is
247+
relative to $GIT_DIR. The repository with commondir is
248+
incomplete without the repository pointed by "commondir".
221249

222250
modules::
223251
Contains the git-repositories of the submodules.
224252

253+
worktrees::
254+
Contains worktree specific information of linked
255+
checkouts. Each subdirectory contains the worktree-related
256+
part of a linked checkout. This directory is ignored if
257+
$GIT_COMMON_DIR is set and "$GIT_COMMON_DIR/worktrees" will be
258+
used instead.
259+
260+
worktrees/<id>/gitdir::
261+
A text file containing the absolute path back to the .git file
262+
that points to here. This is used to check if the linked
263+
repository has been manually removed and there is no need to
264+
keep this directory any more. mtime of this file should be
265+
updated every time the linked repository is accessed.
266+
267+
worktrees/<id>/locked::
268+
If this file exists, the linked repository may be on a
269+
portable device and not available. It does not mean that the
270+
linked repository is gone and `worktrees/<id>` could be
271+
removed. The file's content contains a reason string on why
272+
the repository is locked.
273+
274+
worktrees/<id>/link::
275+
If this file exists, it is a hard link to the linked .git
276+
file. It is used to detect if the linked repository is
277+
manually removed.
278+
225279
SEE ALSO
226280
--------
227281
linkgit:git-init[1],

builtin/branch.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -771,7 +771,6 @@ static const char edit_description[] = "BRANCH_DESCRIPTION";
771771

772772
static int edit_branch_description(const char *branch_name)
773773
{
774-
FILE *fp;
775774
int status;
776775
struct strbuf buf = STRBUF_INIT;
777776
struct strbuf name = STRBUF_INIT;
@@ -784,8 +783,7 @@ static int edit_branch_description(const char *branch_name)
784783
" %s\n"
785784
"Lines starting with '%c' will be stripped.\n",
786785
branch_name, comment_line_char);
787-
fp = fopen(git_path(edit_description), "w");
788-
if ((fwrite(buf.buf, 1, buf.len, fp) < buf.len) || fclose(fp)) {
786+
if (write_file(git_path(edit_description), 0, "%s", buf.buf)) {
789787
strbuf_release(&buf);
790788
return error(_("could not write branch description template: %s"),
791789
strerror(errno));

0 commit comments

Comments
 (0)