<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">
  <id>http://justinhileman.info/</id>
  <title>justin hileman dot info</title>
  <updated>2012-01-11T18:53:09Z</updated>
  <link rel="alternate" href="http://justinhileman.info/" />
  
  <author>
    <name>Justin Hileman</name>
    <uri>http://justinhileman.com</uri>
  </author>
  <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.justinhileman.info/justinhileman/blog" /><feedburner:info uri="justinhileman/blog" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry>
    <id>tag:justinhileman.info,2012-01-11:/article/my-baby-can-dance/</id>
    <title type="html">My Baby Can Dance</title>
    <published>2012-01-11T18:53:09Z</published>
    <updated>2012-01-11T19:02:07Z</updated>
    <link rel="alternate" href="http://feeds.justinhileman.info/~r/justinhileman/blog/~3/0FoEUOiPBDY/" />
    <content type="html">&lt;iframe width="560" height="315" src="http://www.youtube.com/embed/6a3TNV5ApMs" frameborder="0" allowfullscreen="allowfullscreen"&gt;&lt;/iframe&gt;

&lt;p&gt;This is my favorite song by the lovely and talented Carsie Blanton. &lt;a href="http://www.carsieblanton.com/"&gt;And there’s a lot more where that came from&lt;/a&gt;.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/justinhileman/blog/~4/0FoEUOiPBDY" height="1" width="1"/&gt;</content>
    <summary type="html">&lt;iframe width="560" height="315" src="http://www.youtube.com/embed/6a3TNV5ApMs" frameborder="0" allowfullscreen="allowfullscreen"&gt;&lt;/iframe&gt;
</summary>
  <feedburner:origLink>http://justinhileman.info/article/my-baby-can-dance/</feedburner:origLink></entry>
  <entry>
    <id>tag:justinhileman.info,2012-01-01:/article/my-year-in-cities-2011/</id>
    <title type="html">My year in cities, 2011</title>
    <published>2012-01-02T07:18:41Z</published>
    <updated>2012-01-02T07:57:05Z</updated>
    <link rel="alternate" href="http://feeds.justinhileman.info/~r/justinhileman/blog/~3/I8usU-Ta3UE/" />
    <content type="html">&lt;p&gt;It’s that time of year again. I spent at least one night in each of these cities in the past year:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Blue Bell, Pennsylvania&lt;/li&gt;
  &lt;li&gt;Boston, Massachusetts&lt;/li&gt;
  &lt;li&gt;Goreme, Turkey&lt;/li&gt;
  &lt;li&gt;Istanbul, Turkey&lt;/li&gt;
  &lt;li&gt;Logan, Utah&lt;/li&gt;
  &lt;li&gt;New York, New York&lt;/li&gt;
  &lt;li&gt;Orem, Utah&lt;/li&gt;
  &lt;li&gt;Pleasantville, New York&lt;/li&gt;
  &lt;li&gt;Roxbury, New York&lt;/li&gt;
  &lt;li&gt;Saint Paul, Minnesota&lt;/li&gt;
  &lt;li&gt;Salt Lake City, Utah&lt;/li&gt;
  &lt;li&gt;San Francisco, California&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;How about you?&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/justinhileman/blog/~4/I8usU-Ta3UE" height="1" width="1"/&gt;</content>
    <summary type="html">&lt;p&gt;It’s that time of year again. I spent at least one night in each of these cities in the past year:&lt;/p&gt;
</summary>
  <feedburner:origLink>http://justinhileman.info/article/my-year-in-cities-2011/</feedburner:origLink></entry>
  <entry>
    <id>tag:justinhileman.info,2011-11-07:/article/required-git-reading/</id>
    <title type="html">Required (Git) reading</title>
    <published>2011-11-07T18:43:54Z</published>
    <updated>2011-11-07T18:50:26Z</updated>
    <link rel="alternate" href="http://feeds.justinhileman.info/~r/justinhileman/blog/~3/_185Ije_-so/" />
    <content type="html">&lt;ul&gt;
&lt;li&gt;&lt;a href="https://twitter.com/#!/tabqwerty/status/45611899953491968"&gt;git gets easier once you get the basic idea …&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://tomayko.com/writings/the-thing-about-git"&gt;The Thing About Git&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://think-like-a-git.net/"&gt;Think Like (a) Git&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;img src="http://feeds.feedburner.com/~r/justinhileman/blog/~4/_185Ije_-so" height="1" width="1"/&gt;</content>
    <summary type="html">&lt;ul&gt;
  &lt;li&gt;&lt;a href="https://twitter.com/#!/tabqwerty/status/45611899953491968"&gt;git gets easier once you get the basic idea …&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://tomayko.com/writings/the-thing-about-git"&gt;The Thing About Git&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://think-like-a-git.net/"&gt;Think Like (a) Git&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</summary>
  <feedburner:origLink>http://justinhileman.info/article/required-git-reading/</feedburner:origLink></entry>
  <entry>
    <id>tag:justinhileman.info,2011-11-03:/article/changing-history/</id>
    <title type="html">Changing history, or How to Git pretty</title>
    <published>2011-11-04T03:37:20Z</published>
    <updated>2011-11-04T05:15:07Z</updated>
    <link rel="alternate" href="http://feeds.justinhileman.info/~r/justinhileman/blog/~3/oEC-39GbduE/" />
    <content type="html">&lt;p&gt;OpenSky’s engineering and product teams have an ongoing lunchtime presentation series called Lunch and Learn. A couple
