[HN Gopher] The Perfect Commit ___________________________________________________________________ The Perfect Commit Author : todsacerdoti Score : 52 points Date : 2022-10-29 20:52 UTC (2 hours ago) (HTM) web link (simonwillison.net) (TXT) w3m dump (simonwillison.net) | wellpast wrote: | Going to express a counterpoint. | | Maintainable/malleable software is mostly to due with the | architecture of the code at any given point in time, not the | sequence of commits that got it there. (I'll take all N,000 | commits collapsed into one with a message "Stuff" if the code is | well-articulated than a series of perfect commits that culminate | into a highly coupled volatile system.) | | Furthermore, I'll posit that these "perfect commits" have a | tendency to trend toward overall bad code architecture. Primarily | because the attention flashlight is being shined on the wrong | then (the delta as opposed to the resultant codebase). In the | course of working on a system I'll often earmark code | decoupling/cleanup as part of a commit. Or move to get cleanup in | quickly so that my general feature/value delivery is achieved. | But processes that focus attention on commits (like this "perfect | commit" and also formal code review processes) discourage this | kind of continuous cleanup/refactoring that is the only way to | get to good code. | Waterluvian wrote: | Raise your hand if commits are mainly just a way to save | progress. It can't just be me. | | I appreciate that needs differ between projects. In some public | project I'd be more disciplined. But at work I just commit like a | madman and collapse them all automatically upon merge. | ISL wrote: | The key world is "mainly". If things go wrong, you haven't just | saved progress, but also saved history. That distinction is | powerful. | Waterluvian wrote: | Indeed. A clean history can be helpful. And this is certainly | context specific. In my experience it hasn't been as useful | as the cost to do so, so I've relaxed a bit on making my | commits carefully. | [deleted] | harryvederci wrote: | For work it's different, but for my side project: | $ git log --pretty=oneline | wc -l # Total amount of commits. | 1369 $ git log | grep '^ \.$' | wc -l # Count | commits with a message of "." 902 | [deleted] | tkiolp4 wrote: | Here. I have a colleague obsessed with the "perfect" commit, | with rebase instead of fast forward merges and what not. Can't | stand it. I do care about writing a good summary commit title | that includes the Jira issue number that links to a well | description of the feature/issue at hand. | vsviridov wrote: | "Link to issue for context" | | Just no... | | Why would you decouple the change from its context? Just add all | the relevant information to the commit message itself, so it's | preserved. | | I follow my friend's approach which works really well. | | https://yrashk.medium.com/solving-problems-one-commit-at-a-t... | | Too many a times I had to do code archeology to encounter | archived Jira or some old space I don't have permissions for, | that was originally migrated from GitHub issues and all the | ticket numbers are in complete mismatch. | simonw wrote: | You can't put screenshots in a commit message. | | You also can't update a commit message after you've pushed it. | | Agreed though that you shouldn't work like this if you can't | trust your organization to reliably archive your issue threads! | Salgat wrote: | Both Github and Bitbucket support all of that in the PR, so | if necessary, update your PR with additional | comments/information. When I'm looking at a change, I always | go back to the PR anyways since it provides discussion | relevant to the change. | simonw wrote: | Yeah I sometimes use a PR in place of an issue thread for | this kind of thing, because PRs support the exact same | comment system that I find so valuable in issues. | sjansen wrote: | > Why would you decouple the change from its context? | | The issue is the context. | | At work, we require a link to the issue/story because it makes | SOC2 audits much easier. The commit message is a great place to | explain the chosen implementation, but that's not all there is | to software development. | | It rarely makes sense to repeat in commits how the issue was | reported, or why it was given a specific priority. And it can't | track anything after merge, like how the change was tested, or | whether the change was communicated to users. | | Maybe you don't have to deal with auditors. Maybe your work has | different processes to keep them happy. But as far as I'm | concerned, is it important to link the issue for context? Yes! | Just yes. | [deleted] | [deleted] | thunky wrote: | > Sometimes I'll even open an issue seconds before writing the | commit message, just to give myself something I can link to from | the commit itself! | | IMO generally an issue should precede an implementation - it | should track _future_ work to completion, not work that is | already complete. | | Creating a new issue and then immediately closing it is an anti- | pattern, in the same way that creating a pull request and | immediately merging it is. | simonw wrote: | Most of my work has an issue created at the start of the | development process and closed with the final commit. | | But occasionally I'll miss that step - maybe I dived straight | in to fix a new bug without taking the time to open the issue | first. | | This are the cases where I'll open an issue at the last | possible moment - on the basis that an open-and-shut linked | issue is still better than a bug fix with no associated issue | at all. | thunky wrote: | > an open-and-shut linked issue is still better than a bug | fix with no associated issue at all | | It sounds like your issue tracker is a part time | documentation repository. | | I think I view this as an anti-pattern because I look at the | issue tracker as a shared collaboration tool for planning & | tracking, not as a tool to document all code changes. | | For example, if I were solo I'd probably never create an | issue (or a pull request). | simonw wrote: | > It sounds like your issue tracker is a part time | documentation repository. | | Yeah, it's exactly that. | | I'm planning to write more about this. Basically I've | started thinking of issues as "temporaral documentation" - | documentation with an attached timestamp that was known to | be accurate only at the point when it was written. | | A challenge with regular documentation is that when you | first write it you are making a commitment to keep it up- | to-date in the future. A project with thousands of pages of | outdated documentation isn't much better than a project | with no documentation at all (it might even be worse). | | But a project with thousands of pages of timestamped issue | comments feels different to me: there's no expectation that | those will be updated in the future, but they still offer | enormous value in terms of capturing the decisions that | lead to the present day. | | So yes: I do consider my issues as a form of documentation. | They're not a replacement for traditional documentation, | but they're a valuable extension to it. | pkrumins wrote: | My definition of a perfect commit is any commit that goes to | production because only shipping matters. | mejutoco wrote: | Instead of downvoting I am giving my opinion: if you really | believed this you would not be using version control. | | P.S. I am assume you do, since you mention commits. | Supermancho wrote: | > if you really believed this you would not be using version | control. > P.S. I am assume you do, since you mention | commits. | | That's circular logic, at best. This is about the label given | to "perfect" commit(s), for which someone has made an | arbitrary qualitative list of attributes. The GP has a | different qualitative list. | [deleted] | fernandotakai wrote: | at the end of the day, i work to make customers productive and | happy, so the perfect commit is the one that moves the product | towards that goal. | Salgat wrote: | Which includes a sensible (but not excessive) approach to | avoiding technical debt that inhibits future functionality | and feature generation. | simonw wrote: | Probably should have mentioned that in the post: a benefit of | working this way - in particular bundling tests in the same | commit as your implementation - is that it makes it much safer | to implement continuous deployment. | | Many of my projects that use this style of commits are | configured so that code is deployed to production every time a | commit passes CI. | smcleod wrote: | Only shipping matters - _to you_ (and your product owner - but | only in the short term), in the medium to long term shipping | matters (perhaps most), but absolutely not only. | | Maintainability matters. The happiness and health of your peers | matters. Security matters. Ethics matters. | | The culture of 'only shipping matters' is reflective of the | exploitational aspirations of our capitalistic societies, it | devalues the bigger picture. | | If you only care about getting your code out the door - you're | part of the problem. | halayli wrote: | it's easy to ship but it's much harder to continue shipping | quality software with this approach. The more information in a | commit the easier it becomes for newcomers to understand the | context of what they are about to change. I sometimes end up | reading the comments of an old PR to understand why a certain | decision was made when it could have been in the commit. | | It gets worse when you have people in critical positions | backing bad software engineering practices under business | related excuses as this proves nothing but short sighted and | the fact that they aren't a good fit for the job as technical | debt is going to be waiting around the corner for payback. | quickthrower2 wrote: | That is the perfect merge commit onto trunk/main. Branch commits | can be chaotic if needed. The commit is then the unit of | "walkawayability" a checkpoint where if thing get screwy they are | happy to revert to. | thom wrote: | Somehow I'm really wary of all the energy that goes into source | control workflows and commit messages. It's all meta-information | and the only time it really matters is when something has gone | catastrophically wrong. If you genuinely have to go looking at | the history of a codebase to find out why something weird has | happened, that feels like a codebase crying out for a better | structure. New features shouldn't be major surgery, they should | be instances of established abstractions. I'm very interested in | languages that make that modularity easier but if you can't | delete your entire Git history with no negative consequences that | just seems like a disaster to me, on both an individual and | industry-wide scale. | cratermoon wrote: | > the only time it really matters is when something has gone | catastrophically wrong | | Or in other words, it matters most when it's most needed and | the recovery process is glad to have them. | | Think about the airline industry and how many times the causes | of an accident have been found in the months-old maintenance | records of an aircraft, or in an examination of pilot training | from last year. | | Now imagine throwing away all the information that could have | led to finding a cause and putting in place mechanisms and | practices to prevent a recurrence. This is how the software | industry continues to stumble over the same problems that were | known and described in the 70s. | willm wrote: | Great article. I'd like to quote it in a GitHub issue template. | | I struggle with "a single focussed change". As my coworkers will | attest. When working on new features rather than bugs, I find it | hard to say when one feature ends and another begins. Something I | need to work on! | quickthrower2 wrote: | Try to say it before coding, and probably the team should help | with chunking it down. | | Sometimes a thing cannot be chunked down more without silly | inconvenience so keep that in mind. | simonw wrote: | One thing that works for me here is to try and split the work | into changes that could be shipped to production independently | of each other. | ivix wrote: | When in a serverless environment it's easy to get into a | situation where you need to commit to deploy and test anything. | Then git squash is essential, unless you're the only developer. | g051051 wrote: | > Our job as software engineers is not to write new software: | it's to apply changes to existing software. | | Well, I could stop reading right there. | simonw wrote: | I probably should have expanded that point: I was trying to be | pithy. | | What I meant is that we spend 95% of our time making changes to | software - adding new features, fixing bugs etc. | | Starting a new project from scratch is something we might do a | few times a year at most, but changing an existing project is a | thing we do every working day. | g051051 wrote: | Adding new features is writing new software in my book. | unionpivo wrote: | Most developers add new features by modifying/adding to an | existing code/repo most of the time. | | Hell even when you create new project, a lot of development | environments provide basic scaffolding, that you then | modify (or sometimes remove 95% of). | khpart wrote: | It's Python, which is a churnfest by design. Other communities | have this problem to a lesser degree. | ecshafer wrote: | Commit basically doesn't matter to me, I think in the terms of | PR. I can make 100 commits or 1, it doesn't matter because when I | merge I squash them into a single commit that encompasses | everything. There are some exceptions, as splitting a large merge | into several smaller merges can help a lot, for example adding a | database column in a pr, then adding in a separate merge usage of | that column. | | In terms of commits, the commit message should be a good summary | of what is there. In terms of a PR there should be several | things. One is obviously tests present. The next is a what, why | and a how, which should be explanations of why you are doing it, | what the purpose is, how you are doing. Finally I think there | should be a descsription of how this should be tested manually. | simonw wrote: | Totally agree - if I'm working on a larger change I'll usually | do that in a branch, which ends up as a PR which I then squash- | merge into a "perfect commit" as described in the article. | neon_electro wrote: | This is why I now love GitHub's "squash & merge"; it | accomplishes so much of the ideals laid out in this "perfect | commit" article. | rektide wrote: | Its tragic how either/or git is. | | Both are great in different ways. If Im trying to understand a | complex tricky bit of code, a long string of small commits is | ideal. If Im browsing a repo, large squashed commits or PRs are | better. | | It's be great to have better heirarchy, to get both. | drdec wrote: | You can have both if you keep the PR branches | Twisol wrote: | This is why I follow a rebase-then-merge approach. The | commit graph looks like this: | * | |\ | * | | | * |/ * | |\ | * |/ | | | Each PR is neatly delineated, and I can quickly follow | things at coarse-grained level (follow only the left | parents; there's even a `git log` flag for this) or at a | fine-grained level. | | This isn't just pretty -- this has been _actively_ helpful | to me many, many times. I can `git bisect` into a merged PR | to more precisely identify where an issue arose, and `git | rebase` onto intermediate commits instead of jumping all | the way to the end if I find a whole PR to be problematic | to rebase past in one go. | vvillena wrote: | I also try to adopt this approach whenever possible. The | 'git log' flag you mention is '--first-parent'. | dec0dedab0de wrote: | I leave all the commits in without squashing, but filter to | only show merge commits | J-_-_b wrote: | here's 95% of all of my commit messages: "wip" | ChrisMarshallNY wrote: | I will often paste a line from the CHANGELOG.md into the | commit. | | We used to use Perforce, which forced you to write a commit | message. One of my employees used to write "asdf". It got a bit | old. I didn't care that much, myself, as he was responsible for | maintaining his own code, and he did fine, there. | | The Japanese hated it, though, and it probably played a big | part in his getting laid off. I learned a big lesson, there, | and insisted on my employees being more circumspect, after | that. | WesolyKubeczek wrote: | My perfect commits have message ,,WIP on stuff", include changes | to code coupled with formatting changes, have zero tests, nada | documentation, and no links to issues. | | But they are perfect nevertheless, because I judge them so. And | because the code works. | | Also, because I get to get out more. | airstrike wrote: | I feel seen | js2 wrote: | I wanted to get out today, but instead I spent two hours | debugging an issue because I was dealing with code from someone | who thought like you who didn't think documentation, comments, | meaningful commit messages, or tests were a good use of their | time. | | I don't care what you do with your code, but as soon as someone | else inherits it, you're a sociopath if you didn't document | anything along the way. | | And btw, the person who inherits that code may be your future | self, and you'll thank your past self for writing down why you | did something the way you did. | simonw wrote: | This post was extracted from a talk I gave at DjangoCon a few | weeks ago, which was about how this kind of workflow has | /increased/ my personal productivity by a material amount. | https://github.com/simonw/djangocon-2022-productivity | | So I get to get out more because I'm doing this! | WesolyKubeczek wrote: | You may think so ;) | js2 wrote: | Perfect commits are a bulwark against technical debt: | | https://www.infoq.com/articles/business-impact-code-quality/ | | https://news.ycombinator.com/item?id=33372016 | | The extra time spent today on crafting a perfect commit today | will save 10x that time in the future. Your future self will | thank you, and if not your future self, then I will, when I | inherit your code. | psychoslave wrote: | I very rarely check the repository history, even less to find | an answer in how some buggy behavior was introduced. | | At most I'll git blame, search the issue repository and see if | I can chat with the concerned people. | | Understanding the current relevant code and what need to be | done is basically always sufficient to do the job. Digging into | history, while potentially very interesting, never helped to | reduce the time to resolve anything in my experience. If the | code is a mess, the history will be exponentially so. If the | code base is clean and well documented, you might more likely | have a great set of "perfect commits" that you will never need. | [deleted] | quickthrower2 wrote: | History is useful because blame often get's it wrong. So it | is a manual blame. | grogers wrote: | Writing good code and writing good commits definitely | clusters together. It's part of a general pride in quality of | work, organization, and planning. | | Going back into the commit history can be useful to figure | out if something suspicious was introduced intentionally or | if it was just a mistake. Beyond about 3-6 months, the author | will generally not have any context to remember small code | details, so leaving breadcrumbs for your future self and team | can be nice. ___________________________________________________________________ (page generated 2022-10-29 23:00 UTC)