Whether you've published the true history earlier is irrelevant to that discussion.
Whether you've published the true history earlier is irrelevant to that discussion.
If I make three commits and then realize that I should have included something in the first commit, I use rebase to create a new sequence of three commits that has the corrected version of the first commit. I haven't shared those commits with anyone, this is just work that I've done locally.
Are you seriously advocating that creating a pull request with: (A, B, C, A-fixup) is better than using rebase and then creating a pull request with: (better-A, B, C)?
You think that second case is "lying" because I didn't show the intermediate step that included the mistake?
You can mitigate most of the damage if it is convincing enough (for example, go through B' and C' and make sure everything still makes sense at each point), but realistically nobody is going to do that, because it's pretty inefficient way to spend your time. And even then, you're still removing context (unless you're just fixing a typo).
> I'm advocating that you use rebase to improve the quality of your changes that will be reviewed before merging or even before being reviewed at all.
That was clear from the start. But the fact that X breaks Y doesn't imply that Y is a good idea when X doesn't apply.
Us mere humans make mistakes all the time. Typos, omissions, false starts, and so on. What is the value of throwing that raw set of events at a reviewer or complicating the understanding of the changes when viewed in retrospect from the future? What is the reason you call curating the work into a more polished form "lying"? Why do you think the time spent being intentional about changes isn't valuable when compared to the time spent by a reviewer (or your future self) to sort through the flotsam and jetsam of your intermediate work?
You can do it in a way that isn't harmful (as I mentioned earlier), but good luck getting a team to actually stick to that. It also doesn't help that pretty much no tooling encourages doing it properly.
I made a typo when writing this reply, and pressed backspace to correct it. Is use of the backspace key lying?
I think you're placing a value on "history" that doesn't map onto all users of "rebase", or E-Mail client drafts. A lot of advanced users use it as the equivalent of "save" in an editor, sharing all those intermediate states is more noise than value v.s. crafting a sensible patch once you figure out what you want/what change to make.
The true problems begin once you start creating commits that represent repository trees that you never tested or reviewed, for example by editing past commits (invalidating any testing you've done of commits after that point), deleting past commits (aside from squashing an unbroken sequence of commits, or deleting them if the squash would result in a no-op), reordering commits, or rebasing commits.
But yeah, the history you push to a canonical branch should generally be made up of commits that have all been tested in isolation. The rebase command doesn't make this worse, but better, e.g. with "rebase -i --exec='make test'".
I also prune out history of some false steps taken. Have you never written a program and done something like "I'll use a hash here <save><compile><test>, no actually a list makes more sense <save><compile><test> ...". Those intermediate steps are commits for a lot of advanced git users.
Sharing all your mistakes-as-you-go-along with the world doesn't help anyone, I'd typically be sending you a 100 patch merge request for some rather trivial change instead of 1-3 sensible commits.
I rather review the final patch series with changes in logical order and not necessarily in the order the code was written or with intermediate work that was later reverted or changed again. I do look at commits, because also every commit message counts and is supposed to explain the individual change.
The messy reality is valuable, when talking with your teammates about how the work was done and what kind of bumps were along the way. It's not about looking over their shoulders, it's about using data to develop together as a team, eliminating hinderances, etc - if you have the mutual trust to do that. And of course you yourself can go back and look for patterns of mistakes or problematic areas in code based on your history.
Like I said, to judge the change its, the whole PR diff is usually the most useful unit of inspection when you just want to see what happens. And if it's a big pr, you can of course always merge child PR's or branches against the big PR/branch, and look at the merge diffs.
The science principle of publishing your experiments, including failed ones, has the same benefits in sw engineering: others can build on your failed attempts, or save time by not replicating them.
Of course you do! And it's not am inefficient use of your time, because it helps reviewers now, and yourself when you're bisecting later.
> And even then, you're still removing context (unless you're just fixing a typo).
You place that context in the commit message.
And how do you detect that you forgot / was too busy to do it, when you go back 6 months later? It's fragile, "fail-open".
https://github.com/tianocore/tianocore.github.io/wiki/Laszlo...
Say upstream is at A.
I clone it in my local work-space, and make a few commits over the course of a few days. So my local is A B C
During this time other changes have been merged into upstream, so upstream looks like A D E
I now have two options. I can try to merge from upstream or rebase off of upstream. Merging introduces a messy commit history that quickly becomes difficult to follow. Rebasing removes my local commits, applies the changes in upstream, and then re-applies my local commits.
So after rebasing my local is A D E B C. There are no messy merge commits. And ideally, I can squash my local changes into a single feature commit, so upstream ends up incredibly tidy.
At no place in this process is there any dishonesty or lying. I haven't changed the history upstream, which is the source of truth. What's the issue here?
No, your local is now A D E B' C'. Commits aren't just a diff between two tree snapshots, they are tree snapshots.
Hopefully you test and sanity check C' before submitting for review, but it's very unlikely that you're going to give B' the same treatment, making it more difficult for people to understand the history in the future (as well as breaking `git bisect`).
And even if you do, are your coworkers going to? Consistently? No CI tool that I'm aware of will enforce this for you.
> There are no messy merge commits.
No, but the underlying messy workflow is still there. You've just swept it under the rug for the sake of aesthetics, at the cost of future comprehension.
> At no place in this process is there any dishonesty or lying. I haven't changed the history upstream, which is the source of truth. What's the issue here?
Those are completely orthogonal concerns. You're presenting a false version of the repository state.
The common mantra of "don't rewrite public history" is about not creating a mess of duplicate commits, it doesn't imply that rewriting history is fine as long as it's not public.
Your commit history is just a somewhat arbitrary recording of your code at certain points in time that you choose. Rebasing simply makes that less arbitrary, allowing you to document the way your code is built up in a structured way. Rather than having to decide on the spot whenever a certain combination of code is a good candidate for a single, atomic commit, you can make that judgment with the benefit of hindsight.
Yes. A failed attempt is still a useful signal that people shouldn't try to simplify back to that way in the future (and why not). It's also a useful starting point in case the reasons it failed no longer apply.
Commit histories littered with commits that get back-and-forth reverted are frickin unreadable though. Extremely annoying to bisect, painful to comb through when looking for changes, noisy in git blame, etc. There's a ton of downsides for what in practice is very rarely even an upside.
Nobody is suggesting that rebase be used to change the history of a released or published branch (master, develop etc.). If that is your concern and the reason for you not trusting a "rebaser" then you are simply mistaken, you are arguing against an imaginary workflow for which no one is advocating.
Rebase should be used only to curate the commits on a feature branch and to keep the feature branch synchronized with the upstream branch.
The exception to this is when a feature becomes more involved and has several logical steps, or any kind of history worth providing. This should be rare and when it happens, use merge commits to preserve history.
Not polluting the history with N trivial branches for every 1 branch that needs historical context, is a benefit of this.