diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,35 @@
+# Revision history for stack2cabal
+
+## 1.0.12 -- 2020-10-23
+
+- Use multiple subdirs per source-repository wrt #29
+- Merge git repos properly, wrt #30
+
+## 1.0.11 -- 2020-10-05
+
+- Fix bug in `cabal.project.freeze` when git-package in extra-deps doesn't have a subdir
+- Run hpack for git deps as well
+- Fix `--output-file` option to use it as full filepath (instead of base directory)
+
+## 1.0.10 -- 2020-10-04
+
+- Allow to pin hackage state wrt #20
+- Fix missing flags in cabal.project.freeze wrt #24
+- fix bug in ghc-options conversion
+
+## 1.0.9 -- 2020-10-04
+
+- Inspect remote repository package names and exclude them from freeze file (fixes #1), disable with `--no-inspect-remotes`
+- Add `--no-pin-ghc` option
+- Add `--no-run-hpack` option
+- Add `--output-file` option
+- Also parse ghc-options wrt #9
+- Fix path separators on windows wrt #5
+
+## 1.0.8 -- 2020-09-25
+
+- fix not parsing local deps [by d86leader](https://gitlab.com/d86leader/stack2cabal/-/commit/bd2370c8a453d2dec5546ab936604b2d7d9f6be2)
+- add cli argument parses for specifying stack file
+- Make stack2cabal comaptible with HsYAML>=2.0 [by Roman Melnikov](https://gitlab.com/serokell/morley/stack2cabal/-/commit/9c352382788c6f0c1917d877f6b7abdf3f96484a)
+- Relax upper bound on Cabal
+- Allow resolver to point to remote url
diff --git a/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,56 @@
+[![Gitter](https://badges.gitter.im/hasufell/stack2cabal.svg)](https://gitter.im/hasufell/stack2cabal?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
+[![Haskell CI](https://github.com/hasufell/stack2cabal/workflows/Haskell%20CI/badge.svg)](https://github.com/hasufell/stack2cabal/actions)
+[![Docker build](https://github.com/hasufell/stack2cabal/workflows/Docker%20build/badge.svg)](https://github.com/hasufell/stack2cabal/actions)
+[![Hackage version](https://img.shields.io/hackage/v/stack2cabal.svg?label=Hackage)](https://hackage.haskell.org/package/stack2cabal)
+[![license](https://img.shields.io/github/license/hasufell/stack2cabal.svg)](LICENSE)
+
+# stack2cabal
+
+This is forked of [tseenshe/stack2cabal](https://gitlab.com/tseenshe/stack2cabal) and
+the current [hackage package](https://hackage.haskell.org/package/stack2cabal).
+
+## Installation
+
+Clone the repo and build with either cabal or stack or see the [release page](https://github.com/hasufell/stack2cabal/releases)
+for binaries.
+
+### Docker
+
+[![Docker pulls](https://img.shields.io/docker/pulls/hasufell/stack2cabal.svg)](https://hub.docker.com/repository/docker/hasufell/stack2cabal)
+[![Docker stars](https://img.shields.io/docker/stars/hasufell/stack2cabal.svg)](https://hub.docker.com/repository/docker/hasufell/stack2cabal)
+[![Docker image size](https://img.shields.io/docker/image-size/hasufell/stack2cabal/latest.svg)](https://hub.docker.com/repository/docker/hasufell/stack2cabal)
+
+```sh
+docker pull hasufell/stack2cabal:latest
+```
+
+## Usage
+
+To convert a `stack.yaml` to `cabal.project` simply cd to the project directory and run:
+
+```sh
+stack2cabal
+```
+
+This will also create a `cabal.project.freeze` based on the stack resolver.
+
+Also see `stack2cabal --help` for further options.
+
+### Docker
+
+```sh
+docker run --rm \
+  -v /etc/passwd:/etc/passwd:ro \
+  -u `id -u`:`id -g` \
+  -v `pwd`:`pwd` \
+  -w `pwd` \
+  --tmpfs "$HOME/.cache" \
+  hasufell/stack2cabal:latest
+```
+
+## Notes
+
+- Hackage packages that are specified as git repositories in e.g. `extra-deps` might
+have a different version than the stack resolver. Therefore `stack2cabal` will download
+all repos and ignore their package names when generating `cabal.project.freeze`.
+This can take some time depending on your project. Pass `--no-inspect-remotes` to skip this.
diff --git a/lib/StackageToHackage/Hackage.hs b/lib/StackageToHackage/Hackage.hs
--- a/lib/StackageToHackage/Hackage.hs
+++ b/lib/StackageToHackage/Hackage.hs
@@ -13,7 +13,7 @@
     )
 where
 
-import StackageToHackage.Stackage ( localDirs, unroll )
+import StackageToHackage.Stackage ( localDirs, unroll, mergeResolvers )
 import StackageToHackage.Stackage.Types
     ( Resolver(Resolver, compiler, deps, flags)
     , PkgId(unPkgId)
@@ -34,11 +34,10 @@
 import Control.Monad (forM, when, void)
 import Control.Monad.Catch (handleIOError)
 import Data.Hourglass (timePrint, ISO8601_DateAndTime(..), Elapsed)
-import Data.List (nub, sort)
-import Data.List.Extra (nubOrdOn)
+import Data.List (nub, sort, sortOn)
+import Data.List.Extra (nubOrd, nubOrdOn)
 import Data.List.NonEmpty (NonEmpty((:|)))
 import Data.Maybe (fromMaybe, mapMaybe, catMaybes)
-import Data.Semigroup ( Semigroup(sconcat) )
 import Data.Text (Text)
 import Distribution.PackageDescription.Parsec (readGenericPackageDescription)
 import Distribution.Pretty (prettyShow)
@@ -72,7 +71,7 @@
              -> IO (Project, Freeze)
 stackToCabal inspectRemotes runHpack dir stack = do
     resolvers <- unroll dir stack
-    let resolver = sconcat resolvers
+    let resolver = foldr1 mergeResolvers resolvers
         project = genProject stack resolver
     localPkgs <-
         fmap catMaybes
@@ -142,9 +141,11 @@
                 [ "source-repository-package\n    ", "type: git\n    ", "location: "
                 , repo, "\n    ", "tag: ", commit, "\n"
                 ]
-        in if null subdirs
-            then [base]
-            else (\d -> T.concat [base, "    subdir: ", d, "\n"]) <$> subdirs
+        in case sort subdirs of
+            [] -> [base]
+            (x:xs) -> [T.concat $ [base, "    subdir: ", x]
+                      ++ (("\n            " <>) <$> xs)
+                      ++ ["\n"]]
 
     -- Get the ghc options. This requires IO, because we have to figure out
     -- the local package names.
@@ -182,7 +183,7 @@
 genProject stack Resolver { compiler, deps } = Project
     (fromMaybe (Ghc "ghc") compiler)
     (localDirs stack `appendList` localDeps deps)
-    (nubOrdOn repo $ mapMaybe pickGit deps)
+    (sortOn repo $ nubOrd $ mapMaybe pickGit deps)
     (ghcOptions stack)
   where
     pickGit :: Dep -> Maybe Git
diff --git a/lib/StackageToHackage/Stackage.hs b/lib/StackageToHackage/Stackage.hs
--- a/lib/StackageToHackage/Stackage.hs
+++ b/lib/StackageToHackage/Stackage.hs
@@ -13,6 +13,7 @@
 import Control.Applicative ((<|>))
 import Control.Monad.Extra (loopM, unlessM)
 import Data.ByteString.Lazy (toStrict)
+import Data.List (nub, foldl', find, (\\))
 import Data.List.NonEmpty (NonEmpty(..), head, nonEmpty, reverse, (<|))
 import Data.Maybe (fromMaybe, listToMaybe, mapMaybe)
 import Data.Semigroup
@@ -127,6 +128,51 @@
     (new2old' <$> packages)
     flags
     where new2old' (NewDep pkg) = Hackage pkg
+
+
+-- | Merging two resolvers is straight-forward, except for
+-- handling Git deps. These need to be merged carefully, because
+-- stack.yaml may add subdirs to the repo of a resolver.
+-- Also see: https://github.com/hasufell/stack2cabal/issues/30
+mergeResolvers :: Resolver -> Resolver -> Resolver
+mergeResolvers (Resolver r c p f) (Resolver r' c' p' f') =
+    Resolver (r <|> r') (c <|> c') (mergeDeps p p') (f <> f')
+  where
+    mergeDeps :: [Dep] -> [Dep] -> [Dep]
+    mergeDeps lhs rhs =
+        let nonGits = filter (not . isGitDep) lhs <> filter (not . isGitDep) rhs
+            gitsLhs = (\(SourceDep dep) -> dep) <$> filter isGitDep lhs
+            gitsRhs = (\(SourceDep dep) -> dep) <$> filter isGitDep rhs
+            gitMerged = foldl' (\m key -> update key m) gitsRhs gitsLhs
+        in (SourceDep <$> gitMerged) <> nonGits
+
+    -- this is somewhat inefficient due to lists, but they're all fairly small
+    update :: Git -> [Git] -> [Git]
+    update git xs =
+        -- find same repos
+        case find (\g -> git { subdirs = [], commit = "" }
+                     == g { subdirs = [], commit = "" })
+                 xs of
+            Just g
+             -- on same commit, just append subdirs
+             | commit g == commit git
+             -> git { subdirs = nub (subdirs git <> subdirs g) }
+                 : delete g xs
+             -- on different commit need to delete subdirs from lower resolver
+             | otherwise
+             -> git
+                 -- > [0, 0, 0] \\ [0, 0]
+                 -- [0]
+                 : g { subdirs = nub (subdirs g) \\ nub (subdirs git) }
+                 : delete g xs
+            Nothing -> git : xs
+
+    isGitDep :: Dep -> Bool
+    isGitDep (SourceDep _) = True
+    isGitDep _ = False
+
+    delete :: Eq a => a -> [a] -> [a]
+    delete deleted xs = [ x | x <- xs, x /= deleted ]
 
 --------------------------------------------------------------------------------
 -- YAML
diff --git a/lib/StackageToHackage/Stackage/Types.hs b/lib/StackageToHackage/Stackage/Types.hs
--- a/lib/StackageToHackage/Stackage/Types.hs
+++ b/lib/StackageToHackage/Stackage/Types.hs
@@ -4,7 +4,6 @@
 
 module StackageToHackage.Stackage.Types where
 
-import Control.Applicative ((<|>))
 import Data.List.NonEmpty (NonEmpty(..))
 import Data.Map.Strict (Map)
 import Data.Semigroup
@@ -36,7 +35,7 @@
   { repo    :: Repo
   , commit  :: Commit
   , subdirs :: [Subdir]
-  } deriving (Show)
+  } deriving (Show, Eq, Ord)
 
 
 type Repo = Text
@@ -55,7 +54,7 @@
 
 newtype Flags = Flags (Map PkgName (Map FlagName Bool))
               deriving (Show)
-              deriving newtype (Semigroup)
+              deriving newtype (Semigroup, Monoid)
 
 
 newtype PackageGhcOpts = PackageGhcOpts (Map PkgId GhcFlags)
@@ -102,9 +101,6 @@
   , flags    :: Flags
   } deriving (Show)
 
-instance Semigroup Resolver where
-    (Resolver r c p f) <> (Resolver r' c' p' f') =
-        Resolver (r <|> r') (c <|> c') (p <> p') (f <> f')
 
 -- TODO: remote ResolverRefs
 data ResolverRef = Canned Text
diff --git a/stack2cabal.cabal b/stack2cabal.cabal
--- a/stack2cabal.cabal
+++ b/stack2cabal.cabal
@@ -1,20 +1,24 @@
-cabal-version: 2.2
-name:          stack2cabal
-version:       1.0.11
+cabal-version:      2.2
+name:               stack2cabal
+version:            1.0.12
 synopsis:
   Convert stack projects to cabal.project + cabal.project.freeze
 
-license:       GPL-3.0-only
-license-file:  LICENSE
-author:        Tseen She
-maintainer:    Julian Ospald
-copyright:     2018 Tseen She, 2020 Julian Ospald
-bug-reports:   https://github.com/hasufell/stack2cabal/issues
-tested-with:   GHC ^>=8.6.5 || ^>=8.8.4 || ^>=8.10.2
-category:      Building
+license:            GPL-3.0-only
+license-file:       LICENSE
+author:             Tseen She
+maintainer:         Julian Ospald
+copyright:          2018 Tseen She, 2020 Julian Ospald
+bug-reports:        https://github.com/hasufell/stack2cabal/issues
+tested-with:        GHC ^>=8.6.5 || ^>=8.8.4 || ^>=8.10.2
+category:           Building
 description:
   Convert @stack.yaml@ \/ @package.yaml@ to @cabal.project@ \/ @cabal.project.freeze@\/ @*.cabal@.
 
+extra-source-files:
+  README.md
+  CHANGELOG.md
+
 source-repository head
   type:     git
   location: https://github.com/hasufell/stack2cabal.git
@@ -28,25 +32,25 @@
 
 common deps
   build-depends:
-    , base                  >=4.10    && <5.0
+    , base                  >=4.10     && <5.0
     , bytestring
-    , Cabal                 >=3.0     && <3.4
+    , Cabal                 >=3.0      && <3.4
     , containers
     , directory
-    , exceptions
-    , extra                 >=1.6.13
+    , exceptions            ^>=0.10.4
+    , extra                 ^>=1.7.8
     , filepath
-    , filepattern           >=0.1.2
-    , fuzzy-dates           >=0.1.1.2
-    , hourglass
+    , filepattern           ^>=0.1.2
+    , fuzzy-dates           ^>=0.1.1.2
+    , hourglass             ^>=0.2.12
     , hpack                 ==0.34.2
     , HsYAML                ^>=0.2
-    , http-client           >=0.5.14
-    , http-client-tls       >=0.3.5.3
-    , optparse-applicative  >=0.15
+    , http-client           ^>=0.6.4.1
+    , http-client-tls       ^>=0.3.5.3
+    , optparse-applicative  ^>=0.15.1.0
     , process               >=1.6.9.0
-    , safe                  >=0.3
-    , temporary             >=1.3
+    , safe                  ^>=0.3.19
+    , temporary             ^>=1.3
     , text                  >=1.2.3.1
 
   if flag(ghcflags)