of weeks ago, I gave a talk entitled “&lt;a href="/article/git-pretty/slides/"&gt;Lunch and learn2git&lt;/a&gt;”. This article is an expansion on that presentation,
and covers lessons learned from using Git in the open source community.&lt;/p&gt;

&lt;h2 id="lesson-one-code-is-messy"&gt;Lesson one: Code is messy&lt;/h2&gt;

&lt;p&gt;… what with all this branching.&lt;/p&gt;

&lt;p&gt;&lt;a href="/article/changing-history/opensky-branches.png"&gt;&lt;img src="/article/changing-history/opensky-branches.png" alt="OpenSky project branches"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;aside&gt;&lt;p&gt;If you haven’t checked out &lt;a href="https://github.com/symfony/symfony/network"&gt;GitHub’s network graph visualizations&lt;/a&gt;, you should. They’re quite impressive.&lt;/p&gt;
&lt;/aside&gt;&lt;p&gt;The above graph represents approximately a week of development in OpenSky’s primary repository. In a given two-week
period, we branch (and merge) between 75 and 150 discrete feature branches. We began using internal pull requests 77
days ago, and we just closed pull request 718. As you can imagine, it gets a little crazy.&lt;/p&gt;

&lt;h3 id="swimlanes-make-sense-of-the-chaos"&gt;Swimlanes make sense of the chaos&lt;/h3&gt;

&lt;p&gt;One of my favorite ways to wrap my head around development graphs like this comes from
&lt;a href="http://nvie.com/posts/a-successful-git-branching-model/"&gt;Vincent Driessen’s &lt;code&gt;git-flow&lt;/code&gt; branching model&lt;/a&gt;. It takes the standard graph visualization and turns it into
swimlanes:&lt;/p&gt;

&lt;p&gt;&lt;img src="/article/changing-history/git-flow.png" alt="Yay swimlanes!"&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://nvie.com/posts/a-successful-git-branching-model/"&gt;The full article&lt;/a&gt; is well worth a read. For the purposes of our discussion today, it is probably enough to
know that at OpenSky we use a combination of git-flow and &lt;a href="http://scottchacon.com/2011/08/31/github-flow.html"&gt;GitHub flow&lt;/a&gt;, which is a bit more relevant for
the topic at hand.&lt;/p&gt;

&lt;h3 id="git-flow"&gt;git-flow&lt;/h3&gt;

&lt;p&gt;At a high level, &lt;code&gt;git-flow&lt;/code&gt; enforces a branching model with two primary branches: &lt;code&gt;develop&lt;/code&gt; and &lt;code&gt;production&lt;/code&gt;. All
development, unsurprisingly, happens in the &lt;code&gt;develop&lt;/code&gt; branch. More specifically, it happens in feature branches which
are merged back into &lt;code&gt;develop&lt;/code&gt;. This &lt;code&gt;develop&lt;/code&gt; branch is always production-ready. It is periodically tagged and merged
into &lt;code&gt;production&lt;/code&gt;, and released into the wild.&lt;/p&gt;

&lt;p&gt;So rather than worrying about the hundred-ish currently active branches in our repo, all I care about are three:
&lt;code&gt;develop&lt;/code&gt;, &lt;code&gt;production&lt;/code&gt; and whatever &lt;code&gt;feature&lt;/code&gt; branch I’m currently working in.&lt;/p&gt;

&lt;p&gt;With this mental filter in place, our repository becomes much easier to understand:&lt;/p&gt;

&lt;p&gt;&lt;img src="/article/changing-history/git-flow-filtered.png" alt="git-flow swimlanes that I actually care about"&gt;&lt;/p&gt;

&lt;h3 id="github-flow"&gt;GitHub flow&lt;/h3&gt;

&lt;p&gt;Scott Chacon from GitHub &lt;a href="http://scottchacon.com/2011/08/31/github-flow.html"&gt;posted a response to git-flow&lt;/a&gt;, which outlines GitHub’s development workflow.
It’s similar, but optimized for GitHub’s style of continuous deployment.&lt;/p&gt;

