Git Rebase Vs. Merge

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey everyone in this video i want to talk about two get commands get merge and get rebase the first of which people seem pretty comfortable with the latter maybe strike some fear into their heart real quick i want to tell you about my brand new git and github course i just launched it covers all sorts of get and github topics ranging from the basics adding and committing and branching and merging to stashing and diffing resetting reverting and restoring we talk about git and github and collaboration workflows branch protection rules pull requests forking and cloning working with open source projects and then we talk about things like annotated tags and squashing and interactive rebasing how git works behind the scenes and hashing and blobs and trees there's a lot of good stuff in the course so if you're interested uh the links in the description and i'll shut up let's get back to merging and rebasing so both rebasing and merging are two ways of solving the same problem there are two ways of integrating changes from one branch into a second branch so here i've diverged i've created a feature branch and in the meantime master has changed there's four commits on master and i may want to integrate them into feature i could rebase or i could merge now in my experience teaching a lot more people are familiar and comfortable with merge so let's start with that the git merge command is going to take some branch whatever we specify in this case bug fix and merge it onto the existing branch and the way that it does that depends on the structure of those branches so the simplest example is called a fast forward merge where we have one branch and then we've diverged from that first branch but nothing has changed on that initial branch in the meantime so in order to merge these together i could switch to the master branch and then all i would need to do is run git merge bug fix merge the bug fix branch into master and all that happens is that the master pointer moves forward to catch up on those two commits that it's missing it's no longer missing them and it would really look more like this to visualize that there's no diagonal line it's just a series of commits so let me demonstrate this and then we'll go on to merge commits and then on to rebasing so let me quickly demonstrate and create a new repository for us so i'm going to pretend we're working on a website so i'm going to touch a website.html file or maybe index.html and i ran git init let's run our very first commit so i first need to add that file and then commit and my commits are going to follow a pattern here so i'm on the master branch or i will be currently there is no branch and i'm going to name each of these commits on the master branch with m one two three and so on and then on my other branch like the feature branch i'll do f1 or something like that uh so i'll just go with create index file okay so the contents of this don't matter but i have a new empty html file right here now i'm going to form a branch so i'm going to use the git switch command it's the newer way of doing it you can use git checkout or just get branch so git switch dash c will switch me over to a new branch that i'm going to create i'll call this one feet slash nav bar maybe okay so this will be my feature branch and i'm going to open this up and get kraken here we are so get cracking is a gui that i like to use when i'm teaching i'll hopefully zoom in and post production we have two branch references pointing to the same commit but now i'm going to make a new commit on the feature branch so i'm on the feature branch now let's say we're working on a navbar so i'm going to make a navbar.8.html file this is all kind of trivial pretending here i'm going to make a new commit so i'll add that navbar get commit dash m and we're on a feature branch so i'm going to name this commit or give it a commit message of f1 dash something so f1-create navbar file and then i'm going to do the same thing for a second commit uh let's just write the word nav in here and then i'll make a new commit i'll do a commit am instead of having to add that file first this will be f2 my second commit on this branch uh begin navbar work begin work on navbar and then one more i'll write the word bar in here so we have our finished nav bar pretend this has been hours of work i'll do another add-in commits this will be f3 our third commit on the feature branch uh i don't know how about wrap up basic navbar okay so if i look in get kraken we have our master branch right here just one commit and then we diverged with our feature branch that now has three commits so if i want to incorporate these changes into the master branch it's just a matter of having master catch up there's no additional work on the master branch so to do this we switch over to the master branch and then we run git merge with our feature branch so i'm going to switch to master you'll see the navbar file is gone right just index it's an empty file and then git merge and then the name of my branch i'm merging in which is feet slash navbar and it tells me fast forward you can see i have the changes here on my master branch and now we have master and the feet navbar branch reference referring to the same exact commits but as we've talked about not all merges are fast forwards so that's just a special case but often what will happen is we'll be working on some feature branch in my diagrams it's a bug fix branch and in the meantime additional work happens on the master branch so just one commit here uh and if i wanted to merge my bug fix in to the master branch i want everyone else i want the master branch or the main branch or trunk or whatever we use as the branch name i want this branch to have my work my bug fix that i've been working on uh it's not a matter of fast forwarding anymore there's commits over here that don't exist on this branch and there's commits on this branch that don't exist on master so what happens is that instead of performing a fast forward git has to generate a merge commit so it's going to take all of the changes from my feature branch in this case bug fix and it's going to replay them and generate a new commit based on those changes so it kind of condenses that stuff down into this new commit we call it a merge commit we'll be prompted to enter a commit message and then we have a new commit on the master branch right so i'm going to demonstrate this and the easiest way to do that is just to undo that merge and just have master go back to this commit right here where it was so one option to do this uh is just to take the commit hash that i want to go back to i'll grab that and do a git reset dash dash hard i'm on the master branch okay so now if i take a look at git log there's just one commit on master we're back to where we were so now i'm going to make uh some new commits on the master branch so i'm on master now so let's imagine that i have collaborators who have made some changes in the meantime while i'm working on my navbar i don't know somebody named wanda wanda's feature is merged in or incorporated in some way to the master branch so i'm going to add that change i'll pretend i'm wanda and our message will be m2 just to keep with the pattern uh you know add wanda's feature something like that and then let's do at least one more uh let's do a i don't know hagrid our good friend hagrid has been working hard on the feature and he merges that in so we'll add that change and then do m3 for the third commit on the master branch add hagrid's feature okay so now we've diverged right this there's no fast forward merging that could happen so here's master right we have these two commits that navbar does not have and what i want to do is the same thing i'm going to try and merge this in to master so let's do that right now i'm on master no changes here that are uncommitted i'm going to git merge feature slash navbar so git is going to replay these commits well it replaces the changes and generates a new commit on the master branch and it's going to prompt me to enter a message so depending on the editor you have configured git will open it up for me it's a vs code i'll leave this message alone the default is fine merge branch feet slash navbar i'll close out and now notice right there there's a dot on get kraken that's how it indicates a merge commit so there's an actual new commit right there i can also do a git log and you'll see we have a commit right let me make this a bit larger here is that merge command all right so that's the basic idea of a merge commit and it's not a big deal merge commits happen frequently they're a part of life or a part of git uh one thing i want to highlight before we go on to rebasing though is that merges of all types are forward focused it's not the official term but hopefully i can explain what i mean by that no existing git history on either branch none of their existing commits are changed that history is exactly the same so this branch is untouched this is untouched all that changes is a new commit might be generated if there's a merge commit going forward so now we get to the dark side of merging which is a very dramatic way of basically saying there's an issue that some people don't like with merging a lot which is that your history can be very cluttered so imagine that i'm working on some project a very large project lots of collaborators where i make a feature branch like everyone else i'm working on a feature and it's taking me a while in the meantime while i'm still working other collaborators make changes and push them merge them into master so i want those changes on my feature branch i don't want to just diverge away from master over let's say a long period as i'm working on this feature i want to try and stay up to date and as close to master as possible get those changes so that i can incorporate them into what i'm working on so i i need to merge right with what we know so far if i do a merge i get a merge commit on my feature branch so to be clear i didn't merge into master i'm still working but i'm merging master into feature so then i keep working and i'm still not done and i'll multiply this by a lot instead of just four commits or three commits and a merge commits imagine i'm doing a lot more and i'm having to merge frequently there's always new work happening from co-workers collaborators they're updating master i need to merge that yet another merge commit and this is what people some people don't like you can have a ton of merge commits on really active projects and an example like this is not bad right we're talking about two merge commits i guess not the end of the world but if this is a big project and every feature branch has tons of merge commits uh and you have a lot of collaborators and they're constantly making merge commits the history can be very muddy messy so this is not that bad of an example but it's the worst i could find locally on my new machine here this is with get cracking you can see these merge commits happening all over the place these lines that are crossing those are all merge commits again not that bad but some people don't like this approach fortunately we have rebasing rebasing is another option for incorporating changes between two branches so here's how it works the get rebase command is used to reapply commits on top of another base tip now that is from the documentation that's not the way i speak that's just from the docs but in those in that sentence it tells us a little bit reapply commits on top of another base re-base a branch that's where the term comes from meaning with this example if we just look at the right side ignore the text here we have our master branch with some commits that i could merge into feature feature does not have those commits or if i use rebase i can take this feature branch and re-base it on top of the master meaning make the master branch the base the new base for the feature branch so what this means is that history actually is rewritten to move those commits like in a diagram it looks like i'm just dragging them around but from git's perspective these commits in cyan have to be recreated from scratch regenerated with new hashes they are new commits so the changes are still the same we won't lose work at least if we don't screw things up but the commits themselves the objects are different get merged leaves existing work alone git rebase does change history so our master branch is unchanged if we are re-basing feature onto master we're just telling git recreate all of this work so that it starts at the end of master so it's based on master and the way that we do this is by switching to a branch like the feature branch and then telling gets to rebase on master so git rebase master means take the current branch i'm on and base it off of master and to do that it's going to have to go through all the commits on the feature branch and for each commit it will create a new commit and apply them to the specified base to master in our example so i'm going to undo that merge command that i just did so i can demonstrate this so i'm going to reset back to this master three so get reset hard okay so now our feature branch has these three commits and it's missing the work from master we want wanda's feature we want hagrid's feature but i don't want to merge because i'll get a merge commit instead i'm going to rebase so here's what it looks like right now and also i'm going to do a git log i'm going to switch to that branch so i can show you git switch feet nav bar i'm going to do a git log here and screenshot these commit hashes just so you can see them and they will change some of them will change at least this one won't because this is from our master branch originally anyway uh i'm now going to run the rebase command so get rebase and then the branch i want to rebase my feature branch onto so i want to rebase it onto the master branch this is what it looks like right now here we are i'm going to rebase it so it all will begin at the tip of the master branch and that will require get creating new commits for me so they there can be conflicts and that's for another video uh if there are conflicts you've resolved them and you need to tell get keep going with the rebase but in our case there isn't we've been working in different files if i take a look this is my history now nice linear history no merge commits and you'll notice m1 m2 and m3 are all there in a group and then f1 f2 and f3 are all grouped together as well this branch has now been based on the tip of that master branch so it now has a new base and those commits have changed so if i do i mean first i'll just show you we have the changes wanda's feature hagrid's feature we have the navbar stuff but also if i do a git log online again let's see i'll compare these screenshots or put them side by side i'm realizing now my original screenshot i didn't include the context of the message but we still should be able to tell it's these three commits are from f1 f2 and f3 okay so this is our first screenshot where we had be2 and that still exists that's from the master branch this one but then the three feature branch commits here just take a look at their first letters f a and a well we don't have any of them anymore we have one with an f but that's from master so the three commits from the feature branch they all have new hashes but again the outcome the actual changes are the same nothing has been uh updated in terms of the work in those commits but the commits were recreated get regenerated them for us and that led to new commit hashes because the way hashes are generated and how commits work and trees and blobs and stuff that i'm not going to get into here i do talk about it in my git course if you're curious but anyway the work is still there but now we have this linear history so i want to be very clear one more time rebasing does rewrite history it rewrites commits it makes new commits based off of existing commits and it bases them on some other branch so if we were to compare the original we started with this and i used rebase we end up with three brand new commits based upon the three existing feature commits if we did a merge we end up with one brand new commit and it's a merge commit so everything else is unchanged two very different approaches nice and linear here but rewriting history here not so much linear at all but we're also not rewriting history so why rebase well the obvious answer so far at least is that we get a much cleaner history we don't get those merge commits everything's linear and easier to follow and another thing that people use rebase for is to actually edit history selectively to drop commits reword them to squash things this is something that could be a separate video i also cover it in my git course so there are other use cases but it all has to do with the fact that when we rebase git is going to replay these commits each one and generate a new commit based off of each one so along the way we can tell git actually drop that one fix that one squash that one anyway the most important thing to know about rebasing there's a golden rule which is never rebase commits that other people already have don't rebase shared work that can be a big problem because you are rewriting history changing commit hashes and if other people have those commit hashes it's up on github they've pulled it down they've been working off of that that's going to be a pain to reconcile it's not a pleasant process so again don't rewrite history that other people have that's the big issue with rebasing and that's why people can be scared of it it's fine to use a lot of people love rebasing i happen to like rebasing but this is the the general rule you want to follow unless you have a reason to break it at which point you should hopefully have the confidence to know why you're breaking it so quickly this is getting to be quite a long video just to recap the differences merging keeps your original history intact it is forward looking we have a fully traceable history but the downside is that it can be a very muddy history and lots of merge commits rebasing on the other hand is scarier but we end up with a flat and easier to read linear history it's nice and clean but of course it can be dangerous you've got to keep that golden rule in mind and you can lose some context that's more of a problem with squashing anyway and i think that's a good place to stop for now there's a lot more we could talk about with rebasing workflows and merging workflows and squashing and interactive rebasing but that is for my git course or for a future video alright so i hope you learned something if you're still there and that's it
Info
Channel: Colt Steele
Views: 19,257
Rating: 4.986999 out of 5
Keywords:
Id: 7Mh259hfxJg
Channel Id: undefined
Length: 19min 59sec (1199 seconds)
Published: Wed Mar 03 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.