gpt4 book ai didi

git - Git 有多个工作目录?

转载 作者:行者123 更新时间:2023-12-01 17:15:13 24 4
gpt4 key购买 nike

我不确定这是否是 Git 支持的东西,但从理论上讲,它似乎对我有用。

我的工作流程经常涉及同时编辑多个分支中的文件。换句话说,我经常想在一个分支中打开几个文件,而我在另一个分支中编辑另一个文件的内容。

我对此的典型解决方案是进行两次结帐,但很遗憾我无法在它们之间共享分支和引用。我想要的是只有两个工作目录由同一个 .git 文件夹管理。

我知道本地 git clone 解决方案(默认情况下,它是硬链接(hard link)共享对象,以及 --shared 选项,它使用原始存储库设置备用对象存储),但这些解决方案只会减少磁盘空间使用,尤其是在 --shared 的情况下,似乎充满了危险。

有没有办法使用一个 .git 文件夹,并有两个工作目录由它支持?或者 Git 是硬编码的以便在任何时候都只 check out 一个工作目录?

最佳答案

Git 2.5 自 2015 年 7 月起提议替代 contrib/workdir/git-new-workdir : git worktree
参见 commit 68a2e6aJunio C Hamano ( gitster )
release note mentions :

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.


参见 commit 799767cc9 (Git 2.5rc2)
这意味着你现在可以 do a git worktree add <path> [<branch>]

Create <path> and checkout <branch> into it. The new working directoryis linked to the current repository, sharing everything except workingdirectory specific files such as HEAD, index, etc.The git worktree section adds:

A git repository can support multiple working trees, allowing you to check out more than one branch at a time.
With git 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 command git 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 if test-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 (see gc.pruneworktreesexpire in git config), or you can run git worktree prune in the main or any linked working tree toclean up any stale administrative files.



警告:还有一个 git worktree "BUGS" 部分需要注意。

The support for submodules is incomplete.
It is NOT recommended to make multiple checkouts of a superproject.



注意:使用 git 2.7rc1(2015 年 11 月),您可以 列出 您的工作树。
commit bb9c03bcommit 92718b7commit 5193490commit 1ceb7f9commit 1ceb7f9commit 5193490commit 1ceb7f9commit 1ceb7f9(2015年10月8日), commit 92718b7commit 5193490commit 1ceb7f9commit 1ceb7f9(2015年10月8日), commit 5193490commit 1ceb7f9(2015年10月8日), commit 1ceb7f9(2015年10月8日)和 commit ac6c561(2015 年 10 月 2 日),作者 Michael Rappazzo ( rappazzo )
(由 Junio C Hamano -- gitster --commit a46dcfb 中 merge ,2015 年 10 月 26 日)

worktree: add 'list' command


'git worktree list' iterates through the worktree list, and outputsdetails of the worktree including the path to the worktree, the currentlychecked out revision and branch, and if the work tree is bare.

$ 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

例如:
$ 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 文件。
请参阅 commit 618244ecommit d4cddd6(2016 年 1 月 22 日)和 Nguyễn Thái Ngọc Duy ( pclouds )(2016 年 1 月 18 日)。
帮助者: Eric Sunshine ( sunshineco )
(由 Junio C Hamano -- gitster --commit d0a1cbc 中 merge ,2016 年 2 月 10 日)
git 2.8(2016 年 3 月)中的 The new doc 将包括:

If you move a linked working tree, you need to update the 'gitdir' filein 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.



删除分支时要小心:在 git 2.9(2016 年 6 月)之前,您可以删除另一个工作树中正在使用的分支。

When "git worktree" feature is in use, "git branch -d" alloweddeletion of a branch that is checked out in another worktree.


请参阅 commit f292244Kazuki Yamaguchi ( rhenium )(2016 年 3 月 29 日)。
帮助者: Eric Sunshine ( sunshineco )
(由 Junio C Hamano -- gitster --commit 4fca4e3 中 merge ,2016 年 4 月 13 日)

branch -d: refuse deleting a branch which is currently checked out


When a branch is checked out by current working tree, deleting thebranch is forbidden.
However when the branch is checked out only by other working trees, deleting incorrectly succeeds.
Use find_shared_symref() to check if the branch is in use, not justcomparing with the current working tree's HEAD.



同样,在 git 2.9(2016 年 6 月)之前,重命名在另一个工作树中 check out 的分支不会调整所述另一个工作树中的符号 HEAD。
请参阅 commit 18eb3a9(2016 年 4 月 8 日)和 commit 70999e9commit 2233066(2016 年 3 月 27 日)的 Kazuki Yamaguchi ( rhenium )
(由 Junio C Hamano -- gitster --commit 741a694 中 merge ,2016 年 4 月 18 日)

branch -m: update all per-worktree HEADs


When renaming a branch, currently only the HEAD of current working treeis updated, but it must update HEADs of all working trees which point atthe old branch.

This is the current behavior, /path/to/wt's HEAD is not updated:

 % 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 HEADswhen renaming a branch.



