I remember when I first started using Git and before I knew the difference between Rebase and merge, I saw my teammate type commands like a fly, get things done in a few seconds, and then clean up the interface 😂 before I could see what he was doing. At that point, I began to realize that a beautiful GUI is not necessarily as fast and convenient as typing commands.

In this post I’d like to share some of the techniques that I think work well, including:

  • Git command – You are advised to passgit --helpTo see more details and options
  • Quick command for oh-my-zsh – here’s the full Cheatsheet
  • VSCode extension plug-in

Before you start work

Clone the repository locally

Most of the time, just copy and paste the clone command provided on git, or use the following command:

git clone<git_url> [destination address]Copy the code

Using oh-my-zsh can be even shorter:

GCL < gIT_URL > [target address]Copy the code

It also includes an option to recursively clone all submodules.

For now, I prefer to clone with VSCode’s git command tool, so that I can open the new Clone repository and start working:

  1. On Mac, use Command + Shift + P. On Windows, use CTRL + Shift + P to open the command panel and type git to find git: Clone

  2. Paste warehouse address:

    Clone from Github (with a Github account)

  3. Select destination address:

  4. After cloning is completed, a pop-up window in the lower right corner will prompt to open the warehouse:

Switch to a branch

I usually use the command line to auto-complete the branch name with TAB to switch my branches:

Git checkout < branch >Copy the code

When I need to see someone else’s branch and I’m not familiar with the name of the branch, I use the VSCode git extension to put the branch switch entry on the status bar in the lower left corner:

Click and the command line will pop up to select branch:

! [VSCode status bar – switch git branch]

Create a new branch

To create a new branch, add the -b option:

Git checkout -b < branch name >Copy the code

Branch renaming

Sometimes I accidentally make a typo or have a better name, so I rename it as follows:

Git branch -m < new name > // oh-my-zsh: gb < new name >Copy the code

Viewing Branch Status

If a branch has been pushed to a remote location and there are multiple people collaborating, or one person writing code on multiple devices (work computer and home computer), it is a good habit to check the current status of the branch from time to time. This avoids some of the headaches of not starting with the latest code.

Command:

git fetch
git status
// Oh-my-zsh:
gf
gst
Copy the code

It then prints a message like this:

Sometimes it feels like the message is too simple and not clear enough. Then I will check git history. Most of the time only the most basic commands are needed:

git log
Copy the code

–stat shows the changed file, –graph shows the ugly branch graph, –oneline shows each commit in a single line. Many of them are too long, so use oh-my-zsh instead, for example:

glg // git log --stat
glgg // git log --graph
glo // git log --oneline --decorate
Copy the code

Keep branches up to date

If my branch doesn’t have any modifications, howevergit statusTell me there is an update on this branch:

Just use the command:

git pull
// Oh-my-zsh
gl
Copy the code

To update the local branch.

If there happens to be an update on the remote branch, it will be a little more troublesome. We’ll discuss this in more detail later in the conflict Resolution section.

Complete and commit the changes

Verify your changes before committing

Before submitting code, I usually take a second look at my changes to reduce the chance of submitting unnecessary code (such as console.log for testing) and errors. And then I feltVSCode comes with git diffIt works very well:

Click the refresh icon to show the updates, then click the Tree list icon to switch to a clearer table of contents. Clicking on the files in the tree displays a comparison window that makes it easy to see the changes clearly.

Submit changes

After verification, you can select the file to be submitted this time in the “SOURCE CONTROL” (click ➕ on the right of the file or folder) :

Enter the appropriate submission information and click the ✅ icon to submit.

However, the tricky part here is that commits often fail with commit hook style validation and type validation configured, and the error messages printed in the VSCode OUTPUT panel are not as readable as those printed directly on the command line. So I prefer the command line commit:

git commit -m 'My commit message'
// Oh-my-zsh
gc -m 'My commit message'
Copy the code

If you want to skip the manual stage file and commit all changes directly, add the -a option:

git commit -am 'My commit message'
// Oh-my-zsh
gc -am 'My commit message'/ / or gcam'My commit message'
Copy the code

Note that the -a option does not include newly created files that have not been committed before. This requires an additional step:

Git add --all // oh-my-zsh: gaaCopy the code

Modifying Submission Information

The same branch name, sometimes found to be misspelled or missing some files. Then I will modify through the following command:

git commit --am
// Oh-my-zsh
gc --am
Copy the code

Push changes to the remote end

If the push is a new branch, or if the remote upstream branch has never been set, it is recommended to use -u to set upstream:

Git push -u origin // oh-my-zsh: gpsupCopy the code

