多个工作目录与Git?
我不确定这是Git支持的东西,但理论上它似乎应该适用于我。
我的工作流程经常涉及我同时在多个分支中编辑文件。 换句话说,我经常想在一个分支中打开几个文件,而我在另一个分支中编辑另一个文件的内容。
我的典型解决方案是做两个结账,但这是一个耻辱,我不能在他们之间分享分支和参考。 我想只有两个工作目录由相同的.git文件夹管理。
我知道本地git克隆解决方案(默认是硬链接共享对象,和 - 共享选项,它使用原始的repo设置备用对象存储),但这些解决方案仅减少磁盘空间使用,特别是在共享的情况下,似乎充满了危险。
有没有办法使用一个.git文件夹,并有两个工作目录支持它? 或者Git硬编码只是在任何时候检出一个工作目录?
Git 2.5自2015年7月起提议替换contrib/workdir/git-new-workdir
: git worktree
见Junio C gitster
( gitster
)的提交68a2e6a。
发布说明提到:
替代contrib/workdir/git-new-workdir
,它不依赖于符号链接,通过让借款人和借款人相互知道对象和分享对象和参考,从而更安全。
参见提交799767cc9(Git 2.5rc2)
这意味着你现在可以做一个git worktree add <path> [<branch>]
创建<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
目录(或者如果已经采用test-next
则为$GIT_DIR/worktrees/test-next1
)。 在一个链接的工作树中:
$GIT_DIR
被设置为指向这个私有目录(例如/path/main/.git/worktrees/test-next
)和 $GIT_COMMON_DIR
被设置为指向主工作树的$GIT_DIR
(例如/path/main/.git
)。 这些设置是在位于链接工作树顶部目录的.git
文件中进行的。
当你完成一个链接的工作树时,你可以简单地删除它。
存储库中的工作树管理文件最终会自动删除(请参阅git config
gc.pruneworktreesexpire
),或者您可以在主或任何链接的工作树中运行git worktree prune
来清理任何陈旧的管理文件。
警告:还有一个git worktree
“BUGS”部分需要注意。
子模块的支持不完整 。
不建议多次签出超级项目。
注意:使用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
合并 - gitster
- 于2015年10月26日提交a46dcfb)
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)
还有瓷器格式选项可用。
瓷器格式每个属性都有一行。
例如:
$ 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
注意:如果您移动工作文件夹,则需要手动更新gitdir
文件。
见提交618244e(2016年1月22日),并提交d4cddd6(2016年1月18日)由阮泰玉维战( pclouds
)。
帮助:埃里克阳光( sunshineco
)。
(由Junio C gitster
合并 - gitster
- in commit d0a1cbc,2016年2月10日)
git 2.8(2016年3月)中的新文档将包括:
如果您移动链接的工作树,则需要更新条目目录中的' gitdir
'文件。
例如,如果链接的工作树移动到/newpath/test-next
并且其.git
文件指向/path/main/.git/worktrees/test-next
,则更新/path/main/.git/worktrees/test-next/gitdir
来引用/newpath/test-next
。
删除分支时要小心:在git 2.9(2016年6月)之前,您可以删除另一个正在使用的树。
当“ git worktree
”功能正在使用时,“ git branch -d
”允许删除在另一个工作树中检出的分支。
见Kazuki Yamaguchi( rhenium
)提交f292244(2016年3月29日)。
帮助:埃里克阳光( sunshineco
)。
(由Junio C gitster
合并 - gitster
- 于2016年4月13日提交4fca4e3)
branch -d
:拒绝删除当前检出的分支
当一个分支被当前工作树签出时,删除该分支是被禁止的。
但是,只有其他工作树检出分支时,删除不正确才能成功。
使用find_shared_symref()
检查分支是否正在使用,而不仅仅是与当前工作树的HEAD进行比较。
同样,在git 2.9(2016年6月)之前,重命名在另一个工作树中检出的分支不会调整其他工作树中的符号HEAD。
参见承诺18eb3a9(2016年4月8日),承诺70999e9,承诺2233066(2016年3月27日)Kazuki Yamaguchi( rhenium
)。
(由Junio C gitster
合并 - gitster
- 在承诺741a694,2016年4月18日)
branch -m
:更新所有per-worktree 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]
此修补程序通过在重命名分支时更新所有相关的工作头HEAD来解决此问题。
锁定机制正式支持git 2.10(Q3 2016)
请参阅提交080739b,提交6d30862,提交58142c0,提交346ef53,提交346ef53,提交58142c0,提交346ef53,提交346ef53(2016年6月13日),并提交NguyễnTháiNgọcDuy( pclouds
)的984ad9e,提交6835314(2016年6月3日)。
建议者:Eric Sunshine( sunshineco
)。
(由Junio C gitster
合并 - gitster
- 在承诺2c608e0,2016年7月28日)
git worktree lock [--reason <string>] <worktree>
git worktree unlock <worktree>
如果链接的工作树存储在其上并不总是安装在便携式设备或网络共享,可以防止其行政文件从通过发出被修剪git worktree lock
命令,可以选择指定--reason
解释为什么工作树被锁定。
<worktree>
:如果工作树的路径中的最后一个路径组件在工作树中是唯一的,则它可以用于标识工作树。
例如,如果您只需在“ /abc/def/ghi
”和“ /abc/def/ggg
”中工作树,那么“ ghi
”或“ def/ghi
”就足以指向以前的工作树。
Git 2.13(Q2 2017)在NguyễnTháiNgọcDuy( pclouds
)的提交507e6e9(2017年4月12日)中添加了一个lock
选项 。
建议:David Taylor( dt
)。
帮助:杰夫金( peff
)。
(由Junio C gitster
合并 - gitster
- 在2017年4月26日提交的e311597)
允许在创建后立即锁定工作树。
这有助于防止“ git worktree add; git worktree lock
”和“ git worktree prune
”之间的竞争。
所以git worktree add' --lock
git worktree lock
git worktree add
后的git worktree lock
的等价物,但没有竞争条件。
Git 2.17+(Q2 2018)增加了git worktree move
/ git worktree remove
:看到这个答案。
git
发行版附带了一个名为git-new-workdir
的贡献脚本。 你会使用它如下:
git-new-workdir project-dir new-workdir branch
其中project-dir是包含.git
存储库的目录的名称。 这个脚本创建了另一个`.git'目录,其中包含许多符合链接的目录,除了不能共享的文件(如当前分支)外,允许您在两个不同的分支中工作。
这听起来有点脆弱,但它是一种选择。
我遇到了这个问题,希望能找到我在这里找不到的解决方案。 所以,现在我确实找到了我需要的东西,我决定将它发布给其他人。
警告:如果您需要同时编辑多个分支(如OP状态),这可能不是一个好的解决方案。 这是为了同时检出多个分支,您不打算编辑。 (由一个.git文件夹支持的多个工作目录。)
自从我第一次来到这个问题以来,我学到了一些东西:
什么是“裸仓库”。 它实质上是.git
目录的内容,不在工作树中。
事实上,你可以在命令行中用git
选项指定你正在使用的回购库的位置(你的.git
目录的位置)-- git
--git-dir=
您可以使用--work-tree=
来指定工作副本的位置
什么是“镜像回购”?
这最后是一个非常重要的区别。 我实际上并不想在回购协议上工作,我只需要同时签出不同分支和/或标签的副本。 实际上,我需要保证分支机构不会与我的分支机构不同。 所以一面镜子对我来说是完美的。
所以对于我的用例,我得到了我需要做的事情:
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
关于这个的一个重要警告是,这两个副本没有单独的HEAD。 因此,在上述之后,运行git --git-dir=<localgitdir> --work-tree=firstcopy status
会显示从branch2到branch1的所有不同之处,因为未提交的更改 - 因为HEAD指向branch2。 (这就是为什么我使用-f
选项来checkout
原因,因为我实际上并不打算在本地进行任何更改。只要使用-f
选项,我就可以为任何工作树签出任何标签或分支。 )
对于在同一台计算机上同时存在多个结帐而无需编辑它们的情况 ,此功能完美无缺。 我不知道是否有任何方法可以为多个工作树设置多个HEAD,而不需要脚本,如其他答案中所述,但我希望这对其他人有帮助。
链接地址: http://www.djcxy.com/p/4439.html