The author has been working for one and a half years, and has submitted nearly a million lines of code by relying on git three boards and axes, often solving various git operation problems in a very “rough” way. During the Spring Festival, I read the “Pro Git Book”, and understood how to use Git in such an “elegant” way. I summarized some Git improvement skills and shared them with you.

Note that in order to ensure privacy security, all git related screenshots attached to the article are from the Github open source project TDesign-MiniProgram. The author forks this project for operation, and the project path point is here.

1. git log– View the commit history

The git log command used daily during development lists the SHA-1 checksum for each submission, the author’s name and E-mail address, the submission date, and the submission instructions, making it difficult to retrieve. Git log –oneline to output the log as a short hash [commit instructions] format.

1.1 Customizing the History Format

Using –pretty=format:, you can customize the display format of the record, as shown below:

The format command supports common format placeholders, where %h indicates the abbreviated hash value of the submission, %an indicates the author name, %ar indicates the revision date of the author, and %s indicates the submission description. You can also use %C(color) and %Creset to add color to the corresponding label.

Git log --pretty=format:"%h - %an(%ar) : Git log --pretty=format:"%C(yellow)%h%Creset - %Cgreen%an%Creset(%ar) : %s"Copy the code

1.2 Hide merge commit

For a codehouse process developed by multiple people, the record must contain many Merge submissions, such as Merge Pull Request #1 form XXX. This type of merge commit transfers very little information and is an eyesore, so log can be filtered with the –no-merges option.

// Hide merge commit --no-merges git log --pretty=format:"%C(yellow)%h%Creset - %Cgreen%an%Creset(%ar) : %s" --no-mergesCopy the code

1.3 Filtering Historical Records

Git log provides a number of very useful options for filtering records. You can use options like –

to indicate that only n recent commits are displayed. You can also specify filtering the commit records for author Zhenzhencai using –author=”zhenzhencai”. You can also use –since, –until to filter commits after (before) a specified time.

For example, to query the last 10 commit records of user Zhenzhencai from September 1 to September 30, 2021, you can use the following command.

// Filter criteria:  --author="zhenzhencai" --since="2021-09-01" --until="2021-09-30" -10 git log --pretty=format:"%C(yellow)%h%Creset - %Cgreen%an%Creset(%ar) : %s" --author="zhenzhencai" --since="2021-09-01" --until="2021-09-30" -10Copy the code

Screening records are as follows:

1.4 Viewing the Submission Interval

To see which commits in the Experiment branch have not been merged into the master branch, use the master.. Experiment to make Git display these commits.

git log master.. Experiment // Displays the submission records of C and DCopy the code

Another common scenario is if you want to see what records will be committed before you commit the Mr To the specified branch, you can use:

git log origin/master.. HEADCopy the code

This record shows which commits of the current branch have not been merged into the master branch. If you leave one side blank, Git defaults to HEAD. For example, git log origin/master.. The output is the same as in the previous example — Git uses HEAD instead of the empty side.

To learn more about its use, see # Git Basics – View commit history

2. git commit --amend– Modify the last commit

Git commit commits files in the staging area. In daily development, we often end up committing only to find that we have missed several workspace files that have not been added, or that the submission information has typos.

2.1 Classic Cases

As shown in the figure below, the two files in the workspace are not committed, and the description of the committed information is not clear.

Solutions are as follows:

  1. usegit add .Save files from the workspace to the staging area.
  2. usegit commit --amendCommand to enter the vim editor.
  3. Input keysiMake edits to the content, such as changing the submission instructions.
  4. Input keysescExit edit and enter the keyshift+:And then typewqSave the editing content.

This allows you to accurately modify the original commit without generating additional commit records.

2.2 Case 1: Forgetting to submit unstored files

If you simply forget to commit the staging file, you don’t need to modify the staging information, just add the workspace files to the staging area, and skip the editor section with the –no-edit command.

git add .
git commit --amend --no-edit
Copy the code

2.3 Case 2: Only want to modify the submission instructions

If you just want to modify the submission information, you can use the following command to do so without entering the editor.

Git commit -- amend-m "feat:"Copy the code