You can then see the difference between the local and remote branches when viewing branch status (as mentioned in the “Viewing branch Status” section). And the next time you push it, you don’t need to do this:

git push
// Oh-my-zsh:
gp
Copy the code

Resolve the conflict

The first option is rebase

Rebase is my first option when the changes to the branch are minor. Because it ensures that my updates are based on the latest code, it avoids a lot of problems.

Rebase can be implemented upstream with Git pull:

git pull --rebase
// Oh-my-zsh:
ggu
Copy the code

But I rebase the latest main branch more often:

Git rebase origin/master // oh-my-zsh: GRB origin/master // or GRBMCopy the code

Specifying origin upstream ensures that Git pulls the latest code from the remote end to rebase.

Think about constraining commits before Rebase or merge

Sometimes I commit multiple small changes in development that have no meaning in the main branch, or there are repeated changes to a module. However, these commits cause trouble when I try to rebase or look back to find out why they were changed, so I would consider reducing the commits to one particular description before consolidating the code.

If I wanted to simply compress all the changes into a COMMIT in my branch, I would:

  1. See how many commits there are by merging requests (like this one), or in the Git log (see the section on Checking branch status)
  2. Git reset --soft HEAD~<commit >git reset --soft <commit_SHA>(Note that the commit SHA is the latest commit SHA that needs to be preserved) to remove the commits and restore the changes to staged commits. Resetting the COMMITS of a merged branch resets all the consolidated commits simultaneously. So the number of commits here may not be the same as the count.
  3. gc -m <new_commit_message>To create a new commit
  4. gp -f– If the commit has already been pushed to the remote end, then we need to add it because we changed the original Git history tree structure-fTo force a push. This can be dangerous, so make sure you do it safely.

If you want to keep the original message, and the author information. Consider git’s interactive mode:

  1. Git rebase -i HEAD~

  2. It then opens a command line editor such asvi :

    Modify the operation command word (pick when opened) in the header of each COMMIT message as prompted. If I just merge three commits into one, I need to keep the first commit as pick and change the remaining two to squash or S.

  3. Save and exit. If the modification succeeds, the following confirmation page is displayed:

  4. Save again and exit.

Merge is used for more complex cases

Rebase is not a good option if you want to update a shared branch that many people are developing on, because it causes serious collisions with all the other branches that are based on it.

Another situation is when you are working on a large project and have multiple submissions for better release control. When you use Rebase, you have to resolve multiple code conflicts, and I usually resolve two conflicts and start to lose track of where I am.

This is a good time to merge:

If you just want to merge upstream branches, git pull will do the trick:

git pull
// Oh-my-zsh:
gl
Copy the code

More often I need to merge the main branch, use:

Git origin/master // oh-my-zsh: git origin/master // gMOMCopy the code

Resolve the conflict

When you think of conflict resolution, you think of Webstorm, the awesome conflict resolution tool. However, I ditched Webstorm a few years ago because it was eating up my memory and CPU, the system was stuttering, and I never came back. There is no comparable tool here, so I have a long adaptation period, now I feel that VSCode with git tool is also very good.

When merging or rebase, if you encounter a conflict, switch to the “SOURCE CONTROL” panel and click on the “Refresh” icon to see the conflict file marked with “C” :

Select open the files and see highlights and Current Change and Incoming Change options in the editor. Honestly, this is much better than the ours and theirs that git tools usually display.

The inconvenience here is that it is displayed up and down, not left to right like Webstorm, so it doesn’t work very well when the conflict zone is large. I don’t have a better solution yet, and I don’t want to install a separate software for this rare situation, so LET’s use it like this.

Why is the code written like this

Meaningful commit information and a traceable Git history tree are especially useful when something is broken or looks strange. I love using VSCode’s GitLens plugin here:

It provides a lot of functionality to help us look at HISTORY, but I mostly use LINE HISTORY and FILE HISTORY to help me understand how this piece of code came to be what it is:

Clean up unwanted branches

Clean up the remote branch records

If some remote branches are opened locally, local records about the branch will not be cleared automatically after the branches are merged. In most cases that’s fine, just leave it there. However, in large code repositories there is a fair chance that you will encounter strange problems that make it impossible to do any Git operations. So I clean it up every once in a while:

Git remote prune origin git fetch --all --prune // oh-my-zshCopy the code

Local branch cleanup

Local branches are a bit more cumbersome to clean up. For a long time, I relied only on manual deletion like this:

Git branch | cat / / print out all the local branch git branch - D branch name > <Copy the code

Later I found a quick oh-my-zsh command that deletes all branches that have been merged into master/develop/dev:

gbda
Copy the code