Saturday, August 30, 2014

The Git Hater’s Guide To Git


What is this?

This may shock you given the name of this blog entry, but I really hate Git. It’s become a source of entertainment to my coworkers, and frankly to me as well because if you’re going to hate something then it should at LEAST be a source of amusement.

One day they said hey, at least you have figured out how to work with Git, maybe you should write up what you’ve learned! Maybe it’ll be useful!

I don’t think this is what they intended. But I’m really not sorry. So here is my guide to working with Git. This assumes you have Git working and are banging your head against something while you try to use it.

Start by editing your ~/.gitconfig file. Bring over the alias section from mine, and also bring over the two sections on mergetool and diff tool (see the Perforce tool below on what those are.)

Well then!

Welcome to Git! Let me start by saying I'm very, very sorry. It does get a little better once you're used to it. Not much better. But a little.

I'll put this link first. This is a word document with the commands I need to refer to the most. It's more geared to being a single page than a reference though.


And here is my .gitconfig file, located in my home directory, for reference:


Note that I’m using either a Mac or a Linux box so everything is filtered through that. I’ve happily kept Git off my Windows boxes so far.

Your Mindset

Git hates you. Git is really looking forward to destroying your code. Git is hoping you'll let it destroy other people's code in the process. You HAVE to keep that in mind when you work with Git. Just thinking you can use Git to casually check in code will result in you spending the rest of your day trying to figure out what happened and how to fix it. And it's quite possible that you won't be able to.

I can't stress this enough.  My mental model of using Git has become that of lion taming. You stand there with your chair and your whip and you pay careful attention to everything. The moment you relax, the lion jumps on you and destroys you. This is Git. This is what sets Git aside from everything else. If you're used to trusting your source code repository not to destroy code, that's the very first mindset change you have to make. You can NOT trust Git. EVER.



The internet has many horror stories about Git. The one that stuck with me is the guy that found the command on stack overflow of "git push --mirror". Seem innocuous, it just pushes up code, right? But it just about wiped out his central repository and did so irrevocably. There's nothing in the command to make you THINK it'll do something like that - but it turns out that command will wipe any branches on the central repository that you don't have. And it does it gleefully and permanently. So ... the lesson? Googling for what to do is frequently the only way to work with Git, but check what you find carefully and think about it before you take any advice. And think about where you will restore your code from if Git destroys your repository when you run the command.



Welcome to Git!


Git Concepts As I Translate Them



First, terminology. You have to get used to the word "origin". To me, since I wrote the code, the origin is me. To Git, the origin is the source repository - which to me is the destination. I'd say that therefore this is a TERRIBLE choice of terminology - avoiding ambivalence like this is about the very first step in usability. So let this be the first lesson - Git has not taken that very first step into usability. Get used to that.


I originally renamed "origin" as "mtn" (as I work for MTN) to avoid ambivalence and it helped - but there is a pitfall there. You will not be able to use Git without constantly googling to find out what to do with whatever arcane error it's throwing at you. And everyone has gotten used to "origin" so all the code out there uses that, meaning you'll have to get used to it anyway. So "origin" means ... well, unfortunately, the only unambivalent word to me for Git’s "origin" is "destination". "Origin" is where you want your code to end up, origin is the final destination you push your code to. The Git definition, however, is that it is the original repository. It's just something to get used to.

Branching - The Only Cool Thing About Git.

The original title was "Branching: Git Invents New Ways to Permanently Destroy Your Code Changes". Branching is a great idea, horribly hobbled by the fact that it's in Git.

The basic idea behind branching is that if you want to start making changes to your code base but not put them into the main code repository, you can create a branch. Then you can do work off to the side in that branch, and merge it back to your main repository when it's ready. The idea is cool. The execution, unfortunately, scares me. The main thing to remember is that section above, Git HATES you. So if you branch, Git just sits around hoping you'll type the wrong thing so that it can delete your local branch and destroy your code changes. But there are times you can't avoid it.

I originally tried creating a branch called dev, and doing all development work in it until I learned just how confused this can make Git. (I was hitting regular problems with Git being unable to merge code, even though I’m the only developer and all changes were linear.) So I stopped branching and just live in the master branch, and a lot of issues went away. I’m told this becomes problematic once you have multiple developers, all I can say is that if Git can’t merge my changes when I’m the only developer doing linear changes I live in fear of the day someone else checks in code.

But the idea is great, and other than trying to use Git to implement branches, it’s pretty sweet. I have actually started using branches more as we release code – the released code gets it’s own branch – so I will warn you of the new gotcha I did find where Git gives you no clue what branch you are in and will get hopelessly snarled if you forget, which you will eventually.

