Oli.jp

Articles…

  1. Git config powerup with aliases, diff & log

    Git’s commands tend to have good defaults, but also a lot of customisability via flags. But all that typing, who needs it when we have git aliases?

    Making a git alias via git config or .gitconfig

    There are a couple of ways we can make an alias in git:

    • using the command git config alias
    • editing the .gitconfig file directly

    While you can make aliases per project, I always make ’em global via git config --global alias or by editing ~/.gitconfig.

    Here’s the pattern to make an alias using git config:

    git config --global alias.alias command

    For example, I use git status a lot, so a shorter alias would be nice:

    git config --global alias.s status

    This will add the following to your ~/.gitconfig file:

    [alias]
      s = status

    Now if I type git s I get the same output as git status. Of course you can always open ~/.gitconfig in a text editor and add s = status manually under the [alias] section. Here are some other basic aliases I’m using (more exciting ones to follow):

    Some basic git command aliases
    AliasCommand
    git sgit status
    git a!git add . && git status
    git au!git add -u && git status
    git aa!git add . && git add -u && git status
    git cgit commit
    git cmgit commit -m
    git spullgit svn rebase
    git spushgit svn dcommit

    A couple of things to note:

    • If you’re using git config you’ll need to quote commands that are more than one word, e.g.
      • git config --global alias.c commit
      • git config --global alias.cm "commit -m"
      and escape some characters, e.g. for $ use \$
    • We can alias shell commands, so you can e.g. pipe git output to another tool. Do this by prefixing the whole command with “!” (example that includes shell script in the conclusion).
    • We can chain commands using “&&
    • If the command takes input, like the commit message for git commit -m, as long as -m is last you’re fine e.g. with the above aliases git cm "initial commit" is the same as git commit -m "initial commit"

    Better history with git log

    git log gives us access into git’s history, but for me the default is lacking.

    Example output for a commit from git log

    The main info I want is:

    • an overview of commit messages to find a commit
    • the commit’s hash tag for using with git diff etc
    • what branch/repo a commit is on or from
    • what changed in each commit and by how much

    Let’s fix that — aliases to the rescue!

    git log history overview

    Add this alias then try git l, ideally in a multi-user project with lots of branching and merging:

    # command (this is why aliases rock!)
    $ git log --graph --pretty=format:'%C(yellow)%h%C(cyan)%d%Creset %s %C(white)- %an, %ar%Creset'
    # create alias via shell
    $ git config --global alias.l "log --graph --pretty=format:'%C(yellow)%h%C(cyan)%d%Creset %s %C(white)- %an, %ar%Creset'"
    # or add directly to ~/.gitconfig under [alias]:
    l = log --graph --pretty=format:'%C(yellow)%h%C(cyan)%d%Creset %s %C(white)- %an, %ar%Creset'

    You get an abbreviated commit hash (great for pasting into git diff etc), branch and remote info, the commit message, author and relative date, in a compact format. And it graphically shows branches via railway diagram craziness. ASCII-art FTW!

    git log brings teh awesum

    I originally used an overly colorful version, but this is based on Ben Hoskins’ one in Git for busy people: see what you’re doing.

    git log detailed history

    While the previous alias solved my first three needs, I still sometimes want to see what changed and by how much. This next command gives the same info as the default git log, but adds a list of each file changed per commit, and an indication of how much each file changed. I alias it to git ll.

    # command
    $ git log --stat --abbrev-commit
    # create alias via shell
    $ git config alias.ll log --stat --abbrev-commit
    # or add directly to ~./gitconfig under [alias]
    ll = log --stat --abbrev-commit
    
    Indicating how each file changed in a commit — green pluses are insertions, red minuses are deletions

    It’s handy for seeing which commits involved major changes or touched a lot of files.

    Bonus: total commits, including per-author

    This just tells you how many commits your repo has: git log -a --pretty=oneline | wc -l. You can also break total commits down by author using git shortlog -sn.

    For more info on git log Git Immersion: History is worth a read.

    Better diffs with git diff

    I use git diff a lot, but the default setup has some problems:

    1. the default pager less doesn’t soft-wrap or scroll horizontally
    2. by default lines are compared, so small changes in a paragraph are hard to spot
    Default git diff, with long lines being cut off because they’re not soft-wrapped (boo!)

    We can improve on this with a couple of config tweaks. To add soft wrapping to git diffs we can add pager = less -r under [core] in your .gitconfig, e.g. by using git config --global core.pager less -r.

    Changing the pager settings for a soft wrapped diff — getting better

    To change from per-line to per-word diffs, we can use the flags --word-diff=color or --color-words. The easiest way is to make an alias like git config --global alias.d = diff --color-words.

    Soft wrapping plus OMG THIS IS AWESOME --color-words

    While --color-words automatically turns on diff coloring, I’ve also got the following in .gitconfig under [color]:

    [color]
      ui = auto # covers diff = true, status = auto, branch = auto
      interactive = auto
    

    There’s a lot more we can do with git diff — here’s some patterns I’ve found helpful:

    git diff
    Compare working copy to index (files prepped for committing via git add)
    git diff head
    Compare working copy to head (the most recent commit)
    git diff [filename]
    Compare a specific file (with path if necessary) to index
    git diff --stat
    Show insertion and deletion stats for each file with +-
    git diff [commit] [filename]
    Compare current [filename] to the same in a specific [commit] (via commit hash etc)
    git diff [commit]:[old-name] [new-name]
    Compare a renamed file
    git diff [branch]..[other-branch]
    Compare the most recent commits (tips) of two branches
    git diff [branch]...[other-branch]
    Compare the tip of other-branch and the closest ancestor (fork point) on [branch]
    git diff [branch]:[filename] [other-branch]:filename
    Compare two files on different branches
    git diff --no-index [filename] [filename]
    Compare any two files, even if they’re not in a repo :O

    If terminal-based diff still doesn’t do it for you, try setting opendiff as your diff client.

    Conclusion

    Here’s my .gitconfig file as a gist for your forking pleasure.

    I hope that’s given you some useful aliases, or at least some ideas to make your own. I’ll leave you with one last alias from Bernd Jünger to copy and paste into your ~/.gitconfig under [alias]:

    alias = !git config --list | grep 'alias\\.' | sed 's/alias\\.\\([^=]*\\)=\\(.*\\)/\\1\\\t => \\2/' | sort

    When you’re done it might come in handy ;)

    If you have any feedback or comments, contact me via Twitter (@boblet) or Google+ (Oli Studholme).

