diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,23 @@
+The MIT License (MIT)
+
+Copyright (c) 2013 Noon Silk
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+
diff --git a/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,60 @@
+infer-upstream
+==============
+
+Takes a repo name, and looks up the upstream repository. If there is an
+upstream repository, writes it to standard out. Otherwise writes nothing.
+
+Usage:
+
+````
+noon@dev> infer-upstream -r scirate3 -u silky
+git@github.com:draftable/scirate3.git
+````
+
+Another usage:
+
+````
+cd scirate3
+git remote add upstream `infer-upstream -r scirate3 -u silky`
+````
+
+A more interesting usage (and the reason I wrote this) is to use the
+`upstream_everything.sh` script.  It performs the following task.
+
+For all folders in a given directory:
+
+  * go into each one,
+  * if it is a github repo,
+  * look up the upstream repo,
+  * if we find it,
+  * set it as a new remote.
+
+Usage:
+
+````
+noon@~> cd dev
+noon@dev> git clone git@github.com:silky/infer-upstream
+noon@dev> infer-upstream/upstream_everything.sh
+...
+````
+
+With `upstream` set on your repos, you can then run `fetch_upstreams.sh`, if
+you like, which will bring down any incoming changes and give print out a
+short summary.
+
+Example:
+
+````
+noon@dev>infer-upstream/fetch_upstreams.sh 
+fetching upstream for Javascript-Voronoi ...
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+````
+
+Notes:
+
+  * This script assumes every folder in the ~/dev directory is the clone of a
+  Github repository.
+  * Github currently limits you to 60 unauthenticated API requests *per hour*;
+  this approach uses one API request per folder.
+
+
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,2 @@
+import Distribution.Simple
+main = defaultMain
diff --git a/fetch_upstreams.sh b/fetch_upstreams.sh
new file mode 100644
--- /dev/null
+++ b/fetch_upstreams.sh
@@ -0,0 +1,15 @@
+#!/bin/sh
+
+for i in $(find . -maxdepth 1 -type d -not -name .)
+do
+    if [ -d "$i/.git" ]; then
+        cd "$i"
+        if git remote | grep 'upstream' > /dev/null; then
+            echo "fetching upstream for ${PWD##*/} ..."
+            git fetch upstream
+            # Assume branches are called 'master'.
+            git diff --shortstat master upstream/master
+        fi
+        cd ..
+    fi
+done
diff --git a/infer-upstream.cabal b/infer-upstream.cabal
new file mode 100644
--- /dev/null
+++ b/infer-upstream.cabal
@@ -0,0 +1,21 @@
+name:                infer-upstream
+version:             0.1.0.0
+synopsis:            Find the repository from where a given repo was forked
+description:         Find the repository from where a given repo was forked
+homepage:            https://github.com/silky/infer-upstream
+license:             MIT
+license-file:        LICENSE
+author:              Noon Silk
+maintainer:          noonsilk@gmail.com
+category:            Development
+build-type:          Simple
+cabal-version:       >=1.8
+extra-source-files:  README.md, fetch_upstreams.sh, upstream_everything.sh
+
+executable infer-upstream
+  main-is: infer-upstream.hs
+  build-depends:
+    base                   >= 4.0    && < 5.0,
+    text                   >= 0.10   && < 0.12,
+    optparse-applicative   >= 0.5    && < 0.6,
+    github                 >= 0.8
diff --git a/infer-upstream.hs b/infer-upstream.hs
new file mode 100644
--- /dev/null
+++ b/infer-upstream.hs
@@ -0,0 +1,65 @@
+{-# LANGUAGE OverloadedStrings #-}
+
+module Main where
+
+import Prelude
+import System.Exit               (exitFailure, exitSuccess)
+import Control.Applicative       ((<$>), (<*>))
+import Data.Monoid               (mempty, (<>))
+import Data.Maybe                (fromMaybe)
+import Github.Data               (Repo(..), GithubOwner(..), RepoRef(..))
+import Github.Repos              (userRepo)
+
+import qualified Options.Applicative.Builder.Internal as X
+import qualified Options.Applicative                  as O
+
+data Options = Options { repo :: String
+                       , user :: String
+                       } deriving Show
+
+main :: IO ()
+main = O.execParser (O.info (O.helper <*> options) mempty) >>= start
+
+
+options :: O.Parser Options
+options = Options
+  <$> O.strOption ( O.short 'r' <> O.long "repo" <> 
+          O.help "Name of the repository that we will look up." )
+  <*> O.strOption ( O.short 'u' <> O.long "user" <> 
+          O.help "Name of the user that we will look this repo up on." )
+
+
+defStr :: String -> X.Mod X.ArgumentFields String -> O.Parser String
+defStr a = def a . O.argument O.str
+
+
+def :: a -> O.Parser a -> O.Parser a
+def a = fmap (fromMaybe a) . O.optional
+
+
+start :: Options -> IO ()
+start opts = do
+  d <- userRepo (user opts) (repo opts)
+  case d of
+    Right repo  -> inferUpstream repo opts
+    Left  err   -> do 
+        putStrLn $ show err
+        exitFailure
+
+
+obtainUpstreamRepo :: RepoRef -> IO ()
+obtainUpstreamRepo (RepoRef ghUser repoName) = do
+    rd <- userRepo (githubOwnerLogin ghUser) repoName
+    case rd of
+      -- Print put the ssh repo url
+      Right repo -> putStrLn (repoSshUrl repo)
+      Left  err   -> do 
+        putStrLn $ show err
+        exitFailure
+
+
+inferUpstream :: Repo -> Options -> IO ()
+inferUpstream repo opts = do
+  case (repoParent repo) of
+      Just repoParent     -> obtainUpstreamRepo repoParent
+      Nothing             -> exitSuccess -- No upstream, say nothing.
diff --git a/upstream_everything.sh b/upstream_everything.sh
new file mode 100644
--- /dev/null
+++ b/upstream_everything.sh
@@ -0,0 +1,20 @@
+#!/bin/sh
+
+for i in $(find . -maxdepth 1 -type d -not -name .)
+do
+    if [ -d "$i/.git" ]; then
+        cd "$i"
+        if git remote | grep 'upstream' > /dev/null; then
+            echo "'upstream' remote already exists in ${PWD##*/}"
+        else
+            UPSTREAM=`infer-upstream -r "${PWD##*/}" -u silky`
+            if [ $? -eq 0 ]; then
+                git remote add upstream `infer-upstream -r "${PWD##*/}" -u silky`
+                echo "created 'upstream' remote in ${PWD##*/} pointing at ${UPSTREAM}"
+            else
+                echo "can't determine upstream for ${PWD##*/}"
+            fi
+        fi
+        cd ..
+    fi
+done
