preface
Hello, everyone, unknowingly, the eight day long holiday is coming to an end. After playing for so many days, I have to close my heart and start learning today. I'm going to work tomorrow. Today, my sister suddenly asked me what the GIT rebase instruction is for and how to use it? In fact, I don't want to tell him, but I still haven't escaped my sister's soft grind and hard bubble, so let's take a look at what git rebase is!!!
origin
In other words, the fate between me and my sister was on that dark and windy night. PA, my sister slapped me in the face and said: can you talk about the key points. Ha ha, no kidding, just get to the point. Let's take a look at a scenario first. I checked my personal warehouse on github. There are many commit submissions. The submission contents are as follows:
With so many submissions, many have no standardized names. It's really bad to open them casually because they are used by themselves. In fact, some unnecessary submissions can be merged together, which will lead to the following problems:
- This causes branch pollution. The project is full of many commit records. When there is an urgent problem and the code needs to be rolled back, you can only view it one by one.
- Code review is inconvenient. When you want to do code review, a small function has been submitted many times, which seems not very convenient.
In this article, we won't talk about git submission specification first. Let's solve how to merge multiple submission records first.
rebase: submit record
Through the above scenario, we can extend the first function of GIT rebase: merging and submitting records. Now we want to merge the last 5 submission records and execute:
$ git rebase -i HEAD~2
vim editing mode will pop up automatically after executing the instruction:
pick e2c71c6 update readme pick 3d2c660 wip: merge` # Rebase 5f47a82..3d2c660 onto 5f47a82 (2 commands) # # Commands: # p, pick <commit> = use commit # r, reword <commit> = use commit, but edit the commit message # e, edit <commit> = use commit, but stop for amending # s, squash <commit> = use commit, but meld into previous commit # f, fixup <commit> = like "squash", but discard this commit's log message # x, exec <command> = run command (the rest of the line) using shell # b, break = stop here (continue rebase later with 'git rebase --continue') # d, drop <commit> = remove commit # l, label <label> = label current HEAD with a name # t, reset <label> = reset HEAD to a label # m, merge [-C <commit> | -c <commit>] <label> [# <oneline>] # . create a merge commit using the original merge commit's # . message (or the oneline, if no original merge commit was # . specified). Use -c <commit> to reword the commit message. # # These lines can be re-ordered; they are executed from top to bottom. # # If you remove a line here THAT COMMIT WILL BE LOST. # # However, if you remove everything, the rebase will be aborted. # # Note that empty commits are commented out
From here, we can see that the first five lines are the records we want to merge, but they all have the same instruction: pick, what instruction is this? Don't panic. No, the following commands have been given:
pick: Keep the commit(abbreviation:p) reword: Keep the commit,But I need to change that commit Notes (abbreviations) for:r) edit: Keep the commit, But I'm going to stop and modify the submission(Not just modify comments)(abbreviation:e) squash: Will this commit And the previous one commit Merge (abbreviation):s) fixup: Will this commit And the previous one commit Merge, but I don't want to keep the comment information (abbreviation) of the submission:f) exec: implement shell Command (abbreviation):x) drop: I want to discard the commit(abbreviation:d) label: Mark current with name HEAD(abbreviation:l) reset: take HEAD Reset to label(abbreviation:t) merge: Create a merge branch and use the original branch commit Notes for(abbreviation:m)
According to these instructions, we can make modifications as follows:
pick e2c71c6 update readme s 3d2c660 wip: merge`
After modification, click Save to exit and enter the comment interface:
# This is a combination of 2 commits. # This is the 1st commit message: update readme # This is the commit message #2: wip: merge` # Please enter the commit message for your changes. Lines starting # with '#' will be ignored, and an empty message aborts the commit. # # Date: Thu Sep 17 22:03:52 2020 +0800 # # interactive rebase in progress; onto 5f47a82 # Last commands done (2 commands done): # pick e2c71c6 update readme # squash 3d2c660 wip: merge` # No commands remaining. # You are currently rebasing branch 'master' on '5f47a82'. # # Changes to be committed: # new file: hash/.idea/.gitignore # new file: hash/.idea/hash.iml # new file: hash/.idea/misc.xml # new file: hash/.idea/modules.xml # new file: hash/.idea/vcs.xml # new file: hash/go.mod # new file: hash/hash/main.go # modified: snowFlake/Readme.md
The meassage of each submission is listed above. Because we want to merge the two commit ments, the submission comments can be modified into one, and the final editing is as follows:
# This is a combination of 2 commits. # This is the 1st commit message: fix: merge update and wip: merge` # Please enter the commit message for your changes. Lines starting # with '#' will be ignored, and an empty message aborts the commit. # # Date: Thu Sep 17 22:03:52 2020 +0800 # # interactive rebase in progress; onto 5f47a82 # Last commands done (2 commands done): # pick e2c71c6 update readme # squash 3d2c660 wip: merge` # No commands remaining. # You are currently rebasing branch 'master' on '5f47a82'. # # Changes to be committed: # new file: hash/.idea/.gitignore # new file: hash/.idea/hash.iml # new file: hash/.idea/misc.xml # new file: hash/.idea/modules.xml # new file: hash/.idea/vcs.xml # new file: hash/go.mod # new file: hash/hash/main.go # modified: snowFlake/Readme.md
After editing, save and exit. This completes a merge commit. Let's verify:
$ git log 15ace34 (HEAD -> master) fix: merge update and wip: merge` 5f47a82 update snowFlake code
From here, we can see that two submissions become one, reducing useless submission information.
Role 2: Branch merger
We seldom use this scenario together, but we still need to know its function.
Suppose we have a new project. Now we want to cut out a dev branch from the master branch for development:
$ git checkout -b dev
At this time, your colleague completes a hotfix and merges into the master branch. At this time, the master is already ahead of your dev branch:
After the repair, the colleague notifies you in the group that it is exactly the part you need, so now we need to synchronize the changes of the master branch and merge with merge:
$ git merge master
The green dot in the figure is the result of our merging. If we execute git log, we will find some merge information in the record, but we think this pollutes the commit record. What should we do if we want to keep a clean commit? At this time, git rebase comes in handy.
So now let's try using git rebase. Let's go back to hotfix and merge the master. Now I don't use merge to merge, but use the rebase instruction directly
$ git rebase master
At this time, git will cancel each commit in the dev branch, and then temporarily save the above operation as a patch file and save it git/rebase directory; Then, update the dev branch to the latest master branch; Finally, apply the patch file saved above to the dev branch;
From the commit record, we can see that the dev branch is based on the master after hotfix merger. It naturally becomes the leading branch, and it doesn't have the commit record of merge. Does it feel very comfortable.
When we use rebase to merge branches, conflict will also appear. In this case, GIT will stop rebase and let you solve the conflict. After resolving the conflict, use the git add command to update these contents. Then execute git rebase --continue again, so that git will continue to apply the remaining patch files.
If we don't want to perform this rebase operation now, we can return to the pre start state through -- abort:
git rebase --abort
rebase is a dangerous operation - use with caution
It seems that rebase operation is perfect, but it is also dangerous. Let's take a look at it together.
Now let's assume that after we develop in the dev branch and perform the rebase operation, before submitting the code to the remote, it is as follows:
After submitting the dev branch to the remote code warehouse, it becomes like this:
At this time, your colleague is also developing on dev, and his branch is still the former dev, and there is no synchronization master:
Then when he pull s the remote master, he will lose the submission record. This is why we often hear people say that git rebase is a dangerous command, because it has changed history, and we should use it carefully.
However, if all the commit history of rebase on your branch has not been push ed, you can safely use git rebase to operate.
summary
Under the careful explanation of asong, my sister completely understood how to use git rebase. Let's take a look at my sister's summary:
- When we develop on an outdated branch, we execute rebase to synchronize the latest changes of the master branch;
- If we want to start a parallel work that has been placed for a long time, and now we have time to continue it, it is obvious that this branch has fallen behind. At this time, you need to start working on the latest benchmark, so rebase is the most appropriate choice.
-
Git rebase is perfect and solves our two problems:
- Merge the commit records and keep the branches clean and tidy;
- Compared with merge, it will reduce the records of branch merging;
- One thing to pay attention to when using rebase operation is that if all the commit history of rebase required on your branch has not been push ed, you can safely use git rebase to operate.
It seems that you have learned it. What about your sister?
It doesn't matter if you try it yourself.
Well, that's the end of this article. I'll see you next time.
At the end, I'll give you a little benefit. Recently, I've been reading the book "microservice architecture design pattern", which is very good. I also collected a PDF, which can be downloaded by those in need. Access method: follow the official account: [Golang DreamWorks], and the background reply: [microservice].
I translated a gin Chinese document, which will be maintained regularly. If you need it, you can download it by replying to [gin] in the background.
I'm asong, an ordinary program ape. Let me grow stronger together. I set up a golang exchange group myself. If you need a partner, add me vx, and I'll pull you into the group. Welcome your attention. I'll see you next time~~~
Recommended previous articles:
- Teach your sister to write a message queue
- Explain the Context package in detail. Just read this one!!!
- Getting started with go elastic search (1)
- Interviewer: have you used for range in go? Can you explain the reasons for these questions
- Learning wire dependency injection and cron timing tasks is actually so simple!
- I heard that you can't jwt and swagger - eat. I'll come with the practice project
- Mastering these Go language features will improve your level by N levels (2)
- go to realize multi person chat room, where you can talk about anything you want!!!
- Grpc practice - learning grpc is that simple
- go standard library rpc practice
- 2020 latest Gin framework Chinese document asong picked it up in English and translated it carefully
- Several thermal loading methods based on gin
- boss: the boy can't use the validator library for data verification yet. It's turned on ~ ~