Helpful commands

As a follow-up to my last post here are some commands that I use throughout the day. They are admittedly nothing special but they help me out.

.bashrc aliases:

alias grc='git rebase --continue'
alias gca='git commit -a --amend'
alias gs='git status -sb'
alias gd='git diff'
alias gsn='git show --name-only'

The one worth explaining is gca. This one stages and commits everything to the previous commit. I use this constantly to keep adding stuff to my WIP commits. One thing to watch out for is this will mess up a merge conflict fix inside a rebase operation because you’ll end up putting everything in the merge before the conflict. You want to do grc instead.

scripts:

force_push — I use this to automate the process of updating my remote branch and most importantly to prevent me from force pushing the one branch that I must NEVER force push.

#!/usr/bin/env bash
CURRENT_BRANCH=`git rev-parse --abbrev-ref HEAD`
if [ $CURRENT_BRANCH == 'master' ]; then
  echo "YOU DO NOT WANT TO DO THAT"
  exit 0
fi
 
echo "git push origin $CURRENT_BRANCH --force"
read -p "Are you sure? [Yn] "
if [ "$REPLY" != "n" ]; then
  git push origin $CURRENT_BRANCH --force
fi

rebase_branch — There’s not really a lot to this, but I use it reflexively before I do anything.

#!/usr/bin/env bash
git fetch
git rebase -i origin/master

merge_to_master — I do this when I’m done with a branch. This makes sure that there will be a clean fast-forward push. Notice how it reuses rebase_branch.

#!/usr/bin/env bash
rebase_branch
CURRENT_BRANCH=`git rev-parse --abbrev-ref HEAD`
echo "git checkout master"
git checkout master
echo "pull origin master"
git pull origin master
echo "git merge $CURRENT_BRANCH"
git merge $CURRENT_BRANCH

git-vim — this one is still a bit of a work in progress, but the idea is to grab the files you’ve changed in Git and open them in separate tabs inside Vim. You can then run it with git vim which I alias as gv.

#!/usr/bin/env ruby
 
# uncommitted files
files = `git diff HEAD --name-only`.split("\n")
if files.empty?
  # WIP files
  files = `git show --name-only`.split("\n")
end
 
system("vim -p #{files.join(" ")}")

Of course, all these scripts need to be put somewhere in your executable path. I put them in ~/bin and include this location in my path.

So my workflow would look like this

git checkout -b new_branch
# hack hack hack
git commit -a
# hack hack hack
gca
# hack hack hack
gca
# all done now
rebase_branch
# whoops a merge conflict
# resolve it
git add .
grc
# Time to get this code reviewed on Github
force_push
# Code accepted, gonna merge this
merge_to_master
  • Ian McCracken

    I have a similar library of aliases. A few wrappers around git ls-files, although I have them all as git aliases in ~/.gitconfig. I have tab completion for all git commands, so it’s a bit easier for me than remembering global aliases. They’re just other commands one can run in a git context.

    [alias]
    # My usual commit
    ci = “commit -a”

    # Simple shortcut
    co = checkout

    # In git-svn land, easiest way to squash git commits into a single svn commit
    mg = merge –squash –no-commit

    # Dangerous but useful
    undo = reset –hard HEAD

    # Create a git branch that maps to an svn sandbox branch
    sandbox = !sh -c ‘git svn branch “$0″ && git co sandbox/”$0″ -b “$0″ >/dev/null 2>&1′

    # Use these two when resolving conflicts; git edit-unmerged will open all conflicted files
    # in vim, and add-unmerged will stage them when you’re done
    edit-unmerged = “!f() { git ls-files –unmerged | cut -f2 | sort -u ; }; vim `f`”
    add-unmerged = “!f() { git ls-files –unmerged | cut -f2 | sort -u ; }; git add `f`”

    # My version of “edit modified files”
    vmod = “!vim `git ls-files -m`”

    # List files ignored below $PWD
    ignored = “ls-files -o -d .”

  • method

    Cool. I think I’ll borrow the edit-unmerged and add-unmerged commands. I don’t have a lot of use for the git-svn stuff, fortunately. Maybe that undo alias too. I do that a lot. I also do a lot of “git reset HEAD^ $file; git commit –amend; git checkout $file”.