2.4 Case 3: Eliminating an additional file submission

If you mistakenly submitted a file, such as a mock file, you can use this method to eliminate that file.

<file> git rm -- -- cached <file> git commit -- -- amendCopy the code

Note: corrections change the submitted SHA-1 checksum, which is similar to a small base change. Do not fix it if the last commit has been pushed.

3. git rebase -i– Modify multiple submissions

As mentioned earlier, you can use git commit — Amend to modify the most recent commit, or git rebase -i if you want to modify commits that are further in the commit history.

As shown in the figure above, are the last 6 Git records of the front-end side dish. Near the end of work, Xiao CAI wanted to push the code to the remote branch, but found that the fifth record from the bottom has a typo to modify; The penultimate submission instructions for 2-4 are the same (a qualified engineer should combine them into one record); Meanwhile, Xiao CAI wants to delete the latest submission record.

Git rebase -i HEAD~6 git rebase -i HEAD~6 git rebase -i HEAD~6 git rebase Enter this command to enter the Vim editor.

As shown above, reverse order shows the last six Git records (the oldest is first), because rebasing is a top-down replaying of the changes introduced by each commit, starting with the commit specified on the command line (HEAD~6). The command for each record is pick, which means commit is used. If you want to edit the submission instructions, change to the reword command. If you want to merge a commit, you can use the squash command to squash the commit to the previous commit. If you want to delete a commit, you can use the drop command to drop the Git record.

As shown in the figure above, Koai modified the submission instructions for E6753B6 by merging the 02E350C and A7853AC submissions into 063BFDA and removing the A65477A branch. Save the edits and base each Git record in turn. The following figure shows the modification result.

Note: Rebasing changes the sha-1 checksum of a commit. Do not attempt to rebase a commit if it has already been pushed, or it can cause devastating merge problems in collaborative development.

4. git cherry-pick– Merge part of the commit to another branch

In collaborative development projects, it is common to encounter the problem of interdependence of development functions, and it is necessary to merge some of the contributions from the current development branch into other development branches. Git cherry-pick comes in handy.

The git cherry-pick command, which applies a specified commit to another branch, also supports transferring multiple commits.

git cherry-pick ([commitId] | [first-commitId].. [last-commitid]) // Where [first-commitid].. [last-Commitid] indicates the open-front and closed-back range. That is, it does not include [first-Commitid] but includes [last-Commitid].Copy the code

For example, the code repository has two branches: master and feature:

A-b-c-d-e master branch \ F-g-H-i-j feature branchCopy the code

To merge a partial commit of the feature branch into the master branch, run the following command:

Git cherry-pick g // git cherry-pick g // Git cherry-pick g h // if the commit from commit G to commit I is transferred to the master branch, run git cherry-pick g h // Git cherry-pick f.. iCopy the code

If a code conflict occurs during the operation, Cherry Pick stops and lets the user decide how to proceed. After resolving code conflicts, you can continue with git cherry-pick –continue.

If the user aborts the merge after a code conflict and wants to return to the way it was before the operation, git cherry-pick –abort is executed.

For more configuration options, see the # git cherry-pick tutorial

5. git reflog– To bring the dead back to life

One sunny afternoon, front-end side dishes worked hard and developed 4 new features (4 commit as shown below).

5e5FC6b - Zhenzhencai (2 minutes ago) : Feat: Feature 4 Feature 3 Feature Submission 6A8AF62 - Zhenzhencai (2 minutes ago) : Feat: Feature 2 Feature Submission 53F441A - Zhenzhencai (3 minutes ago) : feat: Feature 1 Feature Submitted 1967DF4 - Zhenzhencai (2 days ago) : Feat: Rate Components Add Variant attributeCopy the code

Git reset –hard 1967DF4 rollback to the original COMMIT

0CA6e09 - Zhenzhencai (8 seconds ago) : Feat: Zhenzhencai (2 days ago) rate components add variant attributeCopy the code

Print the submission log, xiao CAI found that something was wrong, the previous 4 features were all lost, Xiao CAI cried like a 200 kg child, silently moving bricks again…