&lt;p&gt;Like &lt;code&gt;git-flow&lt;/code&gt;, GitHub’s workflow involves a production-ready branch, but in this case it’s the &lt;code&gt;master&lt;/code&gt; branch. All
features branch from &lt;code&gt;master&lt;/code&gt;, and development happens there. When a feature is ready for release, the developer opens a
pull request, inviting code review and feedback. Once the feature has had enough eyeballs on it, the pull request is
merged into &lt;code&gt;master&lt;/code&gt; and released.&lt;/p&gt;

&lt;p&gt;While we’re not (yet) doing continuous deployment, OpenSky has moved toward a GitHub-style workflow, and the primary
reason is pull requests.&lt;/p&gt;

&lt;h3 id="pull-requests"&gt;Pull requests&lt;/h3&gt;

&lt;p&gt;These are the big awesome in GitHub’s workflow.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;GitHub has an amazing code review system called Pull Requests that I fear not enough people know about. Many people
use it for open source work - fork a project, update the project, send a pull request to the maintainer. However, it
can also easily be used as an internal code review system, which is what we do.&lt;/p&gt;

  &lt;p&gt;Actually, we use it more as a branch conversation view more than a pull request. You can send pull requests from one
branch to another in a single project (public or private) in GitHub, so you can use them to say “I need help or review
on this” in addition to “Please merge this in”.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="http://scottchacon.com/2011/08/31/github-flow.html"&gt;Read Scott’s article&lt;/a&gt; for more reasons you should use pull requests as a regular part of your development
workflow. We do, and they have become one of the best code review and collaboration tools we use.&lt;/p&gt;

&lt;h2 id="lesson-two-pretty-pull-requests-get-merged"&gt;Lesson two: Pretty pull requests get merged&lt;/h2&gt;

&lt;p&gt;OpenSky pull request dynamics mirror those that I’ve observed in open source projects. In both cases, as a developer you
have one primary objective:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You’ve made something awesome, and you want to contribute.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Great! We — OpenSky &lt;em&gt;and&lt;/em&gt; open source — welcome your contribution. But in the attention economy we’ve built, we have to
face a tough reality: beauty really does matter.&lt;/p&gt;

&lt;p&gt;Given a queue full of pull requests, the easiest ones to grok will be reviewed first, will get more&lt;sup id="fnref:1"&gt;&lt;a href="#fn:1" rel="footnote"&gt;1&lt;/a&gt;&lt;/sup&gt; feedback,
and as a result, will be merged first.&lt;/p&gt;

&lt;aside&gt;Related lesson: you should always do everything in your power to get your code merged first. Other developers may resent you, but you're not the one stuck resolving merge conflicts, are you?&lt;/aside&gt;&lt;p&gt;So how do you make your pull request pretty?&lt;/p&gt;

&lt;h3 id="make-the-most-of-your-commit-message"&gt;Make the most of your commit message&lt;/h3&gt;

&lt;p&gt;A &lt;a href="http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html"&gt;model commit message&lt;/a&gt; looks something like
this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Capitalized, short (50 chars or less) summary

More detailed explanatory text, if necessary.  Wrap it to about 72
characters or so.  In some contexts, the first line is treated as the
subject of an email and the rest of the text as the body.  The blank
line separating the summary from the body is critical (unless you omit
the body entirely); tools like rebase can get confused if you run the
two together.

Write your commit message in the present tense: "Fix bug" and not "Fixed
bug."  This convention matches up with commit messages generated by
commands like git merge and git revert.

Further paragraphs come after blank lines.

 - Bullet points are okay, too

 - Typically a hyphen or asterisk is used for the bullet, preceded by a
   single space, with blank lines in between, but conventions vary here

 - Use a hanging indent
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The summary line is critical. GitHub’s recent design changes enforce this brevity as well. If you can’t find a way to
summarize your commit in 50 characters or less, you probably should make two commits instead.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Err on the side of bullets.&lt;/li&gt;
  &lt;li&gt;They’re concise, descriptive, and easier to grok at a glance than prose.&lt;/li&gt;
  &lt;li&gt;Too many bullets? You probably should make two commits instead.&lt;/li&gt;
&lt;/ul&gt;&lt;h3 id="make-exactly-as-many-commits-as-you-need"&gt;Make exactly as many commits as you need&lt;/h3&gt;

&lt;p&gt;Too many is confusing. Too few will result in epic diffs. So strive for just the right number.&lt;/p&gt;

&lt;p&gt;But this is easier said than done, right? For now, just commit a bit too often. I’ll show you how to clean that up in a
minute.&lt;/p&gt;

&lt;h3 id="nobody-likes-a-drive-by"&gt;Nobody likes a drive-by&lt;/h3&gt;

&lt;p&gt;Each commit should do one thing. Each pull request should do one (bigger) thing.&lt;/p&gt;

&lt;p&gt;Obviously, the exact definition of “one thing” is very context-dependant, but it’s a solid principle. A few examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
    &lt;p&gt;If you’re editing a file and you reformat whitespace on the lines you change, that’s great. It belongs in your
