Most active commenters
  • keybored(6)
  • mdaniel(4)
  • necovek(3)
  • ervine(3)

←back to thread

362 points mmphosis | 29 comments | | HN request time: 1.828s | source | bottom
1. simonw ◴[] No.42165792[source]
On commit size:

> You just never know when you have to revert a particular change and there's a sense of bliss knowing where you introduced a bug six days ago and only reverting that commit without going through the savagery of merge conflicts.

This is key for me: a good shape to aim for with a commit is one that can be easily reverted.

replies(7): >>42165815 #>>42166356 #>>42166417 #>>42166427 #>>42166824 #>>42167218 #>>42167574 #
2. charles_f ◴[] No.42165815[source]
A trick to help doing that, when you start having multiple changes that could be distinct commits, use git add --patch to select the changes one by one. Not only that can allow you to create smaller changes, it also gives you an opportunity to review your code before you commit
replies(2): >>42165883 #>>42167379 #
3. JoshTriplett ◴[] No.42165883[source]
Agreed, but after decomposing the change into logical commits, doublecheck that the project builds after each commit.
replies(1): >>42165954 #
4. do_not_redeem ◴[] No.42165954{3}[source]
Or even better, set up a pre-commit hook so that happens automatically.
replies(2): >>42166337 #>>42167243 #
5. s4i ◴[] No.42166337{4}[source]
Or even better, do that in CI.
replies(2): >>42166794 #>>42167705 #
6. majormajor ◴[] No.42166356[source]
I've not seen "roll back a bug by reverting a single commit" be a viable option nearly as much as "roll back by manually changing the buggy part," especially for bugs six days old (or older).

It's usually too hard, regardless of what your commits look like individually, to revert "just one buggy small bit" without breaking the rest of the new feature that was supported by that change, or re-introducing an old bug, or having other inconsistent resulting behavior. And "turn off the whole feature" is rarely desirable unless the bug is producing truly catastrophic behavior.

A roll-forward "just fix that bug" is the ideal case. A more complex "roll forward and make a kinda involved fix" is common too. But neither of those regress things from a user or consumer POV.

replies(2): >>42167355 #>>42181410 #
7. patrick451 ◴[] No.42166417[source]
Unless all your features actually fit in one small commit, this doesn't work. Much more common is that you merge a chain of dependent commits, which means you cannot just rollback a single commit, since that will leave your codebase hopelessly broken. Much cleaner to commit the entire feature as one large commit.
replies(2): >>42167264 #>>42167433 #
8. thenoblesunfish ◴[] No.42166427[source]
You don't have to literally revert the commit, but it will make it easier to write commit to undoy plus aiming for this means your commits will be well-contained and reviewable, which is also good.
9. mdaniel ◴[] No.42166794{5}[source]
As someone who works in small companies, and had to endure developers who were using gitlab as "offsite backup" or I guess "push-based 'does this compile?' workflow", please don't do this. CI minutes are rarely free, and for damn sure are not "glucose free". If you can't be bothered to run the local compilation step for your project, that is a wholly different code smell
10. mdaniel ◴[] No.42166824[source]
I agree with this, as well as the $(git add -p) suggestion, which JetBrains tools make super-duper easy, but my reasoning is not for reverts but for cherry-pick. I can count on one hand the number of meaningful reverts I've seen, but have innumerable examples of needs to cherry-pick. I admit that will heavily depend upon the branching style used in the project, but that's my experience
replies(1): >>42167256 #
11. keybored ◴[] No.42167218[source]
I try to do that for legibility and because it’s easier to combine commits than to split them (that’s just how git is). Revertability is pretty meh. It’s nice when you get to revert a single commit and hotfix/solve the problem. But with these commit sizes you hardly save any time that way.
12. keybored ◴[] No.42167243{4}[source]
Stalling a commit for more than a third of a second is way too much.
replies(1): >>42167694 #
13. keybored ◴[] No.42167256[source]
Cherry-pick is the copy-paste of VCS. And although copy-paste in code can work, copy-paste at the version control level itself is suspect if we’re talking about long-term history (why copy the changes of a commit?).
replies(1): >>42167312 #
14. keybored ◴[] No.42167264[source]
You can rollback a merge if that is the goal of this one-large-commit.
replies(1): >>42180843 #
15. mdaniel ◴[] No.42167312{3}[source]
There is a small distinction between copy-paste, which short of using static analysis tooling is undetectable, versus $(git cherry-pick) which is tracked copy-paste

