Live data from Hacker News

Idiot Proof Git

softwaredoug.com

21–30 of 435 posts

Re: Idiot Proof Git

#21
post #5

How is push origin HEAD --force-with-lease different from normal git push? Can someone please explain this to me?

When you work with a rebase-oriented workflow, it's very common to submit a PR for review and then address incoming review comments as fixup commits: https://blog.sebastian-daschner.com/entries/git-commit-fixup...

This necessitates force-pushing to your feature branch after all the fixup commits have been approved and then squashed. At that point you can merge the cleaned up feature branch in to your develop or trunk.

`--force-with-lease` is slightly better than `--force` because in the event that you're also working on a collaborative feature branch you won't overwrite any commits that somebody else pushed up that you haven't fetched yet.

Re: Idiot Proof Git

#22
post #12
post #5

How is push origin HEAD --force-with-lease different from normal git push? Can someone please explain this to me?

It will overwrite the tree on remote as long as remote hasn't changed since you last fetched it. Like --force, but can help to prevent overwriting other people's changes when they push in between you fetching. It doesn't always work, particularly if you have a tool which continuously fetches remote, like an IDE configured to do so such as VSCode. In that case, you will have fetched the other person's changes, and --f…

Oof, thanks for that warning. So it will blow away changes you haven’t merged (only fetched)?

I guess git can’t tell the he difference between “not merged yet” and “don’t want to merge, please destroy”

Re: Idiot Proof Git

#23
post #3

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…

What about squashing commits in a merge? I don't do that all the time, but it is useful for certain things. Like repeated code changes to test something in the CI/CD pipeline (that I can't replicate well locally), where only the last change that got it working is of any interest.

What about squashing commits in a merge? I don't do that all the time, but it is useful for certain things. Like repeated code changes to test something in the CI/CD pipeline (that I can't replicate well locally), where only the last change that got it working is of any interest.

You can get the same effect by reverting-to/checking-out a merge commit, or doing diffs between merge commits. You can also get a fairly clean history by only showing merge commits.

My rule of thumb is that any commit that has been pushed to a shared remote should never be re-written[]. If you're going to rebase, do it on your computer before pushing, or on your own repo before opening a merge/pull request.

[] exceptions would be removing accidentally committed secrets or large files that are no longer needed.

Re: Idiot Proof Git

#24
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…

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

#25
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…

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

#26

Earlier quoted context omitted.

Squashing is rewriting history. It sounds like the grandcomment had a ban against rewriting history across-the-board, which would help make git idiot proof. I love rewriting history, not because it's what I wished I had done but because it's what I am going to want to review when I have to. Rewriting history is a great way for gitiots to shoot themselves in the foot.

Couldn't you rewrite history locally on your own branch and nobody would know?

We informally allowed whatever you wanted until you opened a pull request.

Re: Idiot Proof Git

#27
post #10

Earlier quoted context omitted.

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…

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.

Oh definitely, a clear and enforced strategy and conventions are more important than anything.

Re: Idiot Proof Git

#28

Earlier quoted context omitted.

Squashing is rewriting history. It sounds like the grandcomment had a ban against rewriting history across-the-board, which would help make git idiot proof. I love rewriting history, not because it's what I wished I had done but because it's what I am going to want to review when I have to. Rewriting history is a great way for gitiots to shoot themselves in the foot.

Couldn't you rewrite history locally on your own branch and nobody would know?

Hard agree. Do whatever the heck you want locally, just try not to screw everybody else up when you push.

(From the guy who force-pushed on a personal project yesterday to resolve a situation with multiple remote heads - I am ashamed)

Re: Idiot Proof Git

#29
post #5

How is push origin HEAD --force-with-lease different from normal git push? Can someone please explain this to me?

It's not really, but there are a couple minor differences in practice.

First, it assumes the name of your upstream repository is "origin" which is fine in most cases as that is what `git clone` defaults to naming the remote.

Second, using `HEAD` always pushes your current checked our branch to your remote with a remote branch of the same name. It's a neat trick to skip the "`git push` -> you need to set your upstream branch -> push command the git outputs" loop.

Lastly, `--force-with-lease` is a safer version of `--force` or `-f` because it tries to ensure that you don't overwrite history accidentally. The `--force-with-lease` flag will fail if a coworker for example pushed a commit to your branch that you didn't know about. Where a regular `--force` would just overwrite that change.

I assume that the command is meant to be "safe" and "foolproof", in that this command should always work.

Since the parent post recommends a lot of rebasing in their other commands, you'll need a `--force` or `--force-with-lease` to push new commits because they won't be "fast forwardable"

Re: Idiot Proof Git

#30
post #5

How is push origin HEAD --force-with-lease different from normal git push? Can someone please explain this to me?

A normal push will only advance the remote branch if your local branch has the tip of the remote branch as an ancestor. This ensures you're only adding commits to the remote branch and not replacing any commits on the remote.

But if you've pulled the remote branch, rebased, and now wish to push, the tip of the remote branch is longer an ancestor of your local branch. In this scenario, to update the remote branch you have to do a force push.

But now imaging that another developer has added new commits to the remote branch in the mean time. If you do a force push, you will overwrite those new commits.

Using "--force-with-lease" ensures that the tip of the remote branch hasn't changed since you last pulled it, so that your force push isn't erasing any commits on the remote by accident (i.e. it ensures the remote branch has not changed in between when you last pulled it and your current force push.)

Post reply on HN