def to_file(self, filepath): """Write the contents of the reflog instance to a file at the given filepath. :param filepath: path to file, parent directories are assumed to exist""" lfd = LockedFD(filepath) assure_directory_exists(filepath, is_file=True) fp = lfd.open(write=True, stream=True) try: self._serialize(fp) lfd.commit() except: # on failure it rolls back automatically, but we make it clear lfd.rollback() raise
def append_entry(cls, config_reader, filepath, oldbinsha, newbinsha, message): """Append a new log entry to the revlog at filepath. :param config_reader: configuration reader of the repository - used to obtain user information. May be None :param filepath: full path to the log file :param oldbinsha: binary sha of the previous commit :param newbinsha: binary sha of the current commit :param message: message describing the change to the reference :param write: If True, the changes will be written right away. Otherwise the change will not be written :return: RefLogEntry objects which was appended to the log :note: As we are append-only, concurrent access is not a problem as we do not interfere with readers.""" if len(oldbinsha) != 20 or len(newbinsha) != 20: raise ValueError("Shas need to be given in binary format") # END handle sha type assure_directory_exists(filepath, is_file=True) entry = RefLogEntry( ( bin_to_hex(oldbinsha), bin_to_hex(newbinsha), Actor.committer(config_reader), (int(time.time()), time.altzone), message, ) ) lf = LockFile(filepath) lf._obtain_lock_or_raise() fd = open(filepath, "a") try: fd.write(repr(entry)) finally: fd.close() lf._release_lock() # END handle write operation return entry
def set_reference(self, ref, logmsg = None): """Set ourselves to the given ref. It will stay a symbol if the ref is a Reference. Otherwise an Object, given as Object instance or refspec, is assumed and if valid, will be set which effectively detaches the refererence if it was a purely symbolic one. :param ref: SymbolicReference instance, Object instance or refspec string Only if the ref is a SymbolicRef instance, we will point to it. Everthiny else is dereferenced to obtain the actual object. :param logmsg: If set to a string, the message will be used in the reflog. Otherwise, a reflog entry is not written for the changed reference. The previous commit of the entry will be the commit we point to now. See also: log_append() :return: self :note: This symbolic reference will not be dereferenced. For that, see ``set_object(...)``""" write_value = None obj = None if isinstance(ref, SymbolicReference): write_value = "ref: %s" % ref.path elif isinstance(ref, Object): obj = ref write_value = ref.hexsha elif isinstance(ref, basestring): try: obj = self.repo.rev_parse(ref+"^{}") # optionally deref tags write_value = obj.hexsha except BadObject: raise ValueError("Could not extract object from %s" % ref) # END end try string else: raise ValueError("Unrecognized Value: %r" % ref) # END try commit attribute # typecheck if obj is not None and self._points_to_commits_only and obj.type != Commit.type: raise TypeError("Require commit, got %r" % obj) #END verify type oldbinsha = None if logmsg is not None: try: oldbinsha = self.commit.binsha except ValueError: oldbinsha = Commit.NULL_BIN_SHA #END handle non-existing #END retrieve old hexsha fpath = self.abspath assure_directory_exists(fpath, is_file=True) lfd = LockedFD(fpath) fd = lfd.open(write=True, stream=True) fd.write(write_value) lfd.commit() # Adjust the reflog if logmsg is not None: self.log_append(oldbinsha, logmsg) #END handle reflog return self