commit. If you &lt;strong&gt;reformat all the whitespace&lt;/strong&gt; in the file, that’s a second “thing”, and belongs in a second commit.
Maintaining this distinction will make your life easier when you need someone to review your pull request, or when
you have to resolve the next failed merge.&lt;/p&gt;

    &lt;p&gt;Sometimes your whitespace drive-by is accidental. Perhaps you have &lt;a href="https://www.google.com/search?q=my+IDE+sucks"&gt;an awesome IDE&lt;/a&gt; which likes to reformat
 things for you. Maybe you accidentally did &lt;code&gt;git add .&lt;/code&gt; instead of staging individual files like a responsible adult.
 &lt;em&gt;It’s still your mess.&lt;/em&gt; Take responsibility.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;A &lt;strong&gt;feature drive-by&lt;/strong&gt; is also bad, but this is a harder line to draw. If you make disparate functional changes in a
single commit, it’s nearly impossible to write a pretty first line for the commit message. Similarly, many open
source projects will refuse to accept pull requests containing multiple features, even if they would accept all the
changes independently. Maintain a clear purpose for the code in each commit, and for each of the the commits in your
feature branch, and for your eventual pull request. If you come across something unrelated to change, &lt;code&gt;git stash&lt;/code&gt;
what you’re working on and commit the other change where it belongs.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Use &lt;code&gt;gitx&lt;/code&gt; or &lt;code&gt;git -p&lt;/code&gt; to stage &lt;strong&gt;partial-file changesets&lt;/strong&gt;. I often end up with file changes that should ideally be
split into multiple commits, or even committed into multiple branches. Partial-file commits are a lifesaver.&lt;/p&gt;

    &lt;p&gt;Use them.&lt;/p&gt;

    &lt;p&gt;On a related note, &lt;code&gt;git add .&lt;/code&gt; and &lt;code&gt;git commit -a&lt;/code&gt; are the enemy of clean commits&lt;sup id="fnref:2"&gt;&lt;a href="#fn:2" rel="footnote"&gt;2&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;&lt;h3 id="dont-bite-off-more-than-i-can-chew"&gt;Don’t bite off more than I can chew&lt;/h3&gt;

&lt;p&gt;If you send me an epic pull request, I’m likely to stare blankly at it for a second then move on to a shorter one.
I’ll come back to it, but if it’s too intense there’s a distinct possibility that it’ll stay in the &lt;code&gt;tl;dr&lt;/code&gt; queue
indefinitely.&lt;/p&gt;

&lt;p&gt;Try to isolate &lt;strong&gt;minimum viable pull requests&lt;/strong&gt;. Can you release anything &lt;em&gt;right now&lt;/em&gt;?&lt;/p&gt;

&lt;p&gt;There are undoubtedly groups of functionality which are pre-requisites for your feature, which can be released
independently of your feature. For example, if you need to refactor a heavy controller into a service before you can
write a related controller or add new functionality, then break that into a discrete pull request. As long as it doesn’t
break current code, this sort of thing could be released at any time. Open a pull request now, and it will most likely
be merged into production by the time you’re finishing up your primary feature.&lt;/p&gt;

&lt;h2 id="lesson-three-how-to-change-history"&gt;Lesson three: How to change history&lt;/h2&gt;

&lt;p&gt;So you have a mess on your hands.&lt;/p&gt;

&lt;p&gt;Maybe you took my advice back there and committed too many times. Maybe you merged &lt;code&gt;develop&lt;/code&gt; into your feature branch way
too often and your history is littered with unnecessary merge commits. Maybe you opened a pull request and my only
response was “Arrrgghhhh! Rebase!”&lt;/p&gt;

&lt;p&gt;We can fix that.&lt;/p&gt;

&lt;p&gt;Here are a few of the many ways to change git history, along with a light smattering of advice and best practices.&lt;/p&gt;

&lt;h3 id="revert-what"&gt;Revert, what?&lt;/h3&gt;

&lt;p&gt;In Git, revert doesn’t do what you think it does.&lt;/p&gt;

&lt;aside&gt;(Hint: it makes more commits, not fewer)&lt;/aside&gt;&lt;p&gt;You can think of &lt;code&gt;git revert&lt;/code&gt; as an anti-commit. If you added a file in the last commit, &lt;code&gt;git revert HEAD^&lt;/code&gt; will delete
that file in the next commit. If you removed a line in &lt;code&gt;123&lt;/code&gt;, &lt;code&gt;git revert 123&lt;/code&gt; will add that line again. It’s not doing this
by forgetting about the original commit, it’s doing it by committing a brand new anti-commit to cancel out the effects
of the old one.&lt;/p&gt;

&lt;p&gt;Guess what happens if you try to &lt;code&gt;git revert&lt;/code&gt; a merge?&lt;/p&gt;

