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 with open(new_abs_path, 'rb') as fd1: f1 = fd1.read().strip() with open(cur_abs_path, 'rb') as fd2: f2 = fd2.read().strip() if f1 != f2: 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
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
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, MAXSIZE, 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": if isfile(obj_path): remove(tmp_path) else: rename(tmp_path, obj_path) # end rename only if needed else: rename(tmp_path, obj_path) # END handle win32 # 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
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