From 5d62127b67231e210d792817303f123de5134cfd Mon Sep 17 00:00:00 2001 From: Phil Hord Date: Mon, 21 Sep 2015 17:29:22 -0400 Subject: [PATCH] :bug: Teach git-repository-provider to recognize .git-files Git repositories may be contained in a .git directory or a .git file in the workdir hierarchy, but Atom only recognizes the directory format. Teach Atom to recognize the filesystem-agnostic Git symbolic link used by default in many situations including, for example, submodules. The .git file contains a relative or absolute path to the location of the real git-dir, preceded by the 8-byte string "gitdir: ". Here's a console log showing the normal creation of such a symbolic link. /tmp $ git init --separate-git-dir foo.git bar Initialized empty Git repository in /tmp/foo.git/ /tmp $ ls /tmp $ bar foo.git /tmp $ ls -la bar drwxr-xr-x 2 hordp hordp 4096 Sep 18 15:54 . drwxr-xr-x 4 hordp hordp 4096 Sep 18 15:54 .. -rw-r--r-- 1 hordp hordp 25 Sep 18 15:54 .git /tmp $ ls foo.git branches config description HEAD hooks info objects refs /tmp $ cat bar/.git gitdir: /tmp/foo.git Fixes #8876 --- src/git-repository-provider.coffee | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/git-repository-provider.coffee b/src/git-repository-provider.coffee index 850d30f22..3b4df5d2b 100644 --- a/src/git-repository-provider.coffee +++ b/src/git-repository-provider.coffee @@ -1,6 +1,17 @@ fs = require 'fs' +{Directory} = require 'pathwatcher' GitRepository = require './git-repository' +# Returns the .gitdir path in the agnostic Git symlink .git file given, or +# null if the path is not a valid gitfile. +# +# * `gitFile` {String} path of gitfile to parse +gitFileRegex = RegExp "^gitdir: (.+)" +pathFromGitFile = (gitFile) -> + try + gitFileBuff = fs.readFileSync(gitFile, 'utf8') + return gitFileBuff?.match(gitFileRegex)[1] + # Checks whether a valid `.git` directory is contained within the given # directory or one of its ancestors. If so, a Directory that corresponds to the # `.git` folder will be returned. Otherwise, returns `null`. @@ -11,6 +22,9 @@ findGitDirectorySync = (directory) -> # can return cached values rather than always returning new objects: # getParent(), getFile(), getSubdirectory(). gitDir = directory.getSubdirectory('.git') + gitDirPath = pathFromGitFile(gitDir.getPath?()) + if gitDirPath + gitDir = new Directory(directory.resolve(gitDirPath)) if gitDir.existsSync?() and isValidGitDirectorySync gitDir gitDir else if directory.isRoot()