Git 有多个工作目录?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6270193/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Multiple working directories with Git?
提问by jtolds
I'm not sure if this is something supported by Git, but in theory it seems like it should work to me.
我不确定这是否是 Git 支持的东西,但从理论上讲,它似乎对我有用。
My workflow often involves my editing of files in multiple branches simultaneously. In other words, I often want to open a few files in one branch is while I edit the contents of another file in another branch.
我的工作流程经常涉及同时编辑多个分支中的文件。换句话说,我经常想在一个分支中打开几个文件,而我在另一个分支中编辑另一个文件的内容。
My typical solution to this is to make two checkouts, but it's a shame I can't share branches and refs between them. What I would like is to just have two working directories managed by the same .git folder.
我对此的典型解决方案是进行两次结帐,但很遗憾我无法在它们之间共享分支和引用。我想要的是只有两个工作目录由同一个 .git 文件夹管理。
I'm aware of local git clone solutions (the default, which is to hardlink shared objects, and the --shared option, which sets up an alternate object store with the original repo), but these solutions only cut down on disk space usage, and especially in the case of --shared, seem fraught with peril.
我知道本地 git clone 解决方案(默认情况下,它是硬链接共享对象,以及 --shared 选项,它使用原始存储库设置备用对象存储),但这些解决方案只会减少磁盘空间使用,尤其是在 --shared 的情况下,似乎充满了危险。
Is there a way to use one .git folder, and have two working directories backed by it? Or is Git hardcoded to have just one working directory checked out at any time?
有没有办法使用一个 .git 文件夹,并有两个工作目录由它支持?或者 Git 是硬编码的以便在任何时候都只检出一个工作目录?
回答by VonC
Git 2.5 proposes since July 2015 a replacement for contrib/workdir/git-new-workdir
: git worktree
Git 2.5 自 2015 年 7 月起提议替代contrib/workdir/git-new-workdir
:git worktree
See commit 68a2e6aby Junio C Hamano (gitster
).
看看提交68a2e6a通过JUNIOÇ滨野(gitster
)。
该发行说明中提到:
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.
替代
contrib/workdir/git-new-workdir
它不依赖符号链接,并且通过使借用者和借用者相互了解来使对象和引用的共享更安全。
See commit 799767cc9(Git 2.5rc2)
参见提交 799767cc9(Git 2.5rc2)
That means you now can do a git worktree add <path> [<branch>]
这意味着你现在可以做一个git worktree add <path> [<branch>]
Create
<path>
and checkout<branch>
into it. The new working directory is linked to the current repository, sharing everything except working directory specific files such as HEAD, index, etc. Thegit worktree
section adds:A git repository can support multiple working trees, allowing you to check out more than one branch at a time.
Withgit worktree add
, a new working tree is associated with the repository.This new working tree is called a "linked working tree" as opposed to the "main working tree" prepared by "
git init
" or "git clone
".
A repository has one main working tree (if it's not a bare repository) and zero or more linked working trees.details:
Each linked working tree has a private sub-directory in the repository's
$GIT_DIR/worktrees
directory.
The private sub-directory's name is usually the base name of the linked working tree's path, possibly appended with a number to make it unique.
For example, when$GIT_DIR=/path/main/.git
the commandgit worktree add /path/other/test-next next
creates:
- the linked working tree in
/path/other/test-next
and- also creates a
$GIT_DIR/worktrees/test-next
directory (or$GIT_DIR/worktrees/test-next1
iftest-next
is already taken).Within a linked working tree:
$GIT_DIR
is set to point to this private directory (e.g./path/main/.git/worktrees/test-next
in the example) and$GIT_COMMON_DIR
is set to point back to the main working tree's$GIT_DIR
(e.g./path/main/.git
).These settings are made in a
.git
file located at the top directory of the linked working tree.When you are done with a linked working tree you can simply delete it.
The working tree's administrative files in the repository will eventually be removed automatically (seegc.pruneworktreesexpire
ingit config
), or you can rungit worktree prune
in the main or any linked working tree to clean up any stale administrative files.
创建
<path>
并结帐<branch>
到其中。新的工作目录链接到当前存储库,共享除工作目录特定文件(如 HEAD、索引等)之外的所有git worktree
内容。该部分添加:一个 git 存储库可以支持多个工作树,允许您一次检出多个分支。
使用git worktree add
,新的工作树与存储库相关联。这个新的工作树被称为“链接工作树”,而不是由“
git init
”或“git clone
”准备的“主工作树”。
一个存储库有一个主要的工作树(如果它不是一个裸存储库)和零个或多个链接的工作树。细节:
每个链接的工作树在存储库目录中都有一个私有子目录
$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
位于链接工作树顶部目录的文件中进行。完成链接的工作树后,您可以简单地将其删除。
存储库中工作树的管理文件最终将被自动删除(参见gc.pruneworktreesexpire
参考资料git config
),或者您可以git worktree prune
在主或任何链接的工作树中运行以清除任何陈旧的管理文件。
Warning: there is still a git worktree
"BUGS"section to be aware of.
警告:仍有一个git worktree
“BUGS”部分需要注意。
The support for submodulesis incomplete.
It is NOT recommended to make multiple checkouts of a superproject.
对子模块的支持不完整。
不建议对一个超级项目进行多次签出。
Note: with git 2.7rc1 (Nov 2015) you are able to listyour worktrees.
See commit bb9c03b, commit 92718b7, commit 5193490, commit 1ceb7f9, commit 1ceb7f9, commit 5193490, commit 1ceb7f9, commit 1ceb7f9(08 Oct 2015), commit 92718b7, commit 5193490, commit 1ceb7f9, commit 1ceb7f9(08 Oct 2015), commit 5193490, commit 1ceb7f9(08 Oct 2015), commit 1ceb7f9(08 Oct 2015), and commit ac6c561(02 Oct 2015) by Michael Rappazzo (rappazzo
).
(Merged by Junio C Hamano -- gitster
--in commit a46dcfb, 26 Oct 2015)
注意:使用 git 2.7rc1(2015 年 11 月),您可以列出您的工作树。
见提交bb9c03b,提交92718b7,提交5193490,提交1ceb7f9,提交1ceb7f9,提交5193490,提交1ceb7f9,提交1ceb7f9(2015年10月8日),提交92718b7,提交5193490,提交1ceb7f9,提交1ceb7f9(2015年10月8日),提交5193490,提交 1ceb7f9(2015 年 10 月 8 日),提交 1ceb7f9(2015 年 10 月 8 日),并提交 ac6c561(2015 年 10 月 2 日)作者:Michael Rappazzo ( rappazzo
)。
(由Junio C gitster
Hamano合并-- --in commit a46dcfb,2015 年 10 月 26 日)
worktree
: add 'list
' command'
git worktree list
' iterates through the worktree list, and outputs details of the worktree including the path to the worktree, the currently checked out revision and branch, and if the work tree is bare.
worktree
: 添加 'list
' 命令'
git worktree list
' 遍历工作树列表,并输出工作树的详细信息,包括工作树的路径、当前检出的修订和分支,以及工作树是否是裸露的。
$ git worktree list
/path/to/bare-source (bare)
/path/to/linked-worktree abcd1234 [master]
/path/to/other-linked-worktree 1234abc (detached HEAD)
There is also porcelain format option available.
The porcelain format has a line per attribute.
- Attributes are listed with a label and value separated by a single space.
- Boolean attributes (like 'bare' and 'detached') are listed as a label only, and are only present if and only if the value is true.
- An empty line indicates the end of a worktree
还有瓷器格式选项可用。
瓷器格式的每个属性都有一行。
- 属性列有标签和值,由单个空格分隔。
- 布尔属性(如 'bare' 和 'detached')仅作为标签列出,并且仅当且仅当值为 true 时才存在。
- 空行表示工作树的结尾
For instance:
例如:
$ git worktree list --porcelain
worktree /path/to/bare-source
bare
worktree /path/to/linked-worktree
HEAD abcd1234abcd1234abcd1234abcd1234abcd1234
branch refs/heads/master
worktree /path/to/other-linked-worktree
HEAD 1234abc1234abc1234abc1234abc1234abc1234a
detached
Note: if you MOVE a worktree folder, you need to manuallyupdate the gitdir
file.
注意:如果您移动工作树文件夹,则需要手动更新gitdir
文件。
See commit 618244e(22 Jan 2016), and commit d4cddd6(18 Jan 2016) by Nguy?n Thái Ng?c Duy (pclouds
).
Helped-by: Eric Sunshine (sunshineco
).
(Merged by Junio C Hamano -- gitster
--in commit d0a1cbc, 10 Feb 2016)
请参阅Nguy?n Thái Ng?c Duy ( ) 的commit 618244e(2016 年 1 月 22 日)和commit d4cddd6(2016 年 1 月 18 日)。
帮助者:Eric Sunshine ( )。(由Junio C Hamano合并-- --在d0a1cbc 提交中,2016 年 2 月 10 日)pclouds
sunshineco
gitster
The new docin git 2.8 (March 2016) will include:
git 2.8(2016 年 3 月)中的新文档将包括:
If you move a linked working tree, you need to update the '
gitdir
' file in the entry's directory.
For example, if a linked working tree is moved to/newpath/test-next
and its.git
file points to/path/main/.git/worktrees/test-next
, then update/path/main/.git/worktrees/test-next/gitdir
to reference/newpath/test-next
instead.
如果移动链接的工作树,则需要更新
gitdir
条目目录中的“ ”文件。
例如,如果将链接的工作树移动到/newpath/test-next
并且其.git
文件指向/path/main/.git/worktrees/test-next
,则改为更新/path/main/.git/worktrees/test-next/gitdir
为引用/newpath/test-next
。
Be careful when deleting a branch: before git 2.9 (June 2016), you could delete one in use in anotherworking tree.
删除分支时要小心:在 git 2.9(2016 年 6 月)之前,您可以删除另一个工作树中正在使用的分支。
When "
git worktree
" feature is in use, "git branch -d
" allowed deletion of a branch that is checked out in another worktree.
当“
git worktree
”功能正在使用时,“git branch -d
”允许删除在另一个工作树中检出的分支。
See commit f292244(29 Mar 2016) by Kazuki Yamaguchi (rhenium
).
Helped-by: Eric Sunshine (sunshineco
).
(Merged by Junio C Hamano -- gitster
--in commit 4fca4e3, 13 Apr 2016)
请参阅Kazuki Yamaguchi ( ) 的提交 f292244(2016 年 3 月 29 日)。
帮助者:Eric Sunshine ( )。(由Junio C Hamano合并-- --在4fca4e3 提交中,2016 年 4 月 13 日)rhenium
sunshineco
gitster
branch -d
: refuse deleting a branch which is currently checked outWhen a branch is checked out by current working tree, deleting the branch is forbidden.
However when the branch is checked out only by other working trees, deleting incorrectly succeeds.
Usefind_shared_symref()
to check if the branch is in use, not just comparing with the current working tree's HEAD.
branch -d
: 拒绝删除当前检出的分支当前工作树检出分支时,禁止删除该分支。
然而,当分支仅被其他工作树检出时,错误删除成功。
使用find_shared_symref()
来检查分支正在使用中,不仅与当前工作树的HEAD比较。
Similarly, before git 2.9 (June 2016), renaming a branch checked out in another worktree did not adjust the symbolic HEAD in said other worktree.
同样,在 git 2.9(2016 年 6 月)之前,重命名在另一个工作树中检出的分支不会调整所述另一个工作树中的符号 HEAD。
See commit 18eb3a9(08 Apr 2016), and commit 70999e9, commit 2233066(27 Mar 2016) by Kazuki Yamaguchi (rhenium
).
(Merged by Junio C Hamano -- gitster
--in commit 741a694, 18 Apr 2016)
请参阅Kazuki Yamaguchi ( ) 的commit 18eb3a9(2016 年 4 月 8 日)和commit 70999e9、commit 2233066(2016 年 3 月 27 日)。(由Junio C Hamano合并-- --在commit 741a694,2016 年 4 月 18 日)rhenium
gitster
branch -m
: update all per-worktree HEADsWhen renaming a branch, currently only the HEAD of current working tree is updated, but it must update HEADs of all working trees which point at the old branch.
This is the current behavior, /path/to/wt's HEAD is not updated:
branch -m
: 更新所有每个工作树的 HEAD重命名分支时,目前只更新当前工作树的HEAD,但必须更新所有指向旧分支的工作树的HEAD。
这是当前行为,/path/to/wt 的 HEAD 未更新:
% git worktree list
/path/to 2c3c5f2 [master]
/path/to/wt 2c3c5f2 [oldname]
% git branch -m master master2
% git worktree list
/path/to 2c3c5f2 [master2]
/path/to/wt 2c3c5f2 [oldname]
% git branch -m oldname newname
% git worktree list
/path/to 2c3c5f2 [master2]
/path/to/wt 0000000 [oldname]
This patch fixes this issue by updating all relevant worktree HEADs when renaming a branch.
此补丁通过在重命名分支时更新所有相关工作树 HEAD 来解决此问题。
The locking mechanism is officially supported with git 2.10 (Q3 2016)
git 2.10 (Q3 2016) 正式支持锁定机制
See commit 080739b, commit 6d30862, commit 58142c0, commit 346ef53, commit 346ef53, commit 58142c0, commit 346ef53, commit 346ef53(13 Jun 2016), and commit 984ad9e, commit 6835314(03 Jun 2016) by Nguy?n Thái Ng?c Duy (pclouds
).
Suggested-by: Eric Sunshine (sunshineco
).
(Merged by Junio C Hamano -- gitster
--in commit 2c608e0, 28 Jul 2016)
见提交080739b,提交6d30862,提交58142c0,提交346ef53,提交346ef53,提交58142c0,提交346ef53,提交346ef53(2016年6月13日),以及提交984ad9e,提交6835314(2016年6月3日)由Nguy 2 N泰伍2 C维战( pclouds
)。
推荐人:Eric Sunshine ( sunshineco
)。
(由Junio C gitster
Hamano合并-- --在commit 2c608e0,2016 年 7 月 28 日)
git worktree lock [--reason <string>] <worktree>
git worktree unlock <worktree>
If a linked working tree is stored on a portable device or network share which is not always mounted, you can prevent its administrative files from being pruned by issuing the
git worktree lock
command, optionally specifying--reason
to explain why the working tree is locked.
<worktree>
: If the last path components in the working tree's path is unique among working trees, it can be used to identify worktrees.
For example if you only have to working trees at "/abc/def/ghi
" and "/abc/def/ggg
", then "ghi
" or "def/ghi
" is enough to point to the former working tree.
如果链接的工作树存储在并非总是挂载的便携式设备或网络共享上,您可以通过发出
git worktree lock
命令来防止其管理文件被修剪,可选择指定--reason
解释工作树被锁定的原因。
<worktree>
:如果工作树路径中的最后一个路径组件在工作树中是唯一的,则可以使用它来标识工作树。
例如,如果您只需要在 "/abc/def/ghi
" 和 "/abc/def/ggg
"处工作树,那么 "ghi
" 或 "def/ghi
" 足以指向前一个工作树。
Git 2.13 (Q2 2017) add a lock
optionin commit 507e6e9(12 Apr 2017) by Nguy?n Thái Ng?c Duy (pclouds
).
Suggested-by: David Taylor (dt
).
Helped-by: Jeff King (peff
).
(Merged by Junio C Hamano -- gitster
--in commit e311597, 26 Apr 2017)
Git 2.13(2017 年第二季度)在Nguy?n Thái Ng?c Duy ( ) 的提交 507e6e9(2017 年 4 月 12日)中添加了一个lock
选项。
推荐人:大卫·泰勒 ( )。
帮助者:杰夫·金 ( )。(由Junio C Hamano合并-- --在提交 e311597 中,2017 年 4 月 26 日)pclouds
dt
peff
gitster
Allow to lock a worktree immediately after it's created.
This helps prevent a race between "git worktree add; git worktree lock
" and "git worktree prune
".
允许在创建后立即锁定工作树。
这有助于防止“git worktree add; git worktree lock
”和“git worktree prune
”之间的竞争。
So git worktree add' --lock
is the equivalent of git worktree lock
after git worktree add
, but without race condition.
所以git worktree add' --lock
是相当于git worktree lock
后git worktree add
,但没有竞争条件。
Git 2.17+ (Q2 2018) adds git worktree move
/ git worktree remove
: see this answer.
Git 2.17+(2018 年第二季度)添加了git worktree move
/ git worktree remove
:请参阅此答案。
Git 2.19 (Q3 2018) add a "--quiet
" option to make "git worktree add
" less
verbose.
Git 2.19(2018 年第 3 季度)添加了一个 " --quiet
" 选项,使 " git worktree add
" 不那么冗长。
See commit 371979c(15 Aug 2018) by Elia Pinto (devzero2000
).
Helped-by: Martin ?gren , Duy Nguyen (pclouds
), and Eric Sunshine (sunshineco
).
(Merged by Junio C Hamano -- gitster
--in commit a988ce9, 27 Aug 2018)
请参阅Elia Pinto ( ) 的提交 371979c(2018 年 8 月 15 日)。
帮助者:Martin?gren、Duy Nguyen ( )和Eric Sunshine ( )。(由Junio C Hamano合并-- --在commit a988ce9,2018 年 8 月 27 日)devzero2000
pclouds
sunshineco
gitster
worktree
: add--quiet
optionAdd the '
--quiet
' option togit worktree
, as for the othergit
commands.
'add
' is the only command affected by it since all other commands, except 'list
', are currently silent by default.
worktree
: 添加--quiet
选项对于其他命令,将 '
--quiet
' 选项添加到。 “ ”是唯一受其影响的命令,因为除“ ”之外的所有其他命令当前默认处于静默状态。git worktree
git
add
list
Note that "git worktree add
" used to do a "find an available name with stat
and then mkdir
", which is race-prone.
This has been fixed with Git 2.22 (Q2 2019) by using mkdir
and reacting to EEXIST
in a loop.
请注意,“ git worktree add
”用于“使用 stat 查找可用名称,然后mkdir
”,这很容易发生竞争。
这已在 Git 2.22(2019 年第二季度)中通过循环使用mkdir
和反应得到修复EEXIST
。
See commit 7af01f2(20 Feb 2019) by Michal Suchanek (hramrach
).
(Merged by Junio C Hamano -- gitster
--in commit 20fe798, 09 Apr 2019)
请参阅Michal Suchanek ( ) 的commit 7af01f2(20 Feb 2019 )。(由Junio C Hamano合并-- --在2019 年 4 月 9 日提交 20fe798 中)hramrach
gitster
worktree
: fixworktree add
raceGit runs a stat loop to find a worktree name that's available and then does
mkdir
on the found name.
Turn it tomkdir
loop to avoid another invocation of worktree add finding the same free name and creating the directory first.
worktree
: 修复worktree add
种族Git 运行一个 stat 循环来查找可用的工作树名称,然后
mkdir
在找到的名称上执行。
将其转为mkdir
循环以避免再次调用 worktree add 找到相同的空闲名称并首先创建目录。
Git 2.22 (Q2 2019) fixes the logic to tell if a Git repository has a working tree protects "git branch -D
" from removing the branch that is currently checked
out by mistake.
The implementation of this logic was broken for repositories with unusual name, which unfortunately is the norm for submodules these days.
Git 2.22(2019 年第 2 季度)修复了判断 Git 存储库是否具有工作树的逻辑,以保护“ git branch -D
”免于删除当前错误检出的分支。
对于具有不寻常名称的存储库,此逻辑的实现被破坏,不幸的是,这已成为如今子模块的规范。
See commit f3534c9(19 Apr 2019) by Jonathan Tan (jhowtan
).
(Merged by Junio C Hamano -- gitster
--in commit ec2642a, 08 May 2019)
请参阅Jonathan Tan ( ) 的commit f3534c9(2019 年 4 月 19 日)。(由Junio C Hamano合并-- --在ec2642a 提交中,2019 年 5 月 8 日)jhowtan
gitster
Code Pull requests 178 Insights
worktree
: updateis_bare
heuristicsWhen "
git branch -D <name>
" is run, Git usually first checks if that branch is currently checked out.
But this check is not performed if the Git directory of that repository is not at "<repo>/.git
", which is the case if that repository is a submodule that has its Git directory stored as "super/.git/modules/<repo>
", for example.
This results in the branch being deleted even though it is checked out.This is because
get_main_worktree()
inworktree.c
setsis_bare
on a worktree only using the heuristic that a repo is bare if the worktree's path does not end in "/.git
", and not bare otherwise.
Thisis_bare
code was introduced in 92718b7("worktree
: add details to the worktree struct", 2015-10-08, Git v2.7.0-rc0), following apre-core.bare
heuristic.This patch does 2 things:
- Teach
get_main_worktree()
to useis_bare_repository()
instead, introduced in 7d1864c("Introduce is_bare_repository() and core.bare configuration variable", 2007-01-07, Git v1.5.0-rc1) and updated in e90fdc3("Clean up work-tree handling", 2007-08-01, Git v1.5.3-rc4).
This solves the "git branch -D <name>
" problem described above.However... If a repository has
core.bare=1
but the "git
" command is being run from one of its secondary worktrees,is_bare_repository()
returns false (which is fine, since there is a worktree available).And, treating the main worktree as non-bare when it is bare causes issues:
For example, failure to delete a branch from a secondary worktree that is referred to by a main worktree's HEAD, even if that main worktree is bare.
In order to avoid that, also check
core.bare
when settingis_bare
.
Ifcore.bare=1
, trust it, and otherwise, useis_bare_repository()
.
代码拉取请求 178 个见解
worktree
: 更新is_bare
启发式当“
git branch -D <name>
”运行时,Git 通常首先检查该分支当前是否已检出。
但是,如果该存储库的 Git 目录不在“<repo>/.git
”处,则不会执行此检查,例如,如果该存储库是其 Git 目录存储为“super/.git/modules/<repo>
”的子模块,就会出现这种情况。
这会导致分支被删除,即使它被检出。这是因为
get_main_worktree()
在worktree.c
台is_bare
只使用启发式,一个回购是裸露的,如果worktree的路径不以“结束worktree/.git
”,否则不裸露。
此is_bare
代码在92718b7(“worktree
:向工作树结构添加详细信息”,2015-10-08,Git v2.7.0-rc0)中引入,遵循pre-core.bare
启发式。这个补丁做了两件事:
- Teach
get_main_worktree()
to useis_bare_repository()
,在7d1864c 中引入(“Introduce is_bare_repository() and core.bare configuration variable”,2007-01-07,Git v1.5.0-rc1)并在e90fdc3 中更新(“清理工作树处理”,2007 -08-01,Git v1.5.3-rc4)。
这解决了上述“git branch -D <name>
”问题。但是...如果存储库具有
core.bare=1
但git
正在从其辅助工作树之一运行“ ”命令,则is_bare_repository()
返回 false(这很好,因为有可用的工作树)。并且,将主工作树视为非裸会导致问题:
例如,无法从主工作树的 HEAD 引用的辅助工作树中删除分支,即使该主工作树是空的。
为了避免这种情况,请
core.bare
在设置时检查is_bare
。
如果core.bare=1
,相信它,否则,使用is_bare_repository()
。
回答by adl
The git
distribution comes with a contributed scriptcalled git-new-workdir
.
You would use it as follows:
该git
发行版带有一个名为git-new-workdir
. 您可以按如下方式使用它:
git-new-workdir project-dir new-workdir branch
where project-dir is the name of the directory containing your .git
repository.
This scripts creates another .git
directory with many symlinks to the original one except for files that cannot be shared (like the current branch), allowing you to work in two different branches.
其中 project-dir 是包含您的.git
存储库的目录的名称。.git
除了不能共享的文件(如当前分支)外,此脚本创建另一个目录,其中包含许多指向原始目录的符号链接,允许您在两个不同的分支中工作。
It sounds a bit fragile, but it's an option.
这听起来有点脆弱,但它是一种选择。
回答by Wildcard
I came across this question hoping for a solution I didn't find here. So now that I didfind what I needed, I decided to post it here for others.
我遇到了这个问题,希望能找到我在这里找不到的解决方案。所以现在我确实找到了我需要的东西,我决定在这里发布给其他人。
Caveat: This is probably not a good solution if you need to editmultiple branches simultaneously, like OP states.It is for having multiple branches checked outsimultaneously that you don'tintend to edit. (Multiple working directories backed by one .git folder.)
警告:如果您需要同时编辑多个分支,例如 OP 状态,这可能不是一个好的解决方案。它用于同时签出您不打算编辑的多个分支。(多个工作目录由一个 .git 文件夹支持。)
There were a few things I've learned since I came to this question the first time:
自从我第一次遇到这个问题以来,我学到了一些东西:
What a "bare repository" is. It is essentially the contents of the
.git
directory, without being located in a working tree.The fact that you can specify the location of the repo you are using (the location of your
.git
dir) on the command line with thegit
option--git-dir=
The fact that you can specify the location of your working copy with
--work-tree=
What a "mirror repo" is.
什么是“裸仓库”。它本质上是
.git
目录的内容,而不是位于工作树中。您可以使用选项
.git
在命令行上指定正在使用的存储库的位置(目录的位置)这一事实git
--git-dir=
您可以使用以下命令指定工作副本的位置
--work-tree=
什么是“镜像回购”。
This last is a pretty important distinction. I don't actually want to workon the repo, I just need to have copies of different branches and/or tags checked out simultaneously. In actual fact, I need to guarantee that the branches don'tend up different from my remote's branches. So a mirror is perfect for me.
最后一个是非常重要的区别。我实际上并不想在 repo上工作,我只需要同时检出不同分支和/或标签的副本。实际上,我需要保证分支最终不会与我的远程分支不同。所以镜子对我来说是完美的。
So for myuse case, I got what I needed by doing:
因此,对于我的用例,我通过执行以下操作获得了所需的信息:
git clone --mirror <remoteurl> <localgitdir> # Where localgitdir doesn't exist yet
mkdir firstcopy
mkdir secondcopy
git --git-dir=<localgitdir> --work-tree=firstcopy checkout -f branch1
git --git-dir=<localgitdir> --work-tree=secondcopy checkout -f branch2
The big caveat about this is that there isn't a separate HEAD for the two copies. So after the above, running git --git-dir=<localgitdir> --work-tree=firstcopy status
will show all the differences from branch2 to branch1 as uncommitted changes - because HEAD is pointing at branch2. (That's why I use the -f
option to checkout
, because I'm not actually planning to make any changes locally at all. I can checkout any tag or branch for any work-tree, as long as I use the -f
option.)
关于这一点的重要警告是,这两个副本没有单独的 HEAD。所以在上述之后,运行git --git-dir=<localgitdir> --work-tree=firstcopy status
会将所有从 branch2 到 branch1 的差异显示为未提交的更改 - 因为 HEAD 指向 branch2。(这就是我使用-f
to 选项的原因checkout
,因为我实际上根本不打算在本地进行任何更改。只要我使用该-f
选项,我就可以检查任何工作树的任何标签或分支。)
For my use case of having multiple checkouts co-existing on the same computer withoutneeding to edit them, this works perfectly. I don't know if there is any way to have multiple HEADs for the multiple work trees without a script such as is covered in the other answers, but I hope this is helpful to someone else anyway.
对于我在同一台计算机上共存多个结帐而不需要编辑它们的用例,这非常有效。我不知道是否有任何方法可以在没有其他答案中涵盖的脚本的情况下为多个工作树设置多个 HEAD,但我希望这对其他人有帮助。
回答by vhallac
The only solution I can think of is to clone two directories and add them as remote repositories of each other. You can then keep pulling stuff from the changed one into the other without actually pushing anything to the remote repository.
我能想到的唯一解决方案是克隆两个目录并将它们添加为彼此的远程存储库。然后,您可以继续从更改的一个中提取内容到另一个中,而无需实际将任何内容推送到远程存储库。
I am assuming you want to have two working directories and not two clones of the remote because you don't want to push some branches to the remote. Otherwise, two clones of your remote would work just fine - you just need to do some pushes and pulls to keep all three in sync.
我假设您想要两个工作目录而不是远程的两个克隆,因为您不想将某些分支推送到远程。否则,你的遥控器的两个克隆就可以正常工作——你只需要做一些推拉来保持所有三个同步。