&lt;p&gt;Yeah. Don’t do that.&lt;/p&gt;

&lt;p&gt;There’s a good chance one of the next few options is a better choice for your current needs. But sometimes you want to
use &lt;code&gt;git revert&lt;/code&gt; anyway.&lt;/p&gt;

&lt;h3 id="your-last-commit-can-be---amended"&gt;Your last commit can be &lt;code&gt;--amend&lt;/code&gt;ed&lt;/h3&gt;

&lt;p&gt;Did you forget a file, or write a lame commit message for your last commit? As long as you haven’t pushed your latest
commit upstream, you can use &lt;code&gt;git commit --amend&lt;/code&gt; to fix it up.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;git add myawesomefile.txt
git commit --amend
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;or…&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;git commit --amend -m "With a better message..."
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id="just-throw-the-last-commit-away"&gt;Just throw the last commit away&lt;/h3&gt;

&lt;p&gt;If you committed something dumb, you can actually just remove it. &lt;strong&gt;This will remove both the commit and all changes in
your code&lt;/strong&gt;… but if that’s what you want, simply &lt;code&gt;git reset --hard HEAD^&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Bam. Your last commit is gone.&lt;/p&gt;

&lt;p&gt;If you’ve been on a dumb-commit rampage for a while, and need to get rid of more, &lt;code&gt;git reset --hard HEAD~N&lt;/code&gt; will
disappear N commits.&lt;/p&gt;

&lt;p&gt;You can’t use this method to get rid of commits if you’ve already already pushed ‘em upstream. If published, these commits
are like those stupid trick birthday candles that you can’t ever really blow out. The next time you pull, your commits
will be merged back into your current branch.&lt;/p&gt;

&lt;h3 id="reset-and-re-commit"&gt;Reset and re-commit&lt;/h3&gt;

&lt;p&gt;This is the second easiest method of changing history. If you haven’t published your changes, sometimes the easiest
thing to do is pretend you never committed your changes. For example, &lt;code&gt;git reset HEAD^&lt;/code&gt; will put your pointer back the
way it was right before your last commit — uncommitted changes and all — giving you a mulligan on staging and committing
your changes.&lt;/p&gt;

&lt;p&gt;Most of the time you will use &lt;code&gt;git reset COMMITISH&lt;/code&gt;, where &lt;code&gt;COMMITISH&lt;/code&gt; is any commit, tag or branch name in recent
history.&lt;/p&gt;

&lt;p&gt;You shouldn’t use the “reset and re-commit” method to fix up any commits which have already been published, as you’re
guaranteed to give everyone downstream merge conflicts and rage issues.&lt;/p&gt;

&lt;h3 id="rebase-before-or-after-opening-your-pull-request"&gt;Rebase before (or after) opening your pull request&lt;/h3&gt;

&lt;p&gt;A simple rebase can be used to &lt;strong&gt;remove your merge commits&lt;/strong&gt; and make like they never happened. Assuming you’re
working in the &lt;code&gt;feature/awesomesauce&lt;/code&gt; feature branch, you can &lt;code&gt;git rebase origin/develop&lt;/code&gt; to re-apply all of your
awesomesauce changes onto the current &lt;code&gt;HEAD&lt;/code&gt; of the &lt;code&gt;develop&lt;/code&gt; branch.&lt;/p&gt;

&lt;p&gt;For most things, you’ll use the more complicated
“&lt;a href="http://book.git-scm.com/4_interactive_rebasing.html"&gt;interactive rebase&lt;/a&gt;”. Among other things, an interactive rebase
will allow you to&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fix commit messages&lt;/li&gt;
  &lt;li&gt;Permanently remove a commit&lt;/li&gt;
  &lt;li&gt;Squash commits into something that makes sense&lt;/li&gt;
  &lt;li&gt;Split a commit in two (or more)&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Be sure to &lt;a href="http://book.git-scm.com/4_interactive_rebasing.html"&gt;follow that last link&lt;/a&gt; for a more in-depth look at
interactive rebasing.&lt;/p&gt;

&lt;h3 id="origin-doesnt-like-it-when-you-change-history"&gt;
&lt;code&gt;origin&lt;/code&gt; doesn’t like it when you change history.&lt;/h3&gt;

&lt;p&gt;If you rebase or &lt;code&gt;--amend&lt;/code&gt; something that you’ve already pushed upstream, &lt;code&gt;origin&lt;/code&gt; will refuse your rewritten commits.
This is because your histories have diverged and are no longer compatible.&lt;/p&gt;