Git reflog: Git reflog: Git reflog: Git reflog: Git reflog: Git reflog: Git reflog: Git reflog

Git reflog displays a list of times when the HEAD points to changes. For example, when you switch branches, commit with Git commit, or cancel commit with Git reset, the HEAD will change and reflog will record this. But when you do git checkout —

undo or Git Stash store files, the HEAD doesn’t change. These changes are never committed, so reflog can’t help us recover them.

Git reflog logs every step you make, so we can print it out and look at it

As shown in the figure above, after switching to the feat/rate-update branch and using git reset –hard Origin /feat/ rate-Update to keep the local branch consistent with the remote associated branch commit, the four features are gradually developed and committed. Then, Koai forced rollback to 1967DF4, submitting the Feature 5 functionality.

Our requirement is to retrieve the previous four feature features submitted, without saying much, and start doing.

Git reset --hard 5e5fc6b // then cherry-pick 0ca6e09 HEAD@{0}: Git cherry-pick 0ca6e09 // Plan 2: Cherry-pick 1967DF4.. 5e5fc6b // .. It represents the front open and rear closed interval, that is, excluding 1967df4 but including 5e5fc6bCopy the code

The difference between the two schemes lies in the timing of Git records. Scheme 1 is recommended for current scenarios.

8f82482 - zhenzhencai(21 分钟) : feat. 5e5fc6b - zhenzhencai(31 分钟) : feat. Feature 4 Feature Submission 2B389B6 - Zhenzhencai (31 minutes ago) : Feat. 3 Feature Submission 6A8AF62 - Zhenzhencai (32 minutes ago) : feat. Feature 2 Feature Submission 53F441A - Zhenzhencai (32 minutes ago) : Feat: Feature 1 Feature Submission 1967DF4 - Zhenzhencai (2 days ago) : feat: rate components add variant attributeCopy the code

After the operation, the small dishes smoothly find 5 records, happy to work!

6. git revert– to cancel

As we mentioned in the last section, Cabbage painstakingly developed five features and submitted them to a remote warehouse. The next day, when preparing for confluence, the boss informed me urgently that features 1 and 2 were not online due to uncontrollable factors!! (꒪ ⌓ ꒪)

We know that if we want to cancel all functionality, we can use Git reset to roll back to a particular commit.

The format of the reset command is as follows:

git reset [option] [commitId]
Copy the code

Option has three values, with the following meanings:

  • --hard: cancelcommitThat the removal ofaddDelete the workspace change code. the[commitId]toHEADAll submissions are cleared.
  • --mixed: Default parameter. undocommitThat the removal ofaddTo restore the workspace change code. the[commitId]toHEADAll commits are restored to the workspace.
  • --soft: cancelcommit, don’t canceladdTo restore the workspace change code. the[commitId]toHEADAll commits are restored to the staging area.

Our requirement is that feature 345 be online, and feature 12 be temporarily offline. There are two solutions, one is to create a new branch and commit all of the original development branch feature 345 to cherry-pick. Another option is to use Git Revert.

Like reset, revert is a restore version, but they are implemented differently. Simply put, reset rolls directly to [commitId], while revert adds a new submission that changes the contents of [commitId] back.

git revert [option] ([commitId] | [first-commitId].. [last-commitid]) // Undo 53f441A, 6a8AF62 commit git 1967DF4.. 6a8af62 // .. Git revert --no-edit 1967DF4... git revert --no-edit 1967DF4 6a8af62Copy the code

The log is as follows, and two submissions of feature 1 and Feature 2 are added:

9F498D8 - Zhenzhencai (13 seconds ago) : Revert "feat: 5e5FC6b - Zhenzhencai (2 days ago) : feat: Feature 4 Feature Submitted 2B389B6 - Zhenzhencai (2 days ago) : Feat Feature 2 Feature Submission 53F441A - Zhenzhencai (2 days ago) : Feat: Feature 1 Feature Submission 1967DF4 - Zhenzhencai (4 days ago) : feat: rate components add variant attributeCopy the code

Since local repositories are always adding new submissions, they can be pushed directly to remote repositories, eliminating the need to add a -f parameter to a reset push.

