2

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

  1. bare repo only contains Git related information and does not contain our actual project files ( .java / .js / .py ), while non-bare repo contains all our information
  2. The bare repo name .git suffix 061a6d02319bfe by default, which just proves the first point
  3. .git folder does not exist in the bare repo, which means that it cannot be like non-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

  1. https://www.blopig.com/blog/2017/06/using-bare-git-repos/
  2. https://lists.mcs.anl.gov/pipermail/petsc-dev/2021-May/027448.html
  3. https://www.saintsjd.com/2011/01/what-is-a-bare-git-repository/
  4. https://infrequently.org/2021/07/worktrees-step-by-step/
  5. https://morgan.cugerone.com/blog/how-to-use-git-worktree-and-in-a-clean-way/

Ri Gong Yibing| Original


日拱一兵
3.4k 声望25.1k 粉丝