Contrast:

  git checkout -b feat-1
  echo 'awesome change' > README.md
  git commit -am'fix'
  git checkout main
  git checkout -b feat-2
  echo 'awesome change' > README.md
  git commit -am'moar awesome fix'
  git checkout main
  git merge feat-1
  git merge feat-2
with its cherry-pick friend

If one is curious why in the world multiple branches would need the exact same commit, I'm sure there are hundreds of answers but the most immediate one is CI manifests are per-branch so if one needs a change to CI, I would a thousand times rather $(for b in $affected_branches; do git checkout $b; git cherry-pick $my_awesome_ci_fix; done) which will survive those branches re-joining main

replies(1): >>42168245 #
16. necovek ◴[] No.42167355[source]
Yeah, a rollback might be unfeasible for most things, but more "atomic" commits allow anyone handling an issue to better understand the reasoning behind any change, and if something was amiss in that particular change.
17. necovek ◴[] No.42167379[source]
Also look up at any one of the "stacked branches" approaches (plenty of git extensions or tutorials that work natively with newer git versions).

For those still in bzr land, there used to be a wonderful "bzr-pipelines" plugin to enable seamlessly working on a set of interdependent changes.

18. necovek ◴[] No.42167433[source]
If your "features" don't fit in one small commit, you should probably look to redefine what "features" are or at least not tie them to a commit.

You can and should split your features into a series of product/codebase improvements that end up delivering the full "feature" with the last of your commits. If done smartly, along the way, you'll be delivering parts of the feature so your users would start benefiting sooner.

19. jamietanna ◴[] No.42167574[source]
Related: https://news.ycombinator.com/item?id=40949229
20. ervine ◴[] No.42167694{5}[source]
Slightly-longer commits to have never-broken commits... hmmmmmm.
replies(2): >>42168168 #>>42170498 #
21. ervine ◴[] No.42167705{5}[source]
Not for things like type / lint / formatting errors. Tests too if not too long.

I mean have them in the CI as well, but for sure have them as pre-commit hooks.

22. Izkata ◴[] No.42168168{6}[source]
If you hit a full second, that's just right back to the svn days where there was just enough friction people wouldn't bother to commit until everything was completely done, then the commit would often be too big to easily describe why things were done in the commit message.
replies(2): >>42168174 #>>42168289 #
23. JoshTriplett ◴[] No.42168174{7}[source]
I don't think taking one second to commit is a problem. However, verifying that software builds typically takes a lot longer than a second.
24. Izkata ◴[] No.42168245{4}[source]
> Merge made by the 'recursive' strategy.

There's a few things people think git tracks that it actually doesn't, instead it compares diffs and presents the user with extra information that looks like tracking. The go-to example is renaming files, there is a "git mv" but it doesn't actually track the rename. Git reconstructs the rename when looking at history based on if there was a file removed and a file added in the same commit that are some percentage the same.

In this case, if that last line was "git cherry-pick feat-2", it does the same (or at least similar) comparisons as "git merge feat-2", but errors because the user would expect cherry-pick to create a new commit and in this case it won't, instead presenting a message asking the user how to continue.

replies(1): >>42168436 #
25. ervine ◴[] No.42168289{7}[source]
Huh, I guess we have different expectations. I really don't mind a few seconds even to know I didn't totally break things in a commit.
26. mdaniel ◴[] No.42168436{5}[source]
Fine, I may be guilty of "coding in a textarea" and obviously did not actually open a terminal and execute those instructions. But I hope a reasonable person could agree that manually redoing a change to .gitlab.yml over and over is not reasonable, regardless of whether git is smart enough to realize what has gone on or not
27. keybored ◴[] No.42170498{6}[source]
Second-order effects. Longer to commit means less commits which means more grab-bag commits which means less useful commits.
28. keybored ◴[] No.42180843{3}[source]
More precisely: you can revert a merge.
29. gabeidx ◴[] No.42181410[source]
The way I frame it is less of rollback, more of bisect: If I have to use `git bisect` to find a problem's root cause, will this commit be enough?

Make it bisectable and life will be easier down the line.