7. git bisec– Find which commit introduced the error

In the collaborative development of multiple people, it is common to encounter the confluence of multiple development features, resulting in “defects” in the project operation, and some defects are difficult to identify intuitively. So how do you figure out which developer is responsible?

Git Bisec comes in handy to find out which code commit introduced an error. The idea is simply to narrow down the history of code submissions in a dichotomy. The idea of “dichotomy” is to split the code history into two parts, determine whether the problem is in the first or the second half, and continue this process until it Narrows down to a single code commit.

Git bisect start starts error checking in the following format.

Git bisect good start [end-commit] [start-commit] Git bisect bad was introduced in the first half of the code historyCopy the code

Where, [end-commit] is the most recent commit, and [start-commit] is the more recent commit. This history between them is the extent of the error.

For example, the following log shows the last 7 feature submissions of a widget. The widget wants to find out which one of those submissions caused the runtime bug.

F0a7500 (HEAD -> feat/ Rate-Update) feat: Feature 7 Feature Submitted 8b75e0c feat: Feature 6 Feature Submitted e83ebe1 feat: Feature 5 Feature Submitted 5e5FC6b feat: Feat: Feat: Feat: Feat: Feat: Feat: Feat: Feat: Feat. Dependabot (Fix/Tabs/Controlled, feat/ Steps/Controlled, Docker/Node-17) Feat: rate components add variant attributeCopy the code

Git bisect start git bisect start

Git bisect start f0a7500 53f441a git bisect start f0a7500 Git bisect start HEAD 53f441ACopy the code

Git bisect Good: git bisect Good: Git bisect Good: Git Bisect Good: Git Bisect This proves that the defect was introduced between the submission records of feature 5, feature 6, and feature 7.

On the second binary search, the workspace rollback to 8 b75e0c feat: submit features 6 function, after testing, code has flaws, prove that defects may be introduced in front of the records or this article submission. Enter the Git bisect bad tag.

E83ebe1 after the third binary search, the workspace is rolled back to e83ebe1. After a test, a defect exists in the code operation. The defect may be introduced in this section or in the previous submission. Enter the Git bisect bad tag.

E83ebe1 下 载 this entry is the cause of the error.

8. git branch– Branch management

In the process of collaborative development, it is common to encounter the problem of switching different branches at the same time. After processing the problem, you want to go back to the original development branch, but forget the branch name. Git branch is used to look at the list of local branches. When the list is sorted by branch name, it is impossible to tell which branch is which when there are hundreds of local branches.

8.1 Sort the branch list by submission date

If you sort the branches by the time they were used, the problem is solved. Use –sort=-committerdate to display a list of all local branches and sort them based on the date they were last committed.

To see the last commit for each branch, run the git branch -vv command.

// --sort= -committerDate: sort branches based on the last commit date Git branch --sort=-committerdate -vv git branch --sort=-committerdate -vv Feat /rate-update 1967df4 [Origin /feat/rate-update: behind 1] feat: rate components add variant attribute feat/steps/controlled 1967df4 feat: rate components add variant attribute * bugfix/badge-fix 792cd51 [origin/bugfix/badge-fix: ahead 2] feat: update rate readme.md develop a170b57 [origin/develop] Merge pull request #1 from zhenzhencai/feat/rate-updateCopy the code

8.2 Checking Whether Branches are Merged

In addition, the –merged and –no-merged options filter the list of branches that are merged or not merged into the current branch to check if there are any missing submissions that are not merged.

// Check which branches have been merged with the current branch, Git branch --no --merged master git branch --no --merged master git branch --merged developCopy the code

8.3 Checking whether a Branch contains a Commit

The –contains and –no-contains options are useful for filtering branches in the branch list that contain or do not contain a particular commit to detect whether a particular commit conjoins.

Git branch --contains <commit> git branch --no-contains <commit>Copy the code

8.4 Deleting merged Branches

As developers contribute more and more code, more and more locally maintained branches need to be cleaned up periodically. The first target for cleanup is the branch that has been merged into the main branch. The operation steps are as follows:

  1. usegit branch --merged <branch>Lists all that have been merged to<branch>The branch.
  2. usegrep -v "(^*|<branch>)"Filters out current branches (with *) and those you want to filter<branch>.
  3. usexargs git branch -dDelete all found branches.