Workflow - A New Height in Unusability

The basic idea of workflow that I've always had is that you check code in. Not complex. This is where Git really spent effort making itself convoluted. I found some graphs comparing Git to Subversion which illustrate this wonderfully on Steve Bennett’s blog. Here's the subversion workflow (Perforce and most other tools have a similar workflow):




Not bad. You checkout code to get the latest code from the central repository. And you checkin (or commit) code to push it back up. And then there is the Git workflow:



Realize they effectively do the same things. The difference is that Git hates you.

To cope with this, I stick to the same golden path workflow as strictly as I can. If I step outside of this golden path, I consider myself in a minefield. And even in this workflow? Remember that lion taming module. If you get complacent, something will get corrupted. I guarantee it.



We'll talk about that in a minute but first - there are some tools to install to make things easier.


There are two toolsets I've been using to make Git suck a little bit less - Perforce and SourceTree. I'd consider SourceTree optional, though extremely helpful. Perforce I consider mandatory.

Perforce for Merging


I found this on the net. It summarizes my experience merging in Git’s default tools.

There are some areas in Git that are so unusable that I just flat out gave up. Merging is one. I tried, but this is where Git really took unusability to new heights. I recommend trying to do a merge with Git to entertain yourself one day. Just don't expect to come out of it with a merged file. I think they included merging as a practical joke.

Git does have hooks that let you use other tools though, fortunately. I played with some of them, and Perforce won hands down. So I recommend wiring Perforce in for merging. Perforce is another source control system. But unlike Git, Perforce likes you. They like you so much that they made some of their tools free, and they really save the day here.

So download and install them!

Then in your .gitconfig file make sure you have the following sections, with the path for "cmd" modified as needed. See my gitconfig (attached above) for reference. This will use the Perforce tools in both the git commandline and in SourceTree.


[mergetool "p4merge"]

cmd = /Applications/ "\"$PWD/$BASE\"" "\"$PWD/$REMOTE\"" "\"$PWD/$LOCAL\"" "\"$PWD/$MERGED\""

keepTemporaries = false

trustExitCode = false

keepBackup = false

[difftool "p4merge"]

cmd = /Applications/ \"$LOCAL\" \"$REMOTE\"

keepTemporaries = false

trustExitCode = false

keepBackup = false

[difftool "sourcetree"]

cmd = /Applications/ \"$LOCAL\" \"$REMOTE\"

path =

[mergetool "sourcetree"]

cmd = /Applications/ \"$BASE\" \"$LOCAL\" \"$REMOTE\" \"$MERGED\"

trustExitCode = true


tool = p4merge


tool = p4merge


Then when you need to merge files just type the following:

git mergetool

and you'll get Perforce's merge tool instead of Git's merge. Note that the download page has a video on how to use these tools. In essence the top has three columns, the original file, the file with your changes, and the file with the other changes you're trying to merge in. The bottom has all the changes merged using P4's best guess. Just look for the button at the top to go to the next conflict, and edit the code at the bottom to be as desired.


I looked for tools to give Git a front-end that would give it similar usability to the other tools on the market. Frankly I failed. Git is never going to be in the same league as the other tools when it comes to usability, nor does it have any interest in this. But SourceTree helps a LOT.


It's a free tool that you can download it for Mac or Windows here:

It is on the Mac App Store, but they aren't updating that version anymore, so I recommend downloading it directly.

I tend to do my most basic workflow in SourceTree, then break out to the command line for anything out of the norm.

In SourceTree, click "File -> New" and paste in the repository URL from Github. It will clone that repository for you. Add a bookmark as well.

When you open a repository in SourceTree, it shows you all changed files in a bottom window pane. Highlight a file (or all files) and click the Add button. It moves them to the upper pane - and note that the right side shows you a diff. So that's pretty nice.

Once you have the top pane the way you want it, click "commit". This commits to the local git repository, and does NOT go off your machine. But look at the bottom of the window that pops up and you'll see a checkbox that says "push commit immediately to " and a dropdown box. Mine defaults to "origin" and I haven't been able to change that to my personal repository, but so I just check the box and change it to my local repository. Put your comment in the top, hit "commit", and it's off!

If you hit "Repository -> settings" you can see the repositories you have set up and change them.

Now look at the left of the screen. Note that you can see repositories and branches. It will default to the active branch, so normally it just does what you'd expect. And normally I just keep it on "Working Copy" which shows me what I want to see. Highlight any other branch, and you can see history of all the branches that have happened. 

