Worktree & Bare Repo
首先说一个基础概念,我们通常克隆 git clone https://xxx.com/repo.git 时,我们实际上是做了两件事情
在对应的 <repo>/.git 目录下,创建了一堆 Git 相关的文件
在 <repo> 目录下,放置(下载)了我们的项目代码
<repo>/.git 目录叫做 GIT_DIR、而 <repo>目录则是 Work Tree,所以执行 git clone 命令实际做的事情是:
从服务器拉取 Repo 的所有内容,并存储到 .git 目录下(且将远端服务器的相关信息记录到 <repo>/.git/remotes 中)
根据远端的 HEAD 信息,得到当前默认分支是什么、并将本地 HEAD 指向该分支,然后将这一分支的代码 checkout 出来放到 <repo> 下
然后我们实际上可以把这两个步骤拆开
第一种办法是,依然用现在的结构,但是加上 --no-checkout 参数,会发现,<repo>/.git 目录不变,但是 <repo> 下没有任何文件(除了 .git 目录),此时,本地分支已创建并指向了远端分支、本地 HEAD 也指向了正确的分支,但并没有将该分支的文件 checkout 到 work tree 目录,去看 git status 能看到 git 显示的状态等同于「删除了所有文件」(如果想将这种仓库还原到普通的仓库,执行 git reset --hard HEAD 即可)
第二种办法则是,用 --bare 参数,会发现,克隆下来的目录叫做 <repo>.git 里面就直接是原来 <repo>/.git 内容,直接不存在任何 worktree,也没有创建任何本地分支(如果想将这种仓库还原成「第一种」的或是普通 clone 得仓库,参考 https://stackoverflow.com/questions/10637378/how-do-i-convert-a-bare-git-repository-into-a-normal-one-in-place )
Mirror
git clone 时还可以指定一个 --mirror 参数,当以 mirror 模式克隆一个 repo 时,在 --bare 的基础上,
参考
https://git-scm.com/docs/gitrepository-layout
https://git-scm.com/docs/git-clone
https://git-scm.com/docs/git-worktree