What does it mean to git rebase a branch on top of incoming changes?

tl;dr A fundamental misunderstanding of the rebase operation. I confused myself yesterday and I've not quite recovered. Rider's phraseology isn't helping me either, but maybe that's just me. When Rider offers to "Rebase the current branch on top of incoming changes, what does "on top" mean? I checked with two branches that were too similar to see the difference without making a change in one, and I am hesitant to make any changes anyway in case the rebase is different to branch and doesn't leave me with a nice, atomic "rebase commit" like a merge does. I visualise commit "trails" as vertical lines starting with the first commit at the bottom. First I imagined the proposed rebase to be like a merge, with two parallel commit trails, both starting at bottom and being joined by a zip. But that's an actual merge not a rebase, my first mistake. The "on top" phrase made me think of the commit trails as horizontal lines, with the incoming changes being the top line, to be "zipped" onto the bottom line, my second mistake because that's still really a merge. Now I think what Rider actually means by "on top" is like what I've read about rebase in some docs, where the local branch is a single vertical line starting at the bottom. Then the rebase will take incoming commits and place them in the same line as the local branch, at the bottom, pushing the newer local branch commits up to be on top of the incoming commits, thus remaking the base of the local branch, hence the term rebase. But then the order of the commits in the local branch doesn't add up because some incoming ones would have originally been made after some local ones. To keep them in order git would have to insert incoming commits in the correct order between local commits, but isn't that just a merge?
54 Replies
ero
ero2y ago
Rebasing something "on top of" something else does not make any sense in my mind at all Something can be "based on" something else But not "based on top of" something else
Brady Kelly
Brady Kelly2y ago
On top of is Rider's exact term
ero
ero2y ago
That much i understood In my mind, rebasing means you basically re-write your branch to pretend it's been "based on" another commit entirely the whole time
Pokey
Pokey2y ago
Rebasing "on top of" is like having a multi layer cake. If I have 3 green layers (branch I was based on's commits) and 3 red layers of cake (my new commits) then rebasing my cake would mean the branch I was based on has had additional commits since I took a copy. So I will take off my red layers, add on the new green layers and plop my red layers back on, I have changed the base of my cake to have more green layers than before, I have "rebased" my red layers
ero
ero2y ago
That's my understanding of rebasing yeah The "on top of" still doesn't make sense in my mind "rebase on" is enough imo
Pokey
Pokey2y ago
I am "rebasing" my cake to be "on top of" the new incoming commits
ero
ero2y ago
No yeah i get it I just hate it The fun begins when you have conflicts :3 With rebase --skip and rebase --continue mmmm
Pokey
Pokey2y ago
With regards to commits after the ones you've made.... I dunno, I don't think it cares if theres no merge conflict, I have never really thought about it personally, it just works. Create a git repo, test and come back to us!
ero
ero2y ago
I've done this and I've had huge headaches I had 3 PRs which were basically all based on one another On 3 separate branches, which i created off of the previous (after making the PR) But then changes were requested on the first PR and the fun began
Pokey
Pokey2y ago
Rebased Seem they aren't in order of time anymore And heres after a merge Hope that was useful @Doktor9, I'll be deleting those in a mo because obvious name reasons
Aaron
Aaron2y ago
so, it doesn't take commits from your local branch what a rebase does, in essence, is re-do every commit so if master gets a new commit and you rebase your feature branch "on top of" master rebase gets rid of every commit you've made pulls the commit from master then re-does what happened in every commit, in order, but now with that new commit from master at the start
ero
ero2y ago
What i meant to say with this
Aaron
Aaron2y ago
you could do this yourself if you wanted
Brady Kelly
Brady Kelly2y ago
Thanks, I think half my confusion here started with the fact that both my branches are master and origin/master
Aaron
Aaron2y ago
ah, yeah that's never fun always really hard to tell what's from where
ero
ero2y ago
Then it's not really a rebase right? Or it shouldn't be at least?
Brady Kelly
Brady Kelly2y ago
Exactly
ero
ero2y ago
Just a normal pull should do it here
Aaron
Aaron2y ago
no, you can rebase a local branch onto a remote one if you have local commits on your branch, and the remote master got different new commits in the meantime
ero
ero2y ago
Sounds weird
Brady Kelly
Brady Kelly2y ago
Yes! That'
Aaron
Aaron2y ago
it basically deletes your local copy and starts from scratch
ero
ero2y ago
Yeah I'd just pull for this. Never even considered rebasing
Aaron
Aaron2y ago
with whatever is on your new master
Brady Kelly
Brady Kelly2y ago
That's what is making me pause, is commits to origin made before commits to local
Aaron
Aaron2y ago
that would make a merge commit
ero
ero2y ago
Hm
Aaron
Aaron2y ago
which you might not want you don't actually have to use the rebase command for this though
ero
ero2y ago
Just squash i guess lol
Aaron
Aaron2y ago
you can do git pull --rebase although I'd be careful with it especially if there would be conflicts
Brady Kelly
Brady Kelly2y ago
Aha, OK, I see a straight pull is missing from the git toolbar in Rider, leaving me a "Fetch" which is where I must decide if I want a rebase or a merge commit
Aaron
Aaron2y ago
the default for just pull with no flags is to make a merge commit iirc
ero
ero2y ago
Makes sense
Brady Kelly
Brady Kelly2y ago
It's not just "Pull", it's explicitly a different operation called "Fetch" In Rider that is not in git
Aaron
Aaron2y ago
fetch just asks the remotes for what has changed
Brady Kelly
Brady Kelly2y ago
I think Rider then sees there are changes and wants to know how to apply them, rebase or merge
Unknown User
Unknown User2y ago
Message Not Public
Sign In & Join Server To View
Aaron
Aaron2y ago
I think I have mine set to fast-forward only
Brady Kelly
Brady Kelly2y ago
"Pull is just a fetch and merge" - Ooh, more rays of light in the darkness, thanks
Aaron
Aaron2y ago
fast-forward is basically "there are no actual changes here compared to what we're pulling, we can just grab the new commits and add them to the branch without any fuss" if that fails, my git yells at me and tells me I should pick what to do :p you know, I wonder if any universities have classes dedicated to just learning source control
Brady Kelly
Brady Kelly2y ago
I still don't quite get it, but now I have time to make a test project myself, but thanks a lot, you can remove your images
canton7
canton72y ago
Gist
git-ffwd.pdf
GitHub Gist: instantly share code, notes, and snippets.
Brady Kelly
Brady Kelly2y ago
I must finish my PluralSight git course, it's varsity level, but we're still exploring the content of object files in the .git folder
Aaron
Aaron2y ago
I have no idea what git is actually doing to store these commits lmao
Brady Kelly
Brady Kelly2y ago
It's not as opaque as it might seem, all a bunch of lists (files) of hashes, just like your history
canton7
canton72y ago
git cat-file -p HEAD, and work from there. Use that to print the contents of any hashes you find, and keep digging
Brady Kelly
Brady Kelly2y ago
I think my takeaway here is that rebase may well result in the commits not being in order?
Unknown User
Unknown User2y ago
Message Not Public
Sign In & Join Server To View
canton7
canton72y ago
Ish. Rebase takes a set of commits, and rewrites them to sit on top of another commit that you specify. So the order of the set of commits that you're rebasing won't change, but they will be sat on top of a new parent Remember that git's commit history is a graph anyway, so there isn't a single total order across all branches to start with ... and it you're doing any of these operations without visualising what they're doing to the graph of commits, then stop, open a history viewer like gitk --all, and make sure you're comfortable with how things look now, and what you want them to look like after you've finished Interactive rebase, with commit --fixup / --squash, is one of my favourite things
Brady Kelly
Brady Kelly2y ago
I think more than half my problem is trying to visualise a single history behind the graph representing it, i.e. eventually, somehow, commits from all branches on the graph appear to be in some order
canton7
canton72y ago
There's no notion of that though. This isn't SVN Your history really is a gragh, with no total order
Brady Kelly
Brady Kelly2y ago
My very first VCS, maybe that's why lol I lie, my first was SourceSafe
canton7
canton72y ago
You poor thing History is a singly-linked list, where each commit has a single parent (merge commits have 2+ parents), and multiple commits can share the same parent Anyway, your course should get onto that. Other good resources: * https://git-scm.com/book * https://jwiegley.github.io/git-from-the-bottom-up/ * http://pcottle.github.io/learnGitBranching/ That last one is particularly good if you're struggling to visualise things, as it's all about the visualisation
Brady Kelly
Brady Kelly2y ago
Thanks man, I think I've tried that last one before, looks very familiar, but I didn't give it enough time, or didn't properly follow the lessons. I know I gave up quickly