preface
Last article Git Worktree Dharma is really fragrant Let's learn how git worktree helps me work in multiple branches at the same time without affecting each other. However, the directory where the worktree is created is not under the current project. I always feel that these created WorkTrees do not belong to the current project, which is very uncomfortable for me with disk management obsessive-compulsive disorder. Today I'll take you to learn about an advanced usage to solve this pain point
Preparation knowledge
Before using advanced usage, you need to know a little about bare repo. Let's start with the commands you are familiar with
git init git clone https://github.com/FraserYu/amend-crash-demo.git
These two commands will generate a non bare repo. We usually do our daily work in this repo. You can add/commit/pull/push here
To generate a bare repo is also very simple, just add the -- bare parameter to the above two commands
git init --bare git clone --bare https://github.com/FraserYu/amend-crash-demo.git
To execute the two clone commands and look at the contents of the file, you will see the difference
- Bare repo only contains Git related information, not our actual project file (. java/.js/.py), while non bare repo contains all our information
- bare repo names are suffixed with. git by default, which proves the first point
- The. git folder does not exist in bare repo, which makes it impossible to add/commit/pull/push like non bare repo
Seeing this, you may feel that bare repo is a Git empty shell folder, which is good for nothing. In fact, these features of bare repo (which cannot be changed) prevent the contents of repo from being messed up, so it can be used for private centralized repo. As explained in a figure, it is actually like this:
If you are interested, you can experiment the whole process locally according to the following command:
user@server:$~ git init --bare name_to_repo.git user@machine1:$~ git clone user@server:/path/to/repo/name_to_repo.git . user@machine1:$~ cd name_to_repo user@machine1:$~ touch README user@machine1:$~ echo "Hello world" >> README user@machine1:$~ git add README user@machine1:$~ git commit -m "Adding a README" user@machine1:$~ git push origin master user@server:$~ ls /path/to/repo/name_to_repo.git/ branches/ config description HEAD hooks/ info/ objects/ refs/ user@machine2:$~ git clone user@server:/path/to/repo/name_to_repo.git . user@machine2:$~ ls name_to_repo.git/ README user@machine2:$~ cat README Hello world
The experimental result is that no matter how you push the file under machine1, there will be no file you push in bare repo, only Git related information. However, when machine2 clone the latest repo, you can see the file of machine1 push, which is the magic of Git
Here, bare repo explains. Next, the next one Git Worktree Dharma is really fragrant Content, with the help of the characteristics of bare repo, you can optimize the practice of working in multiple branches at the same time
Git Worktree advanced usage
First, create a separate folder for your project (for example, amend crash demo) in the directory you selected, and cd it in
mkdir amend-crash-demo cd amend-crash-demo
Next, clone the project code in the form of bare, and clone the contents into the. Bare folder:
git clone --bare git@github.com:FraserYu/amend-crash-demo.git .bare
We also need to create a. git file in the current directory. The contents of the file point to our. bare folder in the form of gitdir (if you don't understand the meaning of gitdir, please go back to it) Git Worktree Dharma is really fragrant )
echo "gitdir: ./.bare" > .git
Then we need to edit the. bare/config file and modify the [remote "origin"] content to be consistent with the following content (that is, add line 6), which ensures that we can create a worktree switch branch and display the correct branch name
vim .bare/config # ----------------------------------------------- [remote "origin"] url = git@github.com:FraserYu/amend-crash-demo.git fetch = +refs/heads/*:refs/remotes/origin/*
Next, we can create a worktree. First, we need to create a worktree for the main branch, because the commit ish pointed to by the main branch HEAD is the commit ish of other WorkTrees you create
git worktree add main # -------------------------------- Preparing worktree (checking out 'main') HEAD is now at 82b8711 add main file
Usually, instead of working directly on the main branch, we create other types of branches and continue to create a worktree named feature/JIRA234-feature3
git worktree add -b "feature/JIRA234-feature3" feature3 # ------------------------------------------------ Preparing worktree (new branch 'feature/JIRA234-feature3') HEAD is now at 82b8711 add main file
Looking at the contents of the current folder, you will find that there are only two folders: main and feature3 (because. bare and. git are hidden folders / files). Isn't this quite refreshing?
ls -l # ------------------------------------------- total 0 drwxr-xr-x 10 rgyb staff 320 Nov 23 21:44 feature3 drwxr-xr-x 10 rgyb staff 320 Nov 23 21:36 main ls -al # ------------------------------------------- total 8 drwxr-xr-x 6 rgyb staff 192 Nov 23 21:44 . drwxr-xr-x 3 rgyb staff 96 Nov 23 21:14 .. drwxr-xr-x 12 rgyb staff 384 Nov 23 21:36 .bare -rw-r--r-- 1 rgyb staff 16 Nov 23 21:29 .git drwxr-xr-x 10 rgyb staff 320 Nov 23 21:44 feature3 drwxr-xr-x 10 rgyb staff 320 Nov 23 21:36 main
Next, we can do add/commit/pull/push operations on our various branches without affecting each other
echo "feature3 development" > feature3.yaml git add feature3.yaml git commit -m "feat: [JIRA234-feature3] feature3 development" # ------------------------------------------------------------------ [feature/JIRA234-feature3 aeaac94] feat: [JIRA234-feature3] feature3 development 1 file changed, 1 insertion(+) create mode 100644 feature3.yaml git push --set-upstream origin feature/JIRA234-feature3
Through the four commands of worktree in the previous article, multi branch collaborative development is no longer a problem:
git worktree add git worktree list # ------------------------------------------------------------------------------------------------ /Users/rgyb/Documents/projects/amend-crash-demo/.bare (bare) /Users/rgyb/Documents/projects/amend-crash-demo/feature3 aeaac94 [feature/JIRA234-feature3] /Users/rgyb/Documents/projects/amend-crash-demo/main 82b8711 [main] git worktree remove git worktree prune
summary
With the help of the feature of bare repo, we can manage all WorkTrees in the current project directory very neatly, and multi branch collaborative development, like this:
. └── amend-crash-demo ├── feature3 │ ├── README.md │ ├── config.yaml │ ├── feat1.txt │ ├── feature3.yaml │ ├── file1.yaml │ ├── hotfix.yaml │ ├── main.properties │ └── main.yaml └── main ├── README.md ├── config.yaml ├── feat1.txt ├── file1.yaml ├── hotfix.yaml ├── main.properties └── main.yaml 3 directories, 15 files
If you have disk management obsessive-compulsive disorder, this is definitely a good way.
If you want to better understand the whole process, you need to check the Git related file information while operating the commands in this article
If you have any questions, please communicate in the message area
reference resources
- https://www.blopig.com/blog/2...
- https://lists.mcs.anl.gov/pip...
- https://www.saintsjd.com/2011...
- https://infrequently.org/2021...
- https://morgan.cugerone.com/b...
Rigong Yibing | original