12

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:

image.png

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:

image.png

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:

image.png

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:

image.png

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:

image.png

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:

image.png

After the above process is over, check the log again, and you will find that two commits have become one:

image.png

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:

image.png

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:

image.png

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:

image.png

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:

image.png

The picture will look like this:

image.png

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 :

image.png

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":

image.png

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:

image.png

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:

image.png

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:

image.png

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:

image.png

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:

image.png

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

  1. No redundant commits are generated when merging.
  2. Conflicts can be handled in units of commits during replay.
  3. 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.
  4. 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

Original: https://medium.com/starbugs/git-%E6%88%91%%BB%A5%E7%82%BA%E7%9A%84-git-rebase-%E8%88%87%E5 %92%8C-git-merge-%E5%81%9A%E5%90%88%E4%BD%B5%E88%86%E6%94%AF%E7%9A%84%E5%B7%AE% E7%95%B0-cacd3f45294d

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.


王大冶
68.1k 声望105k 粉丝