SourceTree is also the best place to view checkin history. Git and Github are TERRIBLE at this, so this was huge to me. In SourceTree, find the remote branch you're interested in on the left and click it. You'll see a list of all commits in the upper right pane - highlight one, and all the code changes show up below it. If you right click a file, you can choose "log select" and it'll show you the history of that file. No, I have NO idea what they were thinking when they labelled that "log select". My only guess is that someone at SourceTree hates you in subtle ways. They ARE a Git front end, so there has to be usability issues somewhere. If not they’d be thrown out of the Git community I suspect.

Github does have a history button now that's good for checking the history of a single file. Pull up the file in Github and you'll see the history button.

If you get more advanced, select a branch in SourceTree. View the history. Right-click a commit in the history picture and you'll have access to tools that will corrupt your Git repository in more ways than I care to document. If you do a LOT of reading they'll let you do cool things, but for now just assume each one of them will corrupt your repository in different and entertaining ways.


IntelliJ has a lot of Git support built in, and can actually issue a lot of Git commands. Frankly I just don't trust Git enough to do this. Remember that lion taming mental picture? Somehow to me this is just jumping into the lion cage with blinders on so that you can’t see everything and then hoping it’ll all work out. I don't trust that this will not result in my being eaten by the lions. So while I tinkered with the Git plugin I don't use it.


When you're looking at a single file, hit control-V. A CVS popup will appear. If you hit "local history" you can see some history of the file. This has been pretty handy. It's not a full history - I think it's just a history of the branch - but it's still quite useful!

The Golden Path


Fetching Code

Don't write any code without making sure what branch you're in. Unless you aren't using branches, which means you can skip over several potential problem areas.

git branch

If you aren't in the branch you think you are, then change branches:

git checkout {branchname}

Then get the latest code from origin. That doesn't actually do anything with the code though, so you have to then tell git to actually put the code in your local branch.

git fetch origin

git mf origin/master

Git will ONLY apply those changes to the branch you're in, though. So you have to rerun the "git mf origin/master" in each branch when you get there. Frankly I just scripted the whole thing. Then I added some cleanup code to it. I put these lines in my alias file:

alias git=hub

alias gitprune='echo before;git branch -a;git fetch --prune;git fetch --prune origin; git fetch --prune evanthx;echo after;git branch -a'

alias gitmf='git mf origin/master'

alias gitfetch='gitprune; git fetch origin; gitmf'

Now just type gitfetch. The prune commands delete the old branches that you THOUGHT you deleted and that git TOLD you it deleted, but git lies constantly. So I just stuck those in my aliases because frankly, when I told git I wanted to delete a branch I actually wanted the branch deleted. This way it will eventually get git to do what it already lied to me about doing.

Note that using this relies on aliases being defined in your .gitconfig. I thought about rewriting all my scripts for this without aliases, but frankly you'll be happier with them.

Also feel free to rename the "gitfetch" command to something really snarky so that you can stick it to the man every time you fetch code.

Pushing Code

Now we have all the tools we actually need to use Git and hide a lot of the horribleness. I'll be honest. This workflow is still just insane. But you eventually get used to it. Git is one of those things where you really just have to hold on until Stockholm Syndrome sets in and then you finally start explaining to people why the workflow below really makes sense! No, really! It does!




Create a branch and get into it (IF you are using branches.)

Make some code changes.

Go into SourceTree. Highlight each changed file and click "add".

