Home > Article > Development Tools > Teach you how to work on multiple branches at the same time without switching Git branches (detailed examples)
This article brings you relevant knowledge about Git branches. It mainly introduces related issues on how to work on multiple branches without switching branches. I hope it will be helpful to everyone.
It is common for us who are developing a certain feature and the boss suddenly jumps out and asks you to make a hotfix for production. Faced with this situation, we who use Git There are usually two solutions:
Commit the unfinished feature hastily, and then switch the branch to hotfix
git stash | git stash pop
Temporarily save the work content, and then switch to hotfix
The second method is much better than the first one, but in the face of the following scenarios, stash is still not very Good solution
We are running long-term tests on the main branch, switch to hotfix or feature, and test It will be interrupted
The project is very large, frequent index switching, the cost is very high
The old version released a few years ago, the settings and It is different now. IDE restructure adaptation switching will also bring a lot of overhead.
When switching branches, you need to reset the corresponding environment variables, such as dev/qa/prod
Need to switch to a colleague's code to help debug code recurrence issues
Some students thought that wouldn't it be enough to git clone multiple repos? This is a way to solve the above problems, but there are also many problems hidden behind it:
The status of multiple repos is not easy to synchronize, for example, there is no way to quickly cherry-pick, a repo checkout branch, another repo needs to be checked out again
git history/log is repeated. When the project history is very long, the contents of the .git
folder are very Taking up disk space
The same project and multiple repos are difficult to manage
So how can we meet these special scenarios without causing them to appear? What about these above issues?
In fact, this is a function that Git has supported since 2015, but few people know about it. git-worktree is very convenient to use. Enter in the terminal:
git worktree --help
and you can quickly see the help document description:
To explain the function of git-worktree in simple words:
You only need to maintain one repo, and you can work on multiple branches at the same time without affecting each other
There are many commands outlined in red above, but we only use the following four commonly used ones :
git worktree add [-f] [--detach] [--checkout] [--lock] [-b <new-branch>] <path> [<commit-ish>] git worktree list [--porcelain] git worktree remove [-f] <worktree> git worktree prune [-n] [-v] [--expire <expire>]
Before starting the explanation, we need to popularize two Git knowledge points that you may have overlooked:
By default, git init
Or git clone
The initialized repo has only one worktree
, called main worktree
in a certain directory Using the Git command, there is either a .git
folder or a .git
file in the current directory. If there is only a .git
file, the content inside must point to .git
The second sentence of the folder’s
feels quite confusing. Let’s use an example to illustrate it and it will be easy to understand.
If you are learning Spring Cloud, I recommend a free tutorial that has been serialized for many years and continues to be updated: https://blog.didispace.com/spring-cloud-learning/
The current project directory structure is like this (amend-crash-demo
is the root of the repo):
. └── amend-crash-demo 1 directory cd amend-crash-demo` 运行命令 `git worktree add ../feature/feature2 ➜ amend-crash-demo git:(main) git worktree add ../feature/feature2 Preparing worktree (new branch 'feature2') HEAD is now at 82b8711 add main file
Review the directory structure
. ├── amend-crash-demo └── feature └── feature2 3 directories
By default, this command will create a branch named feature2 based on the commit-ish where HEAD is located (of course, you can also specify any commit-ish in the git log). The branch disk location is as shown in the above structure
cd ../feature/feature2/
You will find that the .git
folder does not exist under this branch, but there is a .git
file. Open the file , the content is as follows:
gitdir: /Users/rgyb/Documents/projects/amend-crash-demo/.git/worktrees/feature2
At this point, if you understand the above knowledge point 2, will it be much clearer?
Next, you can do whatever you want on the feature2 branch (add/commit/pull/push) without interfering with the main worktree
一般情况下,项目组都有一定的分支命名规范,比如 feature/JIRAID-Title
, hotfix/JIRAID-Title
, 如果仅仅按照上面命令新建 worktree,分支名称中的 /
会被当成文件目录来处理
git worktree add ../hotfix/hotfix/JIRA234-fix-naming
运行完该命令,文件目录结构是这样的
. ├── amend-crash-demo ├── feature │ └── feature2 └── hotfix └── hotfix └── JIRA234-fix-naming 6 directories
很显然这不是我们想要的,这时我们就需要 -b 参数的支持了,就像 git checkout -b
一样
执行命令:
git worktree add -b "hotfix/JIRA234-fix-naming" ../hotfix/JIRA234-fix-naming
再来看一下目录结构
. ├── amend-crash-demo ├── feature │ └── feature2 └── hotfix ├── JIRA234-fix-naming └── hotfix └── JIRA234-fix-naming 7 directories
进入 JIRA234-fix-naming
目录,默认是在 hotfix/JIRA234-fix-naming
分支上
worktree 建立起来很容易,不加管理,项目目录结构肯定乱糟糟,这是我们不想看到的,所以我们需要清晰的知道某个 repo 都建立了哪些 worktree
所有的worktree 都在共用一个 repo,所以在任意一个 worktree 目录下,都可以执行如下命令来查看 worktree 列表
git worktree list
执行完命令后,可以查看到我们上面创建的所有 worktree 信息, main worktree
也会显示在此处
/Users/rgyb/Documents/projects/amend-crash-demo 82b8711 [main] /Users/rgyb/Documents/projects/chore/chore 8782898 (detached HEAD) /Users/rgyb/Documents/projects/feature/feature2 82b8711 [feature2] /Users/rgyb/Documents/projects/hotfix/hotfix/JIRA234-fix-naming 82b8711 [JIRA234-fix-naming] /Users/rgyb/Documents/projects/hotfix/JIRA234-fix-naming 82b8711 [hotfix/JIRA234-fix-naming]
worktree 的工作做完了,也是要及时删除的,否则也会浪费很多磁盘空间
另外,如果您正在学习Spring Cloud,推荐一个连载多年还在继续更新的免费教程:https://blog.didispace.com/spring-cloud-learning/
这个命令很简单了,worktree 的名字叫什么,直接就 remove 什么就好了
git worktree remove hotfix/hotfix/JIRA234-fix-naming
此时,分支名弄错的那个 hotfix 就被删掉了
/Users/rgyb/Documents/projects/amend-crash-demo 82b8711 [main] /Users/rgyb/Documents/projects/chore/chore 8782898 (detached HEAD) /Users/rgyb/Documents/projects/feature/feature2 82b8711 [feature2] /Users/rgyb/Documents/projects/hotfix/JIRA234-fix-naming 82b8711 [hotfix/JIRA234-fix-naming]
假设你创建一个 worktree,并在里面有改动,突然间这个worktree 又不需要了,此刻你按照上述命令是不能删掉了,此时就需要 -f
参数来帮忙了
git worktree remove -f hotfix/JIRA234-fix-naming
删除了 worktree,其实在 Git 的文件中,还有很多 administrative 文件是没有用的,为了保持清洁,我们还需要进一步清理
这个命令就是清洁的兜底操作,可以让我们的工作始终保持整洁
到这里,你应该理解,整个 git-worktree 的使用流程就是下面这四个命令:
git worktree add git worktree list git worktree remove git worktree prune
你也应该明白 git worktree 和 git clone 多个 repo 的区别了。只维护一个 repo,创建多个 worktree,操作间行云流水
我的实践:通常使用 git worktree,我会统一目录结构,比如 feature 目录下存放所有 feature 的worktree,hotfix 目录下存放所有 hotfix 的 worktree,这样整个磁盘目录结构不至于因为创建多个 worktree 而变得混乱
在磁盘管理上我有些强迫症,理想情况下,某个 repo 的 worktree 最好放在这个 repo 的文件目录里面,但这就会导致 Git track 新创建的 worktree 下的所有文件,为了避免 Git track worktree 的内容,来来回回修改 gitignore 文件肯定是不合适的!
那么如何解决呢?点击下方卡片,关注“日拱一兵”,正在连载Git的高级技巧!
可以删除 main worktree 吗?为什么
反复创建和删除worktree, repo/.git/wortree 目录的变化你能理解吗?
推荐学习:《Git教程》
The above is the detailed content of Teach you how to work on multiple branches at the same time without switching Git branches (detailed examples). For more information, please follow other related articles on the PHP Chinese website!