&lt;p&gt;You’ll have to &lt;code&gt;push --force&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;DANGER, Will Robinson.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you use &lt;code&gt;git push --force&lt;/code&gt; without explicitly specifying a remote and branch, &lt;em&gt;it will overwrite the remote branch of
all tracking branches&lt;/em&gt;. This usually includes &lt;code&gt;origin/production&lt;/code&gt; and &lt;code&gt;origin/develop&lt;/code&gt;. This is a &lt;strong&gt;Really Bad Thing&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Never, ever, ever use &lt;code&gt;git push --force&lt;/code&gt; without specifying &lt;code&gt;git push --force origin mybranchname&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Ever.&lt;/p&gt;

&lt;p&gt;Also, be sure to read the next few bits before you use &lt;code&gt;push --force&lt;/code&gt;&lt;/p&gt;

&lt;h3 id="dont-rebase-develop-or-master"&gt;Don’t rebase &lt;code&gt;develop&lt;/code&gt; or &lt;code&gt;master&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Seriously, it’s not worth it. Rebase feature branches. Rebase hotfixes. Rebase your local unpublished work all you want.&lt;/p&gt;

&lt;p&gt;But don’t rebase &lt;code&gt;develop&lt;/code&gt; or &lt;code&gt;master&lt;/code&gt;.&lt;/p&gt;

&lt;h3 id="dont-pee-in-the-pool"&gt;Don’t pee in the pool&lt;/h3&gt;

&lt;p&gt;Changing history sometimes has far-reaching implications, and if you’re going to go this route, you should realize the
consequences of your actions.&lt;/p&gt;

&lt;p&gt;Back to the swimlanes for a minute.&lt;/p&gt;

&lt;p&gt;&lt;img src="/article/changing-history/pee-one.png" alt="Peeing in your own swimlane: gross, but your problem"&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src="/article/changing-history/pee-two.png" alt="Peeing in my swimlane: crossing the line"&gt;&lt;/p&gt;

&lt;p&gt;If you pee in your own swimlane, you’re the only person who has to deal with it. But as soon as you pee in someone else’s swimlane, you’ve crossed a line.&lt;/p&gt;

&lt;h3 id="be-aware-of-who-is-downstream"&gt;Be aware of who is downstream&lt;/h3&gt;

&lt;p&gt;Basically, you should only change history if (1) you are the only one affected, or (2) you hate everyone downstream from you.&lt;/p&gt;

&lt;h2 id="wow-thats-a-lot-to-keep-straight"&gt;Wow. That’s a lot to keep straight.&lt;/h2&gt;

&lt;p&gt;I know, right? But look! I made a flowchart!&lt;/p&gt;

&lt;p&gt;&lt;a href="/article/git-pretty/git-pretty.png"&gt;&lt;img src="/article/git-pretty/git-pretty.png" alt="Cleaning up your own mess"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;div class="footnotes"&gt;
  &lt;ol&gt;
&lt;li id="fn:1"&gt;
      &lt;p&gt;Better?&lt;a href="#fnref:1" rev="footnote"&gt;↩&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id="fn:2"&gt;
      &lt;p&gt;And the friend of committing &lt;code&gt;.swp&lt;/code&gt; files.&lt;a href="#fnref:2" rev="footnote"&gt;↩&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
  &lt;/ol&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/justinhileman/blog/~4/oEC-39GbduE" height="1" width="1"/&gt;</content>
    <summary type="html">&lt;p&gt;OpenSky’s engineering and product teams have an ongoing lunchtime presentation series called Lunch and Learn. A couple
of weeks ago, I gave a talk entitled Lunch and learn2git. This article is an expansion on that presentation, and
covers lessons learned from using Git in the open source community.&lt;/p&gt;
</summary>
  <feedburner:origLink>http://justinhileman.info/article/changing-history/</feedburner:origLink></entry>
  <entry>
    <id>tag:justinhileman.info,2011-10-14:/article/git-pretty/</id>
    <title type="html">Git pretty</title>
    <published>2011-10-14T14:36:55Z</published>
    <updated>2011-10-14T14:45:08Z</updated>
    <link rel="alternate" href="http://feeds.justinhileman.info/~r/justinhileman/blog/~3/uoOanzkVM04/" />
    <content type="html">&lt;p&gt;&lt;a href="/article/git-pretty/git-pretty.png"&gt;&lt;img src="/article/git-pretty/git-pretty.png" alt="So you've made a mess of things?"&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/justinhileman/blog/~4/uoOanzkVM04" height="1" width="1"/&gt;</content>
    <summary type="html">&lt;p&gt;&lt;a href="/article/git-pretty/"&gt;&lt;img alt="So you've made a mess of things?" src="/article/git-pretty/git-pretty-thumb.png" /&gt;&lt;/a&gt;&lt;/p&gt;
