News for hackers. Stuff that matters.
Re:Idiot Proof Git by idop on Wednesday November 09, 2022 @10:10AM (#33532665)
Obviously what works for you works for you, but I respectfully disagree with everything you said.

The "history should be exactly what you did" argument - which many people make - is really funny to me because a pull/merge-only strategy only preserves the _wrong_ history. As a tech lead, for example, I absolutely do not care one bit about the date of a commit, or when the developer started working on it, or what was the commit they started working on top of. That may be "what really happened", but it's worth nothing in the grand scheme of things. When a commit _has made it into the product_ is the only " what really happened" there is, and that is what I care about. And a linear history makes this much easier to analyze and understand, reducing cognitive load considerably.

Also, it's strange that you see merges as a contributor to keeping repos from breaking, as my experience is the opposite.

I advocate for a rebase-based strategy wherever I go as it helps developers push better code, it actually curbs hysteria-driven "merge it as fast as possible no matter how shit it is" cases, and I see how it turns the Git log into an actually useful source of information for developers and other personas. People start reading the logs!

The log should track the product's evolution, not the developers' activities.

Re:Idiot Proof Git by dec0dedab0de on Wednesday November 09, 2022 @10:24AM (#33532883)
The log should track the product's evolution, not the developers' activities.

Git is a development tool, not a product release tool. If you want to see the product evolution you could filter to just merge commits, or just merge commits in a specific format.

If you want to keep track of releases specifically, then use tags, that's what they're for. I suppose you could make a separate branch/repo where every commit = a release, but that opens you up to merge conflicts without any benefit over tags

Re:Idiot Proof Git by idop on Wednesday November 09, 2022 @10:37AM (#33533087)
At the end of the day everything depends on the organization. In a hectic startup where requirements change on an hourly basis and releases are made several times a day, I would absolutely insist on keeping the log linear and as clear as possible. Tags are important, of course, but they're not that useful for analyzing a repository.

When I say "the evolution of the product" I really mean "the "evolution of the code". When a small feature branch with 5 commits - four of which say "wip" and the last one says "added color support" - gets merged as is, and all relevant information is held hostage by whatever Git platform the company is using this week and not inside the repository itself, the log is not useful to me regardless of any strategy.

But in a different setting I would not necessarily insist in the same way.

Re:Idiot Proof Git by dec0dedab0de on Wednesday November 09, 2022 @10:59AM (#33533465)
When I say "the evolution of the product" I really mean "the "evolution of the code". When a small feature branch with 5 commits - four of which say "wip" and the last one says "added color support" - gets merged as is, and all relevant information is held hostage by whatever Git platform the company is using this week and not inside the repository itself, the log is not useful to me regardless of any strategy.

Yes, it can be annoying if your developers are committing nonsense, but then just tell them to not do that, or to rebase locally before pushing.

If you find yourself troubleshooting a bunch of nonsense commits, you can just do a diff to the merge commit, and it will show you all the changes. But you also have the option of figuring out exactly which commit caused the problem, and seeing it in context. If I see an error in the middle of a bunch of commits that look like "trying x with y." Then I know that this is a tricky problem, and the developer was lucky to get it to work at all. If it is in the middle of a standard looking commit, then the developer didn't struggle with this. So maybe they didn't put enough effort into it, or maybe it is a rare corner case.

When I'm troubleshooting other peoples problems, every bit of information helps. Especially when the developer who introduced the problems is no longer with the company. Squashing commits removes some of that information, without providing anything that I can't approximate by using merge commits in logging/diffs.

Re:Idiot Proof Git by Quekid5 on Wednesday November 09, 2022 @11:41AM (#33534136)
> If I see an error in the middle of a bunch of commits that look like "trying x with y." Then I know that this is a tricky problem, and the developer was lucky to get it to work at all.

Just an aside, but if there problem being solved is harder than it looks then this deserves a comment explaining why in either the commit message or in the code itself.

Re:Idiot Proof Git by idop on Wednesday November 09, 2022 @11:11AM (#33533663)
To be clear, what I'm advocating for is that feature branches get rebased regularly by the developer until PR-time and a clean merge into the mainline. I usually recommend squashing to one commit but do not insist.

I can definitely see how those intermediate commits can provide more information, but there's a tradeoff. More often than not, they do not provide me much value, and instead give me bloat, so I prefer to keep things simple.

Telling developers not to do something is like telling a kid not to push that red button. The average developer chooses what's easiest _right now_ and thinks it's someone else's job to fix the mess at PR time. And they're afraid, because that one time five years ago they ran a rebase without knowing what it does, and lost some code without knowing it's actually right there in the reflog, and since then they are deathly afraid of Git. I know how to use log and diff and all the others quite well, but most don't. So I'm trying to make things easier on everyone in the long term, not the short term.

Re:Idiot Proof Git by P5fRxh5kUvp2th on Wednesday November 09, 2022 @07:16PM (#33540263)
"Why doesn't git bisect work?"

"well, it landed on this rebased commit that's huge. I guess it was a kind of useful, just not as useful as we'd like".

Re:Idiot Proof Git by firesloth on Wednesday November 09, 2022 @07:42PM (#33540541)
Haha, true! On the other hand, is that better or worse than running into a string of "wip" commits that had the code in a broken state.
Re:Idiot Proof Git by Dylan16807 on Wednesday November 09, 2022 @10:37PM (#33541885)
But if the alternative is that it's ten commits and most of them don't work anyway, the bisect takes longer to give you the same lousy information.
Re:Idiot Proof Git by P5fRxh5kUvp2th on Thursday November 10, 2022 @05:13AM (#33544488)
That's not the alternative, who develops like that?

It's like the first time I saw the essay calling ORM's the "vietnam of the software industry". I remember reading it and wondering who the hell would use ORM's in that manner?

Apparently a lot of people, but if you're using rebase because you don't know how to create commits that build and are functional then I submit the issue is with you.

Re:Idiot Proof Git by idop on Thursday November 10, 2022 @11:06AM (#33548468)
> That's not the alternative, who develops like that?

As an independent contractor working with many different companies, unfortunately, virtually everybody.

Re:Idiot Proof Git by firesloth on Wednesday November 09, 2022 @07:39PM (#33540511)
I've been recommending making a git tag before rebasing. eg:

  git tag -f pre-rebase
Re:Idiot Proof Git by krinchan on Wednesday November 09, 2022 @12:35PM (#33534995)

    git add .; and git commit --amend --no-edit; git push origin --force
Rarely, I have to do pipeline work on repositories. You'd normally see twenty "Fix Jankins Issue" commits on the main branch because of some nonsense that only happens when you deploy UAT or whatever. Once I learned this little gem, this is also how I manage my feature branches mostly. But also my employer's fleet of laptops has been aging and I've had to do 3 swap outs this year, so I like to keep my in progress work pushed up just in case.
Re:Idiot Proof Git by sixstringtheory on Wednesday November 09, 2022 @01:29PM (#33535839)
I did this for a while but have moved on to

    git commit --fixup HEAD
and you can tack an -e on the end to add more notes in the commit message body. You can fixup prior commits by supplying their short hash, which is how I originally discovered this: I essentially wanted to amend a commit farther back in my branch.

This makes a commit with a “fixup!” prefix that works with

    git rebase --interactive --autosquash
you can also form that kind of commit directly, and there is also a “squash!” directive. Now you don’t have to force push amended commits. And it helps sometimes when you accidentally amend something you didn’t mean to–now you can just soft reset to HEAD~1 and try again.

I don’t even bother locally rebasing to autosquash it all anymore since we use squash-to-merge/rebase in github PRs now.

Re:Idiot Proof Git by firesloth on Wednesday November 09, 2022 @07:30PM (#33540423)
I did something very similar with a bash function:

  function git-commit-fixup() {
    git commit --fixup ":/$*"
  }
  alias gcf="git-commit-fixup"
  # Looks for the most recent commit that matches its arg
  # eg: we have three commits with messages: 
  #   "fix: the thing" 
  #   "feat: 5 percent cooler"
  #   "test: test coolness"
  # then we do some work and git add, then do:
  gcf cooler"
  # now we have 4 commits: "
  #   "fix: the thing" 
  #   "feat: 5 percent cooler"
  #   "test: test coolness"
  #   "fixup! feat: 5 percent cooler"
  # And autosquash will combine the fixup commit with the appropriate semantic commit as you say.
Sadly I've stopped using it as someone introduced a bunch of commit lint git hooks that choke horribly on the "fixup!" part. And you can't pass --no-verify while rebasing.
Re:Idiot Proof Git by tkot on Wednesday November 09, 2022 @04:31PM (#33538168)
I'd probably suggest --force-with-lease just to be sure ;)
Re:Idiot Proof Git by firesloth on Wednesday November 09, 2022 @07:36PM (#33540494)
Me too. I made an alias that was _shorter_ than --force to make it easier to type (and hence more likely for me to use by default).
Re:Idiot Proof Git by tremon on Wednesday November 09, 2022 @05:41PM (#33539119)
git add .

We have had multiple security incidents because some developer left a credential file inside the local git clone (no, not all tooling supports out-of-tree stored credential). Blind 'git add .' is the first thing I teach my developers not to do.

Re:Idiot Proof Git by ratorx on Wednesday November 09, 2022 @08:16PM (#33540861)
git add . is very useful though. Surely, the first thing to teach here is to always git status before committing?

My typical workflow is to git add . to see the mess I’ve made then decide how to clean it up. If I’ve mistakenly added a credentials file, the fix is to add it to the gitignore and unstage it, not JUST unstage it.

Not saying that you shouldn’t do both, but maintaining a gitignore and completely removing the potential problem for other people seems better than pretending your tool is more limited than it is.

Re:Idiot Proof Git by notpushkin on Thursday November 10, 2022 @02:31AM (#33543357)
If you can tolerate a GUI, Git Cola might be a solution. I'm using it exclusively for some 5 years now – it's lightweight enough, but still makes you think about what you're about to commit. You can add things to .gitignore directly from there, too.

https://git-cola.github.io/

Default layout is a bit weird IMO, here's what I'm doing instead: https://u.ale.sh/my-git-cola-screenshot.png

Re:Idiot Proof Git by krinchan on Thursday November 10, 2022 @09:43AM (#33547145)
You don't use .gitignore? All our projects use dotenv for local credentials with a .gitignore that covers build, log, and any *.env file.

Sounds like you need better tooling, tbh.

Re:Idiot Proof Git by ernestns on Tuesday November 15, 2022 @10:49AM (#33610655)
You can combine

  git add .; git commit --amend --no-edit;
with the `-a` option

  git -a --amend --no-edit;
Re:Idiot Proof Git by xenomachina on Wednesday November 09, 2022 @01:25PM (#33535792)
> Yes, it can be annoying if your developers are committing nonsense, but then just tell them to not do that, or to rebase locally before pushing.

I'm pretty sure rebasing locally is exactly what the person you're arguing with is arguing for. The original comment in this thread was saying you should never rebase, always just merge.

Re:Idiot Proof Git by mixmastamyk on Wednesday November 09, 2022 @02:50PM (#33536915)
> feature branch with 5 commits - four of which say "wip"

Merge+squash eliminates this and it works every time. One or two clicks on gitlab for example.

Re:Idiot Proof Git by smaudet on Wednesday November 09, 2022 @10:56AM (#33533429)
Actually you're both wrong, its a change tool, not a development or a product release tool.

"then use tags, that's what they're for"

No they're not - that's definitely a useful way of using them, but they are just labels.

Why is it useful to know this? Well, when you know your tool better (how it operates, not the porcelain or CLI), you have better insights and are able to use it better.

You can manage Agile-style "features" with nothing but hashes and tags, no branches necessary. Branches are actually somewhat antithetical to distributed development, they're a useful concept, but that's all they are.

I do tend to agree though, re-base is superior to merge, in a product setting. If you want to track a feature set, having the set of commits which represents that feature set is better than a litany of nonsense tangled up in twelve feature "roots" (branches which have been merged together).

In a "do what I want" setting, rebase and merge are about equal, though. If I want to work on 3 features independently, I'd like to be able to easily see both features in parallel. I also would like to squash my features to single commits, and rebase them into feature branches where I can then merge/rebase/whatever those into my final "product" branch.

Re:Idiot Proof Git by copperx on Wednesday November 09, 2022 @06:54PM (#33539987)
> Actually you're both wrong, its a change tool, not a development or a product release tool.

It's funny that HN can't agree on what Git is.

Re:Idiot Proof Git by idop on Thursday November 10, 2022 @11:12AM (#33548591)
If you ask me: a low-level SCM framework.
Re:Idiot Proof Git by idop on Wednesday November 09, 2022 @10:17AM (#33532777)
Also, keep on mind that Git is the engine with which Continuous Integration is made. CI is developers integrating with the work of one another on a regular basis. If the product changed since you started working on your new brach, then your branch is stale and you need to integrate with the recent changes. Why wait until you're done to find out that your branch can't be merged anymore and you have to make a ton of changes when you can keep on top of things at regular intervals and make the final merge as easy as possible, not just for you, but for the code reviewers, the QA guys, the DevOps guys, everyone.
Re:Idiot Proof Git by hinkley on Wednesday November 09, 2022 @10:33AM (#33533025)
Usually my strategy, but it breaks down if you have someone who is bad enough at merge conflict resolution. We had one guy Steve who was upset that he was not as in charge as he wants to be, but he was doing a few things that break my trust so we are keeping him on a shorter leash than he likes. His code and ideas are okay but not great. He’s picking on this guy Mark, who sat next to me, to make himself look more valuable. Mark was not the brightest senior dev I ever worked with but he had his uses, and I hate bullies. Last but not least he was that he was terrible at merges and his solution to this problem was to delay as long as possible. We are a full CI environment and he’s making work for others by doing this. Namely me. None of these are conducive to me giving out a lot of responsibility, so he has some but not what he was after.

One day he’s blaming Mark for a regression in the code. Being pretty loud about it in fact. When I look at the bug, it sure looks like the sort of mistake Mark would make, and the annotation says Mark. Only the thing is that I’m the one who reviewed this code and I know Mark so I was looking for exactly this sort of bug and was pleasantly surprised to find that he was learning and had dodged that pitfall. So I go excavating the history and sure enough, that bug wasn’t in the code I reviewed. It was in Steve’s merge resolution. Fuckin’ Steves, man. And the fact that git lets you do things like that is not a great feature either.

Re:Idiot Proof Git by smaudet on Wednesday November 09, 2022 @11:04AM (#33533545)
The one who does the merge is always the one responsible... even if your code is amazing if it doesn't work with the (working) body of code that's on you, not the people who came before.

Of course Steve can just commit terrible code to main-line, and Mark (or yourself) are always stuck fixing their code, but that's what review/testing are supposed to be for - maybe blame the reviewers and testers in that case instead.

Re:Idiot Proof Git by bornfreddy on Wednesday November 09, 2022 @04:30PM (#33538152)
I don't know either Steve, Mark or you, of course - but this sounds like a broken dynamic where boss's preference of one person (sitting next to Mark, probably mentoring him) pushes another, Steve, to show his fighting side.

Yes, Steve should have kept things honest. But being the boss, you need to be careful not to pick favorites and to treat everybody in a similar fashion. People are very touchy about how they are treated within the "tribe".

Also, if you identified the issues both of them are bad at, are you all solving them? Being "terrible at merges"... how does that even work? Isn't that kind of an important skill? As their boss, their know-how is your responsability too, are you solving it?

Sorry if I have misjudged the situation, I obviously don't know it first-hand, so you will need to see for yourself if the above is true. There were just too many red flags (for me) in your comment to let it pass... And the reason I see them is that I have misjudged colleagues in the past, and wish I had known better then. Ah well.

Re:Idiot Proof Git by Jenk on Wednesday November 09, 2022 @10:31AM (#33532992)
I advocate for rebasing, but I discourage using a linear history. The two may seem to contradict one another but they are distinct (enough) that I felt it worth mentioning. When a developer pushes, it makes sense for them to rebase first because they are shipping those commits at the time of the push.

But, depending on your git workflow, when merging to main, I prefer a merge commit so I can see the tree of activities that lead to any particular release.

Re:Idiot Proof Git by idop on Wednesday November 09, 2022 @10:43AM (#33533208)
That's fine of course. Personally, I prefer to make things as easy as possible to understand at that unspecified but probable future date when a customer opens a SEV1 and I have to consult with the log, among other things. Make it idiot proof later, when time is _really_ of the essence, rather than now, when you're being artificially pressured to deliver that story for the sprint review in two hours.
Re:Idiot Proof Git by Jenk on Wednesday November 09, 2022 @12:15PM (#33534702)
I'm advocating that merge commits in main make it easier precisely for the requirements you specify: To track what feature(s) was introduced at a given release. With merge commits you not only have groupings of commits for features developed, you have that ability to revert a whole feature with just one revert. If you rebase onto main you are flattening those groupings and the entire commit stack into one serial history. For super quick "fix forward" products, that's fine and I would be happy with that. In products that are not so quick or perhaps you have tighter controls/SLAs/etc. Being able to immediately identify and revert an entire feature from main is very valuable, above and beyond a feature toggle imho.
Re:Idiot Proof Git by pierrebai on Wednesday November 09, 2022 @02:39PM (#33536795)
Squash commit will squash everything done into a single commit, so reverting it is easier.

Also when you have to cherry-pick fixes into an older release branch, you get to fully appreciate squashed merges. If you did not squash, you need to cherry-pick all commits from the merge. If the feature branch was not rebased and the dev merged main into the feature branch multiple times, then the branch commits are inter-mingled with main commits and it is so easy to mess up the cherry-picking. Just imagine if the dev had to fix conflicts...

All that makes squash commit a time-saver.

Re:Idiot Proof Git by tremon on Wednesday November 09, 2022 @05:47PM (#33539204)
so reverting it is easier.

Only reverting the entire feature is easier. Reverting a single change (for example, because it introduced a bug but is not critical to the feature itself) becomes much harder after squash.

Re:Idiot Proof Git by seba_dos1 on Wednesday November 09, 2022 @05:52PM (#33539288)
> Squash commit will squash everything done into a single commit, so reverting it is easier.

No, it's just as easy, while needlessly throwing away other useful information.

> If you did not squash, you need to cherry-pick all commits from the merge.

...or use a single `git rebase` invocation.

> If the feature branch was not rebased

Linear workflows with merge commits usually require feature branches to be rebased on merge (just like squashes, just without the actual squashing), so that's not a problem at all.

Re:Idiot Proof Git by danpalmer on Wednesday November 09, 2022 @10:16AM (#33532769)
My point wasn't that this strategy was the right one, but that having a clear strategy is more important.

I personally prefer a more rebase-heavy approach, but what we had worked very well for us.

Re:Idiot Proof Git by idop on Wednesday November 09, 2022 @10:18AM (#33532787)
Oh definitely, a clear and enforced strategy and conventions are more important than anything.
Re:Idiot Proof Git by smaudet on Wednesday November 09, 2022 @11:09AM (#33533634)
Boundaries are equally important - a set of expectations in context is fine, letting people know there is a world outside your little ego-bubble is also important, them knowing how and when to live in both is valuable.
Re:Idiot Proof Git by Shacklz on Wednesday November 09, 2022 @11:49AM (#33534259)
> And a linear history makes this much easier to analyze and understand, reducing cognitive load considerably.

This, so much this! And the price you pay for it is a slightly more difficult "insert". We started to enforce linear history in one of our bigger repositories (about 100 devs) about two years back; the first months were quite the ride (I had to do plenty of support-sessions to recover 'lost' changes). But the devs really started to see the benefits, and once they got the hang of it which was actually faster than I anticipated for most, it was smooth sailing. Many actually started to embrace it and advocate it for other repositories as well.

For me, it became also evident that filtering for people capable of learning git (rebase, cherry-pick, reset etc.) was very good at finding out who I'd want to work with and who not. It's really not that big of a deal, the UX of the CLI might be lackluster but the underlying datamodel is rather straight-forward. It's such a quintessential tool in our every-day-workflow that it's really worth putting a bit of time into understanding it, and if someone can't or doesn't want to, well, it might just be better if they work somewhere else than I do.

Re:Idiot Proof Git by dbt00 on Wednesday November 09, 2022 @04:14PM (#33537934)
You can, 99.9% of the time, emulate linear history with first parent history, which is a post-hoc tooling choice that doesn't remove context.

Developers shouldn't try to merge branches with wip/wip/wip/wip histories either, that's just garbage. Commit messages are documentation, fix your documentation before you publish.

Re:Idiot Proof Git by Shacklz on Thursday November 10, 2022 @03:09AM (#33543604)
> You can, 99.9% of the time, emulate linear history with first parent history

Fully agreed, but that requires first of all to understand how this works and second requires you to run commands locally. If you're unfortunate enough to have to use e.g. bitbucket-server at work like I do, you'll always see the full graph, there which is A LOT easier to grok if it's linear. And since that's what's most devs look at (instead of git-log using some extra options) and also where CI-state happens to be reported (green/red build), that's worth a ton :)

Re:Idiot Proof Git by mibollma on Wednesday November 09, 2022 @05:22PM (#33538869)
I disagree with both of you :). Personally I prefer to squash to one commit per ticket but on a team level I don't care about a consistent way.

I've found that the history rarely doesn't matter at all to me. Finding out who modified a specific code section (git blame) is usually good enough.

Re:Idiot Proof Git by CBarkleyU on Saturday November 12, 2022 @10:59AM (#33574222)
In the hopes someone will see this: Why isnt this the standard? I've never been in the position of coordinating multiple engineers, but when I look at my colleagues code I never ever once cared about their individual commits. What am I missing?
Re:Idiot Proof Git by rtepopbe on Wednesday November 09, 2022 @05:26PM (#33538937)
My current thought on this is that the git model (or at least the interface for it) is probably a touch too simple to accommodate all the things people want to use it for. As a result, you get this whole 'clean history' vs 'what really happened' split. And often you can find a few more splits if you dig in a bit deeper into the actual mechanics people prefer.

Generally, bigger picture stuff works best with cleaner histories as they mop up a bunch of unnecessary and distracting details, and neatly package things together. But doing so also means you're getting rid of, well, the details. If you need them later - and some poor bastard always will - you're just screwed.

Unfortunately all we've got are commits, so you're constantly fighting different groups and even different people who value the benefits of different approaches due to their positions, histories, or preferences.

This isn't even a half-baked idea at this point, but at first glance something like a meta-commit which just contains more commits and a message seems like it might be better. The top-level commits could just be the 'clean history' while deeper levels could record more of the as-happened details.

Re:Idiot Proof Git by P5fRxh5kUvp2th on Wednesday November 09, 2022 @07:13PM (#33540235)
Most of what you said there isn't actually true. I don't doubt you believe what you're saying, I'm just pointing out it's not true.

My favorite is how apparently rebasing causes developers to write better code. If you say so.

Re:Idiot Proof Git by idop on Thursday November 10, 2022 @11:11AM (#33548569)
Thanks for pointing out my errors, I now see where I was wrong.