Movatterモバイル変換


[0]ホーム

URL:


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

Sign up
Appearance settings

Commitec0657c

Browse files
committed
Unified object and commit handling which should make the reflog handling much easier. There is some bug in it though, it still needs fixing
1 parenta17c43d commitec0657c

File tree

6 files changed

+97
-94
lines changed

6 files changed

+97
-94
lines changed

‎refs/log.py‎

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -191,8 +191,11 @@ def to_file(self, filepath):
191191
#END handle change
192192

193193
@classmethod
194-
defappend_entry(cls,filepath,oldbinsha,newbinsha,message):
195-
"""Append a new log entry to the revlog at filepath.
194+
defappend_entry(cls,config_reader,filepath,oldbinsha,newbinsha,message):
195+
"""Append a new log entry to the revlog at filepath.
196+
:param config_reader: configuration reader of the repository - used to obtain
197+
user information. May be None
198+
:param filepath: full path to the log file
196199
:param oldbinsha: binary sha of the previous commit
197200
:param newbinsha: binary sha of the current commit
198201
:param message: message describing the change to the reference
@@ -205,7 +208,7 @@ def append_entry(cls, filepath, oldbinsha, newbinsha, message):
205208
raiseValueError("Shas need to be given in binary format")
206209
#END handle sha type
207210
assure_directory_exists(filepath,is_file=True)
208-
entry=RefLogEntry((bin_to_hex(oldbinsha),bin_to_hex(newbinsha),Actor.committer(), (int(time.time()),time.altzone),message))
211+
entry=RefLogEntry((bin_to_hex(oldbinsha),bin_to_hex(newbinsha),Actor.committer(config_reader), (int(time.time()),time.altzone),message))
209212

210213
lf=LockFile(filepath)
211214
lf._obtain_lock_or_raise()

‎refs/reference.py‎

Lines changed: 1 addition & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ class Reference(SymbolicReference, LazyMixin, Iterable):
1818
"""Represents a named reference to any object. Subclasses may apply restrictions though,
1919
i.e. Heads can only point to commits."""
2020
__slots__=tuple()
21+
_points_to_commits_only=False
2122
_resolve_ref_on_create=True
2223
_common_path_default="refs"
2324

@@ -36,42 +37,6 @@ def __init__(self, repo, path):
3637
def__str__(self):
3738
returnself.name
3839

39-
def_get_object(self):
40-
"""
41-
:return:
42-
The object our ref currently refers to. Refs can be cached, they will
43-
always point to the actual object as it gets re-created on each query"""
44-
# have to be dynamic here as we may be a tag which can point to anything
45-
# Our path will be resolved to the hexsha which will be used accordingly
46-
returnObject.new_from_sha(self.repo,hex_to_bin(self.dereference_recursive(self.repo,self.path)))
47-
48-
def_set_object(self,ref):
49-
"""
50-
Set our reference to point to the given ref. It will be converted
51-
to a specific hexsha.
52-
If the reference does not exist, it will be created.
53-
54-
:note:
55-
TypeChecking is done by the git command"""
56-
abs_path=self.abspath
57-
existed=True
58-
ifnotisfile(abs_path):
59-
existed=False
60-
open(abs_path,'wb').write(Object.NULL_HEX_SHA)
61-
# END quick create
62-
63-
# do it safely by specifying the old value
64-
try:
65-
self.repo.git.update_ref(self.path,ref, (existedandself._get_object().hexsha)orNone)
66-
except:
67-
ifnotexisted:
68-
os.remove(abs_path)
69-
# END remove file on error if it didn't exist before
70-
raise
71-
# END exception handling
72-
73-
object=property(_get_object,_set_object,doc="Return the object our ref currently refers to")
74-
7540
@property
7641
defname(self):
7742
""":return: (shortest) Name of this reference - it may contain path components"""

‎refs/symbolic.py‎

