I didn't even see that this post got any comments/views on HN - thanks for all of the comments, I've just updated it and hopefully the issues with the colours should be fixed now :)
A disadvantage of git add -p is that it allows you to create a commit that never existed on the development system, and, hence, cannot have been tested.
How do people handle that? One way would be to follow it up with git stash, running tests, and, if necessary, git amend, but that can get cumbersome soon.
It hasn't been an issue in my experience at $DAY_JOB, but for us all commits must pass CI and not just the tip of whatever branch was just pushed. So branches with partial commits that fail CI cannot be merged. So if you commit an incorrect partial commit, you either squash it into a commit that does pass CI (usually the next one forward) or you rebase and edit the failed commit and fix it and force push your branch and run CI on the whole changeset again.
>A disadvantage of git add -p is that it allows you to create a commit that never existed on the development system, and, hence, cannot have been tested.
The things you commit can always be different from what you test. In fact, if you know what you are doing, it is a feature to be able to create commits like this without testing. I certainly don't need to test my "Fixed typo in comments" commits...
>How do people handle that? One way would be to follow it up with git stash, running tests, and, if necessary, git amend, but that can get cumbersome soon.
Well, your CI system should be testing for you. But if you must test it locally, `git rebase` can either pause between steps or execute commands between steps. Finish making commits. If you made, say, 3 commits, then do `git rebase -i HEAD~3` and do break/exec as desired.
This is one place jj really shines. Using jj new to quickly switch to a new change makes it easier to not drop flow but still break up work. You can come back later and add descriptions or reorder and squash. That way, you don't get into as many situations where splitting a commit is necessary. For those that remain, jj split works well.
Your mileage may vary, because the workflow you described does not suit me. I rarely want to put on hold my commit, work on a new one, then go back later to the former commit.
Most of the time, when working on a new commit I have a few changes related to recent commits. So _when I'm done with all that_, I commit selectively the new work, then dispatch the rest among the other commits:
git add -p ; git commit
git add -u ; git absorb
Sometimes, I use `commit --fixup` instead of the automatic `absorb`. Anyway, I tried Jujutsu for a few weeks, some was good and some was bad; it didn't "shine" enough and I went back to pure Git.
I’ve looked at jj, but couldn’t make sense of the proposed benefits. I always stage individual files and never the entire working directory, so I’m confused how it improves that over git.
I almost exclusively use add -p. It's another moment to review my changes and it saves me from having to type out the names of the files I've changed. I don't know if I've ever committed a file unintentionally since adopting it.
I like it especially in concert with git commit --amend, which lets me tack my newest changes onto the previous commit. (Though an interactive rebase with fixup is even better)
> I don't know if I've ever committed a file unintentionally since adopting it.
I’ve had the opposite problem: forgetting to add new files.
> I like it especially in concert with git commit --amend, which lets me tack my newest changes onto the previous commit. (Though an interactive rebase with fixup is even better)
No need for the rebase to be interactive:
$ git commit --fixup=<commit>
$ git rebase --autosquash <base>
Another excellent GUI is gitg. You can select specific lines for staging, but also for discarding. The latter is especially useful for temporary debug only changes that you want to throw away.
What's wrong with a big end of day commit? Sure, a well crafted git history can be very valuable. But then comes somebody and decides to just flush your well curated history down the toilet (=delete it and start somewhere else from scratch) and then all the valuable metadata stored in the history is lost.
Maybe consider putting your energy into a good documentation inside the repository. I would love to have more projects with documentations which cover the timeline and ideas during development, instead of having to extract these information from metadata - which is what commit messages are, in the end.
> But then comes somebody and decides to just flush your well curated history down the toilet (=delete it and start somewhere else from scratch) and then all the valuable metadata stored in the history is lost.
How does this happen? I haven't run into this.
> Maybe consider putting your energy into a good documentation inside the repository
I'd say both are valuable.
I use git log and git blame to try to understand how a piece of code came to be. This has saved me a few times.
Recently, I was about to replace something strange to something way more obvious to fix a rendering issue (like, in some HTML, an SVG file was displayed by pasting its content into the HTML directly, and I was about to use an img tag to display it instead), but the git log told me that previously, the SVG was indeed displayed using an img tag and the change was made to fix the issue that the links in the SVG were not working. I would have inadvertently reverted a fix and caused a regression.
I would have missed the reason a code was like this with a big "work" end of the day commit.
It would have been better if the person had commented their change with something like "I know, looks weird, but we need this for the SVG to be interactive" (and I told them btw), but it's easy to not notice a situation where a comment is warranted. When you've spent a couple of hours in some code, your change can end up feeling obvious to you.
The code history is one of the strategies to understand the code, and meaningful commits help with this.
When working on a feature branch it can be useful to break up your changes into logical commits. This gives you the flexibility to roll back to an earlier iteration when still working on the feature if needed.
One of my git habits is to git reset the entire feature branch just before opening a PR, then rebuild it with carefully crafted commits, where i try to make each commit one "step" towards building the feature. This forces me to review every change one last time and then the person doing code review can also follow this progression.
These benefits hold even if the branch ultimately gets squashed when merging into main/master. I also found that even if you squash when merging you can still browse back to the PR in your git repository web UI and still see the full commit history there.
It's useless for all but the code preservation part, it doesn't tell you anything.
> But then comes somebody and decides to just flush your well curated history down the toilet (=delete it and start somewhere else from scratch) and then all the valuable metadata stored in the history is lost.
I would be very angry if someone deletes my work, why would I accept that? When my colleague throws my work into the bin, I will complain to my superior, they pay me for it after all.
> Maybe consider putting your energy into a good documentation inside the repository. I would love to have more projects with documentations which cover the timeline and ideas during development
That's what commit messages are? They provide the feature that you can click on any line in your codebase and get an explanation, why that line is there, what it is supposed to do, and how it came to be. That's very valuable and in my opinion, much more useful than a static standalone documentation.
First you think of commits as backups, then you think of them as a code distribution. Later you see them as a way to record time. What has been a useful insight to me was, what time is a prerequisite to: causality. Now I see that a VCS is less about recording actual history, but about recording evolution dependency, causality and intent. Also I perceive my work less to be about producing a final state of a codebase, but about producing part of the history of a codebase. My work output is not a single distribution of code, but documented, explainable and attributed diffs, i.e. commits.
Atomic commits compose easier. In case you want to pull a few out to ship as their own topic. Or separate out the noisy changes so rebases are quicker. Separate out the machine-generated commit so you can drop it and regenerate it on top of whatever.
My commit messages are pretty basic “verbed foo” notes to myself, and I’m going to squash merge them to mainline anyway. The atomic commits, sometimes aided by git add -p, are to keep me nimble in an active codebase.
> Maybe consider putting your energy into a good documentation inside the repository.
Commit messages are documentation.
If you have a good commit history you don't need write tons of documents explaining each decision. The history will contain everything that you need, including: when and who changed the code, what was the code change and why the code exists. You have a good interface for retrieving that documentation (git log, perhaps with -S, -G, --grep, -L and some pathspecs) without needing to maintain extra infrastructure for that and without being cluttered over time (it will be mostly hidden unless you actively search that). You also don't need to remember to update the documents, you are forced to do that after each commit.
For me the point of splitting commit is not for documentation (though it can be an added benefit). It is so that you can easily rollback a feature, or cherry pick, it also makes the use of blame and bisect more natural. Anyways, that's git, it gives you a lot of options, do what you want with them. If a big end-of-day commit is fine for you, great, but some people prefer to work differently.
But that's not actually the reason I use "git add -p" the most. The way I use it is to exclude temporary code like traces and overrides from my commits while still keeping them in my working copy.
if commit messages are meaningful and the commits are well crafted (with the help of git add -p for example) this documentation can be generated from the metadata ;P
Also, big end of day commits normally cover multiple different fixes. Which is, I hope you can understand, not very nice to have in one big commit.
If someone else decides your implementation of something is not good enough, and they manage to get enough buy-in to rewrite it from scratch, maybe they were right to start with?.
And if your history is not clear about the why of your changes, you have 0 to defend your work
Hoo boy I guess you never tried to use `git blame` on years-old shit huh? Don't push a commit for every line, but for logical units like one particular feature or issue.
>But then comes somebody and decides to just flush your well curated history down the toilet (=delete it and start somewhere else from scratch) and then all the valuable metadata stored in the history is lost.
This doesn't just accidentally happen. There are tools to migrate repositories and to flush ancient commits in huge repositories. If you curate your commit history, this is probably never necessary, or may only become necessary after decades.
>Maybe consider putting your energy into a good documentation inside the repository.
Commit messages are documentation for code, basically. `git blame` associates the messages with individual lines and lets you step through all the revisions.
>I would love to have more projects with documentations which cover the timeline and ideas during development, instead of having to extract these information from metadata - which is what commit messages are, in the end.
The commit messages are for detailed information, not so much for architectural or API documentation. This doesn't mean you should get rid of commit metadata! Eventually, you will find a situation where you wonder what the hell you or someone else was doing, and the commit message will be a critical piece of the puzzle. You can also leave JIRA links or whatever in the message, although that adds a dependency on JIRA for more details.
I've been using this UI git diff add script for years: https://github.com/ismell/diffadd
I think it works better then the TUI. Surprised something like it hasn't landed in upstream git.
for one, it lets me create small patches of related stuff. There's nothing wrong with major patchsets in general but it makes it harder to cherry-pick little fixes to old stable branches for example
two, I notice other developers making me do the work for them because crap sneaks into their commits, like debugging statements or accidentally removed hunks. Instead I have to do "git add -p" when reviewing their commit.
Essentially, it's a first pass staging area you can review what you did. beautiful.
I've been using lazygit [https://github.com/jesseduffield/lazygit] which is a friendly TUI that makes selecting which lines to commit relatively painless. As a heavy user of hunk-by-hunk or line-by-line commits, I used to use tortoisehg, but on my current distro its showing some bitrot, so I decided to try something else.
Is there any tool that allows you to pass the line numbers that you want to stage as arguments to the command, instead of having to do it interactively?
My two favourite bits of git add -p that aren't mentioned here:
the / (search) command to search unstaged hunks for a specific keyword rather than having to jump through all the individual changes you've made when there's lots.
and the e (edit) command to manually split out two changes that end up in one hunk that I'd rather have in individual commits.
I love Zed editor's git UI for this. If you click on the left gutter of a hunk, it opens a little interface in the top right corner that lets you either Stage or Restore that hunk.
poly2it|2 months ago
fixedprog|2 months ago
ellisv|2 months ago
Someone|2 months ago
How do people handle that? One way would be to follow it up with git stash, running tests, and, if necessary, git amend, but that can get cumbersome soon.
throwaway613745|2 months ago
wakawaka28|2 months ago
The things you commit can always be different from what you test. In fact, if you know what you are doing, it is a feature to be able to create commits like this without testing. I certainly don't need to test my "Fixed typo in comments" commits...
>How do people handle that? One way would be to follow it up with git stash, running tests, and, if necessary, git amend, but that can get cumbersome soon.
Well, your CI system should be testing for you. But if you must test it locally, `git rebase` can either pause between steps or execute commands between steps. Finish making commits. If you made, say, 3 commits, then do `git rebase -i HEAD~3` and do break/exec as desired.
1718627440|2 months ago
hbogert|2 months ago
franky47|2 months ago
pseufaux|2 months ago
idoubtit|2 months ago
Most of the time, when working on a new commit I have a few changes related to recent commits. So _when I'm done with all that_, I commit selectively the new work, then dispatch the rest among the other commits:
Sometimes, I use `commit --fixup` instead of the automatic `absorb`. Anyway, I tried Jujutsu for a few weeks, some was good and some was bad; it didn't "shine" enough and I went back to pure Git.minton|2 months ago
kevinmchugh|2 months ago
I like it especially in concert with git commit --amend, which lets me tack my newest changes onto the previous commit. (Though an interactive rebase with fixup is even better)
spider-mario|2 months ago
I’ve had the opposite problem: forgetting to add new files.
> I like it especially in concert with git commit --amend, which lets me tack my newest changes onto the previous commit. (Though an interactive rebase with fixup is even better)
No need for the rebase to be interactive:
howToTestFE|2 months ago
felubra|2 months ago
rogerbinns|2 months ago
andrewshadura|2 months ago
kapacuk|2 months ago
ktpsns|2 months ago
Maybe consider putting your energy into a good documentation inside the repository. I would love to have more projects with documentations which cover the timeline and ideas during development, instead of having to extract these information from metadata - which is what commit messages are, in the end.
jraph|2 months ago
How does this happen? I haven't run into this.
> Maybe consider putting your energy into a good documentation inside the repository
I'd say both are valuable.
I use git log and git blame to try to understand how a piece of code came to be. This has saved me a few times.
Recently, I was about to replace something strange to something way more obvious to fix a rendering issue (like, in some HTML, an SVG file was displayed by pasting its content into the HTML directly, and I was about to use an img tag to display it instead), but the git log told me that previously, the SVG was indeed displayed using an img tag and the change was made to fix the issue that the links in the SVG were not working. I would have inadvertently reverted a fix and caused a regression.
I would have missed the reason a code was like this with a big "work" end of the day commit.
It would have been better if the person had commented their change with something like "I know, looks weird, but we need this for the SVG to be interactive" (and I told them btw), but it's easy to not notice a situation where a comment is warranted. When you've spent a couple of hours in some code, your change can end up feeling obvious to you.
The code history is one of the strategies to understand the code, and meaningful commits help with this.
ViVr|2 months ago
One of my git habits is to git reset the entire feature branch just before opening a PR, then rebuild it with carefully crafted commits, where i try to make each commit one "step" towards building the feature. This forces me to review every change one last time and then the person doing code review can also follow this progression.
These benefits hold even if the branch ultimately gets squashed when merging into main/master. I also found that even if you squash when merging you can still browse back to the PR in your git repository web UI and still see the full commit history there.
1718627440|2 months ago
It's useless for all but the code preservation part, it doesn't tell you anything.
> But then comes somebody and decides to just flush your well curated history down the toilet (=delete it and start somewhere else from scratch) and then all the valuable metadata stored in the history is lost.
I would be very angry if someone deletes my work, why would I accept that? When my colleague throws my work into the bin, I will complain to my superior, they pay me for it after all.
> Maybe consider putting your energy into a good documentation inside the repository. I would love to have more projects with documentations which cover the timeline and ideas during development
That's what commit messages are? They provide the feature that you can click on any line in your codebase and get an explanation, why that line is there, what it is supposed to do, and how it came to be. That's very valuable and in my opinion, much more useful than a static standalone documentation.
First you think of commits as backups, then you think of them as a code distribution. Later you see them as a way to record time. What has been a useful insight to me was, what time is a prerequisite to: causality. Now I see that a VCS is less about recording actual history, but about recording evolution dependency, causality and intent. Also I perceive my work less to be about producing a final state of a codebase, but about producing part of the history of a codebase. My work output is not a single distribution of code, but documented, explainable and attributed diffs, i.e. commits.
a13o|2 months ago
My commit messages are pretty basic “verbed foo” notes to myself, and I’m going to squash merge them to mainline anyway. The atomic commits, sometimes aided by git add -p, are to keep me nimble in an active codebase.
lucasoshiro|2 months ago
Commit messages are documentation.
If you have a good commit history you don't need write tons of documents explaining each decision. The history will contain everything that you need, including: when and who changed the code, what was the code change and why the code exists. You have a good interface for retrieving that documentation (git log, perhaps with -S, -G, --grep, -L and some pathspecs) without needing to maintain extra infrastructure for that and without being cluttered over time (it will be mostly hidden unless you actively search that). You also don't need to remember to update the documents, you are forced to do that after each commit.
And that's not a hack, Git was made for that.
GuB-42|2 months ago
But that's not actually the reason I use "git add -p" the most. The way I use it is to exclude temporary code like traces and overrides from my commits while still keeping them in my working copy.
mvanbaak|2 months ago
If someone else decides your implementation of something is not good enough, and they manage to get enough buy-in to rewrite it from scratch, maybe they were right to start with?. And if your history is not clear about the why of your changes, you have 0 to defend your work
wakawaka28|2 months ago
Hoo boy I guess you never tried to use `git blame` on years-old shit huh? Don't push a commit for every line, but for logical units like one particular feature or issue.
>But then comes somebody and decides to just flush your well curated history down the toilet (=delete it and start somewhere else from scratch) and then all the valuable metadata stored in the history is lost.
This doesn't just accidentally happen. There are tools to migrate repositories and to flush ancient commits in huge repositories. If you curate your commit history, this is probably never necessary, or may only become necessary after decades.
>Maybe consider putting your energy into a good documentation inside the repository.
Commit messages are documentation for code, basically. `git blame` associates the messages with individual lines and lets you step through all the revisions.
>I would love to have more projects with documentations which cover the timeline and ideas during development, instead of having to extract these information from metadata - which is what commit messages are, in the end.
The commit messages are for detailed information, not so much for architectural or API documentation. This doesn't mean you should get rid of commit metadata! Eventually, you will find a situation where you wonder what the hell you or someone else was doing, and the commit message will be a critical piece of the puzzle. You can also leave JIRA links or whatever in the message, although that adds a dependency on JIRA for more details.
yx827ha|2 months ago
calvinmorrison|2 months ago
for one, it lets me create small patches of related stuff. There's nothing wrong with major patchsets in general but it makes it harder to cherry-pick little fixes to old stable branches for example
two, I notice other developers making me do the work for them because crap sneaks into their commits, like debugging statements or accidentally removed hunks. Instead I have to do "git add -p" when reviewing their commit.
Essentially, it's a first pass staging area you can review what you did. beautiful.
gary_0|2 months ago
prodigycorp|2 months ago
philo23|2 months ago
the / (search) command to search unstaged hunks for a specific keyword rather than having to jump through all the individual changes you've made when there's lots.
and the e (edit) command to manually split out two changes that end up in one hunk that I'd rather have in individual commits.
littlecranky67|2 months ago
RunningDroid|2 months ago
https://archive.today/Ig42c (has issues with Cloudflare DNS)
https://web.archive.org/web/20251214151943/https://techne98....
vermon|2 months ago
petepete|2 months ago
ethmarks|2 months ago
Brian_K_White|2 months ago
fixedprog|2 months ago
EstanislaoStan|2 months ago
Lol or they could use VSCode's integrated source control and stage stuff manually that way. Both are better than bare `git add -p` in my opinion.
s1mplicissimus|2 months ago
tome|2 months ago
yjftsjthsd-h|2 months ago
fixedprog|2 months ago
jyscao|2 months ago
There are many other plugins for vim and emacs (e.g. magit) that enhance one’s git workflow.
vim-guru|2 months ago
miduil|2 months ago
unknown|2 months ago
[deleted]