Git Practical Cheat Sheet#
Git - the stupid content tracker.
In the process of project development, Git is a very powerful version control management tool. It allows developers to collaborate efficiently regardless of time and place. This article briefly explains the basic usage of Git, introduces tips to improve efficiency, and discusses Git workflow branch management.
Common Git Commands#
git status#
Use git status
to check the status of the index and workspace. Here you can see:
- Current branch
- Untracked files
- Modified files
- Staged files
- Additional information
Frequent use of git status
can help you keep track of the repository status at all times.
git add#
Use the git add
command to stage specified files to the index. It is recommended to use it in conjunction with git status
to carefully review the modifications that need to be added to the index, to avoid committing files that are not within the scope of the commit log description or are not ignored by the .gitignore
file.
git commit#
Use git commit
to commit changes to the local repository. Git requires a description for each commit. If after committing you suddenly realize, "I committed the wrong thing!", you can use git reset
to recover, or use git commit --amend
to modify the latest commit. If you don't care about creating a new commit record, you can also use git revert
to generate a new commit to undo your changes. The information in git commit
should be formatted properly, ideally allowing anyone to understand what changes were made just by looking at the commit log.
git commit Standards#
The standard requires that the commit log is meaningful for tracing project history and obtaining commit information with minimal cost when updating code—what changes were made in this update. In a commit log, try to describe a commit through three dimensions: type, scope, and subject.
type (Required)#
Type represents the type of a commit. When tracing history later, filtering by type can save a lot of time.
type (Required) | English | Description |
---|---|---|
feat | feature | New feature |
fix | fix | Bug fix |
docs | documents | Documentation update |
style | style | Code formatting |
refactor | refactor | Code refactoring |
perf | performance | Performance improvement |
test | test | Testing related |
build | build | Build related |
ci | continuous integration | Continuous integration |
revert | revert | Revert code |
chore | chore | Other modifications |
scope (Optional)#
Scope represents the area of the commit changes, such as view layer, control layer, model layer, etc.
subject (Required)#
Subject represents the description of a commit, ideally no more than 50 characters. The description should accurately describe the modification for easy tracing. To achieve this, the granularity of the commit can be smaller, and later multiple commits can be merged using git rebase
to organize the commit history.
Good historical records are visually pleasing. In fact, I recommend that Chinese people write subjects in Chinese...
Bad historical records are visually jarring. But he is a big shot, and he must have his reasons for writing it this way (confident)
git pull#
Use git pull
to synchronize remote changes to the local repository. It is recommended to pull
regularly to ensure that you are modifying the latest branch. If you have uncommitted changes, the merge part of the git pull
command will fail, and your local branch will remain unchanged. Therefore, you should always commit your changes in the branch before pulling new commits from the remote repository.
To fully understand how git pull
works, we need to understand two commands: git fetch
and git merge
.
git fetch#
Use git fetch
to update all remote tracking branches in the repository. In fact, no changes are reflected in any local working branches. This means that your local repository is aware of updates in the remote repository but has not yet synchronized. IDEA
has related plugins for automatic fetch
, which is recommended to install for timely awareness of branch updates.
git merge#
Use git merge target-branch
to merge the target branch into the current branch. There are two merging strategies for merge
: fast-forward and three-way merge:
- Fast-forward merge: If there are no changes between the two branches, Git will directly point the target branch to the commit object of the source branch. This is called a fast-forward merge. This operation does not create a new commit object because earlier commits already contain all the changes.
-
Three-way merge: If there are conflicting changes between the two branches, a three-way merge is required. In a three-way merge, Git creates a new commit object that contains the common points between the two branches and the changes of each branch relative to the common point. Git will also attempt to resolve conflicts into consistent changes.
git push#
Use git push
to upload changes to the remote repository. It is recommended to pull
the code from time to time.
Other Useful Git Commands#
git diff#
Use git diff
to view modifications in the workspace that have not yet been added to the index; use git diff --cached
to view modifications in the index that have not yet been committed; use git diff branch1 branch2
to view the differences between two branches.
git stash#
The git stash
series of commands introduces a new area—the stash entry. Use git stash push
to push your uncommitted changes into the stash, and your workspace and index will revert to the latest commit's changes. Use git stash pop
to pop the top changes from the stash. Use git stash list
to view the list of changes saved in the stash.
git stash
is often used to indicate situations where you cannot pull, which usually means there are uncommitted changes in the workspace or index. In this case, you can first push the changes into the stash, restore the workspace and index, and after the pull operation is completed, pop the changes back out.
git stash
is also suitable for switching branches. For example, when you are developing on your feature branch and suddenly there is a bug in production that needs your attention, you need to switch branches to create a hotfix branch from master. However, your current changes have not been committed because the feature is not yet complete. In this case, you can use the git stash
command to push the changes into the stash, switch branches to develop, and then return to the original branch to pop the changes back out.
git rebase#
The git rebase
series of commands gives us the opportunity to reorganize our commits, making the history clean and easy to trace. Vue author Evan You once mentioned on Zhihu:
The aggression is still quite strong 2333
The essence of git rebase target-branch
is: find the common ancestor between the current branch and the target branch, first "set aside" the modifications of the current branch to make the commit history of the current branch consistent with the target branch, and then apply the "set aside" commits back to the current branch. The difference between this merging strategy and git merge
is:
git merge
leaves unnecessary commit log information, polluting the history.git rebase
modifies the current branch's commits to organize the history. Therefore, after rebasing on a branch, the order of that branch is different from before. If someone else is also on that branch, they may encounter errors when they push, and may even lose changes.
Therefore, it is recommended to use git rebase
only to modify commits that have not yet been pushed to the remote repository, or to apply it on branches that only you use.
Of course, git rebase
can also be used to merge multiple commits. We use git rebase -i [startpoint] [endpoint]
with the -i
option—i.e., --interactive
to open the interactive editing interface. Here [startpoint] [endpoint]
is a left-open right-closed interval, and [startpoint]
must be specified, with the default [endpoint]
being the commit pointed to by HEAD
. For example, we can edit the latest 3 commits using git rebase -i HEAD~3
.
pick 54f88ff First commit
pick 41346f3 Second commit
pick 3b9307e Third commit
# Rebase edb3a72..3b9307e onto edb3a72 (3 commits)
#
# Commands:
# p, pick <commit> = use commit
# r, reword <commit> = use commit, but edit commit message
# e, edit <commit> = use commit, but stop to amend commit
# s, squash <commit> = use commit, but squash into previous commit
# f, fixup [-C | -c] <commit> = like "squash", but keep only previous commit's
# message unless -C is used, in which case only
# this commit's message is kept. Using -c and -C is similar,
# but opens the editor to modify the commit message
# x, exec <command> = run command using shell (rest of line)
# b, break = stop here (use 'git rebase --continue' to continue rebasing)
# d, drop <commit> = remove commit
# l, label <label> = label the current HEAD
# t, reset <label> = reset HEAD to this label
# m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]
# . create a merge commit and use the original merge commit message (if not specified
# . original commit, use the oneline in the comment section as the commit message). Use
# . -c <commit> to edit the commit message.
# u, update-ref <ref> = set a placeholder for reference <ref> to update this reference to the new commit here.
# This <ref> is updated after the rebase ends.
#
# You can reorder these lines, and they will be executed from top to bottom.
#
# If you delete a line here, the corresponding commit will be lost.
#
# However, if you delete all content, the rebase operation will terminate.
The comments explain the available commands in detail. In this scenario, suppose we want to merge these three commits, we modify it as follows:
r 54f88ff First commit
f 41346f3 Second commit
f 3b9307e Third commit
Next, we modify the commit log information:
Repeat output "HelloWorld" to the console
# Please enter the commit message for your changes. Lines starting with '#' will be ignored, and an empty commit
# message will terminate the commit.
#
# Date: Sat Mar 25 11:28:26 2023 +0800
#
# Interactive rebase in progress; onto edb3a72
# Last command done (1 command executed):
# reword 54f88ff First commit
# Next commands to be executed (remaining 2 commands):
# fixup 41346f3 Second commit
# fixup 3b9307e Third commit
# You are currently editing the commit while rebasing branch 'master' onto 'edb3a72'.
#
# Changes to be committed:
# modified: HelloWorld.java
After completing the modifications, check git log
and the history has been successfully merged:
Through the git rebase
command, we can edit, reorganize, merge, and arrange commits in the local repository before pushing them to the remote repository to obtain a clean and tidy history with reasonable granularity. Avoid modifying commits that have already been pushed to the remote repository!!!
git cherry pick#
Using the git cherry pick
command, you can explicitly apply certain commits to the current branch. For example, the current branch situation is:
Now I want to directly apply this commit to the main branch. Enter:
git cherry pick C2 (the Hash value of this commit)
This has already taken effect, creating a new commit C2' on the main branch. These two commits have the same content, but the Hash values are different.
Git Workflow#
Finally, a brief description of the Git workflow, which illustrates how a project needs to use various types of branches to isolate different states of code to achieve rapid iteration. Currently popular branching models include feature branch development model, trunk development model, etc.
Feature Branch Development Model#
- Complex branch management;
- Relatively long development cycle;
- Over time, the gap with the master branch will widen, potentially leading to conflicts that are difficult or impossible to resolve.
Trunk Development Model#
- Simple branch management;
- Development cycle can be very short, allowing for new version branches to be checked out at any time;
- High code quality requirements.
Conclusion#
- Mastering Git tools helps improve development and collaboration efficiency;
- The commonly used commands:
add
,commit
,push
,pull
,status
should be mastered, and their functionality can be enhanced through optional[option]
parameters; - The commit log standard is for easy tracing of history and recording project changes. More importantly, it allows people to quickly understand the project by viewing the history;
- Frequently pull. Regularly pulling ensures that you are modifying the latest branch, which can be guaranteed by frequent commits. When pushing at the end, consider whether to organize the history with rebase before pushing to the remote repository;
- Use the stash to ensure that urgent code switches do not lead to potential code pollution due to forgotten commits;
- Follow the actual branching model used. Once decided, it should be actively implemented; otherwise, due to the broken window theory, good branch management will be disrupted, and project quality and iteration speed will not be guaranteed.
Related Links
Only know git log? Actually, Git has two other useful log commands
Three lines of code to keep your git records tidy
How to standardize your Git commits?