| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 61f3db7 commit 7029773
4 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -2,12 +2,15 @@ | |||
| 2 | 2 | join_path, | |
| 3 | 3 | Actor, | |
| 4 | 4 | LockedFD, | |
| 5 | + LockFile, | ||
| 6 | + assure_directory_exists, | ||
| 7 | + to_native_path, | ||
| 5 | 8 | ) | |
| 6 | 9 | ||
| 7 | 10 | from gitdb.util import ( | |
| 8 | 11 | bin_to_hex, | |
| 9 | 12 | join, | |
| 10 | - file_contents_ro_filepath | ||
| 13 | + file_contents_ro_filepath, | ||
| 11 | 14 | ) | |
| 12 | 15 | ||
| 13 | 16 | from git.objects.util import ( | |
@@ -151,7 +154,7 @@ def path(cls, ref): | |||
| 151 | 154 | instance would be found. The path is not guaranteed to point to a valid | |
| 152 | 155 | file though. | |
| 153 | 156 | :param ref: SymbolicReference instance""" | |
| 154 | - return join(ref.repo.git_dir, "logs", ref.path) | ||
| 157 | + return join(ref.repo.git_dir, "logs", to_native_path(ref.path)) | ||
| 155 | 158 | ||
| 156 | 159 | @classmethod | |
| 157 | 160 | def iter_entries(cls, stream): | |
@@ -175,6 +178,8 @@ def to_file(self, filepath): | |||
| 175 | 178 | """Write the contents of the reflog instance to a file at the given filepath. | |
| 176 | 179 | :param filepath: path to file, parent directories are assumed to exist""" | |
| 177 | 180 | lfd = LockedFD(filepath) | |
| 181 | + assure_directory_exists(filepath, is_file=True) | ||
| 182 | + | ||
| 178 | 183 | fp = lfd.open(write=True, stream=True) | |
| 179 | 184 | try: | |
| 180 | 185 | self._serialize(fp) | |
@@ -185,22 +190,34 @@ def to_file(self, filepath): | |||
| 185 | 190 | raise | |
| 186 | 191 | #END handle change | |
| 187 | 192 | ||
| 188 | - def append_entry(self, oldbinsha, newbinsha, message, write=True): | ||
| 189 | - """Append a new log entry to the revlog, changing it in place. | ||
| 193 | + @classmethod | ||
| 194 | + def append_entry(cls, filepath, oldbinsha, newbinsha, message): | ||
| 195 | + """Append a new log entry to the revlog at filepath. | ||
| 190 | 196 | :param oldbinsha: binary sha of the previous commit | |
| 191 | 197 | :param newbinsha: binary sha of the current commit | |
| 192 | 198 | :param message: message describing the change to the reference | |
| 193 | 199 | :param write: If True, the changes will be written right away. Otherwise | |
| 194 | 200 | 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.""" | ||
| 196 | 204 | if len(oldbinsha) != 20 or len(newbinsha) != 20: | |
| 197 | 205 | raise ValueError("Shas need to be given in binary format") | |
| 198 | 206 | #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 | - if write: | ||
| 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 | + | ||
| 204 | 221 | return entry | |
| 205 | 222 | ||
| 206 | 223 | def write(self): | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -266,8 +266,19 @@ def log(self): | |||
| 266 | 266 | applied to this reference | |
| 267 | 267 | ||
| 268 | 268 | .. 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.""" | ||
| 270 | 270 | return RefLog.from_file(RefLog.path(self)) | |
| 271 | + | ||
| 272 | + def log_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 | + return RefLog.append_entry(RefLog.path(self), oldbinsha, | ||
| 280 | + (newbinsha is None and self.commit.binsha) or newbinsha, | ||
| 281 | + message) | ||
| 271 | 282 | ||
| 272 | 283 | @classmethod | |
| 273 | 284 | def to_full_path(cls, path): | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -72,17 +72,12 @@ def test_base(self): | |||
| 72 | 72 | # ... as well as each bytes of the written stream | |
| 73 | 73 | assert open(tfile).read() == open(rlp).read() | |
| 74 | 74 | ||
| 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) | ||
| 77 | 77 | assert entry.oldhexsha == IndexObject.NULL_HEX_SHA | |
| 78 | 78 | assert entry.newhexsha == 'f'*40 | |
| 79 | 79 | assert entry.message == msg | |
| 80 | - assert treflog == RefLog.from_file(tfile) | ||
| 81 | - | ||
| 82 | - # but not this time | ||
| 83 | - treflog.append_entry(binsha, binsha, msg, write=False) | ||
| 84 | - assert treflog != RefLog.from_file(tfile) | ||
| 85 | - | ||
| 80 | + assert RefLog.from_file(tfile)[-1] == entry | ||
| 86 | 81 | # END for each reflog | |
| 87 | 82 | ||
| 88 | 83 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -22,7 +22,7 @@ | |||
| 22 | 22 | ||
| 23 | 23 | __all__ = ( "stream_copy", "join_path", "to_native_path_windows", "to_native_path_linux", | |
| 24 | 24 | "join_path_native", "Stats", "IndexFileSHA1Writer", "Iterable", "IterableList", | |
| 25 | - "BlockingLockFile", "LockFile", 'Actor', 'get_user_id' ) | ||
| 25 | + "BlockingLockFile", "LockFile", 'Actor', 'get_user_id', 'assure_directory_exists') | ||
| 26 | 26 | ||
| 27 | 27 | #{ Utility Methods | |
| 28 | 28 | ||
@@ -73,6 +73,20 @@ def join_path_native(a, *p): | |||
| 73 | 73 | needed to play it safe on my dear windows and to assure nice paths that only | |
| 74 | 74 | use '\'""" | |
| 75 | 75 | return to_native_path(join_path(a, *p)) | |
| 76 | + | ||
| 77 | + def assure_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 | + if is_file: | ||
| 83 | + path = os.path.dirname(path) | ||
| 84 | + #END handle file | ||
| 85 | + if not os.path.isdir(path): | ||
| 86 | + os.makedirs(path) | ||
| 87 | + return True | ||
| 88 | + return False | ||
| 89 | + | ||
| 76 | 90 | ||
| 77 | 91 | def get_user_id(): | |
| 78 | 92 | """:return: string identifying the currently active system user as name@node | |
| Back | FazBrowse Home | New Git URL |
0 commit comments