def make_blob(string, path): b = string.encode('utf-8') stream = io.BytesIO(b) istream = gitdb.IStream('blob', len(b), stream) repo.odb.store(istream) blob = Blob(repo, istream.binsha, mode=100644, path=path) return blob
def fu(repo, text): for header in Diff.re_header.finditer(text): a_path, b_path, similarity_index, rename_from, rename_to, \ old_mode, new_mode, new_file_mode, deleted_file_mode, \ a_blob_id, b_blob_id, b_mode = header.groups() # new_file, deleted_file = bool(new_file_mode), bool(deleted_file_mode) # Our only means to find the actual text is to see what has not been matched by our regex, # and then retro-actively assin it to our index # if previous_header is not None: # index[-1].diff = text[previous_header.end():header.start()] # end assign actual diff # Make sure the mode is set if the path is set. Otherwise the resulting blob is invalid # We just use the one mode we should have parsed a_mode = old_mode or deleted_file_mode or (a_path and (b_mode or new_mode or new_file_mode)) b_mode = b_mode or new_mode or new_file_mode or (b_path and a_mode) ablob = Blob(repo, hex_to_bin(a_blob_id), mode=a_mode, path=a_path) bblob = Blob(repo, hex_to_bin(b_blob_id), mode=b_mode, path=a_path) return ablob, bblob
def commit(self, message='', branch='master', parent=None, **kwargs): repo = Repo(self.path) index = repo.index for path, (action, data) in self.changes.iteritems(): abspath = os.path.join(self.path, path) if action == WRITE: istream = IStream(Blob.type, len(data), StringIO(data)) repo.odb.store(istream) blob = Blob(repo, istream.binsha, self.file_mode, path) index.entries[(path, 0)] = BaseIndexEntry.from_blob(blob) elif action == DELETE: #for bit in path.split(os.path.sep): self.repo.git.rm(['--cached', '--'], [path], r=True) elif action == RENAME: #print self.repo.git.status() self.repo.git.rm(['--cached', '--'], [data], r=True) data = self.read(data) istream = IStream(Blob.type, len(data), StringIO(data)) repo.odb.store(istream) blob = Blob(repo, istream.binsha, self.file_mode, path) index.entries[(path, 0)] = BaseIndexEntry.from_blob(blob) committer_name = kwargs.get('committer_name', self.committer_name) committer_email = kwargs.get('committer_email', self.committer_email) author_name = kwargs.get('author_name', self.committer_name) author_email = kwargs.get('author_email', self.committer_email) with ENV(GIT_AUTHOR_NAME=author_name, GIT_AUTHOR_EMAIL=author_email, GIT_COMMITTER_EMAIL=committer_email, GIT_COMMITTER_NAME=committer_name): commit = index.commit(message) self.changes = {} return commit.hexsha
def handle_blobs(self, blobs): for b in blobs: if b.path[-3:] == '.py': if b.binsha not in self.blob_map: virgin = b.data_stream.read().decode('utf-8') fmt_code, err = self.yapify(virgin, b.path) fmt_code2 = fmt_code.encode('utf-8') if not err: istream = self.repo.odb.store( IStream(Blob.type, len(fmt_code2), BytesIO(fmt_code2))) self.blob_map[b.binsha] = istream.binsha log.debug('converted: {}'.format(b.path)) self.blob_map[b.binsha] = istream.binsha else: emsg = 'yapf error: {} {}'.format(b.path, err) self.convert_errors.append(emsg) log.warning(emsg) self.blob_map[b.binsha] = b.binsha yield Blob(self.repo, self.blob_map[b.binsha], b.mode, b.path) else: yield Blob(self.repo, b.binsha, b.mode, b.path)
def build_phase_3(repo, addresses): """Third phase which requires some "big repository" search skills. Sometimes we know how to reference a certain commit and would like to see its message or contents, like when we want to know why a certain change was made (and hopefully the author is responsible enough to describe that in the commit message), or when we want to understand what changed along with the code we're currently engaged with (so we'll know what other parts of the codebase might require tweaking for the change we have in mind). On the other hand, using relative references can at least save us time copying hashes around, but can also be useful when using reference ranges (for example to set a commit to rebase on). The third step in the mystery will lead to player to both reference a given commit as the N-th parent of a known reference, and also display its contents and message using `git show`. The fourth step will use hashes to show that any type of reference can be provided to `git show`. """ eyewitness_time = DATE_MURDER - timedelta(hours=1) blob_ids = random_ids() blobs = [] commit_investigation_path = Path(repo.working_tree_dir) / 'investigate' for (street_name, street_residents) in addresses.items(): with restore_head(repo): # Detach head from current commit. We want only the tag to lead to the "house" commits. repo.head.reference = repo.commit('HEAD') assert repo.head.is_detached # Iterate in reverse so that house number N will be the tag's N-th parent. # The `+1` is because we also count the creation of the tag. with progressbar(length=len(street_residents) + 1, label=f'Generating street commits: {street_name}') as bar: for (i, person) in enumerate(reversed(street_residents)): if person in SUSPECTS: suspect_index = SUSPECTS.index(person) + 1 interview_path = DATA_DIR / f'interview-{suspect_index}.txt' interview = interview_path.read_text() investigation_path = DATA_DIR / f'investigation-{suspect_index}.txt' investigation = investigation_path.read_text().format( eyewitness_time=f'{eyewitness_time:%I%p}'.lstrip('0')) else: interview = random_paragraphs() investigation = random_paragraphs() # We generate a new blob to be added to the 'investigations' branch later on. # We have to have the contents under an actual reference, otherwise they won't # be cloned along with the repository by the player. with NamedTemporaryFile('w') as investigation_file: investigation_file.write(wrap_paragraphs(investigation)) investigation_file.flush() blobs.append(Blob( repo, bytes.fromhex(repo.git.hash_object('-w', investigation_file.name)), mode=Blob.file_mode, path=str(next(blob_ids)))) commit_investigation_path.write_text(blobs[-1].hexsha) repo.index.add(commit_investigation_path.as_posix()) git_commit(repo, MAYOR, DATE_START, f'{len(street_residents) - i} {street_name}', interview) bar.update(1) # Create the tag to the "beginning" of the street. git_commit(repo, MAYOR, DATE_START, f'{street_name}') street_tag_name = street_name.lower().replace(' ', '_') repo.create_tag(f'street/{street_tag_name}') bar.update(1) for (i, suspect) in enumerate(SUSPECTS): if suspect in street_residents: house_number = street_residents.index(suspect) + 1 echo(f' Suspect #{i + 1} lives at #{house_number}') # Create a new branch, not connected to the repository's root, which will hold the # investigations texts' commits. If we don't place those commits somewhere addressable, when # the player `git clone`-s the repository they won't get them and cannot solve the mystery. echo('Creating the investigations branch') with restore_head(repo): repo.git.checkout('--orphan', 'investigations') repo.index.remove('*', force=True, working_tree=True) repo.index.add(blobs) git_commit(repo, MAYOR, DATE_START, 'Investigations', COMMIT_MSG_INVESTIGATIONS)
def test_mime_type_should_return_text_plain_for_unknown_types(self): blob = Blob(self.rorepo, **{ 'binsha': Blob.NULL_BIN_SHA, 'path': 'something' }) self.assertEqual("text/plain", blob.mime_type)
def test_mime_type_should_return_mime_type_for_known_types(self): blob = Blob(self.rorepo, **{ 'binsha': Blob.NULL_BIN_SHA, 'path': 'foo.png' }) self.assertEqual("image/png", blob.mime_type)
def make_blob(repo, blob_bytes, mode, path): stream = io.BytesIO(blob_bytes) istream = repo.odb.store(IStream(Blob.type, len(blob_bytes), stream)) return Blob(repo, istream.binsha, mode, path)