Exemplo n.º 1
0
    def rename(self, new_path, force=False):
        """Rename self to a new path
		
		:param new_path:
			Either a simple name or a full path, i.e. new_name or features/new_name.
			The prefix refs/ is implied for references and will be set as needed.
			In case this is a symbolic ref, there is no implied prefix
			
		:param force:
			If True, the rename will succeed even if a head with the target name
			already exists. It will be overwritten in that case
			
		:return: self
		:raise OSError: In case a file at path but a different contents already exists """
        new_path = self.to_full_path(new_path)
        if self.path == new_path:
            return self

        new_abs_path = join(self.repo.git_dir, new_path)
        cur_abs_path = join(self.repo.git_dir, self.path)
        if isfile(new_abs_path):
            if not force:
                # if they point to the same file, its not an error
                if open(new_abs_path, 'rb').read().strip() != open(
                        cur_abs_path, 'rb').read().strip():
                    raise OSError("File at path %r already exists" %
                                  new_abs_path)
                # else: we could remove ourselves and use the otherone, but
                # but clarity we just continue as usual
            # END not force handling
            os.remove(new_abs_path)
        # END handle existing target file

        dname = dirname(new_abs_path)
        if not isdir(dname):
            os.makedirs(dname)
        # END create directory

        rename(cur_abs_path, new_abs_path)
        self.path = new_path

        return self
Exemplo n.º 2
0
    def _set_alternates(self, alts):
        """Sets the alternates

        :parm alts:
            is the array of string paths representing the alternates at which 
            git should look for objects, i.e. /home/user/repo/.git/objects

        :raise NoSuchPathError:
        :note:
            The method does not check for the existance of the paths in alts
            as the caller is responsible."""
        alternates_path = self._alternates_path() 
        if not alts:
            if isfile(alternates_path):
                os.remove(alternates_path)
        else:
            try:
                f = open(alternates_path, 'w')
                f.write("\n".join(alts))
            finally:
                f.close()
Exemplo n.º 3
0
    def _set_alternates(self, alts):
        """Sets the alternates

        :parm alts:
            is the array of string paths representing the alternates at which 
            git should look for objects, i.e. /home/user/repo/.git/objects

        :raise NoSuchPathError:
        :note:
            The method does not check for the existance of the paths in alts
            as the caller is responsible."""
        alternates_path = self._alternates_path()
        if not alts:
            if isfile(alternates_path):
                os.remove(alternates_path)
        else:
            try:
                f = open(alternates_path, 'w')
                f.write("\n".join(alts))
            finally:
                f.close()
Exemplo n.º 4
0
    def rename(self, new_path, force=False):
        """Rename self to a new path

        :param new_path:
            Either a simple name or a full path, i.e. new_name or features/new_name.
            The prefix refs/ is implied for references and will be set as needed.
            In case this is a symbolic ref, there is no implied prefix

        :param force:
            If True, the rename will succeed even if a head with the target name
            already exists. It will be overwritten in that case

        :return: self
        :raise OSError: In case a file at path but a different contents already exists """
        new_path = self.to_full_path(new_path)
        if self.path == new_path:
            return self

        new_abs_path = join(self.repo.git_dir, new_path)
        cur_abs_path = join(self.repo.git_dir, self.path)
        if isfile(new_abs_path):
            if not force:
                # if they point to the same file, its not an error
                if open(new_abs_path, 'rb').read().strip() != open(cur_abs_path, 'rb').read().strip():
                    raise OSError("File at path %r already exists" % new_abs_path)
                # else: we could remove ourselves and use the otherone, but
                # but clarity we just continue as usual
            # END not force handling
            os.remove(new_abs_path)
        # END handle existing target file

        dname = dirname(new_abs_path)
        if not isdir(dname):
            os.makedirs(dname)
        # END create directory

        rename(cur_abs_path, new_abs_path)
        self.path = new_path

        return self
