14 ms·
The point of rebasing for clarity, IMHO, is to take what might be a large, unorganized commit or commits (i.e. the result of a few hours good hacking) and turni
by phs2501 11y ago
The point of rebasing for clarity, IMHO, is to take what might be a large, unorganized commit or commits (i.e. the result of a few hours good hacking) and turning it into a coherent story of how that feature is implemented. This means splitting it into commits (which change one thing), giving them good commit messages (describing the one thing and its effects), and putting them in the right order.
Rather than hiding bugs, usually I wind up finding bugs when doing this because teasing apart the different concerns that were developed in parallel in the hacking session (while keeping your codebase compiling/tests running at every step) tends to expose codependence issues that you wouldn't find when everything's there at once.
It's basically a one-person code review. And when you're done you have a coherent story (in commits) which is perfectly suited for other people to review, rather than just a big diff (or smaller messy diffs).
It also lets me commit whenever I want to during development, even if the build is broken. This is useful for finding bugs during development as you'll have more recorded states to, i.e., find the last working state when you screw something up. And in-development commits can be more notes to myself about the current state of development rather than well-reasoned prose about the features contained.
I realize not everyone agrees with it, but I hope I've described some good reasons why I think modifying history (suitably constrained by the don't-do-it-once-you've-given-your-branch-to-the-public rule) is a good thing, not something to be shunned.
- wylee 11y agoI agree with you, but only for local commits that haven't been pushed to a shared repo. Rewriting local history seems no different than rewriting code in your editor. Rewriting shared history is (almost) always bad.
- phs2501 11y agoI like "Rewriting local history seems no different than rewriting code in your editor", that's a pretty good analogy I hadn't thought of. There are a (very) few instances where you'd want to rewrite something pushed to a shared repo. One is if there's a shared understanding that that branch will be rewritten. Some examples would include git's own "pu" and "next" branches. "pu" is rebased every time it changes, and "next" is rebased after every release. Everyone knows this and knows not to base work off these branches. There's also the occasional "brown paper bag" cleanup like some proprietary information got into the repository by mistake and all the contributors have to cooporate to get it removed. But all of these take out-of-band communication somehow.
- ori_b 11y ago> I agree with you, but only for local commits that haven't been pushed to a shared repo. Yes, that's why Git doesn't allow you to push rewrites, at least not without '--force'.
- sbov 11y agoDoes anyone advocate rewriting shared history? Oddly I see this "exception" a lot in reply to this person but I'm not sure I ever read anywhere anyone saying rewriting shared history is a good idea.
- cpitman 11y agoI think its less people saying you should rebase shared history, and more people saying you should rebase without realizing shared history matters. Then some poor confused soul starts always rebasing before pushing/merging and they mess up their local history and do not know how to fix it. A lot of git is "magic" to many developers, and the way that rebase works is certainly one of the features poorly understood.
- mcv 11y agoMy rule of thumb is that rewriting shared history is always, always bad. There may be situations where the proper precautions can mitigate the risk, but I've never seen a good example where it's actually a completely good idea without downsides.
- talideon 11y agoOnly in extreme circumstances where something sensitive (such as credentials) or otherwise (such as other people's copyrighted assets, or .svn directories in the case of some repos that were moved from SVN to get in a hamfisted manner) was checked into the repository and needs to be removed. Those are the only reasons for rewriting shared history.
- Jacqued 11y agoWe've been fine using rebase on already pushed branches. This comes from the understanding that a feature branch belongs to one developer, ever, and that no one else is supposed to work off of it (or at their own peril). Everyone knows that it's "my branch" and that they're absolutely not supposed to use it for anything until it's merged back into master or whatever authoritative branch.
- aoeuasdf1 11y agoOk, that makes sense... but then why bother pushing the branch in the first place?
- zastrowm 11y agoIt allows builds off of that branch, so you can get test feedback etc. It also acts as sort of a backup or a sync if you switch machines.
- davidp 11y agoCode reviews -- you can create a PR on the pushed code, make fixes in response to the comments, rebase, and re-push.
- sopooneo 11y agoWe have a rule that you never go home at night without pushing your work, even if it's garbage. Put it in a super-short-term feature branch if needed, and push that, but don't leave it imprisoned on your machine.
- goostavos 11y agoThere are people who follow this rule, and there are people that think disk failures are what happen to other people. Few things sting as bad as loosing hours or days worth of work.
- icebraining 11y ago
- moron4hire 11y agoI don't think I've ever seen anyone advocate rewriting shared history.
- talideon 11y agoI've came across reasons, but they've always been pretty marginal, such as somebody checking in sensitive credentials without realising what they were doing.
- moron4hire 11y agoI think I would like the ability to edit commit messages for typos without having to force everyone to reset --hard.
- talideon 11y agoThe thing is, the commit message is part of the commit, not something separate from it. Irritating as it might be, this is good for traceability. What I do to avoid that is work on a separate branch, rebase against master, then review the commits on my branch after getting rid of any WIP commits and shuffling them around to make more sense. Finally, I make sure the commit messages are (a) accurate and (b) have no typos. Once I'm satisfied with that, I merge. I treat merging as a big deal, but not committing.
- geertj 11y ago> Rewriting shared history is (almost) always bad. Agreed. The one counterexample that I have is Github pull requests. Those are actually branches in your fork, and you do want to rewrite those when you get feedback on a pull request. That makes it easier for the owner of the repo to do the merge later.
- clinta 11y agoWhy do you need to rewrite? If a pull request is not completed, you can continue to push it and the PR is updated to pull the latest commit.
- sorbits 11y agoI will get pull requests where later commits fix bugs introduced in former commits. I generally ask people to rewrite such PRs, as I’m not going to pull known buggy commits into master, even if they are followed by fixes. That is just noise. It might also be that some commits in the PR has changed tabs to spaces or vice versa.
- hayd 11y agoI think the point was: if you have a PR with two commits, you can squash it to a single commit and force push. This will update the PR to just have the single commit. (Similarly with a rebase.)
- RickHull 11y agosorbits' point was in response to: clinta > Why do you need to rewrite? If a pull request is not completed, you can continue to push it and the PR is updated to pull the latest commit. sorbits is saying that no, you really should rewrite your PR. You, hayd, seem to be merely reiterating sorbits' point.
- pyre 11y agoMaking 'temporary' commits and rewriting local history before pushing to a shared repo has analogs in other revision control systems: * In Subversion, people track patches using tools like quilt to manage them before actually putting them together into a commit. * In Mercurial, people use `hg mq` which is like a more featureful version `git-stash`. These are basically all ways to track a series of patches prior to 'committing' them into the code base shared with others.
- qu4z-2 11y agoSpeaking of `git-stash` I've always thought of `git-stash` as a less featureful version of `git-branch stash`
- dkubb 11y agoAnother nice side benefit is that you are able to use git bisect to find bugs more easily. If some of the commits fail the build then it becomes difficult to separate commits that actually introduce a bug from those that are just incomplete. The team I work with has recently started making sure every commit passes the build and it's had some fantastic results in our productivity. We know every individual commit passes on it's own. If we cherry-pick something in that it's most likely going to pass; so if it fails then usually the problem is in that specific commit, not one made days or weeks ago.
- twic 11y agoYou don't have to rewrite history to do this. You just have to run your tests before committing. You know, like people used to in the old days. Indeed, i think the widespread rewriting of history that goes on in the Git world makes it more likely that there will be failing commits, because every time you rewrite, you create a sheaf of commits which have never been tested. Now, in your case, it sounds like you have set up processes to check these commits, and that's absolutely great. Everyone should do this! But why not combine this with a non-rewriting, test-before-commit process that produces fewer broken commits in the first place?
- dkubb 11y agoYeah, obviously we do that (well maybe not so obvious to some, but I never push unless the tests pass). We sometimes perform lots of other things like static analysis that get in the way of a rapid feedback loop. We also run mutation testing, which can sometimes take several hours for the whole codebase -- although we don't have this run on every commit, just ones that we merge into a specific branch. The problem I have with non-linear commit history is that I find it impossible to keep all the paths straight in my head when I am trying to understand a series of changes. Maybe you can do that, and I think that's awesome, but I like to see a master branch and then smaller feature branches that break off and then combine back with master.
- CrystalGamma 11y agoA tool that does not naively sort the commits by date but groups linear parts of history together should allow for better overview.
- ravishi 11y agoPrecisely.
- pacala 11y ago> The point of rebasing for clarity, IMHO, is to take what might be a large, unorganized commit or commits (i.e. the result of a few hours good hacking) and turning it into a coherent story of how that feature is implemented. This means splitting it into commits (which change one thing), giving them good commit messages (describing the one thing and its effects), and putting them in the right order. To my understanding, Gerrit does grouped commits as part of the flow. Even better, groups all review-triggered commits under the same master commit, with the nice, extensive description that one carved for the PR. It's regrettable that GitHub popularized fork/pull request model instead. https://www.gerritcodereview.com/ https://www.gerritcodereview.com/
- LoSboccacc 11y agosame here. it is much more clear to me to reapply my commits, as long as I constrain myself to clear, coherent and atomic commits. replaying changes is much more comfortable to me, especially when I have them in shot term memory, surely easier than merging other people stuff within your files my average feature is around 7-10 commits, all replayed on latest commit on the branch. it forces me to catch up with other people work on shared areas and gives me quite some more confidence that merge isn't messing up with problematic files.
- scelerat 11y ago> The point of rebasing for clarity, IMHO, is to take what might be a large, unorganized commit or commits (i.e. the result of a few hours good hacking) and turning it into a coherent story of how that feature is implemented. Isn't this the same rationalization that drives Git Flow's feature branches and merging via --no-ff ? You can see the messy real work in the feature branch, but it gets merged to the main branch as one clean commit.
- pbh101 11y agoOnce the merge commit occurs, the 'messy real work' is now part of the main branch's history just as much as the rest of the commits, as they are ancestors of that merge commit.
- kiallmacinnes 11y agoAgreed, most people hear "rewrite history" and immediately assume "public history". Rebase is a part of code review. If someone spots a typo and a "fix typo" commit follows it up as happens for a good proportion of GitHub model projects, I cringe. This information is uttery useless to the projects history, and should be rebased as a fixup. Only once code review is done, should a commit be considered for merge. It's at this point that rewriting becomes a problem. I think most people forgot where Git came from, git is designed from the ground up for this! When someone emails a series of patches to the kernel mailing list for review, they iterate that series of commits over and over until its ready. They don't keep adding new patches on top like the Pull Request model proposed by GitHub/GitLab etc do.
- ealloc 11y agoIn my Github experience, rebasing/tidying your commits is expected before a Pull Request is merged, just like your description of Linux development. Eg, the numpy/scipy/matplotlib projects.
- z1mm32m4n 11y agoUnfortunately, this is not true for many repositories. GitHub's interface (i.e., the "Merge" button), encourages users to merge from the web interface, where this tidying can't happen.
- hayd 11y agoThen someone else rebases over that commit, there's a conflict and lo! the tests fail. Why? typo. It's fixed in the subsequent commit (which you can't see). Lovely. There's something to be said for having every commit pass tests/work (or if it doesn't saying explicitly in the commit message), if anyone is ever going to step over this commit.
- damm 11y agoThat's a hard one; trying to make a single commit in a pull request helps me but sometimes even then a pull request gets ignored and they want me to rebase it. The problem is they ask /me/ to rebase it; I think they should take a little ownership in the potential rewriting of history.