If you have dreams and dry goods, you can search for [Great Move to the World] on WeChat and pay attention to this Shawanzhi who is still washing dishes in the early hours of the morning.
This article GitHub https://github.com/qq449245884/xiaozhi has been included, there are complete test sites, materials and my series of articles for interviews with first-line manufacturers.
Hi! Hello everyone, I'm Xiao Zhi! Using Git for version control should be one of the workflows that most engineers encounter every day, but I use it nothing more than push
, pull
, merge
, checkout
or log
and a few more instructions, if you are more in-depth, you will ask three questions 😂, I was asked this question during the interview: "Do you know Git's merge and Does rebase make any difference?"
After listening to it, I was immediately confused. For me, rebase is a tool used to organize commits. How can it be compared with merge?
git-rebase
Let's talk about what I usually do with the rebase command. If I add a unit test, and then commit
, then log
will add one more commit
Records:
But it was only after the commit that I found out that I omits another test case, so after making it up, I made another commit:
At this time, there will be another one in the record commit
, but for me, these two commit
are actually doing the same thing, so before I push to remote, I will want to sort out the commit first and merge the two records together.
There are two ways to combine these two records, the first is reset
before adding the first test case, and then do it directly once commit
. The second method is to use rebase
to deal with it!
First let's look at the current log:
My purpose is to organize 9dc67ff
and 87af945
into one, so the commit to be adjusted is from init, that is, the commit id is 7eb57cb
after all the commits With the rebase
instruction, it is:
git rebase -i 7eb57cb
After entering, it will jump to the editing screen of vim:
On the screen, you will see all the commits after 7eb57cb
(currently only 9dc67ff
and 87af945
), and then put 9dc67ff
of pick
310433db72daa68383 pick
change to squash
, which means to merge it with the previous commit. First click i and start editing the content with vim:
After editing, you can click esc and enter :wq
to save it. If you are just curious and have a look, if you don't want to save it, enter :q!
. After the above process is over, check the log again, and you will find that the two commits have become one. After saving, it will jump to the commit message screen, here you can enter the merged commit message, but I will not change it, just save it directly:
After the above process is over, check the log again, and you will find that two commits have become one:
Nice first, the above operation is the interactive mode of rebase, the -i entered after git rebase is actually the abbreviation of interactive
.
git-merge
Everyone should be very familiar with the merge command, because when a new function is made, a branch is usually pulled out, and after completion merge
return to the main branch such as master or develop. The operation process is as follows:
There are two situations when merging. The first is fast-forward
, which will move the reference of the HEAD of the merged branch to the latest commit in the branch to be merged. The merge result of the above operation is f ast-forward
, the HEAD of the master is moved to the latest commit of the string-library, and the drawing looks like this:
But if there is a conflict when executing merge, the merge behavior of the branch will be a little different from fast-forward. For example, if I add content to the same file in master and string-library, then when I execute merge, it will ask to fix conflicts first:
After the repair is completed, execute commit to complete the merge, and this time, when merging, there will be one more commit record about the merged string-library branch:
The picture will look like this:
Differences between git-rebase and git-merge
After reading the introduction to rebase
and merge
above, you may want to say:
"Huh? Aren't these two completely different things?"
Yes, I thought so too, until I read the documentation of git-rebase, only to realize that I had been misunderstanding it. In the rebase chapter of the git book , the first paragraph explains that there are two ways to integrate two branches in Git, and these two are mentioned above, namely merge
and rebase
:
As you already know from the merge example above, the merge will have fast-forward
when merging, and there are two situations in which a commit is used to record the merge changes when there is a conflict. The integration method of rebase is very interesting. According to another description about rebase, it can "replay all the commits in a branch based on the commits of another branch":
What does it mean? First let's go back to the above example and use reset
on the master branch to get the master version back before the string-library was merged:
Now we use the rebase command to modify all the commits of string-library and run it once based on the commit of the master. The first step in merging with rebase is to switch to the branch where you want to replay the commit:
git checkout string-library
Then enter the git rebase
command, and specify on which branch to replay:
git rebase master
Results of the:
In the process of rebase replaying the commit, similar to merge is that if there is a conflict, it still needs to be resolved, but after resolving, instead of using the commit command to merge, enter git rebase --continue, so that rebase can continue Replay the next commit:
When the replay is completed, it will display which commit is currently replayed to, which is the latest string-library
in terms of add string unit test D
. The branch relationship at this time, when drawn as a diagram, will become:
After the above picture is rebase, string-library
07e38fb is modified, and it will be replayed again based on the master's commit.
It should be noted that the commit id after replay will be different from the original one, which is equivalent to completely rewriting all the commit history records in the branch.
In addition, after executing the rebase, string-library
has not been merged back to the master branch, so it is still necessary to switch back to the master and execute merge to complete the merge:
Because rebase has already been used to deal with the conflict of commits during replay, merge will go directly to the fast-forward merge now, and there will be no additional commit records of the merge.
Pros and cons of merging with git-rebase
advantage
- No redundant commits are generated when merging.
- Conflicts can be handled in units of commits during replay.
- When merging, it will be arranged according to the commit of the branch, which can clearly review the issue or feature processing process. If merge is used, the commits of the two branches will be interspersed in chronological order after the merge.
- When contributing to an open source project, if rebase is done before push, the author can merge directly in a fast-forward manner, without the need for additional conflict resolution.
shortcoming
The biggest disadvantage is mentioned above. Using rebase will modify the history of commits. If you organize commits or branches in your own local area, that's fine, but if you accidentally change to the remote branch, you will use it more accidentally. git push -f
, it may be hated by colleagues, or submitted to Pure North Engineers😂.
Should I use git-rebase or git-merge?
After checking some information, I found that rebase and merge have their own advocates. I will first explain their ideas, and then subjectively put forward my own views.
git-merge pie
Support git-merge
The engineers believe that the value of the version record lies in the commit of the project, that is, "what happened in the history of the project", if you modify these historical records, then very bad. So even though the contents of the different branches are all mixed up after the merge, they still tell the history of the project.
git-rebase pie
The engineers who support git-rebase
feel that the commit is talking about the "evolution process" of the project, and what happened is the important thing. Even if the history of the commit is modified, what happened has not changed. Since it is possible to use a clearer and more concise record for future reading, it should be done.
personal subjective opinion
Personally, I will still use git-rebase to modify commits to make historical records easier and easier to read, but the use is limited to before push to remote. If the record has been pushed to remote today, I will not modify it even if it is messy. They, after all, the records of the remote are shared by everyone, not to be modified at will, and also to respect other members of the team.
The bugs that may exist after the code is deployed cannot be known in real time. In order to solve these bugs afterwards, a lot of time is spent on log debugging. By the way, I recommend a useful bug monitoring tool , Fundebug .
Author: God Q Superman> Source: medium
comminicate
If you have dreams and dry goods, you can search for [Great Move to the World] on WeChat and pay attention to this Shawanzhi who is still washing dishes in the early hours of the morning.
This article GitHub https://github.com/qq449245884/xiaozhi has been included, there are complete test sites, materials and my series of articles for interviews with first-line manufacturers.
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。