summaryrefslogtreecommitdiff
path: root/gitdb/db/py/git.py
blob: bc148c6f14e14e150af245d140bfc3e9c290d09d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# Copyright (C) 2010, 2011 Sebastian Thiel (byronimo@gmail.com) and contributors
#
# This module is part of PureGitDB and is released under
# the New BSD License: http://www.opensource.org/licenses/bsd-license.php
from base import (
						PureCompoundDB, 
						PureObjectDBW, 
						PureRootPathDB, 
						PureRepositoryPathsMixin,
						PureConfigurationMixin,
					)

from resolve import PureReferencesMixin

from loose import PureLooseObjectODB
from pack import PurePackedODB
from ref import PureReferenceDB

from gitdb.util import (
						LazyMixin, 
						normpath,
						join,
						dirname
					)
from gitdb.exc import (
						InvalidDBRoot, 
						BadObject, 
						AmbiguousObjectName
						)
import os

__all__ = ('PureGitODB', 'PureGitDB')


class PureGitODB(PureRootPathDB, PureObjectDBW, PureCompoundDB):
	"""A git-style object-only database, which contains all objects in the 'objects'
	subdirectory.
	:note: The type needs to be initialized on the ./objects directory to function, 
		as it deals solely with object lookup. Use a PureGitDB type if you need
		reference and push support."""
	# Configuration
	PackDBCls = PurePackedODB
	LooseDBCls = PureLooseObjectODB
	PureReferenceDBCls = PureReferenceDB
	
	# Directories
	packs_dir = 'pack'
	loose_dir = ''
	alternates_dir = os.path.join('info', 'alternates')
	
	def __init__(self, root_path):
		"""Initialize ourselves on a git ./objects directory"""
		super(PureGitODB, self).__init__(root_path)
		
	def _set_cache_(self, attr):
		if attr == '_dbs' or attr == '_loose_db':
			self._dbs = list()
			loose_db = None
			for subpath, dbcls in ((self.packs_dir, self.PackDBCls), 
									(self.loose_dir, self.LooseDBCls),
									(self.alternates_dir, self.PureReferenceDBCls)):
				path = self.db_path(subpath)
				if os.path.exists(path):
					self._dbs.append(dbcls(path))
					if dbcls is self.LooseDBCls:
						loose_db = self._dbs[-1]
					# END remember loose db
				# END check path exists
			# END for each db type
			
			# should have at least one subdb
			if not self._dbs:
				raise InvalidDBRoot(self.root_path())
			# END handle error
			
			# we the first one should have the store method
			assert loose_db is not None and hasattr(loose_db, 'store'), "First database needs store functionality"
			
			# finally set the value
			self._loose_db = loose_db
		else:
			super(PureGitODB, self)._set_cache_(attr)
		# END handle attrs
		
	#{ PureObjectDBW interface
		
	def store(self, istream):
		return self._loose_db.store(istream)
		
	def ostream(self):
		return self._loose_db.ostream()
	
	def set_ostream(self, ostream):
		return self._loose_db.set_ostream(ostream)
		
	#} END objectdbw interface
	
	
class PureGitDB(PureGitODB, PureRepositoryPathsMixin, PureConfigurationMixin, PureReferencesMixin):
	"""Git like database with support for object lookup as well as reference resolution.
	Our rootpath is set to the actual .git directory (bare on unbare).
	
	The root_path will be the git objects directory. Use git_path() to obtain the actual top-level 
	git directory."""
	#directories
	
	def __init__(self, root_path):
		"""Initialize ourselves on the .git directory, or the .git/objects directory."""
		PureRepositoryPathsMixin._initialize(self, root_path)
		super(PureGitDB, self).__init__(self.objects_path())