Tag Archives: bash

Git goodies

Oh, Git! The thing that makes our developers life so much easier, yet – as, perhaps, any involved system – having so much left out of attention of the most. It’s far from original to post this XKCD gag here, but it’s just too true:

Git by XKCD

Me myself, I don’t really understand Git. I mean sure, I’ve read few articles on its structure and what acyclic graphs are and how it works etc., but when things go awry – I’m still puzzled.

To help that a little, I started to collect a set of shortcuts and tricks to make frequent problems less hassle. These come in form of scripts – while I could make aliases, I somehow prefer separate scripts as they let you use bash syntax if task is a little more complex than a simple shortcut. What’s also nice is if you name your file (or alias, I suppose) “git-kill-all-humans“, you can then run it as “git kill-all-humans” and even see it in the tab completion for Git commands!

The full set could be found under “git-tools” directory at https://bitbucket.org/hydralien/tools, below are just a couple of the most used ones.

  • git-forget – to use as “git forget .” to loose all the uncommitted changes or “git forget filename” to just a specific file to revert
git checkout -- $@
  • git-origin – to get the remote URL of the repository, useful to share or to clone other repository that resides at the same server (so I just need to change the name)
git config --get remote.origin.url
  • git-out – to see what changes are scheduled to be pushed to origin
git diff origin/`git rev-parse --abbrev-ref HEAD` -- $@
  • git-import – get changeset from a different host, useful when development happens on same repository cloned on many instances – sometimes changes end up on a wrong instance and need to be moved without getting them into the repository
curdir=`pwd`; ssh $1 "cd $curdir ; git diff"|git apply 
  • git-rush – probably the most used command – when the repository is large and there’s many people pushing to it, getting your changes into the origin might be a daunting process. So this one just tries till it’s done – it’s a little overcomplicated for stats reasons (and uses another shortcut, so there’s two of them here), but here it is:
attempt=1 ; time until git repush; do let "attempt++"; echo "No luck, once again..."; done ; echo "Finished in $attempt tries" ; date

and the git-repush:

git pull --rebase && git push

Bottom line here… Git is good – it just takes a few shortcuts to fully appreciate it =)

And of course there’s a hell lot more to automate if required – hooks, configuration etc. etc. etc.

Neat little thing, or bash tab-completion for your tools

You know that thing, the magic of having all the options listed in front of you when you [double-]press Tab after typing something on the console? Or the unique option completing itself if there’s a match? Of course you do. One thing that bothered me is the frustration of when it’s suddenly not there.

For general tools it’s already alright, they either come bundled with tab-completion or you can easily set it up – for instance, there’s a setup tutorial for Mac, coming with a Git bundle. One important note on that one: in iTerm, you have to go to settings -> Profiles and change Command to /opt/local/bin/bash -I for your/default profile to run proper bash version.

But then there are your own little tools that start as a one-parameter two-liner but eventually grow to 30-params fire-breathing hydra. And that’s when you start missing that tab-completion thing.

But that’s easy (for simple cases – see a note below) – you just create a script named, say, mycomplete.bash, containing something like this:

_completecmd()
{
  local complist=`fdisk 2>&1|grep -Eo ‘^ +[a-z]+’|tr ‘\n’ ‘ ‘`
  local cur=${COMP_WORDS[COMP_CWORD]}
  COMPREPLY=( $(compgen -W “$complist” — $cur) )
}
complete -F _completecmd yourcmd

where _compelecmd is a unique function name, yourcmd is a command this should be applied to, and complist is constructed from fdisk output just to illustrate the approach – it should be output of yourcmd parsed there. Note: try your parser before you set it up, I faced weird differences on different platforms.

Then you need to add this to your ~/.bashrc:

source /path/to/mycomplete.bash

and you’re done. To have it right away, you can also run source /path/to/mycomplete.bash directly in your bash prompt.

Mind that that this approach wouldn’t work for intricate cases when you have a deep parameter sequence dependency – have a look at Git approach, it’s a bloody burning hell there.