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

Commit7029773

Browse files
committed
Implemented revlog.append_entry as classmethod, to assure we will always actually write_append the new entry, instead of rewriting the whole file. Added file-locking and directory handling, so the implementation should be similar (enough) to the git reference implementation.
Next up is to implement a way to update the reflog when changing references, which is going to be a little more complicated
1 parent61f3db7 commit7029773

File tree

4 files changed

+57
-20
lines changed

4 files changed

+57
-20
lines changed

‎refs/log.py‎

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,15 @@
22
join_path,
33
Actor,
44
LockedFD,
5+
LockFile,
6+
assure_directory_exists,
7+
to_native_path,
58
)
69

710
fromgitdb.utilimport (
811
bin_to_hex,
912
join,
10-
file_contents_ro_filepath
13+
file_contents_ro_filepath,
1114
)
1215

1316
fromgit.objects.utilimport (
@@ -151,7 +154,7 @@ def path(cls, ref):
151154
instance would be found. The path is not guaranteed to point to a valid
152155
file though.
153156
:param ref: SymbolicReference instance"""
154-
returnjoin(ref.repo.git_dir,"logs",ref.path)
157+
returnjoin(ref.repo.git_dir,"logs",to_native_path(ref.path))
155158

156159
@classmethod
157160
defiter_entries(cls,stream):
@@ -175,6 +178,8 @@ def to_file(self, filepath):
175178
"""Write the contents of the reflog instance to a file at the given filepath.
176179
:param filepath: path to file, parent directories are assumed to exist"""
177180
lfd=LockedFD(filepath)
181+
assure_directory_exists(filepath,is_file=True)
182+
178183
fp=lfd.open(write=True,stream=True)
179184
try:
180185
self._serialize(fp)
@@ -185,22 +190,34 @@ def to_file(self, filepath):
185190
raise
186191
#END handle change
187192

188-
defappend_entry(self,oldbinsha,newbinsha,message,write=True):
189-
"""Append a new log entry to the revlog, changing it in place.
193+
@classmethod
194+
defappend_entry(cls,filepath,oldbinsha,newbinsha,message):
195+
"""Append a new log entry to the revlog at filepath.
190196
:param oldbinsha: binary sha of the previous commit
191197
:param newbinsha: binary sha of the current commit
192198
:param message: message describing the change to the reference
193199
:param write: If True, the changes will be written right away. Otherwise
194200
the change will not be written
195-
:return: RefLogEntry objects which was appended to the log"""
201+
:return: RefLogEntry objects which was appended to the log
202+
:note: As we are append-only, concurrent access is not a problem as we
203+
do not interfere with readers."""
196204
iflen(oldbinsha)!=20orlen(newbinsha)!=20:
197205
raiseValueError("Shas need to be given in binary format")
198206
#END handle sha type
199-
entry=RefLogEntry((bin_to_hex(oldbinsha),bin_to_hex(newbinsha),Actor.committer(), (int(time.time()),time.altzone),message))
200-
self.append(entry)
201-
ifwrite:
202-
self.write()
203-
#END handle auto-write
207+
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))
209+
210+
lf=LockFile(filepath)
211+
lf._obtain_lock_or_raise()
212+
213+
fd=open(filepath,'a')
214+
try:
215+
fd.write(repr(entry))
216+
finally:
217+
fd.close()
218+
lf._release_lock()
219+
#END handle write operation
220+
204221
returnentry
205222

206223
defwrite(self):

‎refs/symbolic.py‎

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -266,8 +266,19 @@ def log(self):
266266
applied to this reference
267267
268268
.. note:: As the log is parsed every time, its recommended to cache it for use
269-
instead of calling this method repeatedly"""
269+
instead of calling this method repeatedly. It should be considered read-only."""
270270
returnRefLog.from_file(RefLog.path(self))
271+
272+
deflog_append(self,oldbinsha,message,newbinsha=None):
273+
"""Append a logentry to the logfile of this ref
274+
:param oldbinsha: binary sha this ref used to point to
275+
:param message: A message describing the change
276+
:param newbinsha: The sha the ref points to now. If None, our current commit sha
277+
will be used
278+
:return: added RefLogEntry instance"""
279+
returnRefLog.append_entry(RefLog.path(self),oldbinsha,
280+
(newbinshaisNoneandself.commit.binsha)ornewbinsha,
281+
message)
271282

272283
@classmethod
273284
defto_full_path(cls,path):

‎test/test_reflog.py‎

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -72,17 +72,12 @@ def test_base(self):
7272
# ... as well as each bytes of the written stream
7373
assertopen(tfile).read()==open(rlp).read()
7474

75-
# append an entry - it gets written automatically
76-
entry=treflog.append_entry(IndexObject.NULL_BIN_SHA,binsha,msg)
75+
# append an entry
76+
entry=RefLog.append_entry(tfile,IndexObject.NULL_BIN_SHA,binsha,msg)
7777
assertentry.oldhexsha==IndexObject.NULL_HEX_SHA
7878
assertentry.newhexsha=='f'*40
7979
assertentry.message==msg
80-
asserttreflog==RefLog.from_file(tfile)
81-
82-
# but not this time
83-
treflog.append_entry(binsha,binsha,msg,write=False)
84-
asserttreflog!=RefLog.from_file(tfile)
85-
80+
assertRefLog.from_file(tfile)[-1]==entry
8681
# END for each reflog
8782

8883

‎util.py‎

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222

2323
__all__= ("stream_copy","join_path","to_native_path_windows","to_native_path_linux",
2424
"join_path_native","Stats","IndexFileSHA1Writer","Iterable","IterableList",
25-
"BlockingLockFile","LockFile",'Actor','get_user_id')
25+
"BlockingLockFile","LockFile",'Actor','get_user_id','assure_directory_exists')
2626

2727
#{ Utility Methods
2828

@@ -73,6 +73,20 @@ def join_path_native(a, *p):
7373
needed to play it safe on my dear windows and to assure nice paths that only
7474
use '\'"""
7575
returnto_native_path(join_path(a,*p))
76+
77+
defassure_directory_exists(path,is_file=False):
78+
"""Assure that the directory pointed to by path exists.
79+
:param is_file: If True, path is assumed to be a file and handled correctly.
80+
Otherwise it must be a directory
81+
:return: True if the directory was created, False if it already existed"""
82+
ifis_file:
83+
path=os.path.dirname(path)
84+
#END handle file
85+
ifnotos.path.isdir(path):
86+
os.makedirs(path)
87+
returnTrue
88+
returnFalse
89+
7690

7791
defget_user_id():
7892
""":return: string identifying the currently active system user as name@node

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2026 Movatter.jp