background
Keep a clean Git submission record, three tips are enough. After reading this, everyone commented privately that this is a very useful feature. I suddenly thought of another Git feature that I use at work that is also quite useful and must come clean
As programmers, we should all have a feeling that once you enter a project, you will be responsible for everything from development, release and production, to hotfix and post-maintenance. When you are developing a feature, it is quite common for the boss to suddenly ask you to do hotfix for production. Faced with this situation, Those of us who use Git usually have two solutions:
- Commit unfinished features hastily, then switch branches to hotfix
git stash | git stash pop
Save work temporarily, then switch to Hotfix
The second way is much better than the first one, but stash is still not a good solution for the following scenarios
The scene we face
- Running a long test on the main branch, switching to hotfix or feature breaks the test
- Projects are very large, with frequent index switching and very high cost
- There are old versions released several years ago, the Settings are different from the current ones, and the switch of IDE Arms adaptation will also bring great overhead
- To switch branches, you need to reset the corresponding environment variables, such as dev/qa/prod
- You need to switch to a colleague’s code to help debug code recurrence problems
Git clone multiple repOs. This is one way to solve the above problems, but it also hides a lot of problems:
- The state of multiple repOs is not synchronized well, for example, there is no quick cherry-pick, a branch of one repo checkout, and another repO needs to checkout again
- Git history/log is repeated when the project history is very long,
.git
The contents of folders are very disk intensive - Multiple REPOs on the same project can be difficult to manage
So how do you satisfy these particular scenarios without having these problems?
git-worktree
Git worktree supports Git worktree since 2015, but few people know about it.
git worktree --help
Copy the code
You can quickly see the help documentation:
The purpose of git-worktree is:
You can maintain a single REPO and work on multiple branches at the same time without affecting each other
There are many red box commands above, but we use only the following four commands:
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>]
Copy the code
Before we get started, there are two Git facts that you might not have noticed:
- By default,
git init
或git clone
There is only one initialized REPOworktree
That is calledmain worktree
- If you use Git in a directory, it is either present in the current directory
.git
Folder. Or have a.git
Files, if only.git
The contents of the file must be pointed to.git
The folder
The second sentence feels quite round, below uses the example to illustrate, is easy to understand
git worktree add
The current project directory structure looks like this (amend-crash-demo is the root of the repo) :
└─ amend-crash-demo 1 directoryCopy the code
CD amend-crash-demo Run 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
Copy the code
Look again at the directory structure
└── ── ── ── ── ── ── ── ── ── ── ── ── ── ── ──Copy the code
By default, this command creates a branch named Feature2 based on the commit-ish location of the HEAD (or, optionally, any commit-ish in the Git log), as shown in the structure above
cd .. /feature/feature2/ You can see that there is a.git folder in this branch, instead of a.git folder.
gitdir: /Users/rgyb/Documents/projects/amend-crash-demo/.git/worktrees/feature2
Copy the code
Here, you understand the above knowledge point 2, is it a lot clearer?
From there, you can do anything you want on the Feature2 branch (add/commit/pull/push), independent of the Main Worktree
In general, the project team has a certain branch naming convention, such as feature/ jiraid-title, hotfix/ jiraid-title. If you just follow the above command to create a worktree, the/in the branch name will be treated as a file directory
git worktree add .. /hotfix/hotfix/JIRA234-fix-namingCopy the code
After running this command, the file directory structure looks like this
. ├ ─ ─ amend - crash - demo ├ ─ ─ feature │ └ ─ ─ feature2 └ ─ ─ hotfix └ ─ ─ hotfix └ ─ ─ JIRA234 - fix - naming six directoriesCopy the code
This is obviously not what we want, so we need support for the -b parameter, just like git checkout -b
Execute command:
git worktree add -b "hotfix/JIRA234-fix-naming" .. /hotfix/JIRA234-fix-namingCopy the code
Take a look at the directory structure
. ├ ─ ─ amend - crash - demo ├ ─ ─ feature │ └ ─ ─ feature2 └ ─ ─ hotfix ├ ─ ─ JIRA234 - fix - naming └ ─ ─ hotfix └ ─ ─ JIRA234 - fix - naming 7 directoriesCopy the code
Enter the jira234-fix-naming directory, which is in the hotfix/ jira234-fix-naming branch by default
Worktrees are easy to set up, unmanaged, and the project directory structure is cluttered, which we don’t want to see, so we need to have a clear idea of what worktrees a repO has set up
git worktree list
All worktrees share the same REPO. Therefore, you can run the following command in any worktree directory to view the worktree list
git worktree list
Copy the code
After executing the command, you can view all the worktree information created above, and the main worktree will also be displayed here
/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]
Copy the code
If you want to delete worktree, you will waste a lot of disk space
git worktree remove
Worktree: remove worktree: remove worktree: remove worktree
git worktree remove hotfix/hotfix/JIRA234-fix-naming
Copy the code
At this point, the hotfix with the wrong branch name is deleted
/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]
Copy the code
If you create a worktree and make changes to it, and suddenly the worktree is no longer needed, you can’t delete it by following the above command. You need the -f parameter to help
git worktree remove -f hotfix/JIRA234-fix-naming
Copy the code
We removed worktree, but there are still many administrative files that are not used in Git files, so we need to clean them further
git worktree prune
This command is the clean bottom operation that keeps our work clean at all times
conclusion
You should understand that the entire process of using Git-worktree consists of the following four commands:
git worktree add
git worktree list
git worktree remove
git worktree prune
Copy the code
Git workTree differs from git Clone with multiple repOs. Maintain a single REPO, create multiple worktrees, and operate smoothly
My practice: Git worktree is usually used. I will unify the directory structure. For example, the feature directory stores all feature worktrees, and the hotfix directory stores all hotfix worktrees. This prevents the entire disk directory structure from becoming cluttered by creating multiple worktrees
I’m a bit obsessive about disk management. Ideally, the worktree of a particular repo would be placed in the repO’s file directory, but this would result in all files under the newly created worktree created by Git Track. It’s definitely not a good idea to go back and forth and modify the Gitignore file to avoid Git track worktree content, but I’ll show you a better way in the next section
Soul asking
- Can I delete main Worktree? why
- Do you understand the changes in the repo/.git/wortree directory?
Personal blog: https://dayarch.top
Day arch a soldier | original