Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 7e0dc3c

Browse filesBrowse files
committed
Applied more fixes and an implementation for the RepositoryPathsMixin. This showed that we need to distinguish between plain object dbs with a respective interface and full repositories, which have references and remotes. Ideally, the ones that require only odbs use the odb member, others use the repo member
1 parent d021904 commit 7e0dc3c
Copy full SHA for 7e0dc3c

File tree

9 files changed

+126
-35
lines changed
Filter options

9 files changed

+126
-35
lines changed

‎doc/source/changes.rst

Copy file name to clipboardExpand all lines: doc/source/changes.rst
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ NEXT
1010
* Added interface to handle git related paths: **RepositoryPathsMixin**
1111
* Added interface to read and write git-like configuration: **ConfigurationMixin**
1212
* Added implementation of git datbase with support for transportation and reference resolution: **RefGitDB**
13+
* Renamed type *GitDB* to **GitODB** to differentiate its object-only property to the **RefGitDB**
1314

1415
*****
1516
0.5.2

‎gitdb/db/base.py

Copy file name to clipboardExpand all lines: gitdb/db/base.py
+78-5Lines changed: 78 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,21 @@
77
pool,
88
join,
99
normpath,
10+
abspath,
1011
dirname,
1112
LazyMixin,
12-
hex_to_bin
13+
hex_to_bin,
14+
expandvars,
15+
expanduser,
16+
exists,
17+
is_git_dir
1318
)
1419

1520
from gitdb.config import GitConfigParser
1621
from gitdb.exc import (
1722
BadObject,
18-
AmbiguousObjectName
23+
AmbiguousObjectName,
24+
InvalidDBRoot
1925
)
2026

2127
from async import (
@@ -484,14 +490,73 @@ class RepositoryPathsMixin(object):
484490
truly is a git repository.
485491
486492
If the underlying type provides the config_reader() method, we can properly determine
487-
whether this is a bare repository as well."""
493+
whether this is a bare repository as well. Otherwise it will make an educated guess
494+
based on the path name."""
488495
# slots has no effect here, its just to keep track of used attrs
489496
__slots__ = ("_git_path", '_bare')
490497

491498
#{ Configuration
499+
repo_dir = '.git'
492500
objs_dir = 'objects'
493501
#} END configuration
494502

503+
#{ Subclass Interface
504+
def _initialize(self, path):
505+
"""initialize this instance with the given path. It may point to
506+
any location within the repositories own data, as well as the working tree.
507+
508+
The implementation will move up and search for traces of a git repository,
509+
which is indicated by a child directory ending with .git or the
510+
current path portion ending with .git.
511+
512+
The paths made available for query are suitable for full git repositories
513+
only. Plain object databases need to be fed the "objects" directory path.
514+
515+
:param path: the path to initialize the repository with
516+
:raise InvalidDBRoot:
517+
"""
518+
epath = abspath(expandvars(expanduser(path or os.getcwd())))
519+
520+
if not exists(epath):
521+
raise InvalidDBRoot(epath)
522+
#END check file
523+
524+
self._working_tree_dir = None
525+
self._git_path = None
526+
curpath = epath
527+
528+
# walk up the path to find the .git dir
529+
while curpath:
530+
if is_git_dir(curpath):
531+
self._git_path = curpath
532+
self._working_tree_dir = os.path.dirname(curpath)
533+
break
534+
gitpath = join(curpath, self.repo_dir)
535+
if is_git_dir(gitpath):
536+
self._git_path = gitpath
537+
self._working_tree_dir = curpath
538+
break
539+
curpath, dummy = os.path.split(curpath)
540+
if not dummy:
541+
break
542+
# END while curpath
543+
544+
if self._git_path is None:
545+
raise InvalidDBRoot(epath)
546+
# END path not found
547+
548+
self._bare = self._git_path.endswith(self.repo_dir)
549+
if hasattr(self, 'config_reader'):
550+
try:
551+
self._bare = self.config_reader("repository").getboolean('core','bare')
552+
except Exception:
553+
# lets not assume the option exists, although it should
554+
pass
555+
#END check bare flag
556+
557+
558+
#} end subclass interface
559+
495560
#{ Interface
496561

497562
def is_bare(self):
@@ -513,6 +578,10 @@ def working_tree_path(self):
513578
#END assertion
514579
return dirname(self.git_path())
515580

581+
def objects_path(self):
582+
""":return: path to the repository's objects directory"""
583+
return join(self.git_path(), self.objs_dir)
584+
516585
def working_dir(self):
517586
""":return: working directory of the git process or related tools, being
518587
either the working_tree_path if available or the git_path"""
@@ -539,7 +608,11 @@ class ConfigurationMixin(object):
539608
#{ Configuration
540609
system_config_file_name = "gitconfig"
541610
repo_config_file_name = "config"
542-
#} END
611+
#} END
612+
613+
def __init__(self, *args, **kwargs):
614+
"""Verify prereqs"""
615+
assert hasattr(self, 'git_path')
543616

544617
def _path_at_level(self, level ):
545618
# we do not support an absolute path of the gitconfig on windows ,
@@ -551,7 +624,7 @@ def _path_at_level(self, level ):
551624
if level == "system":
552625
return "/etc/%s" % self.system_config_file_name
553626
elif level == "global":
554-
return normpath(os.path.expanduser("~/.%s" % self.system_config_file_name))
627+
return normpath(expanduser("~/.%s" % self.system_config_file_name))
555628
elif level == "repository":
556629
return join(self.git_path(), self.repo_config_file_name)
557630
#END handle level

‎gitdb/db/git.py

Copy file name to clipboardExpand all lines: gitdb/db/git.py
+11-22Lines changed: 11 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@
55
from base import (
66
CompoundDB,
77
ObjectDBW,
8-
FileDBBase
8+
FileDBBase,
9+
RepositoryPathsMixin,
10+
ConfigurationMixin
911
)
1012

1113
from loose import LooseObjectDB
@@ -25,11 +27,11 @@
2527
)
2628
import os
2729

