rjbs forgot what he was saying

not logged in (root) | by date | tagcloud | help | login

adding some safety to git force-push

by rjbs, created 2021-06-15 12:29
last modified 2021-07-04 12:14
tagged with: @markup:md git journal programming

Just the other day, I wrote about my little git branch manager tool. I use it to make sure I know what branches I have lying around, and to delete branches that have already been merged. I wrote the post because I had updated the code to work on more kinds of respository.

I updated the code to more on more kinds of respository because I wanted to write a different program to do something similar. See, about a week ago, I did a force-push that I shouldn't have. The history looked something like this:

  * [733401c] (github/rewrites) add the EIGHT file
  * [036a97a] SIX: rewrite file number six
  * [5d8e998] FIVE: rewrite file number five
  * [40778dd] FOUR: rewrite file number four
  * [624f233] THREE: rewrite file number three
  * [249af25] TWO: rewrite file number two
  * [2ac9796] ONE: rewrite file number one
  | * [d2e2cfb] (HEAD -> rewrites) add the ZERO file
  | * [2fadf99] SIX: rewrite file number six
  | * [6a2218f] FIVE: rewrite file number five
  | * [bbbe25a] FOUR: rewrite file number four
  | * [adda952] THREE: rewrite file number three
  | * [5d7c662] TWO: rewrite file number two
  | * [f656f0f] ONE: rewrite file number one
  | * [4623ca5] (github/main, main) add a seventh file for good luck
  |/
  * [4c74ba5] add some random content

What you'll see here is that there's a common base, then two versions of the same branch. One version (the local one) has been rebased on main. The other one is up on GitHub. Both of them have had new commits added. If you did a force-push of the rewrites branch, you'd clobber the "EIGHT" commit.

To avoid screwing up a force push, the advice includes "use --force-with-lease" which is good advice, it means "don't replace the remote if it's different than my fetch of it." That protects you against having it changed out from under you. It still means you have to read and compare the version you see with the version you want to push.

What I wanted was to avoid having to think about that whenever possible, and I knew there was a way to do it.

I wrote a new program, git-publish, that tries to turn the problem into this one:

Already, this is a pretty good win, covering some of the "is it safe?" questions in code so that I don't need to. The last case is "the difference is more than a rebase", and what I wanted was a means to see that explained. So, the last option is:

I'll probably refine this last step a bit more. I think I can at least add a step that's "cherry pick commits from the remote that aren't on this branch", and I'd put them after the common commits but before the new commits on my local branch. Even without that, though, this is a pretty nice little tool. I hope to use it more than git push from now on.

screenshot of git-publish