Once all files are in (and you've checked the diffs on the right) click commit.

Check the commit box to go to your personal repository.

Go to Github, go to the central repository and issue a pull request.

Once the pull has been merged, go to the commandline and type "gitfetch" (which is an alias defined above.)

That fetches your commands and merges them in the nice way. It'll fail a lot. When it does, my default is to type "git pull" which tries to merge the changes a different way. It usually will work. When it doesn't, see the next section.

(Fun note : Compare this to other products. The work flow in Perforce? Add files, commit them. DONE! This is the difference between a tool that loves you and a tool that hates you.)


Git Commands I Use

Even with your best attempts to stay on the golden path, Git will regularly get screwed up. You might consider this surprising, but then just remember to yourself how much Git hates you on a deep, personal level. The real problem as far as I can tell is that when you use branches you have to sort of circularly update back to yourself. If you push something to the central repository, you also have to bring it back down to merge back in with your source code - in other words, you have to commit the code with SourceTree, then pull it back down with the Gitfetch code I have in my alias file. This just opens the doors to Git confusing itself, and it does.

So when it does, what do you do?

Push Your Repository

The first common issue I have is when you have code the way you want it. You need to check it in, but Git is failing on something and won't let you. You can force a push, telling git to shut up and just take the changes.

git push -f origin master

Note "origin" in there. That goes to the central repository, not your local one. So you might consider that. If you put the wrong repository in there, git will actually laugh while it destroys code. And if you do it right, you'll need to tell the other developers in that repository so they don't get confused. It can cause problems otherwise...


The fact that I found this image on the net as is at least lets me know I’m not alone in my pain.

Get Git's Repository

The next common issue is when what is in Git is correct and I want it, but Git can't get it for me. Git reset will do this. To force Git to put it's changes over top of the local repository:

git reset --hard origin/master

By the way, note that for a push there is a space between origin and master. For reset, there is a slash between them. You'd think that sort of thing would be consistent from command to command, but consistency would be a step along the path to usability. Git therefore has ensured a total and complete lack of consistency. It hates you.

One other way to do this that I've used with great success is to just delete your repository and reclone it. That works very well - as long as you aren't using branches. It'll delete any branches you may be using, so that's really not something to do casually. But on build machines, for example, where you just want to check out files and never check in? I've had Git get so snarled up trying to do that that I just gave up and killed and recloned the repository. I have yet to figure out HOW Git got that snarled up. I think it did it on purpose.

Undo A Checkin

So say you accidentally checked code in to the wrong repository and want to undo it. In most other source controls, you'd just check out at the desired spot, then do a new checkin. You can do that in Git as well, but since Git is pretty much geared to lie to you about history, you might as well take advantage of that by combining the two above options.

First, you need the sha-1 of the commit you want to get back to. You can find it in SourceTree, right click it, and choose "Copy Sha-1 to clipboard". You can also find it in GitHub, and it has a button that will let you copy it to the clipboard as well.

Then issue these two commands to set your local branch to that point in history, then to force that up to GitHub. That will erase all branches AFTER the sha-1 you chose - meaning again, do this casually and Git will laugh at you while it wipes code.

git reset --hard {sha-1}

git push -f origin master

Scripting git commands

Banana 6

You may or may not ever script Git commands. It seems like a great idea! It's all command line driven, so just throw things into a script and you're set!

This was my original thinking, so I did some build scripts and a few other things. And I was getting really weird errors. And I finally figured out - Git fails a lot. If you think you can just check out code - even on a build machine that never does anything but get the latest iteration of code - then you really haven't gotten the basic message about Git. You got complacent.



The basic issue is that Git fails. And it hates you, so it'll look for great times to fail when you won't notice, like when you scripted it. So here's a handy command that I use in zshell scripts:

read -p "Press [Enter] key to continue..."

All it does is stop the script until you press the enter key. Put that after EVERY Git command. Then when you run your script, you can actually review the output of the Git commands and see what they say. This was another mindset change for me, I'm used to just writing a script carefully and then it works - but you just can't trust Git to work. Because whenever you just trust Git to work without carefully checking ...


Thursday, July 31, 2014

Las Vegas!


I’m going to be performing in Las Vegas in October!

I wanted to go to Vegas to see some magic shows. I’m not a gambler, but there’s a lot of GREAT magicians there. And a friend of mine said “If you’re going to Vegas you should perform”, made some introductions for me … and I’m going to be in a show in Vegas! The best part is that it is a show run by Jeff McBride, who is a magician I admire. So having him look at my stuff and think I am good enough to be in a show with him has me DELIGHTED.

There’s a magic convention there so I figured I’d time the trip for that convention, which should make a great trip. Only I have been dilly-dallying about polishing up a pet routine so … I showed them the current incarnation of the routine, and I am not committed to performing it for a whole bunch of really good magicians. So yeah. No stress. On the other hand – sometimes a deadline like that really helps get things done, so I’m glad I did it!

Sunday, January 26, 2014

Family Variety Show Finds Itself Pitted Against the Seahawks in The Superbowl


Producer Not Filled with Confidence

Evan’s Family Variety Show runs on the first Sunday of every month at the Jewelbox Theater at Rendezvous, in downtown Seattle. It’s a family oriented show, and the only variety show in town that’s geared to a family audience with a rotating cast magicians, jugglers, acrobats, and much more.

On Sunday the 19th Evan was excited to see the Seahawks win the game against the 49ers – until he realized that the Superbowl was going to be the exact same date and time as his next show on Feb 2nd.


The Discovery

Evan decided to soldier on. Maybe turnout would be low, but he really didn’t want to cancel a show. Ticket pre-sales weren’t bad, so maybe it would all work out!

A day later, the cast was asking if there was any way to get out of the show so they could see the Superbowl, and ticketholders were asking if there was any way to transfer their tickets to a different date. And talking to the theater? They were rather hoping to have a Superbowl party too.

And the kicker? Evan’s eight year old son, who has been to every show and LOVES them, asked to skip this show to go to a Superbowl party their neighbors are having.

So having the cast, audience, venue and even his own family all saying they won’t attend … the outlook for the show has never been worse.

But March! March is going to have a FANTASTIC show!

For details on the show:

Friday, June 07, 2013

CanCan show!

I did a show at the CanCan! I am really pleased about that. It's a different audience for me, a really cool venue, and was just a fantastic experience.

My friend Jozie agreed to help me - having her really cut down on the number of volunteers I'd have to ask for and just made things go more smoothly. The staff was really nice and got us to the changing room, and we got ready and set up the stage. We had several people there and while not a huge crowd, frankly I thought we did well given the limited time we had to advertise the show!

The show seemed to go well and seemed to be received well. I couldn't quite get folks laughing as hard as I usually do, I'm not sure if it was just that this was such a different venue or what, but that being said folks WERE laughing and seemed to be enjoying themselves. All the magic went well, and I heard a lot of compliments afterwards, so THAT made me quite happy.

And frankly I'm still just delighted - I got to do a show at the CanCan! Hopefully I'll get to do more, but even if I don't? I'm pretty thrilled!

Friday, April 26, 2013

First Tin Theater show!


Last weekend was the first show at the Tin Theater. That theater is amazing – it’s a very nice bar/restaurant, with a great theater attached. I got there and got set up, and met Michelle. This was my first show that was done with Michelle – she found the theater and did publicity, and we sold the place out! It was GREAT!

The audience was really friendly and appreciative, too – everyone seemed to laugh a lot and really have a good time. I tried my new routine there and even though this was the first time I had it out, I heard from one person that it looked like a signature routine. YAY! I kind of thought it might work into that, but I was excited to hear it already! But it’s funny and very different – so I was hoping it’d be good.

I talked to lots of people afterwards and it really seemed to go well. I’m very pleased, and really looking forward to doing it again next month!

Saturday, March 16, 2013

More shows coming


Well, THIS got interesting. The March show at the Jewelbox was not only sold out but I had to turn people away. I didn’t like turning people away but that was AWESOME that we sold out. For those wondering what it’s like to run a show, it’s terrifying. You do all this work and then you just hope people will actually show up to see it. So seeing a full house was fantastic.

A lot of folks stayed to eat at Rendezvous to eat afterwards. I gave everyone that did a free gift and did some closeup magic for them – the stuff I do at corporate events – and that went really well and is something I plan to continue doing!

The March show was the last show I had scheduled at the Jewelbox. But between selling out and everyone staying to eat, the Jewelbox seems to be fairly happy with me! YAY! I am now talking to them about what we’re doing next – basically I will be doing more shows there and just need to decide if I can pull together an April show or if I need to skip a month and pick up in March.

But there’s more. I’ve been working with a fantastic woman named Michelle, who ROCKS. And she has managed to hook me up with a second show in Burien! This one is a solo show – I’m not sure I could pull off two variety shows – so it’ll just be me doing my one man show. The theater is the Tin Theater and it’s just a GORGOUS theater. It seats about 50, so the shows will be really intimate. We are sticking with the family show theme, though, and affordable tickets – so bring your kids! I’ll be doing some stuff for your kids, some stuff for you, and everyone should have a really fun show!

That should start on the third Sunday in April and continue on third Sundays. The Jewelbox will be on second Sundays.

And yes, there’s more … I’ve been working with a juggler and acrobat named Will Smith, who has helped behind the scenes with lining up acts for the Jewelbox and just making it work. And occasionally BEING on of the acts with his partner Jenny. Will is going to start helping me onstage as my partner, which should bring a lot of humor and extra fun to the stage!

Tuesday, March 12, 2013

The last show went GREAT. Payne opened and was fantastic as always. Jenn Q and the Fantastic Fonzie did their dog act - it was adorable and I could tell all the kids loved it. My son talked about that one a lot afterwards! Bohemian Acro did a really cool balancing act and I closed.

This is the last of a run of three shows I had at the Jewelbox. Sales went up each time and the show seems to be going great. I want to keep it going, and will be figuring out what happens next very soon!
Copyright © Magic and Technology
Blogger Theme by BloggerThemes | Theme designed by Jakothan Sponsored by Internet Entrepreneur