Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Writing the good quality commit message is not that hard and is sometimes actually enjoyable (after all i get to brag about this feature / bugfix / solution).

What does cause a lot of mental overhead (and consider myself a decent engineer) is creating commits that have a single purpose in the first place.

Working on a new feature I often have to refactor something, and while I am at it, I clean up some related parts. That is at the minimum 3 commits applied in the correct order, sometimes over different branches. At that point there is a lot of `git add -p` and `git stash apply` going on, which takes considerably more mental energy while you see some colleagues getting away with `git commit -a`.

Writing good commit messages itself is the reward for creating good commits.



This is why I work in graphical clients (GitKracken being my current preference). They make interactive staging of individual files or lines utterly trivial.

I do partial commits significantly more often than committing everything, and often do things like a couple commits, checkout another branch (and GitKracken does an auto stash + apply) then commit a separate fix there before switching back to the original branch.

Also there are several other things it makes easier: being able to multi-select commits and see a combined diff, quicky diff between two random branches, and just generally browsing back through history. And importantly, it's easy to do all this without having to remember, copy/paste or type any branch names or commit hashes.


Just an FYI if you ever lack access to GitKraken Git gui does line by line staging. It is not as pretty but it works well.


I'd say it's also not as functional. With a GUI you can click around and browse through other files, as well as stage/unstage with the same interface.

With the CLI, all you can do is cycle through "Stage this hunk [y,n,q,a,d,e,?]?" prompts, and if you mess up, you have to exit completely and do `git reset --patch` and cycle through those prompts again (at least, I don't know another way to do that). Actually it's a bit worse because it has even more options:

    Unstage this hunk [y,n,q,a,d,j,J,g,/,s,e,?]? ?
    y - unstage this hunk
    n - do not unstage this hunk
    q - quit; do not unstage this hunk or any of the remaining ones
    a - unstage this hunk and all later hunks in the file
    d - do not unstage this hunk or any of the later hunks in the file
    g - select a hunk to go to
    / - search for a hunk matching the given regex
    j - leave this hunk undecided, see next undecided hunk
    J - leave this hunk undecided, see next hunk
    s - split the current hunk into smaller hunks
    e - manually edit the current hunk
    ? - print help
If you use this all the time and get used to the commands, and are also good at picturing the separate pieces you are trying to commit in your head, it's probably fully functional.

If you're like me, and come back to your code after an unrelated 1hr meeting (or lunch) and are trying to sort out the 3 or 4 separate changes you did earlier in the day to make nice logical commits... good luck.


> With the CLI, all you can do is cycle through "Stage this hunk [y,n,q,a,d,e,?]?" prompts, and if you mess up, you have to exit completely and do `git reset --patch` and cycle through those prompts again (at least, I don't know another way to do that). Actually it's a bit worse because it has even more options ...

You can get a hybrid of the two if you use commands like recountdiff (from patchutils) and git-apply --cached. I do this by reading the output of git diff into vim, editing diff hunks and running recountdiff on those hunks, and running git-apply --cached. If I mess up, I can always read the output of git diff --cached and run git-apply -R --cached to unstage that hunk.

I find it better than using the CLI menu driven tool that you refer to.


Git gui is a GUI that is part of the core git product...


Oh! Wow, sorry, I didn't even know that existed (run `git gui` to view). Thanks!

And you're right: it's completely functional for doing partial commits, but I agree definitely not as pretty.


Rather than `git add -p`, I suggest creating a second clone of your repo, staging your foundational refactor changes in the second repo, creating and merging your commits there, and then rebasing your working branch.

This makes sure you can fully test your refractors and that their change sets stand alone.


If you know your way around git well enough that you're not going to be screwing up repository state in ways you can't fix, there's no reason to operate from separate clones - check out git worktrees :)


Thanks for that! I've occasionally thought a feature like this would be possible and helpful, but hadn't encountered it until your mention.


I felt the same way when I stumbled across it in a man page :)


I use long-running git rebase -i with a line like “x false” to pause the rebase, run tests or finish packaging the refactor, then git rebase --continue.


YES. It's very easy to write good commit messages; what's much harder is making "good" (as in: atomic, understandable) commits. I know I'm just restating what you said, but...I just agree very strongly.


Part of the problem is it's not obvious why you need to do this until you need it, at which point it's too late.

Reasons include: understanding how a change works (all related code in one place without extra distraction), easy to revert, easy to figure out why that code is there during a blame.


> What does cause a lot of mental overhead (and consider myself a decent engineer) is creating commits that have a single purpose in the first place.

That's why I typically write code where I implement a feature and then go through the diff to determine what to stage and what goes into each commit. Trying to do this while implementing something isn't really something that's worthwhile.


> What does cause a lot of mental overhead (and consider myself a decent engineer) is creating commits that have a single purpose in the first place.

I agree, this is what demonstrates maturity in an engineer. Perhaps we need to focus on commit driven development.

I personally do not allow teammates to ship macro commits covering multiple features. I call this out in code review process.


Staging individual lines and hunks is unbelievably easy with a good git GUI. I don't know how people work without one.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: