1

I often accidentally checkout remote tracking branches incorrectly:

git checkout -b origin/fixbugs

The -b should be a -t.

This mistake creates a branch called "origin/fixbugs". How could I get git to give me an error instead of creating this branch when the branch name begins with "origin/" (or any other remote name)?

idbrii
  • 10,975
  • 5
  • 66
  • 107
  • You can't. Well, you *can* but the easiest way is to retrain your fingers to run a command other than `git checkout`: use your own script that inspects the arguments and decides "bad idea". To make `git checkout` use your script, you will have to resort to writing your own front end `git` command-or-alias that checks the *next* word(s) for `checkout`: if so, run your own inspect-and-detect, otherwise run the real `git `. – torek Jan 09 '22 at 01:24

2 Answers2

2

First, you don't have to use the -t option, since git checkout has a guess mode.

 git checkout fixbugs

If <branch> is not found but there does exist a tracking branch in exactly one remote (call it <remote>) with a matching name, and --no-guess is not specified, treat as equivalent to:

$ git checkout -b <branch> --track <remote>/<branch>

Second, use the new git switch command (with Git 2.23+, Q3 2019):

  • it has the same guess mode as git checkout, so a simple git switch fixbugs is enough.
  • if has a -t option, but no -b option, so you would get an error in this case!
j6t
  • 9,150
  • 1
  • 15
  • 35
VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
  • I've started using switch and like the suggestion. Hopefully, it should resolve my slopping typing if I do an accidental `-b`. Thanks! – idbrii Jan 10 '22 at 21:22
2

Since v2.28 there's a reference-transaction hook you can use to vet all such updates.

#!/bin/bash
case $1 in
prepared)
        while IFS='/ ' read old new refs type name rest; do
                if [[  $type != remotes && $new = *[^0]* ]] && git config remote.$name.url >&-
                then echo $name${rest:+/$rest} would pun remote name $name
                     exit 1
                fi
        done
        ;;
esac

will do it unless you've taken to using multilevel remote names, you could beef up the check loop if you wanted.

jthill
  • 55,082
  • 5
  • 77
  • 137
  • 1
    Hm, this might work, but one should be aware that the reference transaction hook code is, um, "undergoing revision" (i.e., it has been broken in various ways at various points) and it's probably not wise to rely on it too much yet. – torek Jan 09 '22 at 09:51
  • @torek I see some overeager-performance-tweaking glitches that were fixed a year ago and some calls that are currently being made for internal ref-packing getting removed soon since they're just changing how the ref is stored not its value, . . . but this is for refs you don't want in the first place, it won't let you create them but doesn't block deletion, so I'm not seeing any problem cases. Am I missing somethihng? – jthill Jan 09 '22 at 11:23
  • @torek It has been fixed multiple times, more recently in 2.34: https://stackoverflow.com/a/61564736/6309 – VonC Jan 09 '22 at 12:19
  • Probably not missing anything - I just like to let new features settle for a while and get some good tests going. :-) (Note, I'm the one upvote at the moment on your answer.) – torek Jan 10 '22 at 02:24
  • This resolves my direct question, but using `switch` and relying on guess mode seems like a better solution for me since it's crossplatform and works on all repos without setting up hooks. Regardless, thanks for this answer! – idbrii Jan 10 '22 at 21:25