使用worktree将现有目录作为分支添加到git

cld4siwp  于 11个月前  发布在  Git
关注(0)|答案(2)|浏览(120)

我有一个简单的仓库,我需要在不同的目录中 checkout 一个分支。为此,我使用git worktree。通常git worktree add -B hello ../hello mastermaster创建一个名为hello的新分支,并在../hello下 checkout 。
这实际上正是我正在寻找的,除了目录已经存在。根据文档,-B应该忽略这一点,只使用目录中的文件,但它仍然抱怨:

$ git worktree add -B hello ../hello master
Preparing worktree (resetting branch 'hello'; was at 0465e02)
fatal: '../hello' already exists

字符串
为什么我使用的命令不起作用?请参阅下面文档中的引用。我误解了文档吗?
引用文档:
默认情况下,-b拒绝创建已经存在的新分支。-B覆盖此保护,将 * 重置< new-branch >为 < branch >*

zu0ti5jz

zu0ti5jz1#

TL;DR

这是对-B选项的一个基本误解。它告诉Git,* 分支名称 *(在本例中为hello)可以存在,但 * 永远不能允许添加的工作树目录 *(在本例中为../hello)已经存在。

(根据你的问题,你已经知道了很多-这是给其他读者的。
第一:git worktree add添加了一个新的 work-tree,而不仅仅是一个目录。添加的work-tree附带了一个添加的索引:每个工作树有一个Git索引。当git worktree add操作成功时,您会发现,在添加的工作树中,一个名为.git的文件,其中包含原始Git仓库的路径。您可以通过cd ../hello或其他方式导航到添加的工作-添加的工作树可以随意使用;它的Git索引独立于主工作树的Git索引。
第二:在Git中,像master这样的 * 分支 * 只是一个名称-您可以随时更改,甚至在某些情况下完全删除也不会产生明显影响1-它可以让您找到特定的 commit。重要的是提交,而不是分支名称。* commit * 保存文件,每个提交都有自己唯一的真实名称,即其哈希ID。然而,分支名称,仅保存一个现有提交的哈希ID。
现在:

$ git worktree add -B hello ../hello master

字符串
这告诉Git创建一个新目录../hello。这个新目录应该在当前工作树之外(可能是指定的路径../hello),需要 * 不存在 *。因为../hello实际上存在,这就是为什么这一步失败。
这个git worktree add命令的-B hello部分告诉它,在成功创建这个新的空目录并将某个提交检出到该工作树中之后--我们稍后将讨论哪个 * 特定 * 提交--它应该执行一个事务操作,使分支名称hello生效(如果它以前不存在),或者现在标识(如果它以前确实存在),您选择的提交。
这里的形容词 transactional 意味着这一步应该完全成功,这样分支名称hello就存在正确的提交,或者看起来根本没有发生:如果已经有一个分支名称hello,它将保持不受干扰。
信息:

(resetting branch 'hello'; was at 0465e02)


告诉你这个分支名称确实存在,并且确实指向(包含其哈希ID)缩写为0465e02的提交。由于实际命令最终失败,分支名称hello应该继续存在,并继续指向提交0465e02
最后,git worktree add命令的master部分提供了Git应该 checkout 到添加的工作树中的提交的哈希ID。如果你运行:

git rev-parse master


Git将打印出这一步获得的哈希ID(假设名称master还没有被修改以识别其他提交)。
正如我们已经注意到的那样,整个事情失败了,因为../hello已经存在(并且可能包含文件-一些Git操作允许目录存在,只要它们是空的,我不记得git worktree add是过去的,现在的,还是将来的)。要解决这个问题,只需选择其他名称,或者-如果../hello中没有任何文件是有价值的-完全删除../hello
1要使删除分支名称变得无关紧要,您需要能够通过其他方式找到通过该分支名称可以找到的提交。您还需要不受git config删除配置信息的困扰(例如分支的上游),存储在Git配置文件中的该分支名称下,也不是立即删除分支的reflog。(有一些模糊的猜测,关于某一天保留“分支取消删除”操作的reflog,但它已经很长时间没有去任何地方了。)

bxjv4tth

bxjv4tth2#

虽然我不确定您是否可以在现有目录中创建一个 * 工作树 *,但您可以将目录的内容添加到新的分支中。
1.进入你的仓库目录:cd /my/repo
1.创建一个新的分支:git switch --orphan new_branch_name
1.进入现有目录:cd /my/data
1.使用--git-dir存储并提交目录的内容:

git --git-dir=/my/repo/.git/ add --all
git --git-dir=/my/repo/.git/ commit

相关问题