3

Anyone know if it's possible to modify git so it will simply reject git stash and in stead require me to explicitly specify git stash push. I often find myself accidently stashing stuff when I wanna inspect the stash (git stash list). Similarly it's rather annoying if I have stuff in the index and then do git stash (and forget to add --keep-index). Which in turn can have disastrous consequences (How to recover the index after a git stash / git stash pop?)

kostix
  • 51,517
  • 14
  • 93
  • 176
fredefox
  • 681
  • 3
  • 11
  • 2
    You could look into git alias, but I am not sure how will it work well into your context. – Ru Chern Chong Feb 12 '18 at 16:52
  • Aliases won't work, since Git explicitly ignores aliases of known commands. – Matthieu Moy Feb 12 '18 at 16:55
  • 1
    @MatthieuMoy That is not true. You can put `stash = log` under `[alias]` in `.gitconfig` and then `git stash` will print the log. But `git stash pop` then won't work anymore either, so I'm not sure if this approach could lead to something that meets OPs requirements... – anothernode Feb 12 '18 at 16:57
  • 2
    @anothernode: have you actually tried it? I have, it doesn't work (just tested again with Git's master branch in git.git, it still doesn't). It's documented not to work: https://git-scm.com/docs/git-config#git-config-alias "aliases that hide existing Git commands are ignored". – Matthieu Moy Feb 12 '18 at 19:05
  • @MatthieuMoy Yes, I tried and it really works on my machine. Now I found out why: I'm using [hub](https://hub.github.com) and it's apparently interfering with git's alias mechanism. When I remove the `git='hub'` alias from my shell config, git behaves as you are describing. Sorry, I forgot that I put that in my shell config at some point, d'oh :) – anothernode Feb 13 '18 at 09:18

1 Answers1

7

Add the function to ~/.bashrc.

function git() {
  GIT=`which git`
  if [[ "$#" -eq 1 ]] && [[ "$1" = "stash" ]];then
    echo 'WARNING: run "git stash push" instead.'
  else
    $GIT $@
  fi
}

Though I tried on Ubuntu and Windows and both succeeded, I'm not sure if there's any side effect that may cause bugs.

ElpieKay
  • 27,194
  • 6
  • 32
  • 53
  • 2
    Note that instead of `GIT=$(which git)` and then later `$GIT`, you can use `command git` to bypass the shell function when running commands from within the shell function. The overall efficiency is about the same, though. – torek Feb 12 '18 at 19:04
  • You also do not need to use the "function" keyword when delcaring a bash function. Simply git() { ... } will do. – Luke Davis Apr 07 '20 at 07:10
  • The else clause should read "$GIT" "$@" i.e. you should double-quote both the $GIT and the $@. Quoting $GIT will help in case your git has a path with a space (though unlikely). More importantly, the arguments should be "$@" to cater for spaces in the arguments, especially e.g. in a -m message argument. Note that the syntax "$@" is special: bash will not quote the whole string of arguments, but will quote each separately. So "$@" is like "$1" "$2" … rather than "$1 $2 …". That is, bash will do the 'right thing'. See the bash manual (man bash) § Special Parameters for details. – Rhubbarb Apr 09 '21 at 07:57
  • The condition [[ "$#" -eq 1 ]] && [[ "$1" = "stash" ]] perhaps would be better expressed as [[ "$#" -eq 1 && "$1" = "stash" ]] or if you prefer, [[ ( "$#" -eq 1 ) && ( "$1" = "stash" ) ]]. That is, put the && operator inside the [[ … ]] test. Opinions may differ. – Rhubbarb Apr 09 '21 at 08:07