</summary>
  <feedburner:origLink>http://justinhileman.info/article/git-pretty/</feedburner:origLink></entry>
  <entry>
    <id>tag:justinhileman.info,2011-09-28:/article/manipulate-coda-for-the-win/</id>
    <title type="html">Yet another Coda plug-in you can't live without: Manipulate Coda</title>
    <published>2011-09-28T09:01:50Z</published>
    <updated>2011-09-28T09:11:03Z</updated>
    <link rel="alternate" href="http://feeds.justinhileman.info/~r/justinhileman/blog/~3/ioWzgQbgLW4/" />
    <content type="html">&lt;p&gt;I’ve been sitting on this one for way too long, and for that I apologize. I really have no idea how you folks have been living without it all this time, but maybe it’s because you have no idea what you’re missing out on.&lt;/p&gt;

&lt;p&gt;I just released &lt;a href="/manipulate-coda-plugin/"&gt;Manipulate Coda&lt;/a&gt;, a text manipulation plug-in suite for &lt;a href="http://panic.com/coda"&gt;Panic’s Coda&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Grab it while it’s hot!&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/justinhileman/blog/~4/ioWzgQbgLW4" height="1" width="1"/&gt;</content>
    <summary type="html">&lt;p&gt;I’ve been sitting on this one for way too long, and for that I apologize. I really have no idea how you folks have been living without it all this time, but maybe it’s because you have no idea what you’re missing out on.&lt;/p&gt;
</summary>
  <feedburner:origLink>http://justinhileman.info/article/manipulate-coda-for-the-win/</feedburner:origLink></entry>
  <entry>
    <id>tag:justinhileman.info,2011-09-26:/article/analysis-your-website/</id>
    <title type="html">Found in inbox, presented without comment</title>
    <published>2011-09-26T20:02:45Z</published>
    <updated>2011-09-26T20:33:06Z</updated>
    <link rel="alternate" href="http://feeds.justinhileman.info/~r/justinhileman/blog/~3/blaqoPPSypw/" />
    <content type="html">&lt;pre&gt;&lt;code&gt;SEO| Internet Marketing| Website Designing

HI,

I am Bob Smith Online SEO Consultant.

Do you want to see your website in Top 10 position in Google or other
major search engine?

Do you want more targeted visitors on your website?

If yes, please let us know your domain name which you want to
optimize..

We will analysis your website and send full SEO proposal with plan
and activity which will implement on your website.

We are looking forward to a long and fruitful business relationship
with you and your company.

We are waiting for your positive response.

Thanks &amp;amp; Regards  
Bob Smith  
[redacted]@gmail.com    
Online SEO Consultant
&lt;/code&gt;&lt;/pre&gt;&lt;img src="http://feeds.feedburner.com/~r/justinhileman/blog/~4/blaqoPPSypw" height="1" width="1"/&gt;</content>
    <summary type="html">&lt;p&gt;&lt;code&gt;SEO| Internet Marketing| Website Designing&lt;/code&gt;&lt;/p&gt;
</summary>
  <feedburner:origLink>http://justinhileman.info/article/analysis-your-website/</feedburner:origLink></entry>
  <entry>
    <id>tag:justinhileman.info,2011-08-30:/article/a-comprehensive-list/</id>
    <title type="html">A comprehensive list of items consumed at the Minnesota State Fair</title>
    <published>2011-08-31T06:19:54Z</published>
    <updated>2011-08-31T06:21:02Z</updated>
    <link rel="alternate" href="http://feeds.justinhileman.info/~r/justinhileman/blog/~3/ASCfQ-DwGOE/" />
    <content type="html">&lt;ul&gt;
&lt;li&gt;Two one-liter bottles of water.&lt;/li&gt;
  &lt;li&gt;One half bag of miniature donuts.&lt;/li&gt;
  &lt;li&gt;Two thirds of an order of deep fried cheese curds.&lt;/li&gt;
  &lt;li&gt;Two cookies from &lt;a href="http://twitter.com/imjasonh"&gt;@imjasonh&lt;/a&gt;’s giant bucket of Sweet Martha’s.&lt;/li&gt;
  &lt;li&gt;One asparagus and swiss cheese crepe.&lt;/li&gt;
  &lt;li&gt;One third of a pork chop on a stick.&lt;/li&gt;
  &lt;li&gt;One order of fried pickles, with ranch dressing.&lt;/li&gt;
  &lt;li&gt;One slice of Big Fat Bacon — on a stick, of course.&lt;/li&gt;
  &lt;li&gt;One cone of Sweet Martha’s cookies (approx 2 dozen).&lt;/li&gt;
  &lt;li&gt;“All the Milk You Can Drink”, e.g. two glasses, consumed with aforementioned cookies.&lt;/li&gt;