Git branch - merged the branch > | grep -v "(^ * | < branch >)" | xargs git branch - d / /, for example, you want to delete all merged into the master branch, in addition to develop branches, you can use:  git branch --merged master | grep -v "(^*|master|develop)" | xargs git branch -dCopy the code

9. git stash– Save and restore the work progress

It’s a common problem in our daily work that when we’re in the middle of developing a new feature, we suddenly get an urgent bug order assigned to test and need to switch branches to fix it. Occasionally, you’ll get requests from the product and backend guy to switch to a particular branch and run some code for him. In this case, uncommitted changes need to be temporarily stored on the stack, and then switched to another branch to “work”, and then switched to the original branch to retrieve the original changes. I believe you have mastered the two sets of Git Stash and Git Stash Pop.

But there’s more to git Stash than that. Git Stash uses a stack to keep track of work progress, as shown below:

  • Git Stash List: View the stack list of work progress records, as shown in the figure, which currently holds six work progress records. The top of the stack stash@{0} represents the latest record to be pushed.

  • Git stash [Save message]: Saves uncommitted changes to the stack. Where, “Save Message” is optional, and “message” is the saved comment, which is convenient for developers to refer to. As shown in the figure, use the git Stash save “feat: Update document in the Develop branch “command to save the latest progress to the top of the stack.

  • Git stash pop [stash@{num}]: Pops up the stack and applies it to the current branch. Stash @{num} is optional. If you use git stash pop, the top of the stack is popped by default, stash@{0}. To eject the corresponding working record, such as switching to the badger-fix branch, which must be the stash@{2} record cached in that branch, run git stash pop stash@{2}.

  • Git stash apply [stash@{num}]: Pop is a stack unstack operation. If you want to apply the working record in the cache multiple times, you don’t need to unstack. Stash @{num} is optional, and the corresponding working record can be specified by stash@{num}.

  • Git stash drop [stash@{num}]: Removes the specified working record.

  • Git Stash Clear: Clears the stack.

Note: If you want to save untracked files on the stack, you can add the -u parameter, such as using git Stash save “feat: Temporary untracked files “-u

10. git config alais– Configure aliases to improve efficiency

The previous sections have covered a number of git efficiency tips, but they all require typing very long Git commands, and Git doesn’t automatically infer the command you want when you type part of it. If you don’t want to enter a full Git command every time, you can easily set an alias for each command using Git config.

Git config --global alias.<alias> <command> Logs git config --global alias.logs 'log --pretty=format:"%C(yellow)%h%Creset - %Cgreen%an%Creset(%ar) Git logs: %s" --no-mergesCopy the code

Common aliases for authors are listed below:

logs = log --pretty=format:"%C(yellow)%h%Creset - %Cgreen%an%Creset(%ar) : %s" --no-merges logo = log --oneline amend = commit --amend -m cam = commit -am fix = commit --fixup co = checkout cob =  checkout -b coo = ! git fetch && git checkout br = branch brd = branch -d st = status unstage = reset --soft HEAD^ undo = reset HEAD~1 rv = revert cp = cherry-pick pu = ! git push origin `git branch --show-current` fush = push -f mg = merge --no-ff rb = rebase rbc = rebase --continue rba = rebase --abort rbs = rebase --skip rom = ! git fetch && git rebase -i origin/master --autosquash save = stash push pop = stash pop apply = stash apply rl = reflogCopy the code

You can edit the configuration file to add all aliases in one click.

Use git config — global-e to open the configuration file in a text editor, press I to enter edit mode, copy the above alias configuration to the file, press Esc to exit edit mode, type Shift +:, and then enter wq to save the edit.

At this point, the alias has taken effect.

But how do you remember all those aliases? We can print a list of aliases by using the following command.

git config -l | grep alias | sed 's/^alias\.//g'
Copy the code

The last

Creation is not easy, point a thumbs-up to go ೭(total ᴛ ʏ ᴛ Total)౨