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

Use a temporary branch for those. When you come back, undo the commit (git test -- hard if memory serves but i just have an "uncommit" alias) and commit the fully finished work to the real branch.


This is destroying the "real history" though. (Which again, I'm fine with, I like rebasing.)

Two months from now I'm quite likely to say something like "oh yeah, I remember I encountered a bug related to that, I was trying to fix it before lunch". The "wip" and "before lunch" commits are just as likely to be relevant in the future as any other.

It's nice to assume that all commits will compile and pass the tests, but it's sometimes useful to have a snapshot of that weird compiler error you encountered. So much for our nice assumption.

This is why I say it's all up to the author, and if the author likes rebasing, I don't think anyone should have a problem with that. (Don't rewrite public branches, of course.)


There's levels of granularity that matter. You could just as well record all your edits in realtime. Make a script that makes a commit every second or every time you finish editing a line. It might be interesting later, yet that's usually not how people use git. Those changes wouldn't be meaningful units of work.

If you make a commit "wip" or "before lunch" because you want a backup of your work or want to continue on a different computer, then it's not a meaningful unit either. It's OK to throw away.

Most people prefer less granular commits but not to the point of having 1 commit per issue/PR. For example after inheriting someone else's code written in a hurry and not tested, I often end up dividing my work into several commits - first there's a cleanup of all the things that need renaming for consistency, adding docs/tests, removing redundant/unused code, etc. sometimes this ends up being more commits as i reveal more tech debt. Then, when i am confident i actually understand code and it's up to my standards, I make the actual change. This can be again multiple commits. The first and second group are often mixed.

And it's important when it later turns out i broke something - i can focus on the commits that make functional changes as the issue is usually there and not in the cleanup commits which can be 10x larger.

BTW what git is really missing is a way to mark multiple commits as one unit of work so the granularity stays there but is hidden by default and can be expanded.


> BTW what git is really missing is a way to mark multiple commits as one unit of work so the granularity stays there but is hidden by default and can be expanded.

Is that not just a non-FF'd, non-squashed merge of a branch?


This is my preferred branching model. Most forges seem to call it "semi-linear history". If you have a lot of people working on the repo you'll probably want a merge queue to handle landing PRs but that's pretty straight forward.

It works really well with things like git bisect. It also means history is actually useful.


That's the closest you get today but it means having to make, merge and delete branches all the time. What i propose is something like git squash but that keeps the history internally. It would present as one commit in gitk and other GUIs but could be expanded to see more detail.


> it means having to make, merge and delete branches all the time

Isn't this something that git makes simple?


Does gitk have an equivalent of `git log --first-parent`?


In the View menu dialog, there's a checkbox for "Limit to first parent"


> Make a script that makes a commit every second or every time you finish editing a line. It might be interesting later, yet that's usually not how people use git. Those changes wouldn't be meaningful units of work.

Every Jetbrains IDE does this, and VSCode has it's own equivalent feature. They don't use git, but same thing really. It's one of the most useful features ever IMO.


If people say "preserve history" as in "literally don't delete anything", then yeah I see where you're coming from.

I'm not against rebase, and even use it myself. But having a repo where every 3rd commit is a dice roll for git bisect just because straight line pretty, is just as annoying as people shipping their reflog.

A rebase of one commit is harmless. A squash is harmless. A rebase of multiple commits where every commit is deliberate (verifying all rebased commits, etc) is harmless.

A rebase that ignores the fact that any commit whose hash changed can now fail, is irresponsible. Shipping `wip` commit messages is irresponsible. A merge commit with the default message is irresponsible (it's no different from a `wip`-style commit). Having a branch with merge commits that could have been cherry-picks[3].

Also, to me the lie is not some aesthetic thing like commit order or some easily forgeable timestamp; the lie is having a commit that (for example) assumes the `p4tcc` driver is being used[1], and you read the diff and indeed it has assumptions that imply that driver is being used[2], but when you actually checkout that commit and see if that driver exists it turns out no it fucking doesn't, and hours were wasted chasing ghosts. Only because when that commit was created, the p4tcc driver was being used, but when you checked out weeks later now that commit magically uses the `est` driver instead.

If you're going to keep straight line, then test every change; if you don't do it, don't complain about broken middle commits.

If you're going to do merge commits, then keep each commit clean[4], even the merge commit[5]; if you don't don't complain about a history that is polluted with weird commits and looks like the timeline of a time-travelling show.

[1]: Because it did when that commit was created.

[2]: Because, again, it did when that commit was created.

[3]: This assumes the branch will later be integrated into main with a merge commit.

[4]: Squash is harmless. It's just omission. If anyone complains about purity, then just keep them happy with `git reset $COMMIT ; git add --all ; git commit -m "This is a new commit from scratch"`

[5]: Write something that helps those who use `git log --first-parent`. If you're on GitHub, at least use PR title and description as default (can be overriden on a case-by-case basis). If not, then even just "${JIRA_ID}: ${JIRA_TITLE}" is more useful than the default merge commit message while still letting you be lazy.


Yeah, exactly, it’s up to the author to determine what’s important to preserve. Note this is always true, because the author is the one who commits, and can do anything before committing. If keeping the “before lunch” commit is useful for the history, rebasing does not prevent that in any way. Personally, I doubt that particular comment really is just as likely to be useful as something describing what the change is, but I’m with you that it’s author’s choice. It seems like squashing “WIP” and “before lunch” and describing the change content & reasoning has quite a bit higher likelihood of usefulness down the road than a comment on when you planned to eat lunch, and that has been true for me in practice for many years.

There is no “real history” in git, and it’s kind of a fictitious idea, even in Fossil or other VCSes that don’t offer rebase. Think about it: commit order of “WIP” ideas in a branch is already arbitrary, and commits only capture what you committed, not what you typed, nor when you ran the build, nor what bugs you fixed before committing, nor what you had for lunch, nor anything you didn’t choose to commit. Taking away rebase only adds extra pressure to plan your commits and be careful before committing, which means that people will do more editing that is not captured by the commit “history” before committing! Having rebase allows you to commit willy-nilly messes as you go and know that nobody has to see it. It seems like rebase might very well be safer in general because it encourages use of the safety net rather than discouraging frequent messes… and we’re all making frequent messes regardless of VCS, all we’re talking about is whether we force the rest of the team to have to be subjected to our messes.

Git provides change dependencies, and does not offer “history” in the sense you’re implying. People overload the word “history”, and git’s sense of history is to show the chain of state dependencies known as commits, and those have editable metadata on them. In other words, git’s “history” is a side-effect, a view of the dependencies. Git’s “history” does usually have loose association with an order of events, but nothing is or ever was guaranteed. It is by design that you can edit them (meaning build a new set of dependencies with rewritten metadata… the old one is still there until garbage collection), therefore there is no “real history”, that’s not a real thing.


I depends on what you view as the real history. If you link each pull request to a work item you’re not going to really need all the commits on a development branch, because the only part of the history which matters is the pull request.

I think people should just use what works for them, if that’s debase who cares? The important part is being able to commit “asd” 9 billion times. If you can’t do that it will tax your developers with needlessly having to come up with reasons why they committed before lunch… that meeting… going to the toilet and so on.


That's just an interactive rebase with extra steps.




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

Search: