Git Worktree
名称
git-worktree - 管理附加到同一存储库的多个工作树。
语法
git worktree add [-f] [--detach] [--checkout] [--lock [--reason <string>]] [-b <new-branch>] <path> [<commit-ish>]
git worktree list [--porcelain]
git worktree lock [--reason <string>] <worktree>
git worktree move <worktree> <new-path>
git worktree prune [-n] [-v] [--expire <expire>]
git worktree remove [-f] <worktree>
git worktree repair [<path>…]
git worktree unlock <worktree>
描述
管理附加到同一存储库的多个工作树。一个 git 存储库可以支持多个工作树,允许您一次检出多个分支。 使用 git worktree 添加一个新的工作树与存储库相关联。 这个新的工作树被称为“链接工作树”,而不是 git-init(1) 或 git-clone(1) 准备的“主工作树”。 一个存储库有一个主工作树(如果它不是一个裸存储库)和零个或多个链接工作树。 完成链接工作树后,使用 git worktree remove 将其删除。
在最简单的形式中, git worktree add
如果在不使用 git worktree remove 的情况下删除了工作树,则其位于存储库中的相关管理文件(请参阅下面的“详细信息”)最终将被自动删除(请参阅 git-config(1) 中的 gc.worktreePruneExpire), 或者您可以在主工作树或任何链接的工作树中运行 git worktree prune 来清理任何陈旧的管理文件。
如果链接的工作树存储在不总是挂载的便携式设备或网络共享上,您可以通过发出 git worktree lock 命令来防止其管理文件被修剪,可选地指定 --reason 来解释工作树被锁定的原因 .
初始化一个仓库
$ git init
Initialized empty Git repository in D:/VSCode/testGit/.git/
user@NAME MINGW64 /d/VSCode/testGit (master)
$ git status
$ git add .
$ git commit -m 'f commit'
[master (root-commit) f7f05d0] f commit
3 files changed, 18 insertions(+)
create mode 100644 blob.config
create mode 100644 copy.sh
create mode 100644 fff.txt
## 新建两个分支后
user@NAME MINGW64 /d/VSCode/testGit (master)
$ git branch -a
dev
* master
release
新建工作树 add
git worktree add [-f] [--detach] [--checkout] [--lock [--reason <string>]] [-b <new-branch>] <path> [<commit-ish>]
<path> 必填参数
## 创建一个新工作树wtree1
$ git worktree add ./wtree1
Preparing worktree (new branch 'wtree1')
HEAD is now at f7f05d0 f commit
user@NAME MINGW64 /d/VSCode/testGit (master)
$ git worktree list
D:/VSCode/testGit f7f05d0 [master]
D:/VSCode/testGit/wtree1 f7f05d0 [wtree1]
-b/-B 创建一个新分支
使用 add,从
开始创建一个名为 的新分支,然后将 签出到新的工作树中。 如果省略 ,则默认为 HEAD。 默认情况下, -b 如果已经存在,则拒绝创建新分支。 -B 覆盖此保护措施,将 重置为 。
使用 -b 创建一个新分支
## 使用 -b 创建一个新分支
user@NAME MINGW64 /d/VSCode/testGit (master)
$ git worktree add -b nbranch-wtree2 ./wtree2
Preparing worktree (new branch 'nbranch-wtree2')
HEAD is now at f7f05d0 f commit
user@NAME MINGW64 /d/VSCode/testGit (master)
$ git worktree list
D:/VSCode/testGit f7f05d0 [master]
D:/VSCode/testGit/wtree1 f7f05d0 [wtree1]
D:/VSCode/testGit/wtree2 f7f05d0 [nbranch-wtree2]
user@NAME MINGW64 /d/VSCode/testGit (master)
$ git branch -a
dev
* master
+ nbranch-wtree2
release
+ wtree1
删除工作树后 分支还在
## 删除工作树后 分支还在
user@NAME MINGW64 /d/VSCode/testGit (master)
$ git worktree remove wtree2
$ git branch -a
dev
* master
nbranch-wtree2
release
+ wtree1
-b 参数不能创建一个已有的分支
## -b 参数不能创建一个已有的分支
user@NAME MINGW64 /d/VSCode/testGit (master)
$ git worktree add -b dev ./wtree2
Preparing worktree (new branch 'dev')
fatal: A branch named 'dev' already exists.
-B 会覆盖此保护措施
## 在 dev 分支上增加一个提交
user@NAME MINGW64 /d/VSCode/testGit (dev)
$ git log
commit ddfaee1c736a3ad310b46a6ea795eebdbc27b269 (HEAD -> dev)
Author: yuansheng.xu <[email protected]>
Date: Sun Oct 9 23:11:43 2022 +0800
新增一个commit
commit f7f05d0d91e35b69ab6cce50afb8ab9bd6f3c97e (wtree1, release, nbranch-wtree2, master)
Author: yuansheng.xu <[email protected]>
Date: Sun Oct 9 22:57:18 2022 +0800
f commit
## -B 会覆盖原有分支
user@NAME MINGW64 /d/VSCode/testGit (master)
$ git worktree add -B dev wtree2
Preparing worktree (resetting branch 'dev'; was at 96efc84)
HEAD is now at f7f05d0 f commit
## dev分支无法切换,因为已经与工作树wtree2关联,可以直接去工作树中查看
user@NAME MINGW64 /d/VSCode/testGit (master)
$ git checkout dev
fatal: 'dev' is already checked out at 'D:/VSCode/testGit/wtree2'
## 在工作树wtree2中,可以看到当前分支为dev ,且之前添加的log也已经被覆盖,指向了master的HEAD位置
user@NAME MINGW64 /d/VSCode/testGit/wtree2 (dev)
$ git log
commit f7f05d0d91e35b69ab6cce50afb8ab9bd6f3c97e (HEAD -> dev, wtree1, release, nbranch-wtree2, master)
Author: yuansheng.xu <[email protected]>
Date: Sun Oct 9 22:57:18 2022 +0800
f commit
<commit-ish> 新建工作树时指定commit为新工作树的HEAD
在master中添加几个新的commit
user@NAME MINGW64 /d/VSCode/testGit (master)
$ git log
commit 79cb6ff1759dab7484fdd5bd4e1508f951ffc7f8 (HEAD -> master)
第四个 commit
commit e4b08e383c62a332c0517593f1117b93db6b9e2b
第三个 commit
commit b986afc9c223899f3582f8cb2b5d7d7fca57e2c5
第二个 commit
commit f7f05d0d91e35b69ab6cce50afb8ab9bd6f3c97e (wtree1, release, nbranch-wtree2, dev)
f commit
使用指定的commit创建新工作树
user@NAME MINGW64 /d/VSCode/testGit (master)
$ git worktree add wtree3 e4b08e383c62a332c0517593f1117b93db6b9e2b
Preparing worktree (detached HEAD e4b08e3)
HEAD is now at e4b08e3 第三个 commit
## 可以看到,新建的工作树的最新提交为 “第三个 commit”
user@NAME MINGW64 /d/VSCode/testGit/wtree3 ((e4b08e3...))
$ git log
commit e4b08e383c62a332c0517593f1117b93db6b9e2b (HEAD)
Author: yuansheng.xu <[email protected]>
Date: Sun Oct 9 23:39:35 2022 +0800
第三个 commit
## 创建新工作树的同步,使用-b创建新分支
user@NAME MINGW64 /d/VSCode/testGit (master)
$ git worktree add -b nb-wtree4 wtree4 e4b08e383c62a332c0517593f1117b93db6b9e2b
Preparing worktree (new branch 'nb-wtree4')
HEAD is now at e4b08e3 第三个 commit
user@NAME MINGW64 /d/VSCode/testGit/wtree4 (nb-wtree4)
$ pwd
/d/VSCode/testGit/wtree4
新建工作树关联到已有的分支
$ git worktree add ../wt/wtrelease release
Preparing worktree (checking out 'release')
HEAD is now at 562f9cd release commit
-f 强制在已经关联工作树的分支上创建新工作树
## dev已经关联工作树,创建失败
$ git worktree add ../wt/wtdev dev
fatal: 'dev' is already checked out at 'D:/VSCode/wt/wtree2'
Preparing worktree (checking out 'dev')
## 使用-f 强制新建
user@NAME MINGW64 /d/VSCode/testGit (master)
$ git worktree add -f ../wt/wtdev dev
Preparing worktree (checking out 'dev')
HEAD is now at f7f05d0 f commit
-f 强制新建的工作树与原有的工作树共享工作空间
## 在新建的工作树中修改
$ cd wt/wtdev/
user@NAME MINGW64 /d/VSCode/wt/wtdev (dev)
$ git commit -am '在wtdev工作树中修改'
[dev 8ec2b56] 在wtdev工作树中修改
1 file changed, 1 insertion(+)
## 在原有的关联工作树中查看上面的修改
user@NAME MINGW64 /d/VSCode/wt/wtree2 (dev)
$ git log
commit 8ec2b56f3c4da2904fff7671ebaeeca0946eef7b (HEAD -> dev)
在wtdev工作树中修改
commit f7f05d0d91e35b69ab6cce50afb8ab9bd6f3c97e
f commit
## 在不同的工作树中查看修改的文件内容,发现内容不一样,因为原来的工作树中HEAD还没有指向新的commit。
user@NAME MINGW64 /d/VSCode/wt/wtdev (dev)
$ cat fff.txt
在wtdev工作树中修改
user@NAME MINGW64 /d/VSCode/wt/wtree2 (dev)
$ cat fff.txt
--lock 创建新工作树并锁定
user@NAME MINGW64 /d/VSCode/testGit (master)
$ git worktree add --lock --reason='locck reason' ../wt/wtree5
Preparing worktree (new branch 'wtree5')
HEAD is now at f4c1226 merge wtree3 HEAD
user@NAME MINGW64 /d/VSCode/testGit (master)
$ git worktree list
D:/VSCode/wt/wtree5 f4c1226 [wtree5] locked
锁定(解锁)工作树 lock/unlock
锁定的工作树可以防止被修剪(prune)
user@NAME MINGW64 /d/VSCode/testGit (master)
$ git worktree lock --reason='lock reason' wtdev
user@NAME MINGW64 /d/VSCode/testGit (master)
$ git worktree list
D:/VSCode/testGit f4c1226 [master]
D:/VSCode/wt/wtdev 8ec2b56 [dev] locked
D:/VSCode/wt/wtree1 e14fd71 [wtree1]
D:/VSCode/wt/wtree2 8ec2b56 [dev]
D:/VSCode/wt/wtree3 e3a3c4c (detached HEAD)
D:/VSCode/wt/wtree4 e4b08e3 [nb-wtree4]
## 解锁
user@NAME MINGW64 /d/VSCode/wt/wtree5 (wtree5)
$ git worktree unlock wtdev
展示工作树列表 list
## git worktree list [--porcelain]
user@NAME MINGW64 /d/VSCode/testGit (master)
$ git worktree list
D:/VSCode/testGit f4c1226 [master]
D:/VSCode/wt/wtdev 2c05e7a [dev]
D:/VSCode/wt/wtree1 e14fd71 [wtree1]
D:/VSCode/wt/wtree2 2c05e7a [dev]
D:/VSCode/wt/wtree3 e3a3c4c (detached HEAD)
D:/VSCode/wt/wtree4 e4b08e3 [nb-wtree4]
D:/VSCode/wt/wtree5 f4c1226 [wtree5] locked
D:/VSCode/wt/wtrele 7f91b4d [release]
删除工作树 remove
$ git worktree remove wtree2
fatal: 'wtree2' contains modified or untracked files, use --force to delete it
## 使用 -f 强制删除
user@NAME MINGW64 /d/VSCode/testGit (master)
$ git worktree remove -f wtree2
修剪工作树 prune
## 当前仓库中的工作树状态,wtree5 被锁定
$ git worktree list
D:/VSCode/testGit f4c1226 [master]
D:/VSCode/wt/wtdev 2c05e7a [dev]
D:/VSCode/wt/wtree1 e14fd71 [wtree1]
D:/VSCode/wt/wtree3 e3a3c4c (detached HEAD)
D:/VSCode/wt/wtree4 e4b08e3 [nb-wtree4]
D:/VSCode/wt/wtree5 f4c1226 [wtree5] locked
D:/VSCode/wt/wtrele 7f91b4d [release]
## 手动删除工作树目录 D:/VSCode/wt/wtrele 且 把wtree4、wtree5 移动到其他目录 后的状态
$ git worktree list
D:/VSCode/testGit f4c1226 [master]
D:/VSCode/wt/wtdev 2c05e7a [dev]
D:/VSCode/wt/wtree1 e14fd71 [wtree1]
D:/VSCode/wt/wtree3 e3a3c4c (detached HEAD)
D:/VSCode/wt/wtree4 e4b08e3 [nb-wtree4] prunable ## 可修剪
D:/VSCode/wt/wtree5 f4c1226 [wtree5] locked
D:/VSCode/wt/wtrele 7f91b4d [release] prunable ## 可修剪
## 修剪后 的工作树,被锁定的工作树没有变化 ,其他‘可修剪’工作树被删除
$ git worktree prune
$ git worktree list
D:/VSCode/testGit f4c1226 [master]
D:/VSCode/wt/wtdev 2c05e7a [dev]
D:/VSCode/wt/wtree1 e14fd71 [wtree1]
D:/VSCode/wt/wtree3 e3a3c4c (detached HEAD)
D:/VSCode/wt/wtree5 f4c1226 [wtree5] locked
重新关联工作树 repair
## 被修剪掉了的工作树无法被重新关联
user@NAME MINGW64 /d/VSCode/wt/wtinner/wtree4
$ git worktree repair ../../../testGit/
fatal: not a git repository: D:/VSCode/testGit/.git/worktrees/wtree4
## 被锁定的工作树没有被修剪(prune)掉,所有重新关联上了
user@NAME MINGW64 /d/VSCode/wt/wtinner/wtree5 (wtree5)
$ git worktree repair ../../../testGit/
## 现在把 wtree3 移动到其他目录
$ git worktree list
D:/VSCode/testGit f4c1226 [master]
D:/VSCode/wt/wtdev 2c05e7a [dev]
D:/VSCode/wt/wtree1 e14fd71 [wtree1]
D:/VSCode/wt/wtree3 e3a3c4c (detached HEAD) prunable ## 可修剪
D:/VSCode/wt/wtree5 f4c1226 [wtree5] locked
## 在修剪之前直接repair ,也可以成功关联
$ cd wt/wtinner/wtree3
user@NAME MINGW64 /d/VSCode/wt/wtinner/wtree3 ((e3a3c4c...))
$ git worktree repair ../../../testGit/
标签:git,wt,worktree,--,dev,VSCode,testGit
From: https://www.cnblogs.com/xysgo/p/16774164.html