Check Out Bugfix Again and Rebase Onto Master
A programmer since the tender age of x, Christoph Burgdorf is the the founder of the HannoverJS meetup, and he has been an active member in the AngularJS community since its very beginning. He is likewise very knowledgeable almost the ins and outs of git, where he hosts workshops at thoughtram to help beginners primary the technology.
The following tutorial was originally posted on his blog.
Tutorial: Git Rebase
Imagine y'all are working on that radical new feature. It's going to be brilliant but it takes a while. Y'all've been working on that for a couple of days now, perchance weeks.
Your characteristic branch is already six commits ahead of master. You've been a skillful developer and accept crafted meaningful semantical commits. But in that location'southward the matter: you are slowly realizing that this beast will still have some more time before it's really ready to be merged dorsum into master.
m1-m2-m3-m4 (master) \ f1-f2-f3-f4-f5-f6(feature)
What y'all also realize is that some parts are actually less coupled to the new feature. They could land in primary earlier. Unfortunately, the function that you want to port back into master earlier is in a commit somewhere in the middle of your six commits. Even worse, it too contains a change that relies on a previous commits of your feature branch. One could argue that you should take fabricated that ii commits in the first identify, only and then nobody is perfect.
m1-m2-m3-m4 (primary) \ f1-f2-f3-f4-f5-f6(feature) ^ | mixed commit
At the time that you crafted the commit, you didn't foresee that y'all might come into a situation where y'all desire to gradually bring the characteristic into master. Heck! Yous wouldn't take guessed that this whole affair could accept us so long.
What yous need is a way to get back in history, open up up the commit and split it into two commits and then that you can split out all the things that are rubber to be ported back into master by now.
Speaking in terms of a graph, we want to have it like this.
m1-m2-m3-m4 (main) \ f1-f2-f3a-f3b-f4-f5-f6(characteristic)
With the work split into ii commits, we could only cherry-red-pick the precious bits into master.
Turns out, git comes with a powerful command git rebase -i which lets us do exactly that. Information technology lets u.s. alter the history. Irresolute the history can be problematic and equally a dominion of thumb should be avoided as presently as the history is shared with others. In our example though, we are just irresolute history of our local feature branch. Nobody will become injure. Promised!
Ok, allow's accept a closer expect at what exactly happened in commit f3. Turns out nosotros modified two files: userService.js and wishlistService.js. Let's say that the changes to userService.js could become directly dorsum into main whereas the changes to wishlistService.js could not. Because wishlistService.js does not even exist in master. Information technology was introduced in commit f1.
Pro Tip: even if the changes would have been in one file, git could handle that. We keep things unproblematic for this weblog post though.
We've set up a public demo repository that we volition use for this practise. To go far easier to follow, each commit message is prefixed with the pseudo SHAs used in the graphs above. What follows is the branch graph equally printed past git before we start to split the commit f3.
At present the outset thing we want to do is to checkout our feature branch with git checkout feature. To get started with the rebase nosotros run git rebase -i chief.
At present what follows is that git opens a temporary file in the configured editor (defaults to Vim).
This file is meant to provide you some options for the rebase and it comes with a little crook sheet (the blueish text). For each commit we could cull between the actions option, reword, edit, squash, fixup and exec. Each action can likewise exist referred to past its curt form p, r, eastward, s, f and e. It's out of the scope of this article to describe each and every option and so let's focus on our specific task.
We want to choose the edit pick for our f3 commit hence we modify the contents to look like that.
Now we salvage the file (in Vim <ESC> followed by :wq, followed by <RETURN>). The side by side thing we notice is that git stops the rebase at the commit for which we choose the edit selection.
What this means is that git started to apply f1, f2 and f3 equally if it was a regular rebase just so stopped after applying f3. In fact, we tin prove that if we just look at the log at the point where we stopped.
To divide our commit f3 into 2 commits, all nosotros have to do at this point is to reset gits arrow to the previous commit (f2) while keeping the working directory the same as it is right now. This is exactly what the mixed style of git reset does. Since mixed is the default mode of git reset nosotros tin merely write git reset head~ane. Let'due south practice that and also run git status right later information technology to see what happened.
The git condition tells united states that both our userService.js and our wishlistService.js are modified. If we run git diff we can encounter that those are exactly the changes of our f3 commit.
If nosotros look at the log again at this indicate we meet that the f3 is gone though.
We are at present at the point that we take the changes of our previous f3 commit gear up to exist committed whereas the original f3 commit itself is gone. Go on in listen though that we are nevertheless in the middle of a rebase. Our f4, f5 and f6 commits are not lost, they'll exist back in a moment.
Let's make ii new commits: Allow's commencement with the commit for the changes made to the userService.js which are fine to go picked into master. Run git add userService.js followed by git commit -m "f3a: add updateUser method".
Bully! Allow'south create another commit for the changes made to wishlistService.js. Run git add wishlistService.js followed by git commit -m "f3b: add addItems method".
Let'southward take a look at the log again.
This is exactly what we wanted except our commits f4, f5 and f6 are however missing. This is because we are still in the heart of the interactive rebase and we need to tell git to continue with the rebase. This is washed with the command git rebase --proceed.
Permit'due south check out the log once again.
And that's it. Nosotros now have the history we wanted. The previous f3 commit is now carve up into two commits f3a and f3b. The only thing left to practice is to crimson-pick the f3a commit over to the primary branch.
To terminate the final step we first switch to the principal co-operative. We do this with git checkout primary. Now we can choice the f3a commit with the cherry-selection command. Nosotros tin can refer to the commit by its SHA central which is bd47ee1 in this case.
Nosotros at present have the f3a commit sitting on acme of latest master. Exactly what we wanted!
Given the length of the mail this may seem like a lot of attempt but it's actually but a matter of seconds for an advanced git user.
Notation: Christoph is currently writing a book on rebasing with Git together with Pascal Precht, and you lot can subscribe to it at leanpub to become notified when it's ready.
Need Christoph's help? Book a 1-on-1 session!
View Christoph's Profile
or join us as an expert mentor!
Source: https://www.codementor.io/git/tutorial/git-rebase-split-old-commit-master
Postar um comentário for "Check Out Bugfix Again and Rebase Onto Master"