Preface
The last article Git Worktree, the true fragrance of Dafa took you to understand how git worktree helped me work in multiple branches at the same time without affecting each other. But the location of the directory where the worktree is created is not under the current project. I always feel that the worktrees created do not belong to the current project. This is very uncomfortable for me with disk management obsessive-compulsive disorder. Today, I will show you an advanced usage to solve it. This pain point
Prepare knowledge
Before using advanced usage, you need to know a bit of bare repo
. Let’s start with the commands you’re 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 repo
like this, you can here add
/ commit
/ pull
/ push
To generate a bare repo
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 these two clone commands, and check the contents of the file, you will see the difference
bare repo
only contains Git related information and does not contain our actual project files (.java
/.js
/.py
), whilenon-bare repo
contains all our information- The bare repo name
.git
suffix 061a6d02319bfe by default, which just proves the first point .git
folder does not exist in the bare repo, which means that it cannot be likenon-bare repo
add
/commit
/pull
/push
Seeing this, you may feel that bare repo is just a Git shell folder, which is useless. In fact, it is not. Because of these characteristics of bare repo (it cannot be changed), the content in the repo is prevented from being messed up, so it can be used as a private centralized repo. A picture explains, in fact, this is the case of:
If you are interested, you can experiment with 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 result of the : No matter how you push the file under machine1, the file you push will not exist in the bare repo, only Git related information. But when machine2 clones the latest repo, you can see the file of machine1 push. This is the magic of Git
At this point, bare repo is finished. Next, Git Worktree Dafa Really Fragrant 161a6d02319cd9, and use the features of bare repo to optimize the practice of working in multiple branches at the same time.
Advanced usage of Git Worktree
First, create a separate folder for your project in the directory you selected (for example, amend-crash-demo
cd
mkdir amend-crash-demo
cd amend-crash-demo
Next, clone the project code in the form of bare, and clone the content to the .bare
folder:
git clone --bare git@github.com:FraserYu/amend-crash-demo.git .bare
We would also like to create in the current directory .git
file , the file contents are gitdir
form point to our .bare
folder (if you do not understand the meaning of gitdir, please look back at Git Worktree Dafa really fragrant )
echo "gitdir: ./.bare" > .git
Then we have to edit the .bare/config file and modify the [remote "origin"]
to be consistent with the following content (that is, add the content of line 6), which ensures that we create a worktree to switch branches 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 you create other worktrees.
git worktree add main
# --------------------------------
Preparing worktree (checking out 'main')
HEAD is now at 82b8711 add main file
Usually we do not work directly on the main branch, but create other types of branches, and continue to create a feature/JIRA234-feature3
named 061a6d02319e17
git worktree add -b "feature/JIRA234-feature3" feature3
# ------------------------------------------------
Preparing worktree (new branch 'feature/JIRA234-feature3')
HEAD is now at 82b8711 add main file
View the contents of the current folder, you will find only main
and feature3
two folders (because .bare
and .git
is a hidden folder / file), this is not quite refreshing it?
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
add
/ commit
/ pull
/ push
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
Summarize
By taking advantage of the features of bare repo, we can manage all worktrees neatly only in the current project directory and develop 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 view the Git-related file information while operating the commands in this article
If you have any questions, communicate in the message area
refer to
- https://www.blopig.com/blog/2017/06/using-bare-git-repos/
- https://lists.mcs.anl.gov/pipermail/petsc-dev/2021-May/027448.html
- https://www.saintsjd.com/2011/01/what-is-a-bare-git-repository/
- https://infrequently.org/2021/07/worktrees-step-by-step/
- https://morgan.cugerone.com/blog/how-to-use-git-worktree-and-in-a-clean-way/
Ri Gong Yibing| Original
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。