@ -9,6 +9,9 @@ rec {
# Returns true if the path exists and is a directory, false otherwise
pathIsDirectory = p : if builtins . pathExists p then ( pathType p ) == " d i r e c t o r y " else false ;
# Returns true if the path exists and is a regular file, false otherwise
pathIsRegularFile = p : if builtins . pathExists p then ( pathType p ) == " r e g u l a r " else false ;
# Bring in a path as a source, filtering out all Subversion and CVS
# directories, as well as backup files (*~).
cleanSourceFilter = name : type : let baseName = baseNameOf ( toString name ) ; in ! (
@ -110,24 +113,43 @@ rec {
with builtins ;
let fileName = toString path + " / " + file ;
packedRefsName = toString path + " / p a c k e d - r e f s " ;
in if lib . pathExists fileName
in if pathIsRegularFile path
# Resolve git worktrees. See gitrepository-layout(5)
then
let m = match " ^ g i t d i r : ( . * ) $ " ( lib . fileContents path ) ;
in if m == null
then throw ( " F i l e c o n t a i n s n o g i t d i r r e f e r e n c e : " + path )
else
let gitDir = lib . head m ;
commonDir' = if pathIsRegularFile " ${ gitDir } / c o m m o n d i r "
then lib . fileContents " ${ gitDir } / c o m m o n d i r "
else gitDir ;
commonDir = if lib . hasPrefix " / " commonDir'
then commonDir'
else toString ( /. + " ${ gitDir } / ${ commonDir' } " ) ;
refFile = lib . removePrefix " ${ commonDir } / " " ${ gitDir } / ${ file } " ;
in readCommitFromFile refFile commonDir
else if pathIsRegularFile fileName
# Sometimes git stores the commitId directly in the file but
# sometimes it stores something like: «ref: refs/heads/branch-name»
then
let fileContent = lib . fileContents fileName ;
# Sometimes git stores the commitId directly in the file but
# sometimes it stores something like: «ref: refs/heads/branch-name»
matchRef = match " ^ r e f : ( . * ) $ " fileContent ;
in if matchRef == null
in if matchRef == null
then fileContent
else readCommitFromFile ( lib . head matchRef ) path
else if pathIsRegularFile packedRefsName
# Sometimes, the file isn't there at all and has been packed away in the
# packed-refs file, so we have to grep through it:
else if lib . pathExists packedRefsName
then
let fileContent = readFile packedRefsName ;
matchRef = match ( " . * \n ( [ ^ \n ] * ) " + file + " \n . * " ) fileContent ;
in if matchRef == null
in if matchRef == null
then throw ( " C o u l d n o t f i n d " + file + " i n " + packedRefsName )
else lib . head matchRef
else throw ( " N o t a . g i t d i r e c t o r y : " + path ) ;
in readCommitFromFile " H E A D " ;