官术网_书友最值得收藏!

Rebasing

All these extra merge commits you can get from merging and cherry picking make a mess of your commit history. They are all superfluous commits that only exist because you need to merge some changes. Instead of merging, you can rebase your branches. When you rebase a branch, you are basically saying your branch was not branched from commit A, but from commit B. So, imagine you are working on a feature branch, but you do want to keep up with the master branch so your branch is not left behind on features. Besides, if you do not pull regularly, the chances of conflicts increase and it is easier to solve them as they come. Instead of merging or cherry picking everything your coworkers do, you can simply rebase your branch:

git checkout some-feature
git rebase master
First, rewinding head to replay your work on top of it...
Fast-forwarded some-feature to master.

Your branch is now an extension of master, so when you merge a feature into the master branch, you do not need an extra merge commit.

You can also use the shortcut, so you do not need to check out your branch explicitly:

git rebase master some-feature

A more advanced use of rebasing is rebasing commits onto specific other commits. For example, suppose you have a branch that is branched off another branch. In the case of the Iron Man suit, let's say we have the weapons branch and the lasers branch on that branch. Now, if we would rebase lasers to master, the entire history of lasers, which means including the part of the weapons branch, would be rebased to master.

So, here we have our starting situation, the lasers branch was branched off the Added weapons commit:

When we rebase lasers to master, git rebase master lasers, Git will rewind your work until it finds master, which is after the Added weapons commit. Next, Git will replay your commits on master, so the Added weapons commit and the Added lasers commit will be replayed on master. This will leave you in the following situation:

However, we can specify a commit to rebase. In this case, we want the commit Added lasers to rebase to master. We can specify a commit using the --onto switch:

git rebase --onto master weapons lasers

In this example, we are telling Git to rebase lasers to master, but only commit after the weapons branch. This will give us the following situation:

As you can see, the Added weapons commit was not replayed on master.

Using --onto, it is also possible to remove certain commits:

git rebase --onto some-branch~2 some-branch~1 some-branch

Here, we are telling Git to rebase to the commit at the top of some-branch to the commit that is on index 2 (~2), which is the third commit from the top and we start searching from the second commit from the top (index 1, ~1). This means the first commit is rebased to the third commit and, as a side effect, the second commit is removed.

Another cool feature is that of interactive rebasing. This allows you to take your commits and edit them before rebasing. You can combine commits, change commit messages, and remove commits. The following example shows what happens when you rebase master using the rebase -i master command:

This example will drop Commit 3 and merge Commit 2 into Commit 1, creating a single (new) commit.

Of course, as always, rebasing can end up with conflicting files. If this happens, you should fix the conflicts, add them to your staging area (git add some-file), and then use git rebase --continue. In case you decide not to rebase after all, you can use git rebase --abort.

Unfortunately, there is a caveat to rebasing. It will destroy your commits! What Git does is recreate the commits on your new base and discard the old ones. This may be clear in the case of interactive rebasing, for example, when deleting or squashing commits. However, rebasing will always do this. There is a golden rule when rebasing: only rebase local branches! If you ever rebase a branch that your coworkers use as well, they will suddenly miss historic commits. Git will not know what to do with those commits. Your coworkers will curse you for it and you will be doing a lot of apologizing.

主站蜘蛛池模板: 潞西市| 疏附县| 柘荣县| 四川省| 旺苍县| 铁岭县| 朝阳县| 惠水县| 开封市| 满城县| 北京市| 阿鲁科尔沁旗| 聊城市| 太原市| 昂仁县| 南阳市| 日喀则市| 商都县| 富民县| 宁武县| 京山县| 南澳县| 南和县| 平遥县| 逊克县| 唐河县| 桓仁| 辽阳市| 承德市| 南开区| 伊吾县| 交口县| 昆山市| 涞源县| 屏山县| 怀集县| 连城县| 澳门| 中方县| 寿光市| 昌乐县|