Exemplo n.º 5
0
    def _create(cls, repo, path, resolve, reference, force, logmsg=None):
        """internal method used to create a new symbolic reference.
		If resolve is False, the reference will be taken as is, creating 
		a proper symbolic reference. Otherwise it will be resolved to the 
		corresponding object and a detached symbolic reference will be created
		instead"""
        full_ref_path = cls.to_full_path(path)
        abs_ref_path = join(repo.git_dir, full_ref_path)

        # figure out target data
        target = reference
        if resolve:
            # could just use the resolve method, but it could be expensive
            # so we handle most common cases ourselves
            if isinstance(reference, cls.ObjectCls):
                target = reference.hexsha
            elif isinstance(reference, SymbolicReference):
                target = reference.object.hexsha
            else:
                target = repo.resolve_object(str(reference))
            #END handle resoltion
        #END need resolution

        if not force and isfile(abs_ref_path):
            target_data = str(target)
            if isinstance(target, SymbolicReference):
                target_data = target.path
            if not resolve:
                target_data = "ref: " + target_data
            existing_data = open(abs_ref_path, 'rb').read().strip()
            if existing_data != target_data:
                raise OSError(
                    "Reference at %r does already exist, pointing to %r, requested was %r"
                    % (full_ref_path, existing_data, target_data))
        # END no force handling

        ref = cls(repo, full_ref_path)
        ref.set_reference(target, logmsg)
        return ref
Exemplo n.º 6
0
    def _create(cls, repo, path, resolve, reference, force, logmsg=None):
        """internal method used to create a new symbolic reference.
        If resolve is False, the reference will be taken as is, creating 
        a proper symbolic reference. Otherwise it will be resolved to the 
        corresponding object and a detached symbolic reference will be created
        instead"""
        full_ref_path = cls.to_full_path(path)
        abs_ref_path = join(repo.git_dir, full_ref_path)

        # figure out target data
        target = reference
        if resolve:
            # could just use the resolve method, but it could be expensive
            # so we handle most common cases ourselves
            if isinstance(reference, cls.ObjectCls):
                target = reference.hexsha
            elif isinstance(reference, SymbolicReference):
                target = reference.object.hexsha
            else:
                target = repo.resolve_object(str(reference))
            # END handle resoltion
        # END need resolution

        if not force and isfile(abs_ref_path):
            target_data = str(target)
            if isinstance(target, SymbolicReference):
                target_data = target.path
            if not resolve:
                target_data = "ref: " + target_data
            existing_data = open(abs_ref_path, 'rb').read().strip()
            if existing_data != target_data:
                raise OSError("Reference at %r does already exist, pointing to %r, requested was %r" %
                              (full_ref_path, existing_data, target_data))
        # END no force handling

        ref = cls(repo, full_ref_path)
        ref.set_reference(target, logmsg)
        return ref
Exemplo n.º 7
0
    def is_dirty(self, index=True, working_tree=True, untracked_files=False):
        if self._bare:
            # Bare repositories with no associated working directory are
            # always consired to be clean.
            return False

        # start from the one which is fastest to evaluate
        default_args = ('--abbrev=40', '--full-index', '--raw')
        if index:
            # diff index against HEAD
            if isfile(self.index.path) and self.head.is_valid() and \
                    len(self.git.diff('HEAD', '--cached', *default_args)):
                return True
        # END index handling
        if working_tree:
            # diff index against working tree
            if len(self.git.diff(*default_args)):
                return True
        # END working tree handling
        if untracked_files:
            if len(self.untracked_files):
                return True
        # END untracked files
        return False
Exemplo n.º 8
0
    def is_dirty(self, index=True, working_tree=True, untracked_files=False):
        if self._bare:
            # Bare repositories with no associated working directory are
            # always consired to be clean.
            return False

        # start from the one which is fastest to evaluate
        default_args = ('--abbrev=40', '--full-index', '--raw')
        if index:
            # diff index against HEAD
            if isfile(self.index.path) and self.head.is_valid() and \
                    len(self.git.diff('HEAD', '--cached', *default_args)):
                return True
        # END index handling
        if working_tree:
            # diff index against working tree
            if len(self.git.diff(*default_args)):
                return True
        # END working tree handling
        if untracked_files:
            if len(self.untracked_files):
                return True
        # END untracked files
        return False