git 2.10 (Q3 2016) 正式支持锁定机制
参见 commit 080739bcommit 6d30862commit 58142c0commit 346ef53commit 346ef53commit 58142c0commit 346ef53commit 346ef53(2016 年 6 月 13 日)和 commit 984ad9ecommit 6835314(2016 年 6 月 3 日)
建议人: Nguyễn Thái Ngọc Duy ( pclouds )
(由 Eric Sunshine ( sunshineco )Junio C Hamano -- gitster -- 中 merge ,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 sharewhich is not always mounted, you can prevent its administrative files frombeing pruned by issuing the git worktree lock command, optionallyspecifying --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 2.13(2017 年第二季度)通过 commit 2c608e0commit 507e6e9(2017 年 4 月 12 日)中添加了 lock 选项
建议人: Nguyễn Thái Ngọc Duy ( pclouds )
帮助者: David Taylor ( dt )
(由 Jeff King ( peff )Junio C Hamano -- gitster -- 中 merge ,2017 年 4 月 26 日)

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' --lock 相当于 git worktree lock 之后的 git worktree add ,但没​​有竞争条件。

Git 2.17+(2018 年第二季度)添加了 git worktree move/ git worktree remove : commit e311597

Git 2.19(2018 年第三季度)添加了一个“ --quiet”选项来减少“ git worktree add
冗长。
请参阅 see this answercommit 371979c(2018 年 8 月 15 日)。
帮助者:Martin Ågren martin.agren@gmail.com、 Elia Pinto ( devzero2000 )Duy Nguyen ( pclouds )
(由 Eric Sunshine ( sunshineco )Junio C Hamano -- gitster -- 中 merge ,2018 年 8 月 27 日)

worktree: add --quiet option


Add the '--quiet' option to git worktree, as for the other git commands.
'add' is the only command affected by it since all other commands, except 'list', are currently silent by default.



请注意,“ git worktree add ”用于执行“使用 stat 查找可用名称”
然后是 mkdir ",这很容易发生竞争。
这已在 Git 2.22(2019 年第二季度)中通过使用 mkdir 并在循环中对 EEXIST 使用react得到修复。
请参阅 commit a988ce9commit 7af01f2(2019 年 2 月 20 日)。
(由 Michal Suchanek ( hramrach )Junio C Hamano -- gitster -- 中 merge ,2019 年 4 月 9 日)

worktree: fix worktree add race


Git runs a stat loop to find a worktree name that's available andthen does mkdir on the found name.
Turn it to mkdir loop to avoid another invocation of worktree add finding the same free name and creating the directory first.



Git 2.22(2019 年第二季度)修复了判断 Git 存储库是否具有工作树的逻辑,以保护“ git branch -D”免于删除当前检查的分支
误出。
对于具有不寻常名称的存储库,此逻辑的实现被破坏,不幸的是,这已成为如今子模块的规范。
请参阅 commit 20fe798commit f3534c9(2019 年 4 月 19 日)。
(由 Jonathan Tan ( jhowtan )Junio C Hamano -- gitster -- 中 merge ,2019 年 5 月 8 日)

worktree: update is_bare heuristics


When "git branch -D <name>" is run, Git usually first checks if thatbranch 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() in worktree.c sets is_bare on aworktree only using the heuristic that a repo is bare if the worktree'spath does not end in "/.git", and not bare otherwise.
This is_bare code was introduced in 92718b7 ("worktree: add details to the worktree struct", 2015-10-08, Git v2.7.0-rc0), following a pre-core.bare heuristic.

This patch does 2 things:

  • Teach get_main_worktree() to use is_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 setting is_bare.
If core.bare=1, trust it, and otherwise, use is_bare_repository().



在 Git 2.29(2020 年第 4 季度)中,“ worktree ” API 可以更好地确定工作树路径。
请参阅 commit ec2642acommit 918d8ffcommit 1c4854ecommit 246756fcommit 62573a5 (2020 年 7 月 31 日)。
(由 Eric Sunshine ( sunshineco )Junio C Hamano -- gitster -- 中 merge ,2020 年 8 月 10 日)

worktree: drop bogus and unnecessary path munging

Signed-off-by: Eric Sunshine


The content of .git/worktrees/<id>/gitdir must be a path of the form "/path/to/worktree/.git".
Any other content would be indicative of a corrupt "gitdir" file.

To determine the path of the worktree itself one merely strips the "/.git" suffix, and this is indeed how the worktree path was determined from inception.

However, 5193490442 ("worktree: add a function to get worktree details", 2015-10-08, Git v2.7.0-rc0 -- merge listed in batch #7) extended the path manipulation in a mysterious way.
If it is unable to strip "/.git" from the path, then it instead reports the current working directory as the linked worktree's path:

if (!strbuf_strip_suffix(&worktree_path, "/.git")) {
strbuf_reset(&worktree_path);
strbuf_add_absolute_path(&worktree_path, ".");
strbuf_strip_suffix(&worktree_path, "/.");
}

This logic is clearly bogus; it can never be generally correct behavior. It materialized out of thin air in 5193490442 with neither explanation nor tests to illustrate a case in which it would be desirable.

It's possible that this logic was introduced to somehow deal with a corrupt "gitdir" file, so that it returns some sort of meaningful value, but returning the current working directory is not helpful. In fact, it is quite misleading (except in the one specific case when the current directory is the worktree whose "gitdir" entry is corrupt).
Moreover, reporting the corrupt value to the user, rather than fibbing about it and hiding it outright, is more helpful since it may aid in diagnosing the problem.

Therefore, drop this bogus path munging and restore the logic to the original behavior of merely stripping "/.git".

关于git - Git 有多个工作目录?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6270193/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com