git track is where it's at

justin

Posted by justin at January 21st, 2009

Remembering git branch --track local origin/remote && git checkout local is proving to be as difficult as a Chief Justice remembering the presidential oath. On that note, here is a a quick rundown on git alias and a few simple examples to get you started.

git track foo origin/foo

[alias]
  track = !sh -c 'git branch --track "$0" "$1" && git checkout "$0"'

Here is a shorter version that assumes your local branch will be named the same as your remote branch and you'll always be pulling from origin/*.

git track foo

[alias]
  track = !sh -c 'git branch --track "$0" "origin/$0" && git checkout "$0"'

update: Tim points out git checkout -b foo origin/foo will track if you have branch.autosetupmerge=true.

Roll Your Own Git Alias

Git Aliases are a nice way to simplify your common tasks into simple commands. Not only can you chain together git commands like we did above, you can run entire scripts, whether it be bash, ruby, python, etc.

The formatting can sometimes be tricky, but one important thing to keep in mind is that unless you're simply aliasing git's built in commands, you'll need to prefix your commands with the ! sign. If your entire line is in quotes you'll want to put the ! inside the quotes, directly before your starting command only. One final note, you can accept arguments in your aliases using $n. Here are a couple more commands to give you some ideas.

git lh - find all commits affecting a Lighthouse ticket

lh = "!git log --pretty='format:%h [%ar | %aD] [%an] -- %s' | grep -i '\\[#[0-9]*'"
# == Output:
# 658f5c9 [2 months ago | Mon, 10 Nov 2008 13:46:16 -0200] [Nicolas Sanguinetti] -- Ensure managers can see a blog's profile even if it's still pending [#24 state:resolved]
# 48afbb9 [2 months ago | Mon, 10 Nov 2008 13:17:08 -0200] [Daniel Cadenas] -- Fixed. Can only change a user role if user!=current_user [#25 state:resolved]

git ignored - list all files that are ignored

ignored = "!git ls-files --others --exclude-standard"

So that's it! Do you have any useful aliases you want to share?

17 Comments

  1. Matt Todd Matt Todd said on January 21st, 2009

    Great aliases. I use a few, but the ONE that’s most interesting is:

    git ptp = !git pull && rake && git push

    And of course, I have “gist” as a shell alias to “git st”.

  2. Tim Dysinger Tim Dysinger said on January 21st, 2009

    Git tracks by default. You can just type a much shorter:

    git checkout -b local origin/remote

    and it branches, tracks and checks out – example:

    Duece:website tim$ g co -b local origin/qa Branch local set up to track remote branch refs/remotes/origin/qa. Switched to a new branch “local” Duece:website tim$

  3. Justin Palmer Justin Palmer said on January 21st, 2009

    @tim – I answered on twitter, but to keep the conversation centralized I’ll respond here too. If I’m not mistaken, you need autosetupmerge set for that to happen, right?

  4. Justin Palmer Justin Palmer said on January 22nd, 2009

    Just ran a test based on Tim’s comment and he’s right, `git checkout -b foo origin/foo` will track by default. Sweet stuff all around. Thanks Tim!

  5. Nathan de Vries Nathan de Vries said on January 22nd, 2009

    Yeah, you definitely need “branch.autosetupmerge” set to true for auto-tracking to occur. I personally think it should be a default.

  6. Justin Palmer Justin Palmer said on January 22nd, 2009

    OK, apparently I’m blind. I did have autosetupmerge set in my local repo. Otherwise, git checkout won’t track.

  7. Nicolás Sanguinetti Nicolás Sanguinetti said on January 22nd, 2009

    I have on my ~/.gitconfig: nb = checkout -b (git “new branch”). Also of use to me are st = status, co = checkout and my favorite: up = !git fetch origin && git rebase origin/`git branch | grep \"^*\" | cut -d\" \" -f2`.

    That last one can probably be cleaned a bit with some git fu, but basically fetches the refs in origin and then rebases your local branch against the same branch in origin (I don’t like merge commits in my history, they look dirty—specially when it’s just fetching remote commits into the current branch)

  8. Matthew Todd Matthew Todd said on January 22nd, 2009

    These make `git pending` show me what I’m about to push:

    [alias]
            pending = !git --no-pager log origin/master..master && echo
    [format]
            pretty = format:"%Cblue%ar%Creset\t%s" 
    
    • —no-pager to avoid big gaps of whitespace from less
    • echo since git log’s not giving me a trailing newline
    • format is blue relative timestamp, tab, 1st line of commit message
  9. Mike Champion Mike Champion said on January 22nd, 2009

    I set up a ‘git track’ alias but to track an existing branch that I pushed remote (different than starting by cutting a local branch from the remote branch). Details are here: http://graysky.org/2008/12/git-branch-auto-tracking/

  10. Justin Palmer Justin Palmer said on January 22nd, 2009

    @Matthew nice! I didn’t know about the color options in `format`. That cleans up `git lh` a bit:

    lh = "!git log --pretty='format:%Cblue%h %Cred%ar %Cblue%an %Creset -- %s' | grep -i '\\[#[0-9]*'"
  11. Markus Prinz Markus Prinz said on January 22nd, 2009

    I also have a “retrack” alias which allows me to (surprise) retrack a given branch to a different remote one (or set up tracking if there wasn’t any before): http://gist.github.com/29095

  12. Grant Hollingworth Grant Hollingworth said on January 22nd, 2009

    Do you guys only use the first line of the commit message? I normally put the the ticket number in the body of the message. To grep that, too, you need to add %b to the format:

    lh = "!git log --pretty='format:%Cblue%h %Cred%ar %Cblue%an %Creset -- %s %b' | grep -i '\\[#[0-9]*'"

  13. Adam Patten Adam Patten said on January 22nd, 2009

    I tend to be a heavy brancher so I frequently clean up old branches locally and on origin as well. This takes care of it in one step. It also silences any errors that occur if the branch didn’t make it up to origin.

    delete = !sh -c 'git branch -D "$0" && git push origin ":$0"' &> /dev/null
  14. Mislav Mislav said on January 26th, 2009

    Nicolás, dude …

    Just do this on a tracked branch:

    git pull --rebase
  15. raggi raggi said on January 26th, 2009

    I use:

    <macro:jscode> git config branch.master.remote origin git config branch.master.merge some_amazing_branch </macro>

    It offers more flexibility than this ‘tracking’ idea, especially if you deal with very distributed repos.

    You can also do this at any time, on the branch. No need to rebase or reset.

  16. raggi raggi said on January 26th, 2009

    Your comment help text lies!

  17. Nicolás Sanguinetti Nicolás Sanguinetti said on February 8th, 2009

    Lately, for OSS projects I contribute to, I’ve been doing this: fork the project on github, and then clone my fork as origin. Then, I add the canonical repository as “canon”, and before working on anything, I reset (—hard) to canon/master. Thus:

    `update-canon = !git fetch canon &>/dev/null && git checkout master &>/dev/null && git reset—hard canon/master`

Make your voice heard

Sorry, but comments are closed for this item.