Skip to content

Commit d367867

Browse files
committed
dev/git: git worktree
1 parent abf5b5c commit d367867

File tree

2 files changed

+54
-0
lines changed

2 files changed

+54
-0
lines changed

docs/dev/git.md

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -517,6 +517,59 @@ git bisect bad <new-commit>
517517

518518
有时候我们会需要确认哪个 commit **修复**(而不是导致)了问题,但是 `git bisect` 默认 good 需要早于 bad,直接 `git bisect start` 的话很容易误操作。请阅读 [git-bisect(1)][git-bisect.1] 了解应该如何处理此类情况。
519519

520+
### Worktree {#git-worktree}
521+
522+
有时候我们会需要同时在多个分支上进行开发。你可能会这么做:
523+
524+
-`git clone` 一份仓库
525+
- 或者每次切换的时候都要 `git stash`,切换回来之后再 `git stash pop`
526+
527+
可以注意到,这两种方式其实都不是很方便。Git 的 worktree 功能可以帮助解决这个需求:将不同的分支 checkout 到不同的目录下,但是这些目录仍然共享同一个 `.git` 目录,在节约磁盘空间的同时,避免了频繁切换分支的麻烦,特别是在需要并行在多个分支上做处理时非常有用(甚至包括 [Claude Code 的文档](https://code.claude.com/docs/en/common-workflows#run-parallel-claude-code-sessions-with-git-worktrees) 也提到了 worktree 的使用方法)。
528+
529+
在默认情况下,只有一个 worktree,即当前的仓库目录:
530+
531+
```console
532+
$ git worktree list
533+
/home/username/Projects/Linux201-docs abf5b5c8 [master]
534+
```
535+
536+
可以用 `git worktree add` 添加新的 worktree:
537+
538+
```bash
539+
# 新建 dev1 分支,并将其 checkout 到 /tmp/201-dev1 目录下
540+
git worktree add /tmp/201-dev1 -b dev1
541+
542+
git branch --copy dev2
543+
# 将已有的 dev2 分支 checkout 到 /tmp/201-dev2 目录下
544+
git worktree add /tmp/201-dev2 dev2
545+
```
546+
547+
!!! note "新的 worktree 目录结构"
548+
549+
在新的 worktree 目录下,并不会有完整的 `.git` 目录,而是一个 `.git` 文件,内容类似如下:
550+
551+
```text
552+
gitdir: /home/username/Projects/Linux201-docs/.git/worktrees/201-dev1
553+
```
554+
555+
可以使用 `git worktree remove <path>` 来删除指定的 worktree。如果没有用这个指令,而是直接把目录删掉了,那么 `git worktree list` 结果类似如下:
556+
557+
```console
558+
> git worktree list
559+
/home/username/Projects/Linux201-docs abf5b5c8 [master]
560+
/tmp/201-dev1 abf5b5c8 [dev1] prunable
561+
```
562+
563+
需要使用 `git worktree prune` 来清理这些已经不存在的 worktree。
564+
565+
!!! warning "worktree 与 submodule 的兼容性"
566+
567+
目前 worktree 对 submodule 的支持还不完善,这一点在 [git-worktree(1)][git-worktree.1] 中也有提到:
568+
569+
> ... and the support for submodules is incomplete.
570+
571+
<https://stackoverflow.com/questions/31871888/what-goes-wrong-when-using-git-worktree-with-git-submodules> 中整理了不同 Git 版本的 worktree 对 submodule 支持的行为差异。
572+
520573
### Commit Message Convention {#git-commit-message}
521574

522575
对于多人协作的项目,良好的 commit message 是非常重要的。胡乱使用诸如 `update``fix``change` 等无意义的 Commit Message,会使得项目的历史记录变得难以理解,也会给后续的维护带来困难。

includes/man.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
[git-bisect.1]: https://git-scm.com/docs/git-bisect
1212
[git-fetch.1]: https://git-scm.com/docs/git-fetch
13+
[git-worktree.1]: https://git-scm.com/docs/git-worktree
1314
[perf-stat.1]: https://man7.org/linux/man-pages/man1/perf-stat.1.html
1415
[rrsync.1]: https://man7.org/linux/man-pages/man1/rrsync.1.html
1516
[rsync.1]: https://man7.org/linux/man-pages/man1/rsync.1.html

0 commit comments

Comments
 (0)