Lines changed: 78 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
importos
2-
fromgit.objectsimportCommit
2+
fromgit.objectsimportObject,Commit
33
fromgit.utilimport (
44
join_path,
55
join_path_native,
@@ -30,6 +30,7 @@ class SymbolicReference(object):
3030
A typical example for a symbolic reference is HEAD."""
3131
__slots__= ("repo","path")
3232
_resolve_ref_on_create=False
33+
_points_to_commits_only=True
3334
_common_path_default=""
3435
_id_attribute_="name"
3536

@@ -107,66 +108,89 @@ def dereference_recursive(cls, repo, ref_path):
107108
intermediate references as required
108109
:param repo: the repository containing the reference at ref_path"""
109110
whileTrue:
110-
ref=cls(repo,ref_path)
111-
hexsha,ref_path=ref._get_ref_info()
111+
hexsha,ref_path=cls._get_ref_info(repo,ref_path)
112112
ifhexshaisnotNone:
113113
returnhexsha
114114
# END recursive dereferencing
115115

116-
def_get_ref_info(self):
116+
@classmethod
117+
def_get_ref_info(cls,repo,path):
117118
"""Return: (sha, target_ref_path) if available, the sha the file at
118119
rela_path points to, or None. target_ref_path is the reference we
119120
point to, or None"""
120121
tokens=None
121122
try:
122-
fp=open(self.abspath,'r')
123+
fp=open(join(repo.git_dir,path),'r')
123124
value=fp.read().rstrip()
124125
fp.close()
125126
tokens=value.split(" ")
126127
except (OSError,IOError):
127128
# Probably we are just packed, find our entry in the packed refs file
128129
# NOTE: We are not a symbolic ref if we are in a packed file, as these
129130
# are excluded explictly
130-
forsha,pathinself._iter_packed_refs(self.repo):
131-
ifpath!=self.path:continue
131+
forsha,pathincls._iter_packed_refs(repo):
132+
ifpath!=path:continue
132133
tokens= (sha,path)
133134
break
134135
# END for each packed ref
135136
# END handle packed refs
136137

137138
iftokensisNone:
138-
raiseValueError("Reference at %r does not exist"%self.path)
139+
raiseValueError("Reference at %r does not exist"%path)
139140

140141
# is it a reference ?
141142
iftokens[0]=='ref:':
142143
return (None,tokens[1])
143144

144145
# its a commit
145-
ifself.repo.re_hexsha_only.match(tokens[0]):
146+
ifrepo.re_hexsha_only.match(tokens[0]):
146147
return (tokens[0],None)
147148

148-
raiseValueError("Failed to parse reference information from %r"%self.path)
149-
149+
raiseValueError("Failed to parse reference information from %r"%path)
150+
151+
def_get_object(self):
152+
"""
153+
:return:
154+
The object our ref currently refers to. Refs can be cached, they will
155+
always point to the actual object as it gets re-created on each query"""
156+
# have to be dynamic here as we may be a tag which can point to anything
157+
# Our path will be resolved to the hexsha which will be used accordingly
158+
returnObject.new_from_sha(self.repo,hex_to_bin(self.dereference_recursive(self.repo,self.path)))
159+
150160
def_get_commit(self):
151161
"""
152162
:return:
153163
Commit object we point to, works for detached and non-detached
154-
SymbolicReferences"""
155-
# we partially reimplement it to prevent unnecessary file access
156-
hexsha,target_ref_path=self._get_ref_info()
157-
158-
# it is a detached reference
159-
ifhexsha:
160-
returnCommit(self.repo,hex_to_bin(hexsha))
161-
162-
returnself.from_path(self.repo,target_ref_path).commit
164+
SymbolicReferences. The symbolic reference will be dereferenced recursively."""
165+
obj=self._get_object()
166+
ifobj.type!=Commit.type:
167+
raiseTypeError("Symbolic Reference pointed to object %r, commit was required"%obj)
168+
#END handle type
169+
returnobj
163170

164171
defset_commit(self,commit,msg=None):
165-
"""Set our commit, possibly dereference our symbolic reference first.
172+
"""As set_object, but restricts the type of object to be a Commit
173+
:note: To save cycles, we do not yet check whether the given Object
174+
is actually referring to a commit - for now it may be any of our
175+
Object or Reference types, as well as a refspec"""
176+
# may have to check the type ... this is costly as we would have to use
177+
# revparse
178+
self.set_object(commit,msg)
179+
180+
181+
defset_object(self,object,msg=None):
182+
"""Set the object we point to, possibly dereference our symbolic reference first.
166183
If the reference does not exist, it will be created
167184
185+
:param object: a refspec, a SymbolicReference or an Object instance. SymbolicReferences
186+
will be dereferenced beforehand to obtain the object they point to
168187
:param msg: If not None, the message will be used in the reflog entry to be
169-
written. Otherwise the reflog is not altered"""
188+
written. Otherwise the reflog is not altered
189+
:note: plain SymbolicReferences may not actually point to objects by convention"""
190+
ifisinstance(object,SymbolicReference):
191+
object=object.object
192+
#END resolve references
193+
170194
is_detached=True
171195
try:
172196
is_detached=self.is_detached
@@ -175,56 +199,66 @@ def set_commit(self, commit, msg = None):
175199
# END handle non-existing ones
176200

177201
ifis_detached:
178-
returnself.set_reference(commit,msg)
202+
returnself.set_reference(object,msg)
179203

180204
# set the commit on our reference
181-
self._get_reference().set_commit(commit,msg)
205+
self._get_reference().set_object(object,msg)
182206

183207
commit=property(_get_commit,set_commit,doc="Query or set commits directly")
208+
object=property(_get_object,set_object,doc="Return the object our ref currently refers to")
184209

185210
def_get_reference(self):
186211
""":return: Reference Object we point to
187212
:raise TypeError: If this symbolic reference is detached, hence it doesn't point
188213
to a reference, but to a commit"""
189-
sha,target_ref_path=self._get_ref_info()
214+
sha,target_ref_path=self._get_ref_info(self.repo,self.path)
190215
iftarget_ref_pathisNone:
191216
raiseTypeError("%s is a detached symbolic reference as it points to %r"% (self,sha))
192217
returnself.from_path(self.repo,target_ref_path)
193218

194219
defset_reference(self,ref,msg=None):
195220
"""Set ourselves to the given ref. It will stay a symbol if the ref is a Reference.
196-
Otherwisea commmit, given asCommit object or refspec, is assumed and if valid,
221+
Otherwisean Object, given asObject instance or refspec, is assumed and if valid,
197222
will be set which effectively detaches the refererence if it was a purely
198223
symbolic one.
199224
200-
:param ref: SymbolicReference instance, Commit instance or refspec string
225+
:param ref: SymbolicReference instance, Object instance or refspec string
226+
Only if the ref is a SymbolicRef instance, we will point to it. Everthiny
227+
else is dereferenced to obtain the actual object.
201228
:param msg: If set to a string, the message will be used in the reflog.
202229
Otherwise, a reflog entry is not written for the changed reference.
203230
The previous commit of the entry will be the commit we point to now.
204231
205-
See also: log_append()"""
232+
See also: log_append()
233+
:note: This symbolic reference will not be dereferenced. For that, see
234+
``set_object(...)``"""
206235
write_value=None
236+
obj=None
207237
ifisinstance(ref,SymbolicReference):
208238
write_value="ref: %s"%ref.path
209-
elifisinstance(ref,Commit):
239+
elifisinstance(ref,Object):
240+
obj=ref
210241
write_value=ref.hexsha
211-
else:
242+
elifisinstance(ref,basestring):
212243
try:
213-
write_value=ref.commit.hexsha
214-
exceptAttributeError:
215-
try:
216-
obj=self.repo.rev_parse(ref+"^{}")# optionally deref tags
217-
ifobj.type!="commit":
218-
raiseTypeError("Invalid object type behind sha: %s"%sha)
219-
write_value=obj.hexsha
220-
exceptException:
221-
raiseValueError("Could not extract object from %s"%ref)
222-
# END end try string
244+
obj=self.repo.rev_parse(ref+"^{}")# optionally deref tags
245+
write_value=obj.hexsha
246+
exceptException:
247+
raiseValueError("Could not extract object from %s"%ref)
248+
# END end try string
249+
else:
250+
raiseValueError("Unrecognized Value: %r"%ref)
223251
# END try commit attribute
252+
253+
# typecheck
254+
ifobjisnotNoneandself._points_to_commits_onlyandobj.type!=Commit.type:
255+
raiseTypeError("Require commit, got %r"%obj)
256+
#END verify type
257+
224258
oldbinsha=None
225259
ifmsgisnotNone:
226260
try:
227-
oldhexsha=self.commit.binsha
261+
oldbinsha=self.commit.binsha
228262
exceptValueError:
229263
oldbinsha=Commit.NULL_BIN_SHA
230264
#END handle non-existing
@@ -247,14 +281,14 @@ def set_reference(self, ref, msg = None):
247281
# aliased reference
248282
reference=property(_get_reference,set_reference,doc="Returns the Reference we point to")
249283
ref=reference
250-
284+
251285
defis_valid(self):
252286
"""
253287
:return:
254288
True if the reference is valid, hence it can be read and points to
255289
a valid object or reference."""
256290
try:
257-
self.commit
291+
self.object
258292
except (OSError,ValueError):
259293
returnFalse
260294
else:
@@ -288,7 +322,7 @@ def log_append(self, oldbinsha, message, newbinsha=None):
288322
:param newbinsha: The sha the ref points to now. If None, our current commit sha
289323
will be used
290324
:return: added RefLogEntry instance"""
291-
returnRefLog.append_entry(RefLog.path(self),oldbinsha,
325+
returnRefLog.append_entry(self.repo.config_reader(),RefLog.path(self),oldbinsha,
292326
(newbinshaisNoneandself.commit.binsha)ornewbinsha,
293327
message)
294328

‎test/test_reflog.py‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ def test_base(self):
6060
# test serialize and deserialize - results must match exactly
6161
binsha=chr(255)*20
6262
msg="my reflog message"
63+
cr=repo.config_reader()
6364
forrlpin (rlp_head,rlp_master):
6465
reflog=RefLog.from_file(rlp)
6566
tfile=os.path.join(tdir,os.path.basename(rlp))
@@ -73,7 +74,7 @@ def test_base(self):
7374
assertopen(tfile).read()==open(rlp).read()
7475

7576
# append an entry
76-
entry=RefLog.append_entry(tfile,IndexObject.NULL_BIN_SHA,binsha,msg)
77+
entry=RefLog.append_entry(cr,tfile,IndexObject.NULL_BIN_SHA,binsha,msg)
7778
assertentry.oldhexsha==IndexObject.NULL_HEX_SHA
7879
assertentry.newhexsha=='f'*40
7980
assertentry.message==msg

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2026 Movatter.jp