diff --git a/glide.lock b/glide.lock
index 3d3222867ddd50d4f9b9d5432a7c265af17d35a7..62620c5ded26d6461e28801b4c5ce280fdfcb974 100644
--- a/glide.lock
+++ b/glide.lock
@@ -228,4 +228,6 @@ imports:
   - term
 - name: github.com/streadway/simpleuuid
   version: 6617b501e485b77e61b98cd533aefff9e258b5a7
+- name: github.com/Masterminds/glide
+  version: 84607742b10f492430762d038e954236bbaf23f7
 devImports: []
diff --git a/glide.yaml b/glide.yaml
index 6b1ab4221fd9d4dfccf5d67eaea6e9ed43438e48..d832bc2213309b201c8c52bda69fbb9e87ef52f5 100644
--- a/glide.yaml
+++ b/glide.yaml
@@ -29,3 +29,5 @@ import:
 - package: github.com/Sirupsen/logrus
   version: ^0.11.0
 - package: github.com/streadway/simpleuuid
+- package: github.com/Masterminds/glide
+  version: ~0.12.3
\ No newline at end of file
diff --git a/hell/README.md b/hell/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..8fe7fdb9ee299488204c8a9dda55a9b7542ce2dc
--- /dev/null
+++ b/hell/README.md
@@ -0,0 +1,4 @@
+> Hell is other people's packages
+
+While we wait for working package management in go we need a way to make
+maintaining the glide.lock by hand less painful.
\ No newline at end of file
diff --git a/hell/cmd/hell/main.go b/hell/cmd/hell/main.go
new file mode 100644
index 0000000000000000000000000000000000000000..c6837b008a2fbe35fb3e8ff2222c4b99e0fbba0f
--- /dev/null
+++ b/hell/cmd/hell/main.go
@@ -0,0 +1,44 @@
+package main
+
+import (
+	"io/ioutil"
+
+	"github.com/spf13/cobra"
+	"gopkg.in/yaml.v2"
+	"fmt"
+	"os"
+)
+
+func main() {
+	hellCmd := &cobra.Command{
+		Use:   "hell",
+		Short: "Hell makes the most of it being warm",
+		Long:  "",
+		Run:   func(cmd *cobra.Command, args []string) { cmd.Help() },
+	}
+
+	var baseGlideLockFile, depGlideLockFile string
+	dependCmd := &cobra.Command{
+		Use:   "lock-merge",
+		Short: "Merge glide.lock files together",
+		Long:  "",
+		Run: func(cmd *cobra.Command, args []string) {
+			bytes, err := ioutil.ReadFile(baseGlideLockFile)
+			if err != nil {
+				fmt.Printf("Could not read file: %s\n", err)
+				os.Exit(1)
+			}
+			err = yaml.Unmarshal(bytes, &m)
+			bytes, err = ioutil.ReadFile(depGlideLockFile)
+			if err != nil {
+				fmt.Printf("Could not read file: %s\n", err)
+				os.Exit(1)
+			}
+			m := make(map[interface{}]interface{})
+		},
+	}
+	dependCmd.PersistentFlags().StringVarP(&baseGlideLockFile, "base", "b", "", "")
+	dependCmd.PersistentFlags().StringVarP(&depGlideLockFile, "dep", "d", "", "")
+	hellCmd.AddCommand(dependCmd)
+	dependCmd.Execute()
+}
diff --git a/hell/merge.go b/hell/merge.go
new file mode 100644
index 0000000000000000000000000000000000000000..89137da5c5c566583017acdac386f7bf8e0ebed2
--- /dev/null
+++ b/hell/merge.go
@@ -0,0 +1,102 @@
+package main
+
+import (
+	"crypto/sha256"
+	"fmt"
+
+	"sort"
+
+	"github.com/Masterminds/glide/cfg"
+)
+
+// Merges two glide lock files together, letting dependencies from 'base' be overwritten
+// by those from 'override'. Returns the resultant glide lock file bytes
+func MergeGlideLockFiles(baseGlideLockFileBytes, overrideGlideLockFileBytes []byte) ([]byte, error) {
+	baseLockFile, err := cfg.LockfileFromYaml(baseGlideLockFileBytes)
+	if err != nil {
+		return nil, err
+	}
+	overrideLockFile, err := cfg.LockfileFromYaml(overrideGlideLockFileBytes)
+	if err != nil {
+		return nil, err
+	}
+
+	imports := make(map[string]*cfg.Lock, len(baseLockFile.Imports))
+	devImports := make(map[string]*cfg.Lock, len(baseLockFile.DevImports))
+	// Copy the base dependencies into a map
+	for _, lock := range baseLockFile.Imports {
+		imports[lock.Name] = lock
+	}
+	for _, lock := range baseLockFile.DevImports {
+		devImports[lock.Name] = lock
+	}
+	// Override base dependencies and add any extra ones
+	for _, lock := range overrideLockFile.Imports {
+		imports[lock.Name] = mergeLocks(imports[lock.Name], lock)
+	}
+	for _, lock := range overrideLockFile.DevImports {
+		devImports[lock.Name] =  mergeLocks(imports[lock.Name], lock)
+	}
+
+	deps := make([]*cfg.Dependency, 0, len(imports))
+	devDeps := make([]*cfg.Dependency, 0, len(devImports))
+
+	// Flatten to Dependencies
+	for _, lock := range imports {
+		deps = append(deps, pinnedDependencyFromLock(lock))
+	}
+
+	for _, lock := range devImports {
+		devDeps = append(devDeps, pinnedDependencyFromLock(lock))
+	}
+
+	hasher := sha256.New()
+	hasher.Write(baseGlideLockFileBytes)
+	hasher.Write(overrideGlideLockFileBytes)
+
+	lockFile, err := cfg.NewLockfile(deps, devDeps, fmt.Sprintf("%x", hasher.Sum(nil)))
+	if err != nil {
+		return nil, err
+	}
+
+	return lockFile.Marshal()
+}
+
+func mergeLocks(baseLock, overrideLock *cfg.Lock) *cfg.Lock {
+	lock := overrideLock.Clone()
+	if baseLock == nil {
+		return lock
+	}
+
+	// Merge and dedupe subpackages
+	subpackages := make([]string, 0, len(lock.Subpackages)+len(baseLock.Subpackages))
+	for _, sp := range lock.Subpackages {
+		subpackages = append(subpackages, sp)
+	}
+	for _, sp := range baseLock.Subpackages {
+		subpackages = append(subpackages, sp)
+	}
+
+	sort.Stable(sort.StringSlice(subpackages))
+
+	dedupeSubpackages := make([]string, 0, len(subpackages))
+
+	lastSp := ""
+	elided := 0
+	for _, sp := range subpackages {
+		if lastSp == sp {
+			elided++
+		} else {
+			dedupeSubpackages = append(dedupeSubpackages, sp)
+			lastSp = sp
+		}
+	}
+	lock.Subpackages = dedupeSubpackages[:len(dedupeSubpackages)-elided]
+	return lock
+}
+
+func pinnedDependencyFromLock(lock *cfg.Lock) *cfg.Dependency {
+	dep := cfg.DependencyFromLock(lock)
+	dep.Pin = lock.Version
+	return dep
+}
diff --git a/hell/merge_test.go b/hell/merge_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..7194f01bf2ec7a72bc270b6c2651c6c7b4b46cf4
--- /dev/null
+++ b/hell/merge_test.go
@@ -0,0 +1,65 @@
+package main
+
+import (
+	"testing"
+	"github.com/stretchr/testify/assert"
+	"fmt"
+)
+
+
+const baseLockYml =`
+imports:
+- name: github.com/gogo/protobuf
+  version: 82d16f734d6d871204a3feb1a73cb220cc92574c
+- name: github.com/tendermint/tendermint
+  version: aaea0c5d2e3ecfbf29f2608f9d43649ec7f07f50
+  subpackages:
+  - node
+  - proxy
+  - types
+  - version
+  - consensus
+  - rpc/core/types
+  - blockchain
+  - mempool
+  - rpc/core
+  - state
+`
+const overrideLockYml =`
+imports:
+- name: github.com/tendermint/tendermint
+  version: 764091dfbb035f1b28da4b067526e04c6a849966
+  subpackages:
+  - benchmarks
+  - proxy
+  - types
+  - version
+`
+const expectedLockYml =`
+imports:
+- name: github.com/gogo/protobuf
+  version: 82d16f734d6d871204a3feb1a73cb220cc92574c
+- name: github.com/tendermint/tendermint
+  version: 764091dfbb035f1b28da4b067526e04c6a849966
+  subpackages:
+  - benchmarks
+  - node
+  - proxy
+  - types
+  - version
+  - consensus
+  - rpc/core/types
+  - blockchain
+  - mempool
+  - rpc/core
+  - state
+`
+
+
+func TestMergeGlideLockFiles(t *testing.T) {
+	lockYml, err := MergeGlideLockFiles(([]byte)(baseLockYml), ([]byte)(overrideLockYml))
+	assert.NoError(t, err, "Lockfiles should merge")
+	fmt.Println(string(lockYml))
+	assert.Equal(t, expectedLockYml, string(lockYml))
+
+}