为什么后缀会自动附加到 git 工作树内部目录名称?
Why is a suffix automatically appended to the git worktree internal directory name?
当 git worktree add foo <revision>
创建新的工作树时,主工作树 .git/worktrees/foo/
也会被创建。我遇到过几次这种情况,它创建了 .git/worktrees/foo1/
。我认为附加 1
是因为存在一些命名冲突。我想知道为什么会发生这种情况以及如何复制这种情况。谢谢。
仅供参考,多个线程可以在同一个主工作树中工作以创建不同的工作树,git Ubuntu.
版本 2.31.1
git worktree add
代码在 add_worktree
中合成工作树 ID(内部名称),使用此循环:
if (safe_create_leading_directories_const(sb_repo.buf))
die_errno(_("could not create leading directories of '%s'"),
sb_repo.buf);
while (mkdir(sb_repo.buf, 0777)) {
counter++;
if ((errno != EEXIST) || !counter /* overflow */)
die_errno(_("could not create directory of '%s'"),
sb_repo.buf);
strbuf_setlen(&sb_repo, len);
strbuf_addf(&sb_repo, "%d", counter);
}
name = strrchr(sb_repo.buf, '/') + 1;
初始 sb_repo.buf
包含一个从路径派生的“净化”名称,在您的情况下,路径是添加到 Git 目录和工作树中的名称 foo
子目录($GIT_DIR/worktrees/foo
)。这里的 len
是数字后缀部分进入的点。因此,如果初始 mkdir
调用因 EEXIST
失败,则 [=13= 的 foo
部分] strbuf 被替换为 foo1
、foo2
,依此类推,直到 mkdir
调用成功 (returns 0) 或因 EEXIST
以外的原因失败.
[Sometimes Git] creates .git/worktrees/foo1/
instead. I think 1 is appended because there are some naming conflicts.
如果已经有 .git/worktrees/foo
,就会发生这种情况,因此 mkdir
调用返回一个错误,错误编号为 EEXIST
。如果有一个工作树的路径以 foo
结尾,或者经过清理后变为 foo
.]
,那么这又会发生
[请注意,当 Git 存储库存储在 cloud-synced 文件夹(ICloud、Dropbox 等)中时,您也会看到随机错误。 cloud-syncing 软件进入存储库并在尝试同步时损坏了它。不过这里可能不是这种情况。]
(有点奇怪为什么你 关心 worktree-specific 文件在 $GIT_DIR
里面。我不确定为什么 Git 付出所有这些努力来创建一个基本名称,而不是仅仅使用 mkdtemp
或等效的方法生成随机 ID:如果 Git 做到了这一点,人们就不会想在里面四处闲逛 .git/worktrees
一样多。要使用 worktree-specific 引用,如 HEAD
和二等分修订名称,请使用 git rev-parse
或 git update-ref
,它们自己知道如何执行此操作。那里 是,我认为,临时索引文件有点问题:索引文件需要是per-worktree,有git rev-parse --git-internal-worktree-path
或类似的东西会很好用于构建此类名称。)
当 git worktree add foo <revision>
创建新的工作树时,主工作树 .git/worktrees/foo/
也会被创建。我遇到过几次这种情况,它创建了 .git/worktrees/foo1/
。我认为附加 1
是因为存在一些命名冲突。我想知道为什么会发生这种情况以及如何复制这种情况。谢谢。
仅供参考,多个线程可以在同一个主工作树中工作以创建不同的工作树,git Ubuntu.
版本 2.31.1git worktree add
代码在 add_worktree
中合成工作树 ID(内部名称),使用此循环:
if (safe_create_leading_directories_const(sb_repo.buf))
die_errno(_("could not create leading directories of '%s'"),
sb_repo.buf);
while (mkdir(sb_repo.buf, 0777)) {
counter++;
if ((errno != EEXIST) || !counter /* overflow */)
die_errno(_("could not create directory of '%s'"),
sb_repo.buf);
strbuf_setlen(&sb_repo, len);
strbuf_addf(&sb_repo, "%d", counter);
}
name = strrchr(sb_repo.buf, '/') + 1;
初始 sb_repo.buf
包含一个从路径派生的“净化”名称,在您的情况下,路径是添加到 Git 目录和工作树中的名称 foo
子目录($GIT_DIR/worktrees/foo
)。这里的 len
是数字后缀部分进入的点。因此,如果初始 mkdir
调用因 EEXIST
失败,则 [=13= 的 foo
部分] strbuf 被替换为 foo1
、foo2
,依此类推,直到 mkdir
调用成功 (returns 0) 或因 EEXIST
以外的原因失败.
[Sometimes Git] creates
.git/worktrees/foo1/
instead. I think 1 is appended because there are some naming conflicts.
如果已经有 .git/worktrees/foo
,就会发生这种情况,因此 mkdir
调用返回一个错误,错误编号为 EEXIST
。如果有一个工作树的路径以 foo
结尾,或者经过清理后变为 foo
.]
[请注意,当 Git 存储库存储在 cloud-synced 文件夹(ICloud、Dropbox 等)中时,您也会看到随机错误。 cloud-syncing 软件进入存储库并在尝试同步时损坏了它。不过这里可能不是这种情况。]
(有点奇怪为什么你 关心 worktree-specific 文件在 $GIT_DIR
里面。我不确定为什么 Git 付出所有这些努力来创建一个基本名称,而不是仅仅使用 mkdtemp
或等效的方法生成随机 ID:如果 Git 做到了这一点,人们就不会想在里面四处闲逛 .git/worktrees
一样多。要使用 worktree-specific 引用,如 HEAD
和二等分修订名称,请使用 git rev-parse
或 git update-ref
,它们自己知道如何执行此操作。那里 是,我认为,临时索引文件有点问题:索引文件需要是per-worktree,有git rev-parse --git-internal-worktree-path
或类似的东西会很好用于构建此类名称。)