I'm not sure to understand the point about rebase destroying the history. Does he speak specifically about `git rebase -i` ?
I very often run `git rebase master` in my feature branches to avoid having many conflicts to resolve just before my pull request to master. Once merged in master, initial commits I rebased from master did not seem to have changed. Am I missing something, here ?
In layman terms: rebase wipes out your commits and replaces them with new ones. Notice how the hashes change when you do a `git rebase master`, it's not just re-ordering them. If those commits have been published or pulled from someone else, you are destroying history.
I realize it has never been a problem for me because commits replayed when I rebase are always isolated in my feature branch and not pushed anywhere.
I suppose it would be a problem if I rebased from two different branches that were already public.
Also, I often work with "dependent branch". When a change has to be made that does not fit the feature branch "theme", I create a new feature branch from master, make my change, make a PR to master and rebase the dependent branch in the feature branch. It seems it does not cause any history overwrite too.
> I'm not sure to understand the point about rebase destroying the history. Does he speak specifically about `git rebase -i` ?
When rebasing, you're at least changing a parent commit and therefore
changing all of your rebased commits, because their SHA1 is also based on
their parents.
> I very often run `git rebase master` in my feature branches to avoid having many conflicts to resolve just before my pull request to master. Once merged in master, initial commits I rebased from master did not seem to have changed. Am I missing something, here ?
As long as you don't rebase a feature branch after you have pushed it into a
remote repository or merged it into an already published branch, you're fine.
That kind of rebase is great, because you are applying your work on top of the master branch (i.e., making the history read as it should be, that your set of commits was added on top of master). That's why git says it's "replaying" your commits on top of it. That usually works because you and master have a common previous point of reference.
If the master branch went back and changed something before that common point of reference, things get more confusing. If you want to see this yourself, checkout a separate branch, rebase interactively and make a big edit in the past. It's much more painful to add on top of that successfully with the first branch (git will want to do a merge commit) because now the history has diverged between them. (and if you use CI, you might notice that when you rebase a wip topic branch locally, git tells you things like "You are 10 commits behind and 5 commits ahead".
Rebasing and fast-forward merging are two very different things.
whenever you rebase you create _brand new commits_ based off another part of the project history which bear a strong resemblance to the original commits but are nonetheless different.
adding -i allows you to do further modification of commit contents (reordering, squashing, dropping, etc. but a vanilla rebase is still changing history.
Linus addresses this in his mail early on: "People can (and probably should) rebase their _private_ trees (their own
work). That's a _cleanup_. But never other peoples code. That's a "destroy history" "
Are you saying when I rebase off of upstream on my private branch does that change the sha1 of the upstream commits?
That hasn't been my experience. As far as I can tell.
Edit: OK, I did a test and I can see that it is changing the sha1 for my commits on my private branch after I rebase from upstream master. So at least the way I'm doing it I'm not changing public comit hashes.
I very often run `git rebase master` in my feature branches to avoid having many conflicts to resolve just before my pull request to master. Once merged in master, initial commits I rebased from master did not seem to have changed. Am I missing something, here ?