Skip to content

Commit 20f202d

Browse files
committed
Re-designed the tag testing - it does not use fixtures anymore but dyamically checks the existance of tags within the repository - it basically tests the interface and checks that expected return types are actually returned
1 parent 9ee3106 commit 20f202d

File tree

7 files changed

+303
-166
lines changed

7 files changed

+303
-166
lines changed

lib/git/base.py

Lines changed: 158 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,13 @@
33
#
44
# This module is part of GitPython and is released under
55
# the BSD License: http://www.opensource.org/licenses/bsd-license.php
6+
import os
67

78
class LazyMixin(object):
89
lazy_properties = []
9-
10+
11+
__slots__ = "__baked__"
12+
1013
def __init__(self):
1114
self.__baked__ = False
1215

@@ -38,17 +41,19 @@ class Object(LazyMixin):
3841
"""
3942
TYPES = ("blob", "tree", "commit", "tag")
4043
__slots__ = ("repo", "id", "size")
41-
type = None # to be set by subclass
44+
type = None # to be set by subclass
4245

4346
def __init__(self, repo, id, size=None):
4447
"""
4548
Initialize an object by identifying it by its id. All keyword arguments
4649
will be set on demand if None.
4750
4851
``repo``
49-
repository this object is located in
52+
repository this object is located in
53+
5054
``id``
5155
SHA1 or ref suitable for git-rev-parse
56+
5257
``size``
5358
Size of the object's data in bytes
5459
"""
@@ -97,3 +102,153 @@ def __repr__(self):
97102
string with pythonic representation of our object
98103
"""
99104
return '<git.%s "%s">' % (self.__class__.__name__, self.id)
105+
106+
@classmethod
107+
def get_type_by_name(cls, object_type_name):
108+
"""
109+
Returns
110+
type suitable to handle the given object type name.
111+
Use the type to create new instances.
112+
113+
``object_type_name``
114+
Member of TYPES
115+
116+
Raises
117+
ValueError: In case object_type_name is unknown
118+
"""
119+
if object_type_name == "commit":
120+
import commit
121+
return commit.Commit
122+
elif object_type_name == "tag":
123+
import tag
124+
return tag.TagObject
125+
elif object_type_name == "blob":
126+
import blob
127+
return blob.Blob
128+
elif object_type_name == "tree":
129+
import tree
130+
return tree.Tree
131+
else:
132+
raise ValueError("Cannot handle unknown object type: %s" % object_type_name)
133+
134+
135+
class Ref(object):
136+
"""
137+
Represents a named reference to any object
138+
"""
139+
__slots__ = ("path", "object")
140+
141+
def __init__(self, path, object = None):
142+
"""
143+
Initialize this instance
144+
145+
``path``
146+
Path relative to the .git/ directory pointing to the ref in question, i.e.
147+
refs/heads/master
148+
149+
``object``
150+
Object instance, will be retrieved on demand if None
151+
"""
152+
self.path = path
153+
self.object = object
154+
155+
def __str__(self):
156+
return self.name()
157+
158+
def __repr__(self):
159+
return '<git.%s "%s">' % (self.__class__.__name__, self.path)
160+
161+
def __eq__(self, other):
162+
return self.path == other.path and self.object == other.object
163+
164+
def __ne__(self, other):
165+
return not ( self == other )
166+
167+
def __hash__(self):
168+
return hash(self.path)
169+
170+
@property
171+
def name(self):
172+
"""
173+
Returns
174+
Name of this reference
175+
"""
176+
return os.path.basename(self.path)
177+
178+
@classmethod
179+
def find_all(cls, repo, common_path = "refs", **kwargs):
180+
"""
181+
Find all refs in the repository
182+
183+
``repo``
184+
is the Repo
185+
186+
``common_path``
187+
Optional keyword argument to the path which is to be shared by all
188+
returned Ref objects
189+
190+
``kwargs``
191+
Additional options given as keyword arguments, will be passed
192+
to git-for-each-ref
193+
194+
Returns
195+
git.Ref[]
196+
197+
List is sorted by committerdate
198+
The returned objects are compatible to the Ref base, but represent the
199+
actual type, such as Head or Tag
200+
"""
201+
202+
options = {'sort': "committerdate",
203+
'format': "%(refname)%00%(objectname)%00%(objecttype)%00%(objectsize)"}
204+
205+
options.update(kwargs)
206+
207+
output = repo.git.for_each_ref(common_path, **options)
208+
return cls.list_from_string(repo, output)
209+
210+
@classmethod
211+
def list_from_string(cls, repo, text):
212+
"""
213+
Parse out ref information into a list of Ref compatible objects
214+
215+
``repo``
216+
is the Repo
217+
``text``
218+
is the text output from the git-for-each-ref command
219+
220+
Returns
221+
git.Ref[]
222+
223+
list of Ref objects
224+
"""
225+
heads = []
226+
227+
for line in text.splitlines():
228+
heads.append(cls.from_string(repo, line))
229+
230+
return heads
231+
232+
@classmethod
233+
def from_string(cls, repo, line):
234+
"""
235+
Create a new Ref instance from the given string.
236+
237+
``repo``
238+
is the Repo
239+
240+
``line``
241+
is the formatted ref information
242+
243+
Format::
244+
245+
name: [a-zA-Z_/]+
246+
<null byte>
247+
id: [0-9A-Fa-f]{40}
248+
249+
Returns
250+
git.Head
251+
"""
252+
full_path, hexsha, type_name, object_size = line.split("\x00")
253+
obj = Object.get_type_by_name(type_name)(repo, hexsha, object_size)
254+
return cls(full_path, obj)