28-
__all__ = ('GitDB', 'RefGitDB')
30+
__all__ = ('GitODB', 'RefGitDB')
2931

3032

31-
class GitDB(FileDBBase, ObjectDBW, CompoundDB):
32-
"""A git-style object database, which contains all objects in the 'objects'
33+
class GitODB(FileDBBase, ObjectDBW, CompoundDB):
34+
"""A git-style object-only database, which contains all objects in the 'objects'
3335
subdirectory.
3436
:note: The type needs to be initialized on the ./objects directory to function,
3537
as it deals solely with object lookup. Use a RefGitDB type if you need
@@ -46,7 +48,7 @@ class GitDB(FileDBBase, ObjectDBW, CompoundDB):
4648

4749
def __init__(self, root_path):
4850
"""Initialize ourselves on a git ./objects directory"""
49-
super(GitDB, self).__init__(root_path)
51+
super(GitODB, self).__init__(root_path)
5052

5153
def _set_cache_(self, attr):
5254
if attr == '_dbs' or attr == '_loose_db':
@@ -75,7 +77,7 @@ def _set_cache_(self, attr):
7577
# finally set the value
7678
self._loose_db = loose_db
7779
else:
78-
super(GitDB, self)._set_cache_(attr)
80+
super(GitODB, self)._set_cache_(attr)
7981
# END handle attrs
8082

8183
#{ ObjectDBW interface
@@ -92,31 +94,18 @@ def set_ostream(self, ostream):
9294
#} END objectdbw interface
9395

9496

95-
class RefGitDB(GitDB):
97+
class RefGitDB(GitODB, RepositoryPathsMixin, ConfigurationMixin):
9698
"""Git like database with support for object lookup as well as reference resolution.
9799
Our rootpath is set to the actual .git directory (bare on unbare).
98100
99101
The root_path will be the git objects directory. Use git_path() to obtain the actual top-level
100102
git directory."""
101103
#directories
102104

103-
104105
def __init__(self, root_path):
105106
"""Initialize ourselves on the .git directory, or the .git/objects directory."""
106-
root_path = normpath(root_path) # truncate trailing /
107-
self._git_path = root_path
108-
if root_path.endswith(self.objs_dir):
109-
self._git_path = dirname(root_path)
110-
else:
111-
root_path = join(root_path, self.objs_dir)
112-
#END handle directory
113-
assert self._git_path.endswith('.git'), "require initialization on a git directory, got %s" % self._git_path
114-
super(RefGitDB, self).__init__(root_path)
107+
RepositoryPathsMixin._initialize(self, root_path)
108+
super(RefGitDB, self).__init__(self.objects_path())
115109

116110

117-
#{ Interface
118-
def git_path(self):
119-
""":return: main git directory containing objects and references"""
120-
return self._git_path
121111

122-
#} END interface

‎gitdb/db/ref.py

Copy file name to clipboardExpand all lines: gitdb/db/ref.py
+3-3Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ class ReferenceDB(CompoundDB):
1414

1515
# Configuration
1616
# Specifies the object database to use for the paths found in the alternates
17-
# file. If None, it defaults to the GitDB
17+
# file. If None, it defaults to the GitODB
1818
ObjectDBCls = None
1919

2020
def __init__(self, ref_file):
@@ -33,8 +33,8 @@ def _update_dbs_from_ref_file(self):
3333
dbcls = self.ObjectDBCls
3434
if dbcls is None:
3535
# late import
36-
from git import GitDB
37-
dbcls = GitDB
36+
from git import GitODB
37+
dbcls = GitODB
3838
# END get db type
3939