Exemplo n.º 9
0
    def store(self, istream):
        """note: The sha we produce will be hex by nature"""
        tmp_path = None
        writer = self.ostream()
        if writer is None:
            # open a tmp file to write the data to
            fd, tmp_path = tempfile.mkstemp(prefix="obj", dir=self._root_path)

            if istream.binsha is None:
                writer = FDCompressedSha1Writer(fd)
            else:
                writer = FDStream(fd)
            # END handle direct stream copies
        # END handle custom writer

        try:
            try:
                if istream.binsha is not None:
                    # copy as much as possible, the actual uncompressed item size might
                    # be smaller than the compressed version
                    stream_copy(istream.read, writer.write, sys.maxint, self.stream_chunk_size)
                else:
                    # write object with header, we have to make a new one
                    write_object(
                        istream.type, istream.size, istream.read, writer.write, chunk_size=self.stream_chunk_size
                    )
                # END handle direct stream copies
            finally:
                if tmp_path:
                    writer.close()
            # END assure target stream is closed
        except:
            if tmp_path:
                os.remove(tmp_path)
            raise
        # END assure tmpfile removal on error

        hexsha = None
        if istream.binsha:
            hexsha = istream.hexsha
        else:
            hexsha = writer.sha(as_hex=True)
        # END handle sha

        if tmp_path:
            obj_path = self.db_path(self.object_path(hexsha))
            obj_dir = dirname(obj_path)
            if not isdir(obj_dir):
                mkdir(obj_dir)
            # END handle destination directory
            # rename onto existing doesn't work on windows
            if os.name == "nt" and isfile(obj_path):
                remove(obj_path)
            # END handle win322
            rename(tmp_path, obj_path)

            # make sure its readable for all ! It started out as rw-- tmp file
            # but needs to be rwrr
            chmod(obj_path, self.new_objects_mode)
        # END handle dry_run

        istream.binsha = hex_to_bin(hexsha)
        return istream
Exemplo n.º 10
0
    def store(self, istream):
        """note: The sha we produce will be hex by nature"""
        tmp_path = None
        writer = self.ostream()
        if writer is None:
            # open a tmp file to write the data to
            fd, tmp_path = tempfile.mkstemp(prefix='obj', dir=self._root_path)

            if istream.binsha is None:
                writer = FDCompressedSha1Writer(fd)
            else:
                writer = FDStream(fd)
            # END handle direct stream copies
        # END handle custom writer

        try:
            try:
                if istream.binsha is not None:
                    # copy as much as possible, the actual uncompressed item size might
                    # be smaller than the compressed version
                    stream_copy(istream.read, writer.write, sys.maxint,
                                self.stream_chunk_size)
                else:
                    # write object with header, we have to make a new one
                    write_object(istream.type,
                                 istream.size,
                                 istream.read,
                                 writer.write,
                                 chunk_size=self.stream_chunk_size)
                # END handle direct stream copies
            finally:
                if tmp_path:
                    writer.close()
            # END assure target stream is closed
        except:
            if tmp_path:
                os.remove(tmp_path)
            raise
        # END assure tmpfile removal on error

        hexsha = None
        if istream.binsha:
            hexsha = istream.hexsha
        else:
            hexsha = writer.sha(as_hex=True)
        # END handle sha

        if tmp_path:
            obj_path = self.db_path(self.object_path(hexsha))
            obj_dir = dirname(obj_path)
            if not isdir(obj_dir):
                mkdir(obj_dir)
            # END handle destination directory
            # rename onto existing doesn't work on windows
            if os.name == 'nt' and isfile(obj_path):
                remove(obj_path)
            # END handle win322
            rename(tmp_path, obj_path)

            # make sure its readable for all ! It started out as rw-- tmp file
            # but needs to be rwrr
            chmod(obj_path, self.new_objects_mode)
        # END handle dry_run

        istream.binsha = hex_to_bin(hexsha)
        return istream