lib/git/head.py

Lines changed: 17 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@
55
# the BSD License: http://www.opensource.org/licenses/bsd-license.php
66

77
import commit
8+
import base
89

9-
class Head(object):
10+
class Head(base.Ref):
1011
"""
1112
A Head is a named reference to a Commit. Every Head instance contains a name
1213
and a Commit object.
@@ -26,93 +27,37 @@ class Head(object):
2627
'1c09f116cbc2cb4100fb6935bb162daa4723f455'
2728
"""
2829

29-
def __init__(self, name, commit):
30+
def __init__(self, path, commit):
3031
"""
3132
Initialize a newly instanced Head
3233
33-
`name`
34-
is the name of the head
34+
``path``
35+
is the path to the head ref, relative to the .git directory, i.e.
36+
refs/heads/master
3537
3638
`commit`
3739
is the Commit object that the head points to
3840
"""
39-
self.name = name
40-
self.commit = commit
41+
super(Head, self).__init__(name, commit)
4142

42-
@classmethod
43-
def find_all(cls, repo, **kwargs):
44-
"""
45-
Find all Heads in the repository
46-
47-
`repo`
48-
is the Repo
49-
50-
`kwargs`
51-
Additional options given as keyword arguments, will be passed
52-
to git-for-each-ref
53-
54-
Returns
55-
git.Head[]
56-
57-
List is sorted by committerdate
58-
"""
59-
60-
options = {'sort': "committerdate",
61-
'format': "%(refname)%00%(objectname)"}
62-
options.update(kwargs)
63-
64-
output = repo.git.for_each_ref("refs/heads", **options)
65-
return cls.list_from_string(repo, output)
6643

67-
@classmethod
68-
def list_from_string(cls, repo, text):
44+
@property
45+
def commit(self):
6946
"""
70-
Parse out head information into a list of head objects
71-
72-
``repo``
73-
is the Repo
74-
``text``
75-
is the text output from the git-for-each-ref command
76-
7747
Returns
78-
git.Head[]
48+
Commit object the head points to
7949
"""
80-
heads = []
81-
82-
for line in text.splitlines():
83-
heads.append(cls.from_string(repo, line))
84-
85-
return heads
86-
50+
return self.object
51+
8752
@classmethod
88-
def from_string(cls, repo, line):
53+
def find_all(cls, repo, common_path = "refs/heads", **kwargs):
8954
"""
90-
Create a new Head instance from the given string.
91-
92-
``repo``
93-
is the Repo
94-
95-
``line``
96-
is the formatted head information
97-
98-
Format::
99-
100-
name: [a-zA-Z_/]+
101-
<null byte>
102-
id: [0-9A-Fa-f]{40}
103-
10455
Returns
105-
git.Head
56+
git.Head[]
57+
58+
For more documentation, please refer to git.base.Ref.find_all
10659
"""
107-
full_name, ids = line.split("\x00")
108-
109-
if full_name.startswith('refs/heads/'):
110-
name = full_name[len('refs/heads/'):]
111-
else:
112-
name = full_name
113-
114-
c = commit.Commit(repo, id=ids)
115-
return Head(name, c)
60+
return super(Head,cls).find_all(repo, common_path, **kwargs)
11661

11762
def __repr__(self):
11863
return '<git.Head "%s">' % self.name

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy