mirror of
https://github.com/atom/atom.git
synced 2026-02-12 07:35:14 -05:00
71 lines
2.8 KiB
CoffeeScript
71 lines
2.8 KiB
CoffeeScript
fs = require 'fs'
|
|
GitRepository = require './git-repository'
|
|
|
|
# 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`.
|
|
#
|
|
# * `directory` {Directory} to explore whether it is part of a Git repository.
|
|
findGitDirectorySync = (directory) ->
|
|
# TODO: Fix node-pathwatcher/src/directory.coffee so the following methods
|
|
# can return cached values rather than always returning new objects:
|
|
# getParent(), getFile(), getSubdirectory().
|
|
gitDir = directory.getSubdirectory('.git')
|
|
if gitDir.existsSync?() and isValidGitDirectorySync gitDir
|
|
gitDir
|
|
else if directory.isRoot()
|
|
return null
|
|
else
|
|
findGitDirectorySync directory.getParent()
|
|
|
|
# Returns a boolean indicating whether the specified directory represents a Git
|
|
# repository.
|
|
#
|
|
# * `directory` {Directory} whose base name is `.git`.
|
|
isValidGitDirectorySync = (directory) ->
|
|
# To decide whether a directory has a valid .git folder, we use
|
|
# the heuristic adopted by the valid_repository_path() function defined in
|
|
# node_modules/git-utils/deps/libgit2/src/repository.c.
|
|
return directory.getSubdirectory('objects').existsSync() and
|
|
directory.getFile('HEAD').existsSync() and
|
|
directory.getSubdirectory('refs').existsSync()
|
|
|
|
# Provider that conforms to the atom.repository-provider@0.1.0 service.
|
|
module.exports =
|
|
class GitRepositoryProvider
|
|
|
|
constructor: (@project) ->
|
|
# Keys are real paths that end in `.git`.
|
|
# Values are the corresponding GitRepository objects.
|
|
@pathToRepository = {}
|
|
|
|
# Returns a {Promise} that resolves with either:
|
|
# * {GitRepository} if the given directory has a Git repository.
|
|
# * `null` if the given directory does not have a Git repository.
|
|
repositoryForDirectory: (directory) ->
|
|
# TODO: Currently, this method is designed to be async, but it relies on a
|
|
# synchronous API. It should be rewritten to be truly async.
|
|
Promise.resolve(@repositoryForDirectorySync(directory))
|
|
|
|
# Returns either:
|
|
# * {GitRepository} if the given directory has a Git repository.
|
|
# * `null` if the given directory does not have a Git repository.
|
|
repositoryForDirectorySync: (directory) ->
|
|
# Only one GitRepository should be created for each .git folder. Therefore,
|
|
# we must check directory and its parent directories to find the nearest
|
|
# .git folder.
|
|
gitDir = findGitDirectorySync(directory)
|
|
unless gitDir
|
|
return null
|
|
|
|
gitDirPath = gitDir.getPath()
|
|
repo = @pathToRepository[gitDirPath]
|
|
unless repo
|
|
repo = GitRepository.open(gitDirPath, project: @project)
|
|
return null unless repo
|
|
repo.onDidDestroy(=> delete @pathToRepository[gitDirPath])
|
|
@pathToRepository[gitDirPath] = repo
|
|
repo.refreshIndex()
|
|
repo.refreshStatus()
|
|
repo
|