Archive | Programming RSS feed for this section

Git: Squashing commits without merging a thing

This trick has saved me today and I’ve had to use it before… so I’m going to demonstrate how to do this here in my own words to save me Googling for every time!

So imagine the scenario. You’ve done a load of commits and you’re not ready to merge them back into master (or, even worse you’re in master) and you realise you made a massive mistake a few commits back and you need to just squash all the correction commits into it:

commit 6e0fa1b21e760aee2391f73c4905244a229abe8b
Author: Lee Packham <xxx>
Date:   Sat Jul 2 12:47:31 2011 +0100

    More tidy up (I'm a muppet)

commit abe08fd948f81f3366bc9a647e0d0c24ffe5fdc6
Author: Lee Packham <xxx>
Date:   Sat Jul 2 12:46:14 2011 +0100

    Tidy up

commit caefc1c0a8903009af2be8cd37df1ac40366fcce
Author: Lee Packham <xxx>
Date:   Sun Jun 19 08:21:03 2011 -0700

    Initial commit

Well that’s crap really isn’t it? So how do we go about sorting this? Well, we make a good use of rebase and tags to achieve this. There’s a nice answer to this on Stack Overflow – but I’ll replay it here. Props to Charles Bailey for this process.

So, here’s how we fix this:

# Checkout the top commit in a detached branch
git checkout 6e0fa1b21e760aee2391f73c4905244a229abe8b

# Now, do a soft reset back to the original commit
git reset --soft caefc1c0a8903009af2be8cd37df1ac40366fcce

# Now commit --amend it to squash it all
git commit --amend

# Then, tag this new detached commit
git tag tmp

# Now go back onto master
git checkout master

# Awesome now do a quick rebase and it'll replace the upstream with tmp
git rebase --onto tmp 6e0fa1b21e760aee2391f73c4905244a229abe8b

# No need for tmp now
git tag -d tmp

Not overly simple – but brings, in this case, master to where I wanted it to be!

Comments { 0 }

Making Qt Webkit and macdeployqt work

When making a Webkit app with Qt, bundling a .app will not work. Ok, so that’s not quite true – but it won’t run. This is a build bug on the Qt side – fixable with a small post-bundle step:

This will mean your app will no longer crash – so fairly useful.

Comments { 0 }

TweetDeck joins the Twitter flock

The last week has been, as I’m sure you can imagine, hectic. It’s all out the bag now – TweetDeck has been acquired by Twitter. It’s absolutely amazing news and I’m really proud to be a part of it. As part of the deal, my employment, along with the entire team, has transferred over to Twitter.

I came along fairly late in the day in all this having only joined in January of this year. I never guessed that by now I’d be working for Twitter as a Software Engineer. I’m totally stoked.

I’ll still be working on mobile clients – and hopefully I’ll get more time to work on Chrome hacks.

So, congratulations everyone! Special congratulations to Iain… it proves that scratching an itch really can lead you down paths you never expect. Let this be a lesson to Software Engineers / Programmers everywhere.

Comments { 0 }
Video

Hackday – Native TweetDeck

Here’s what I made during today’s HackDay @ TweetDeck. Our illustrious leader is uploading the rest now on the @iaindodsworth YouTube page.

Comments { 0 }
Link

TechCrunch give TweetDeck for iOS a ‘fly’

Very proud of this. TechCrunch do a Fly or Die review of the TweetDeck for iOS that I’ve been working on at TweetDeck for the last 3 months. They give it a fly.

The new TweetDeck for iPhone still lets you add as many columns as you want and swipe through to view different streams, but you also get a unified Home column, which can combine your Twitter and Facebook streams into one. The app has nice subtle touches, such as the diagonal swipe to see more Tweets from the same account (my favorite). And instead of timestamps cluttering each Tweet, the timestamp changes at the top as you scroll through your stream. If you want to jump to the top to the most recent Tweet, just tap the actual time (yeah, someone had to point that one out to me too, but these are the kinds of hidden features power users love).

Comments { 0 }
Link

Web Chat in 12 lines of code – NowJS

Thanks to @rcomian for the tip. Awesome use of Node.js.

Comments { 0 }
Link

Reply to Comments from Email on Github

This new feature from the Github team is just awesome. It’s about time it was added and it is a dream to use. I’ve been using it a lot! Thanks guys.

Comments { 0 }
Link

The 960 Grid System Made Easy

Read this on the way in this morning (thanks @Paul_Kinlan) it is a really good overview of 960.gs.

Comments { 0 }

Making git diff highlight whitespace issues

One of those while I remember posts. @mxcl doesn’t like whitespace randomly appearing in commits. Quite frankly, he shouldn’t like it, it’s evil and leads to merge conflicts. So here, quick config I grabbed off of cheat git which solves that problem without the use of GUI tools:

In .gitconfig

[core]
   whitespace=fix,-indent-with-non-tab,trailing-space,cr-at-eol
[color]
  ui = true
[color "branch"]
  current = yellow reverse
  local = yellow
  remote = green
[color "diff"]
  meta = yellow bold
  frag = magenta bold
  old = red bold
  new = green bold
  whitespace = red reverse
[color "status"]
  added = yellow
  changed = green
  untracked = cyan

Hope it helps someone else as much as it helps me! It not only shows problems, but removes them on commit as well.

Comments { 0 }

Fabric and ssh-agent (aka. Running GIT in Fabric)

When using Fabric for deployment there is one limitation that used to cause me no end of grief; it, thanks to Paramiko, does not allow ssh-agent usage over the connection so doing git stuff tends to fail… miserably.

There are a few examples around. However I found they didn’t work with the Context stuff that Fabric provides (namely the cd decorator) so… I came up with my own.

def _shell_escape(string):
    """
    Escape double quotes, backticks and dollar signs in given ``string``.

    For example::

        >>> _shell_escape('abc$')
        'abc\\\\$'
        >>> _shell_escape('"')
        '\\\\"'
    """
    for char in ('"', '$', '`'):
        string = string.replace(char, '\%s' % char)
    return string

def sshagent_run(cmd, shell=True):
    """
    Helper function.
    Runs a command with SSH agent forwarding enabled.

    Note:: Fabric (and paramiko) can't forward your SSH agent.
    This helper uses your system's ssh to do so.
    """
    real_command = cmd

    # We have to grab the env['cwd'] and then munge it blank
    # otherwise the call to local() will not run as it'll try and
    # do a local cd - that is not desired.
    cwd = env.get('cwd', '')
    env['cwd'] = ''

    if shell:
        # Handle cwd munging via 'cd' context manager
        cwd_cmd = ''
        if cwd:
            cwd_cmd = 'cd %s && ' % _shell_escape(cwd)
        # Construct final real, full command
        real_command = '%s \\"%s\\"' % (env.shell,
            _shell_escape(cwd_cmd + real_command))

    print("[%s] sshagent_run: %s" % (env.host_string, cmd))

    try:
        print local('ssh -p %s -A %s@%s "%s"' % (env.port, env.user, env.host, real_command), capture=False)
    except ValueError, v:
        print v
    finally:
        # Put the cwd back if needed
        env['cwd'] = cwd

Ok, so what’s going on here? First off, local() is context sensitive. We have to pull out the working directory context and stash it locally and ensure we put it back afterwards. This is why the finally is used. I essence this will run the command in the same way as run() would and you can specify that you do/don’t want the shell wrapped around it as required. The context is lost if you don’t use the shell – something that the normal run() command seems to do as well.

I’ve made this more of a drop in replacement – which allows me to do things like:

def update_myproject():
    with cd('/home/user/venv/djangostuff'):
        sshagent_run('/var/lib/gems/1.8/bin/git-up')

Oh and git-up is really your friend… Really really. Hope this is useful to someone.

Comments { 1 }