Skip to content

Commit 808943b

Browse files
author
Adam C. Foltzer
committed
support git repos checked out as submodules
Fixes acfoltzer#13
1 parent 9145019 commit 808943b

File tree

3 files changed

+36
-9
lines changed

3 files changed

+36
-9
lines changed

README.md

+5-5
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,13 @@ places the current git hash might be stored:
1111
1. Detached HEAD: the hash is in `.git/HEAD`
1212
2. On a branch or tag: the hash is in a file pointed to by `.git/HEAD`
1313
in a location like `.git/refs/heads`
14-
3. On a branch or tag but in a repository with packed refs: the hash is
15-
in `.git/packed-refs`
14+
3. On a branch or tag but in a repository with packed refs: the hash
15+
is in `.git/packed-refs`
16+
4. In any of the above situations, if the current repo is checked out
17+
as a submodule, follow the reference to its `.git` directory first
1618

1719
These files are added as dependencies to modules that use `GitRev`, and
1820
so the module should be rebuilt automatically whenever these files
1921
change.
2022

21-
These situations all arise under normal development workflows, but
22-
there might be further scenarios that cause problems. Let me know if
23-
you run into them!
23+
If you run into further scenarios that cause problems, let me know!

gitrev.cabal

+3
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ maintainer: [email protected]
99
category: Development
1010
build-type: Simple
1111
cabal-version: >=1.10
12+
tested-with: GHC == 7.6.3, GHC == 7.8.4, GHC == 7.10.3, GHC == 8.0.2
1213
description: Some handy Template Haskell splices for including the current git hash and branch in the code of your project. Useful for including in panic messages, @--version@ output, or diagnostic info for more informative bug reports.
1314

1415
source-repository head
@@ -17,10 +18,12 @@ source-repository head
1718

1819
library
1920
build-depends: base >= 4.6 && < 5,
21+
base-compat >= 0.6.0,
2022
directory,
2123
filepath,
2224
template-haskell,
2325
process
2426
hs-source-dirs: src
27+
ghc-options: -Wall
2528
default-language: Haskell2010
2629
exposed-modules: Development.GitRev

src/Development/GitRev.hs

+28-4
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
{-# LANGUAGE LambdaCase #-}
2+
{-# LANGUAGE MultiWayIf #-}
3+
14
-- |
25
-- Module : $Header$
36
-- Copyright : (c) 2015 Adam C. Foltzer
@@ -31,7 +34,6 @@
3134

3235
module Development.GitRev (gitHash, gitBranch, gitDirty, gitCommitCount, gitCommitDate) where
3336

34-
import Control.Applicative
3537
import Control.Exception
3638
import Control.Monad
3739
import Data.Maybe
@@ -42,6 +44,9 @@ import System.Exit
4244
import System.FilePath
4345
import System.Process
4446

47+
import Prelude ()
48+
import Prelude.Compat
49+
4550
-- | Run git with the given arguments and no stdin, returning the
4651
-- stdout output. If git isn't available or something goes wrong,
4752
-- return the second argument.
@@ -53,16 +58,15 @@ runGit args def useIdx = do
5358
if gitFound
5459
then do
5560
-- a lot of bookkeeping to record the right dependencies
56-
pwd <- runIO getCurrentDirectory
61+
pwd <- runIO getGitDirectory
5762
let hd = pwd </> ".git" </> "HEAD"
5863
index = pwd </> ".git" </> "index"
5964
packedRefs = pwd </> ".git" </> "packed-refs"
6065
hdExists <- runIO $ doesFileExist hd
6166
when hdExists $ do
6267
-- the HEAD file either contains the hash of a detached head
6368
-- or a pointer to the file that contains the hash of the head
64-
hdRef <- runIO $ readFile hd
65-
case splitAt 5 hdRef of
69+
splitAt 5 `fmap` runIO (readFile hd) >>= \case
6670
-- pointer to ref
6771
("ref: ", relRef) -> do
6872
let ref = pwd </> ".git" </> relRef
@@ -85,6 +89,26 @@ runGit args def useIdx = do
8589
ExitFailure _ -> return def
8690
else return def
8791

92+
-- | Determine where our git directory is, in case we're in a
93+
-- submodule.
94+
getGitDirectory :: IO FilePath
95+
getGitDirectory = do
96+
pwd <- getCurrentDirectory
97+
let dotGit = pwd </> ".git"
98+
oops = return dotGit -- it's gonna fail, that's fine
99+
isDir <- doesDirectoryExist dotGit
100+
isFile <- doesFileExist dotGit
101+
if | isDir -> return dotGit
102+
| not isFile -> oops
103+
| isFile ->
104+
splitAt 8 `fmap` readFile dotGit >>= \case
105+
("gitdir: ", relDir) -> do
106+
isRelDir <- doesDirectoryExist relDir
107+
if isRelDir
108+
then return relDir
109+
else oops
110+
_ -> oops
111+
88112
-- | Type to flag if the git index is used or not in a call to runGit
89113
data IndexUsed = IdxUsed -- ^ The git index is used
90114
| IdxNotUsed -- ^ The git index is /not/ used

0 commit comments

Comments
 (0)