Older articles

  1. Amazon “HTML5” and ebook formats

    Amazon just announced Kindle Format 8, supporting HTML5 and CSS3! Yay! But closer inspection reveals they’re only supporting the marketing version of “HTML5” and “CSS3”. Boo! Won’t someone just give us the web stack for ebooks already?

  2. Don’t use IDs in CSS selectors?

    Is CSS Lint’s “Don’t use IDs in selectors” suggestion just crazy talk? While some are using this suggestion’s supposed ‘obviously bad’-ness as a reason to reject CSS Lint out of hand, it’s more valuable to actually examine the why behind this suggestion. The reasons may surprise you…

  3. Blockquote problems and solutions

    Wherein I cover current uses of block quote metadata that are unsupported by <blockquote>, and consider potential improvements to the situation.

  4. oli.jp style guide

    My style guide for this site, for your edification and copy-and-paste pleasure.

  5. CSS3 Flexbox vs A Princess Bride

    A look at the current CSS3 Flexible Box Layout Module, containing lots of information you don’t want to hear, but with extensive reference to the movie A Princess Bride.

  6. CSS animatable properties

    As with the CSS selectors article, I wanted a summary of animatable CSS properties, so I’ve made a copy of the W3C one and reordered/tweaked it a little. It’s now referenced from the Mozilla Developer Network wiki, so I guess I better keep it updated ;)

  7. CSS selectors

    I wanted a summary of all the CSS selectors, so I’ve made a copy of the W3C one and reordered/tweaked it a little.

  8. The ruby element and friends (on HTML5Doctor)

    My third article for HTML5Doctor.com:

    The <ruby>, <rt> and <rp> elements allow us to add ‘ruby’ phonetic annotations in languages like Japanese and Chinese. Despite the terrors of internationalisation and patchy browser support — with a little fiddling and a lot of caution — this sexy threesome with adorable accents are ready to use now.

    → Read The <ruby> element and her hawt friends, <rt> and <rp>” on HTML5Doctor.com

  9. Block-level links, HTML5 and Firefox

    Firefox breaks HTML5-style block-level links (a link wrapping block not inline elements) when they contain HTML5 semantic elements. The link and first contained element are closed, and multiple new links are inserted. Wrapping the link content in a <div> can help, but the resultant behavior may still appear due to another bug (the infamous packet boundary bug).

  10. 12 common problems with HTML5

    A summary of some common misconceptions about HTML5, with answers and links to more information. An informal FAQ, if you will.

  11. HTML5 structure—HTML 4 and XHTML 1 to HTML5

    A look at the differences between a basic HTML 4 and XHTML 1 page and the same page using HTML5’s structural elements, plus the CSS/JS required for support in browsers, adding HTML5’s semantics via <div class=""> to get around ‘the IE problem’, and a summary of why you should be thinking about HTML5 now.

  12. HTML5 structure—header, hgroup & h1-h6

    Looking at the <header>, <hgroup>, <h1>-<h6> elements, with examples of <hgroup> use and a discussion of HTML5-style heading element levels (basically <h1> almost everywhere).

  13. HTML5 charset declarations & validation

    Updated! An in-depth look at why the W3C Validator lists charset warnings & errors when using the HTML5 doctype, and what you should do about it. This bug has been fixed! <meta charset="utf-8"> is good to go.

  14. HTML5 id/class name cheatsheet

    A concise list of class and id names based on HTML5 element names and general semantic structure. Also suitable for IE-friendly <div class="">-style HTML5.