17 ms·
Linus’s rules on keeping Git history clean (2009)
- AstralStorm 7y agoPlease add (2009) next time.
- sgt 7y agoI bet a lot of people will find this advice completely confusing. Emailing a patch?
- Gorgor 7y agoEven if not many developers use an email-based workflow for their own work, I think it’s pretty well-known that the Linux kernel does.
- Tharkun 7y agoI suspect you're overestimating the number of developers who know or use Linux. Many developers use Git on Windows and don't know anything about Linux, let alone about the workflow of the kernel team.
- snazz 7y agoWhile GitHub and its clones have taken over, Git was intended to be used with emailed patches. The Linux kernel is a good example of a project using Git that way. It’s reasonably common among mature projects and it’s really not that hard: https://git-send-email.io/ https://git-send-email.io/
- u801e 7y agoThe git project uses the same workflow for development that the Linux kernel does. That is, using a mailing list to submit and discuss commits before merging them into the maintainer's repository.
- Tharkun 7y agoSure. But many users of git don't know (or care) about the workflow of the git team. They know github. Maybe gitlab. Or bitbucket. They could go their entire development careers without ever sending a patch as an email, instead relying on feature branches and pull requests. This could be completely alien to them, and it seems wrong to downvote srg for pointing that out.
- asveikau 7y agogit format-patch and git am are still very useful features, even if you're not Linus, not a Linux developer, or on Windows. Basically you can serialize your git history as patches, transmit them any way you like (including email), and seamlessly re-integrate them as fully complete git commits. I sometimes use this even when working only with myself, i.e. if I want to test a change on multiple machines before I'm ready to push. Then I can use normal git workflow to rebase, etc.
- deepsun 7y agoIsn't that obvious? How else could it be?
- nas 7y agoLook at the cpython history. There is a major change from Mercurial to Git. It's not that Mercurial doesn't support the "rebase" workflow. It does discourage it though. Personally, I much prefer the "rebase your WIP changes, avoid merges" style. It is much easier to work with the resulting history.
- Svoka 7y agoI never got this argument. What the point of "clean history"? History is for log of work, not for being nice read.
- Cthulhu_ 7y agoSo said log of work is not to be read? Why even bother with commit messages then? It might not be useful for you or your projects, but that's up to you. Linux is the other side of the coin though - they NEED to be able to read a commit from ten years ago, see what was changed (the diff), why it was changed, and by who it was changed and signed off. Take a look at their repository, e.g. via github for ease of access. Here's a random commit: https://github.com/torvalds/linux/commit/e1e54ec7fb55501c33b117c111cb0a045b8eded2 https://github.com/torvalds/linux/commit/e1e54ec7fb55501c33b.... Even with my complete lack of knowledge of kernel development, I can tell that the minor code change is backed up by a lot of reasoning and intent. But, it's a wholly different use case. Most applications I've worked with are basically webapps that will be thrown away within five years, where it's not as important.
- nomel 7y ago> Why even bother with commit messages then? For me, it's all about understanding context of a change, the "why" (commit message) not "what" (code comments). I can run regression tests to find where things broke and, with the messages, have a good understanding of the context and mindset the developer was working in. In my editor, I can select some code and click "show history for selection" and get a complete log of what happened on those lines. If the commit messages are good, I'll have on understanding of the context of the change. Missing commit messages usually result in "I don't remember" type emails from the author when I inevitably ask what them why they made a change.
- hanniabu 7y agoIf you're working with a group of people you should never git pull prior to a commit and always git push -f
- juliusmusseau 7y agoJoking aside, "git pull -r" is pure magic in the face of upstream rewrites. It always does the right thing: https://mergebase.com/doing-git-wrong/2018/03/07/fun-with-git-pull-rebase/ https://mergebase.com/doing-git-wrong/2018/03/07/fun-with-gi... After I wrote that blog post someone told me the reason for the magic is the use of "git merge-base --fork-point" under the hood.
- yebyen 7y ago`pull --rebase` is nothing, go back and read the history of `rebase --preserve-merges` and now `rebase --rebase-merges` I have worked with both, and the new one is much better. Of course this only matters if the branch you are rebasing has merges in it (so in all likelihood, you must be a release manager to need features like this) Between rebase-merges and --onto, I don't spend hardly any time fixing up bad merges anymore.
- human20190310 7y agoI never type -f or --force on the same line as git. If someone feels it needs to be done, I try to stop them; failing that, I make sure they're the ones doing it. I don't need that kind of risk.
- sqyttles 7y ago--force-with-lease is much safer if you're working with others on a shared branch. :3
- stinos 7y agoWhen I first read the often-repeated advice NEVER change public history or something along those lines I was like 'yeah, 'duh'. My opinion on that changed a bit though and I reckon this advice follows the standard pattern of good guidelines being falsely wrapped as strict rules which must never be broken. In practice: I only work in smaller teams and we use feature branches which get merged into master after review, having the netto effect pretty much no-one is ever working directly on master. So it if happens someone does something like pushing a commit only to figure out 2 days later it has a typo or even needs a small code change or anything which would improve the commit with trivial changes not really worth creating another commit, we just go ahead and fixup/rebase/force push i.e. rewrite public history. Since the rest of the team always does pull --rebase of master anyway and/or rebases feature branches this is not a problem at all.
- unionpivo 7y agoIf you read last Linus message in the chain he says pretty much the same, it's not black and white, and sometimes you need to break the rules. (That said its still a good rule, and unless you know what you are doing you should follow it)
- ptsneves 7y agoIn my opinion the force push option availability decreases proportionally with the number of users of a repo. In a repo where about 400 people work to make a force push we needed to get authorization from management and do it in a weekend. In my own projects I amend quite often and force push about 1/10 times.
- Cthulhu_ 7y agoYeah, pretty much all projects are smaller than the use case Linux has; main differences are scale, number of contributors, hierarchy, etc. In Linux, iirc, there's a lot more sharing code via email and the like, peer-to-peer. In the rest of the world, it goes through a central repository. Anyway, a bit more flexible is that it's fine to rebase history and force push, as long as it's on your own branch or as long as everyone working on the same branch is aware that it's about to happen and acts accordingly. If they don't though, you're going to have a bad time. The most important thing is to be conscious of what effect your actions will have on others. And of course, never do it on master - and if for some reason you have to, take a good look at what caused the problem in the first place. It's good practice in most projects to lock down master in whatever repository host you use (e.g. github) and only allow changes via pull requests.
- ptsneves 7y agoMy work flow consists in working in some topic locally and committing in the smallest topic units possible. Then as I make some fixes due to typos or plain wrong logic I just amend or fix up. The longer I keep branched out then bigger the likelihood of having a lot of fixup commits. Then I use this awesome magic git rebase somehash^ -i --autoquash. It re orders all my fixups automatically so it is very painless to consolidate everything before pushing. Maybe it is very known but this fixup/autosquash thing changed my productivity a lot.
- yebyen 7y agoI don't think this feature is very well-known, in fact I've seen it mentioned before, thought "how useful! I will absorb this into my brain now" – and promptly forgot about it. I think there is a critical mass of advanced git features required to be really fluent in git, and there is a sizeable fraction of everyday git users who simply haven't made it all the way there yet. Some teams have at least one person who has enough git features under their belt... To recognize when merge conflicts are being haphazardly made unnecessarily, to be really particular about the shape of the git commit history and be aware of what merges can make those conflicts, to occasionally show the rest of the team some of these tricks or bail someone out when things go haywire, but at least in my experience spreading all of this knowledge to the rest of the team is a long slow process.
- stinos 7y agoI do this the whole time, creating many small commits, fixing up, squashing etc but to keep things a bit orderly I also usually do the rebase -i fairly often in order not to end up with more fixup commits that are easy to fit on screen. But yes: this workflow seems to suit me particularily well and changed the way I work with git. And it tends to lead to a nicely crafted, clear and easy to follow history of all steps of adding a new feature and/or refactoring things and made me more productive and seems to cause less bugs/mess overall because I review pieces of code more often.
- throwamay1241 7y ago'Commit to master, that way merging is somebody elses problem'
- yters 7y agoIs this all about making it possible to do delta debugging with git commits?
- kazinator 7y agoIf you want clean git history, you must burn "git merge". No commit should ever have more than one parent.
- favorited 7y agoThat might be clean, but it's not history.
- d_burfoot 7y agoIn my opinion source control history is much overrated. Instead of documenting your diffs, you should just document the code itself. Every developer has some limited time budget for writing documentation. If you spend lots of time and frustration trying to get the git history correct, you have less time left over for actual code documentation. > See? All the rules really are pretty simple. Hmmmm.
- viklove 7y agoI'm guessing you've never had to find the source of a bug via git bisect.
- ahaferburg 7y agoI'm not very experienced with git. I use `git rebase` to pull changes from a remote into my private repo in order to prepare pushing my changes. My understanding of rebase is that it takes a commit history with one parent and replays them all onto a different parent. So I don't understand how rebasing would destroy history. Could someone explain what the issue is?