&lt;/ul&gt;&lt;img src="http://feeds.feedburner.com/~r/justinhileman/blog/~4/ASCfQ-DwGOE" height="1" width="1"/&gt;</content>
    <summary type="html">&lt;ul&gt;
  &lt;li&gt;Two one-liter bottles of water.&lt;/li&gt;
  &lt;li&gt;One half bag of miniature donuts.&lt;/li&gt;
  &lt;li&gt;Two thirds of an order of deep fried cheese curds.&lt;/li&gt;
  &lt;li&gt;Two cookies from &lt;a href="http://twitter.com/imjasonh"&gt;@imjasonh&lt;/a&gt;’s giant bucket of Sweet Martha’s.&lt;/li&gt;
  &lt;li&gt;One asparagus and swiss cheese crepe.&lt;/li&gt;
  &lt;li&gt;One third of a pork chop on a stick.&lt;/li&gt;
  &lt;li&gt;One order of fried pickles, with ranch dressing.&lt;/li&gt;
  &lt;li&gt;One slice of Big Fat Bacon — on a stick, of course.&lt;/li&gt;
  &lt;li&gt;One cone of Sweet Martha’s cookies (approx 2 dozen).&lt;/li&gt;
  &lt;li&gt;“All the Milk You Can Drink”, e.g. two glasses, consumed with aforementioned cookies.&lt;/li&gt;
&lt;/ul&gt;
</summary>
  <feedburner:origLink>http://justinhileman.info/article/a-comprehensive-list/</feedburner:origLink></entry>
  <entry>
    <id>tag:justinhileman.info,2011-07-22:/article/this-music-video-makes-me-happy/</id>
    <title type="html">This music video makes me happy</title>
    <published>2011-07-22T14:01:03Z</published>
    <updated>2011-07-22T14:07:08Z</updated>
    <link rel="alternate" href="http://feeds.justinhileman.info/~r/justinhileman/blog/~3/sqETUvlrBRU/" />
    <content type="html">&lt;object width="560" height="349"&gt;&lt;param name="movie" value="http://www.youtube.com/v/j95HbhTl60k?version=3&amp;amp;hl=en_US"&gt;
&lt;param name="allowFullScreen" value="true"&gt;
&lt;param name="allowscriptaccess" value="always"&gt;
&lt;embed src="http://www.youtube.com/v/j95HbhTl60k?version=3&amp;amp;hl=en_US" type="application/x-shockwave-flash" width="560" height="349" allowscriptaccess="always" allowfullscreen="true"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;img src="http://feeds.feedburner.com/~r/justinhileman/blog/~4/sqETUvlrBRU" height="1" width="1"/&gt;</content>
    <summary type="html">&lt;object width="560" height="349"&gt;&lt;param name="movie" value="http://www.youtube.com/v/j95HbhTl60k?version=3&amp;amp;hl=en_US" /&gt;&lt;param name="allowFullScreen" value="true" /&gt;&lt;param name="allowscriptaccess" value="always" /&gt;&lt;embed src="http://www.youtube.com/v/j95HbhTl60k?version=3&amp;amp;hl=en_US" type="application/x-shockwave-flash" width="560" height="349" allowscriptaccess="always" allowfullscreen="true" /&gt;&lt;/object&gt;
</summary>
  <feedburner:origLink>http://justinhileman.info/article/this-music-video-makes-me-happy/</feedburner:origLink></entry>
  <entry>
    <id>tag:justinhileman.info,2011-06-11:/article/mongodb-virtual-machine/</id>
    <title type="html">Impossibly simple instructions for setting up a dedicated MongoDB server virtual machine with Vagrant</title>
    <published>2011-06-11T21:12:56Z</published>
    <updated>2011-06-11T21:45:44Z</updated>
    <link rel="alternate" href="http://feeds.justinhileman.info/~r/justinhileman/blog/~3/YEKh3U9O4d8/" />
    <content type="html">&lt;ol&gt;
&lt;li&gt;
    &lt;p&gt;Install &lt;a href="http://www.virtualbox.org/wiki/Downloads"&gt;VirtualBox 4.0&lt;/a&gt;.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Do this. In a terminal:&lt;/p&gt;

    &lt;pre&gt;&lt;code&gt;gem install vagrant
git clone --recursive https://github.com/bobthecow/vagrant-mongobox.git mongobox
cd mongobox
vagrant up
&lt;/code&gt;&lt;/pre&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;That last line might take a minute. Go get yourself a sandwich. I went with &lt;a href="http://www.lukeslobster.com/"&gt;a lobster roll from Luke’s&lt;/a&gt;.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Connect to your new dedicated MongoDB virtual machine on localhost port 27018:&lt;/p&gt;

    &lt;pre&gt;&lt;code&gt;mongo --port 27018
&lt;/code&gt;&lt;/pre&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;…&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Profit!&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;&lt;img src="http://feeds.feedburner.com/~r/justinhileman/blog/~4/YEKh3U9O4d8" height="1" width="1"/&gt;</content>
    <summary type="html">&lt;p&gt;Exactly what it says on the tin.&lt;/p&gt;
</summary>
  <feedburner:origLink>http://justinhileman.info/article/mongodb-virtual-machine/</feedburner:origLink></entry>
</feed>

