Exemplo n.º 1
0
    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
Exemplo n.º 2
0
    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
Exemplo n.º 3
0
    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 Exception:
            # on failure it rolls back automatically, but we make it clear
            lfd.rollback()
            raise
Exemplo n.º 4
0
    def append_entry(cls,
                     config_reader: Union[Actor, 'GitConfigParser',
                                          'SectionConstraint', None],
                     filepath: PathLike,
                     oldbinsha: bytes,
                     newbinsha: bytes,
                     message: str,
                     write: bool = True) -> 'RefLogEntry':
        """Append a new log entry to the revlog at filepath.

        :param config_reader: configuration reader of the repository - used to obtain
            user information. May also be an Actor instance identifying the committer directly or 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)
        first_line = message.split('\n')[0]
        if isinstance(config_reader, Actor):
            committer = config_reader  # mypy thinks this is Actor | Gitconfigparser, but why?
        else:
            committer = Actor.committer(config_reader)
        entry = RefLogEntry((bin_to_hex(oldbinsha).decode('ascii'),
                             bin_to_hex(newbinsha).decode('ascii'), committer,
                             (int(_time.time()), _time.altzone), first_line))

        if write:
            lf = LockFile(filepath)
            lf._obtain_lock_or_raise()
            fd = open(filepath, 'ab')
            try:
                fd.write(entry.format().encode(defenc))
            finally:
                fd.close()
                lf._release_lock()
            # END handle write operation
        return entry
Exemplo n.º 5
0
    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, hexadecimal sha string 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, self.ObjectCls):
            obj = ref
            write_value = ref.hexsha
        elif isinstance(ref, basestring):
            try:
                obj = self.repo.resolve_object(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
Exemplo n.º 6
0
    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. Everything
            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, str):
            try:
                obj = self.repo.rev_parse(ref + "^{}")  # optionally deref tags
                write_value = obj.hexsha
            except (BadObject, BadName) as e:
                raise ValueError("Could not extract object from %s" %
                                 ref) from e
            # 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)
        ok = True
        try:
            fd.write(write_value.encode('ascii') + b'\n')
            lfd.commit()
            ok = True
        finally:
            if not ok:
                lfd.rollback()
        # Adjust the reflog
        if logmsg is not None:
            self.log_append(oldbinsha, logmsg)

        return self