Git命令列表--git-worktree

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 add ../hotfix 创建新的分支 hotfix 并在路径 ../hotfix 处检出。 要改为在新工作树中的现有分支上工作,请使用 git worktree add 。 另一方面,如果您只是打算进行一些实验性更改或在不干扰现有开发的情况下进行测试,那么创建一个不与任何分支关联的一次性工作树通常会很方便。 例如, git worktree add -d 在与当前分支相同的提交处创建一个具有分离 HEAD 的新工作树

如果在不使用 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 <804288658@qq.com>
Date:   Sun Oct 9 23:11:43 2022 +0800

    新增一个commit

commit f7f05d0d91e35b69ab6cce50afb8ab9bd6f3c97e (wtree1, release, nbranch-wtree2, master)
Author: yuansheng.xu <804288658@qq.com>
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 <804288658@qq.com>
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 <804288658@qq.com>
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/

posted @ 2023-02-12 20:29  菜阿  阅读(281)  评论(0编辑  收藏  举报