4040
# try to get as many as possible, don't fail if some are unavailable

‎gitdb/object/commit.py

Copy file name to clipboardExpand all lines: gitdb/object/commit.py
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ def _get_intermediate_items(cls, commit):
118118
def _set_cache_(self, attr):
119119
if attr in Commit.__slots__:
120120
# read the data in a chunk, its faster - then provide a file wrapper
121-
binsha, typename, self.size, stream = self.odb.odb.stream(self.binsha)
121+
binsha, typename, self.size, stream = self.odb.stream(self.binsha)
122122
self._deserialize(StringIO(stream.read()))
123123
else:
124124
super(Commit, self)._set_cache_(attr)

‎gitdb/ref/symbolic.py

Copy file name to clipboardExpand all lines: gitdb/ref/symbolic.py
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ class SymbolicReference(object):
3232
3333
A typical example for a symbolic reference is HEAD."""
3434
__slots__ = ("odb", "path")
35+
3536
_resolve_ref_on_create = False
3637
_points_to_commits_only = True
3738
_common_path_default = ""

‎gitdb/test/db/test_git.py

Copy file name to clipboardExpand all lines: gitdb/test/db/test_git.py
+3-3Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,14 @@
44
# the New BSD License: http://www.opensource.org/licenses/bsd-license.php
55
from lib import *
66
from gitdb.exc import BadObject
7-
from gitdb.db import GitDB
7+
from gitdb.db import GitODB
88
from gitdb.base import OStream, OInfo
99
from gitdb.util import hex_to_bin, bin_to_hex
1010

1111
class TestGitDB(TestDBBase):
1212

1313
def test_reading(self):
14-
gdb = GitDB(fixture_path('../../../.git/objects'))
14+
gdb = GitODB(fixture_path('../../../.git/objects'))
1515

1616
# we have packs and loose objects, alternates doesn't necessarily exist
1717
assert 1 < len(gdb.databases()) < 4
@@ -40,7 +40,7 @@ def test_reading(self):
4040

4141
@with_rw_directory
4242
def test_writing(self, path):
43-
gdb = GitDB(path)
43+
gdb = GitODB(path)
4444

4545
# its possible to write objects
4646
self._assert_object_writing(gdb)

‎gitdb/test/test_refs.py

Copy file name to clipboardExpand all lines: gitdb/test/test_refs.py
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ def test_heads(self, rw_repo):
9090
# after the clone, we might still have a tracking branch setup
9191
head.set_tracking_branch(None)
9292
assert head.tracking_branch() is None
93-
remote_ref = rw_repo.remotes[0].refs[0]
93+
remote_ref = RemoteReference.list_items(rw_repo)[0]
9494
assert head.set_tracking_branch(remote_ref) is head
9595
assert head.tracking_branch() == remote_ref
9696
head.set_tracking_branch(None)

‎gitdb/util.py

Copy file name to clipboardExpand all lines: gitdb/util.py
+27Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#
33
# This module is part of GitDB and is released under
44
# the New BSD License: http://www.opensource.org/licenses/bsd-license.php
5+
import platform
56
import binascii
67
import os
78
import mmap
@@ -74,6 +75,9 @@ def unpack_from(fmt, data, offset=0):
7475
dirname = os.path.dirname
7576
basename = os.path.basename
7677
normpath = os.path.normpath
78+
expandvars = os.path.expandvars
79+
expanduser = os.path.expanduser
80+
abspath = os.path.abspath
7781
join = os.path.join
7882
read = os.read
7983
write = os.write
@@ -112,6 +116,29 @@ def __getslice__(self, start, end):
112116

113117
#{ Routines
114118

119+
def get_user_id():
120+
""":return: string identifying the currently active system user as name@node
121+
:note: user can be set with the 'USER' environment variable, usually set on windows"""
122+
ukn = 'UNKNOWN'
123+
username = os.environ.get('USER', os.environ.get('USERNAME', ukn))
124+
if username == ukn and hasattr(os, 'getlogin'):
125+
username = os.getlogin()
126+
# END get username from login
127+
return "%s@%s" % (username, platform.node())
128+
129+
def is_git_dir(d):
130+
""" This is taken from the git setup.c:is_git_directory
131+
function."""
132+
if isdir(d) and \
133+
isdir(join(d, 'objects')) and \
134+
isdir(join(d, 'refs')):
135+
headref = join(d, 'HEAD')
136+
return isfile(headref) or \
137+
(os.path.islink(headref) and
138+
os.readlink(headref).startswith('refs'))
139+
return False
140+
141+
115142
def stream_copy(source, destination, chunk_size=512*1024):
116143
"""Copy all data from the source stream into the destination stream in chunks
117144
of size chunk_size

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.