Live data from Hacker News

Idiot Proof Git

softwaredoug.com

311–320 of 435 posts

Re: Idiot Proof Git

#311

Modern Git workflow is very simple on its own: 1. Your codebase has a `main` branch which is write-protected 2. Devs submit changes to `main` from their own branches using PRs 3. Devs can do whatever the fuck they want on their own branch 4. PRs are merged one at a time 5. When merge happens a dev's PR is squashed into one commit that gets appended to `main` 6. If next dev wants to merge their PR with a conflicting c…

I agree with most of this, except:

> 5. When merge happens a dev's PR is squashed into one commit that gets appended to `main`

I don't know if GitHub supports this, but GitLab has a semi-linear history feature. When enabled, it won't let you merge unless a fast-forward merge is possible, but it never does a fast-forward merge.

This give you (IMHO) the best of both worlds: your history is pretty linear and easy to reason about. The "first parent" of each commit on the main branch is a linear chain of the main branch history. However, for more complex changes you don't have to squash. Those intermediate commits will be on the second parent of merges, so they're easy to filter out:

    M─┐ [main] merge
    │ o commit
    M─┤ merge
    │ o commit
    M─┤ merge
    │ o commit
    │ o commit
    M─┤ merge
    │ o commit
> If you want interactive rebase then make 2 PRs.

What do you mean?

Re: Idiot Proof Git

#312

Modern Git workflow is very simple on its own: 1. Your codebase has a `main` branch which is write-protected 2. Devs submit changes to `main` from their own branches using PRs 3. Devs can do whatever the fuck they want on their own branch 4. PRs are merged one at a time 5. When merge happens a dev's PR is squashed into one commit that gets appended to `main` 6. If next dev wants to merge their PR with a conflicting c…

It's flat out amazing how often people want to complicate git.

My current company, everyone is in love with git flow. I pointed out the person who originally created it literally wrote a blog post explaining why it was designed for very specific needs that most projects don't have, and yet ...

I constantly see people doing presentations on how this is all supposed to work. And why? You can get away with very simple flows.

Re: Idiot Proof Git

#313
post #10

Big fan of Git style guides in teams. We had one at Thread. It was common for engineers to come in and find we didn't do rebasing and find it weird, but we took the opinion that history should be exactly what you actually did, not some clean and idealised version of what you wish you had done. There are advantages and disadvantages to this, but having a defined approach was the most important aspect. Also the fact th…

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 t…

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

#314
post #98

Earlier quoted context omitted.

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,…

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 k…

"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

#315
post #188

Earlier quoted context omitted.

It works, but it works better when you have the original 10000 commits. You can tell exactly what the committer was attempting when the bug was introduced. It may have been as a fix to something else, it may have been a typo when linting, it may even have been been intentional and the bug report is wrong. Other comments I made on another recent git post: https://news.ycombinator.com/item?id=33395616 https://news.ycom…

Hah, I must admit I thought you meant that you preferred squashing! Agree 100% that a huge number of small commits are easier to find bugs in than a small number of huge commits.

I meant my response more to the last part of what I'd quoted, the "because in the end it doesn't actually matter.".

Over the past few months we've been trying to formalize our git usage since we're split across a bunch of teams, and on this particular issue I've found a very hard split: People on the new-feature-development teams love squashing and squash-merge, people on the maintenance teams who have done work in git repos for a while are almost all against it (of the ones with no opinion, several are still only working in svn repos so haven't had a chance to form an opinion), but most people on the maintenance teams don't really speak up about it so our company-wide guidelines remain heavily in the squash-merge camp.

Re: Idiot Proof Git

#316

Earlier quoted context omitted.

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…

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…

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 haven't been using it much 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

#317
post #282

Earlier quoted context omitted.

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…

I'd probably suggest --force-with-lease just to be sure ;)

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

#318
post #98

Earlier quoted context omitted.

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,…

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 k…

I've been recommending making a git tag before rebasing. eg:

  git tag -f pre-rebase

Re: Idiot Proof Git

#319
post #98

Earlier quoted context omitted.

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 k…

"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".

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

#320

Earlier quoted context omitted.

Haha. what's the git reflog talk? To be clear I know what reflog is, but what's "the talk"?

Probably just making them aware of it. But I can give a slightly longer spiel: Commits in git are immutable. They're identified by their hash, so they have to be. What's more they have the hash of the previous commits so the whole chain back to the first commit can't be changed. You can only add new chains. As a consequence, if your main branch points to commit abc123 and your feature branch points to commit def456 t…

I'm certainly aware of reflog and have (thankfully) only had occasion to use it once or twice that I can remember.

To my original comment - having to force-push in order to resolve heads - is there a "correct" way to do this that doesn't feel gross?

Post reply on HN