def test_commit_serialization(self): assert_commit_serialization(self.gitrwrepo, self.gitrwrepo.head, True) rwrepo = self.gitrwrepo make_object = rwrepo.odb.store # direct serialization - deserialization can be tested afterwards # serialization is probably limited on IO hc = rwrepo.commit(rwrepo.head) nc = 5000 st = time() for i in xrange(nc): cm = Commit(rwrepo, Commit.NULL_BIN_SHA, hc.tree, hc.author, hc.authored_date, hc.author_tz_offset, hc.committer, hc.committed_date, hc.committer_tz_offset, str(i), parents=hc.parents, encoding=hc.encoding) stream = BytesIO() cm._serialize(stream) slen = stream.tell() stream.seek(0) cm.binsha = make_object(IStream(Commit.type, slen, stream)).binsha # END commit creation elapsed = time() - st print("Serialized %i commits to loose objects in %f s ( %f commits / s )" % (nc, elapsed, nc / elapsed), file=sys.stderr)
def create_commit(self, repo: Repository, commit: git.Commit): c = Commit(repo=repo) c.author = commit.author c.authored_datetime = commit.authored_datetime c.message = commit.message c.hex_sha = commit.hexsha c.bin_sha = commit.binsha c.committed_datetime = commit.committed_datetime c.count = commit.count() try: diffs = commit.diff( commit.hexsha, create_patch=True, ignore_blank_lines=True, ignore_space_at_eol=True, diff_filter="adm", ) diff_text = "\n".join([str(x) for x in diffs]) c.line_additions = len(re.findall(r"^\+ ", diff_text, re.MULTILINE)) c.line_subtractions = len( re.findall(r"^- ", diff_text, re.MULTILINE)) except git.GitCommandError: pass return c
def test_serialization_unicode_support(self): assert Commit.default_encoding.lower() == 'utf-8' # create a commit with unicode in the message, and the author's name # Verify its serialization and deserialization cmt = self.rorepo.commit('0.1.6') assert isinstance(cmt.message, text_type) # it automatically decodes it as such assert isinstance(cmt.author.name, text_type) # same here cmt.message = u"üäêèß" assert len(cmt.message) == 5 cmt.author.name = u"äüß" assert len(cmt.author.name) == 3 cstream = BytesIO() cmt._serialize(cstream) cstream.seek(0) assert len(cstream.getvalue()) ncmt = Commit(self.rorepo, cmt.binsha) ncmt._deserialize(cstream) assert cmt.author.name == ncmt.author.name assert cmt.message == ncmt.message # actually, it can't be printed in a shell as repr wants to have ascii only # it appears cmt.author.__repr__()
def git_repo(self): with mock.patch("publish.Repo", spec=Repo, spec_set=True) as mock_repo: commits = [ Commit(mock_repo, _h2b("111111"), message="First commit", parents=tuple()), Commit(mock_repo, _h2b("222222"), message="Second commit", parents=("111111",)), Commit(mock_repo, _h2b("333333"), message="Third commit", parents=("222222",)) ] mock_repo.iter_commits.return_value = commits rev_parse_returns = { "heads/master": commits[-1], PREVIOUS_TAG: TagObject(mock_repo, _h2b("aaaaaa"), object=commits[-2], tag=PREVIOUS_TAG), CURRENT_TAG: TagObject(mock_repo, _h2b("bbbbbb"), object=commits[-1], tag=CURRENT_TAG) } mock_repo.rev_parse.side_effect = lambda x: rev_parse_returns[x] mock_repo.git.rev_parse.side_effect = lambda x, **kwargs: x def describe(rev=None, **kwargs): print("call to describe(%r, %r)" % (rev, kwargs)) if rev is None: return CURRENT_TAG if rev.endswith("^"): if rev.startswith(CURRENT_TAG): return PREVIOUS_TAG raise GitCommandError("describe", "failed") raise AssertionError("Test wants to describe something unexpected: rev=%r, kwargs=%r" % (rev, kwargs)) mock_repo.git.describe.side_effect = describe yield mock_repo
def test_iteration(self): # we can iterate commits all_commits = Commit.list_items(self.rorepo, self.rorepo.head) assert all_commits self.assertEqual(all_commits, list(self.rorepo.iter_commits())) # this includes merge commits mcomit = self.rorepo.commit('d884adc80c80300b4cc05321494713904ef1df2d') assert mcomit in all_commits # we can limit the result to paths ltd_commits = list(self.rorepo.iter_commits(paths='CHANGES')) assert ltd_commits and len(ltd_commits) < len(all_commits) # show commits of multiple paths, resulting in a union of commits less_ltd_commits = list( Commit.iter_items(self.rorepo, 'master', paths=('CHANGES', 'AUTHORS'))) assert len(ltd_commits) < len(less_ltd_commits) class Child(Commit): def __init__(self, *args, **kwargs): super(Child, self).__init__(*args, **kwargs) child_commits = list( Child.iter_items(self.rorepo, 'master', paths=('CHANGES', 'AUTHORS'))) assert type(child_commits[0]) == Child
def git_commit(): time = "Sat, 13 Dec 2019 12:40:00 +0000" repo = Repo(path) os.environ["GIT_AUTHOR_DATE"] = time os.environ["GIT_COMMITTER_DATE"] = time repo.git.add('--all') comm = Commit(repo, Commit.NULL_BIN_SHA, None, None, time, 0, None, time, 0, COMMIT_MESSAGE, None, None) #for x in range(0, 100000): #try: comm.message = 'noonce' + COMMIT_MESSAGE print(comm.hexsha)
def assert_commit_serialization(self, rwrepo, commit_id, print_performance_info=False): """traverse all commits in the history of commit identified by commit_id and check if the serialization works. :param print_performance_info: if True, we will show how fast we are""" ns = 0 # num serializations nds = 0 # num deserializations st = time.time() for cm in rwrepo.commit(commit_id).traverse(): nds += 1 # assert that we deserialize commits correctly, hence we get the same # sha on serialization stream = BytesIO() cm._serialize(stream) ns += 1 streamlen = stream.tell() stream.seek(0) istream = rwrepo.odb.store(IStream(Commit.type, streamlen, stream)) self.assertEqual(istream.hexsha, cm.hexsha.encode('ascii')) nc = Commit(rwrepo, Commit.NULL_BIN_SHA, cm.tree, cm.author, cm.authored_date, cm.author_tz_offset, cm.committer, cm.committed_date, cm.committer_tz_offset, cm.message, cm.parents, cm.encoding) self.assertEqual(nc.parents, cm.parents) stream = BytesIO() nc._serialize(stream) ns += 1 streamlen = stream.tell() stream.seek(0) # reuse istream istream.size = streamlen istream.stream = stream istream.binsha = None nc.binsha = rwrepo.odb.store(istream).binsha # if it worked, we have exactly the same contents ! self.assertEqual(nc.hexsha, cm.hexsha) # END check commits elapsed = time.time() - st if print_performance_info: print( "Serialized %i and deserialized %i commits in %f s ( (%f, %f) commits / s" % (ns, nds, elapsed, ns / elapsed, nds / elapsed), file=sys.stderr)
def assert_commit_serialization(rwrepo, commit_id, print_performance_info=False): """traverse all commits in the history of commit identified by commit_id and check if the serialization works. :param print_performance_info: if True, we will show how fast we are""" ns = 0 # num serializations nds = 0 # num deserializations st = time.time() for cm in rwrepo.commit(commit_id).traverse(): nds += 1 # assert that we deserialize commits correctly, hence we get the same # sha on serialization stream = BytesIO() cm._serialize(stream) ns += 1 streamlen = stream.tell() stream.seek(0) istream = rwrepo.odb.store(IStream(Commit.type, streamlen, stream)) assert istream.hexsha == cm.hexsha.encode('ascii') nc = Commit(rwrepo, Commit.NULL_BIN_SHA, cm.tree, cm.author, cm.authored_date, cm.author_tz_offset, cm.committer, cm.committed_date, cm.committer_tz_offset, cm.message, cm.parents, cm.encoding) assert nc.parents == cm.parents stream = BytesIO() nc._serialize(stream) ns += 1 streamlen = stream.tell() stream.seek(0) # reuse istream istream.size = streamlen istream.stream = stream istream.binsha = None nc.binsha = rwrepo.odb.store(istream).binsha # if it worked, we have exactly the same contents ! assert nc.hexsha == cm.hexsha # END check commits elapsed = time.time() - st if print_performance_info: print("Serialized %i and deserialized %i commits in %f s ( (%f, %f) commits / s" % (ns, nds, elapsed, ns / elapsed, nds / elapsed), file=sys.stderr)
def archive(test_viewer: TestViewer) -> Experiment: """ 将某次 test 对应 commit 的文件打包,相关命令为 git archive -o <filename> <commit-id> :param test_viewer: :return: """ repo = test_viewer.repo commit = Commit(repo, hex_to_bin(test_viewer.json_info['commit_hash'])) old_path = os.getcwd() os.chdir(commit.tree.abspath) exp = Experiment('Archive') revert_path = exp.makedir('archive') revert_fn = os.path.join(revert_path, "file.zip") exp.regist_plugin('archive', { 'file': revert_fn, 'test_name': test_viewer.test_name }) with open(revert_fn, 'wb') as w: commit.repo.archive(w, commit) exp.end() os.chdir(old_path) return exp
def assert_gpgsig_deserialization(self, cstream): assert 'gpgsig' in 'precondition: need gpgsig' class RepoMock: def __init__(self, bytestr): self.bytestr = bytestr @property def odb(self): class ODBMock: def __init__(self, bytestr): self.bytestr = bytestr def stream(self, *args): stream = Mock(spec_set=['read'], return_value=self.bytestr) stream.read.return_value = self.bytestr return ('binsha', 'typename', 'size', stream) return ODBMock(self.bytestr) repo_mock = RepoMock(cstream.getvalue()) for field in Commit.__slots__: c = Commit(repo_mock, b'x' * 20) assert getattr(c, field) is not None
def test_list(self): # This doesn't work anymore, as we will either attempt getattr with bytes, or compare 20 byte string # with actual 20 byte bytes. This usage makes no sense anyway assert isinstance( Commit.list_items( self.rorepo, '0.1.5', max_count=5)['5117c9c8a4d3af19a9958677e45cda9269de1541'], Commit)
def test_iteration(self): # we can iterate commits all_commits = Commit.list_items(self.rorepo, self.rorepo.head) assert all_commits assert all_commits == list(self.rorepo.iter_commits()) # this includes merge commits mcomit = self.rorepo.commit('d884adc80c80300b4cc05321494713904ef1df2d') assert mcomit in all_commits # we can limit the result to paths ltd_commits = list(self.rorepo.iter_commits(paths='CHANGES')) assert ltd_commits and len(ltd_commits) < len(all_commits) # show commits of multiple paths, resulting in a union of commits less_ltd_commits = list(Commit.iter_items(self.rorepo, 'master', paths=('CHANGES', 'AUTHORS'))) assert len(ltd_commits) < len(less_ltd_commits)
def get_files_list(args, head_commit: Commit, latest_commit: Commit) -> List[RemoteFile]: diff_list = head_commit.diff(latest_commit.hexsha) return [ RemoteFile(args.file_url_pattern, path=name, revision=head_commit.hexsha) for name in _get_files_in_diff_list(diff_list) ]
def __init__(self, url_pattern: str, source: Commit): self.revision: str = source.hexsha self.message: str = source.message author: Actor = source.author self.author = RemoteUser(author.name, author.email) self.date: datetime = source.committed_datetime self.files: Set[str] = set() self.parents: Set[str] = set(p.hexsha for p in source.iter_parents()) self.url = url_pattern.replace("REVISION", self.revision)
def get_commit_diff(commit: git.Commit) -> List[git.Diff]: """Get modified files of the given commit.""" if len(commit.parents) == 1: return commit.parents[0].diff(commit, create_patch=True) elif len(commit.parents) == 0: # First commit in the repo return commit.diff(git.NULL_TREE, create_patch=True) else: # Probably a merge commit, we can't do much about it return []
def get_news_between_commits(commit1: Commit, commit2: Commit, news_fragment_dir: Path) -> List[News]: diffs = commit1.diff(commit2) paths = [ diff.a_path for diff in diffs if diff.change_type in ("A", "C", "R", "M") and news_fragment_dir == Path(diff.a_path).parent ] return [ News(file_name=path, content=file_content_from_commit(commit2, path)) for path in paths ]
def get_commits_not_in_prs(start_ref, end_ref): """ Return a tuple of commits that exist between start_ref and end_ref, but were not merged to the end_ref. If everyone is following the pull request process correctly, this should return an empty tuple. """ return tuple(Commit.iter_items( repo, "{start}..{end}".format(start=start_ref, end=end_ref), first_parent=True, no_merges=True, ))
def test_commit_iteration(self): # bound to stream parsing performance nc = 0 st = time() for c in Commit.iter_items(self.gitrorepo, self.gitrorepo.head): nc += 1 self._query_commit_info(c) # END for each traversed commit elapsed_time = time() - st print("Iterated %i Commits in %s [s] ( %f commits/s )" % (nc, elapsed_time, nc / elapsed_time), file=sys.stderr)
def test_commit_serialization(self): self.assert_commit_serialization(self.gitrwrepo, '58c78e6', True) rwrepo = self.gitrwrepo make_object = rwrepo.odb.store # direct serialization - deserialization can be tested afterwards # serialization is probably limited on IO hc = rwrepo.commit(rwrepo.head) nc = 5000 st = time() for i in range(nc): cm = Commit(rwrepo, Commit.NULL_BIN_SHA, hc.tree, hc.author, hc.authored_date, hc.author_tz_offset, hc.committer, hc.committed_date, hc.committer_tz_offset, str(i), parents=hc.parents, encoding=hc.encoding) stream = BytesIO() cm._serialize(stream) slen = stream.tell() stream.seek(0) cm.binsha = make_object(IStream(Commit.type, slen, stream)).binsha # END commit creation elapsed = time() - st print( "Serialized %i commits to loose objects in %f s ( %f commits / s )" % (nc, elapsed, nc / elapsed), file=sys.stderr)
def modified_files_for_commit(commit: Commit, log: Any) -> Set: """ Return modified, added, renamed, and removed files for a given commit and its parent. :param commit: The commit to query. :param log: A logger. :return: The set of changed files. """ if not commit.parents: return set() parent = commit.parents[0] diff = commit.diff(parent) return get_changed_files(diff, log)
def _find_parents(self, child: Commit, file_path): history = list(child.iter_parents(paths=file_path)) from_id = self._map[child.hexsha] if len(history) >= 1: parent_1 = history[0] to_id = self._map[parent_1.hexsha] self.edges.append((from_id, to_id)) if len(history) >= 2: parent_2 = history[1] hist_p_1 = list(parent_1.iter_parents(paths=file_path)) if parent_2 not in hist_p_1: to_id = self._map[parent_2.hexsha] self.edges.append((from_id, to_id))
def get_modifications(commit: Commit) -> List[Modification]: """Extracts all the modifications from a given commit. Arguments: commit {Commit} -- A git commit. Returns: List[Modification] -- All modifications contained within the git commit. """ if commit.parents: diffs = commit.parents[0].diff(commit) else: # initial commit diffs = commit.diff(NULL_TREE) return [Modification.from_diff(d, tree=commit.tree) for d in diffs]
def _do_commit (self, repo, head, tree_binsha, msg, parent=None): """ if parent parameter is None, we make it default to be [head.commit] return new commit's hexsha, on error return None and output error """ assert (repo) assert head is None or isinstance (head, HEAD) or isinstance (head, Head) assert msg != None if parent is None: try: parent = [head.commit] except ValueError: pass new_commit = Commit.create_from_tree (repo, Tree (repo, tree_binsha), msg, \ parent_commits=parent, head=False) # because the first commit has no parent, parameter head==True likely fails head.commit = new_commit #modify head's ref to commit return new_commit
def whatchanged(commit_a: Commit, commit_b: Commit) -> Tuple[List[str], List[str], List[str]]: """Get files added, modified and deleted between commits.""" diffs = commit_b.diff(commit_a) added_files = [] modified_files = [] deleted_files = [] for diff in diffs: if diff.new_file: added_files.append(diff.b_path) elif diff.deleted_file: deleted_files.append(diff.a_path) elif diff.renamed_file: added_files.append(diff.b_path) deleted_files.append(diff.a_path) elif diff.change_type == "M": modified_files.append(diff.a_path) return added_files, modified_files, deleted_files
def test_rev_list_bisect_all(self): """ 'git rev-list --bisect-all' returns additional information in the commit header. This test ensures that we properly parse it. """ revs = self.rorepo.git.rev_list('933d23bf95a5bd1624fbcdf328d904e1fa173474', first_parent=True, bisect_all=True) commits = Commit._iter_from_process_or_stream(self.rorepo, StringProcessAdapter(revs.encode('ascii'))) expected_ids = ( '7156cece3c49544abb6bf7a0c218eb36646fad6d', '1f66cfbbce58b4b552b041707a12d437cc5f400a', '33ebe7acec14b25c5f84f35a664803fcab2f7781', '933d23bf95a5bd1624fbcdf328d904e1fa173474' ) for sha1, commit in zip(expected_ids, commits): assert_equal(sha1, commit.hexsha)
def blobs_in_commit_range( start_commit: git.Commit, end_commit: git.Commit ) -> Generator[Tuple[str, bytes, bytes], None, None]: """Generate (blob_path, start_blob, end_blob).""" if start_commit: for diff in end_commit.diff(start_commit): # diff.a_xxx goes with end_commit. if diff.a_blob: a_blob = diff.a_blob.data_stream.read() if diff.b_blob: b_blob = diff.b_blob.data_stream.read() else: b_blob = b"" yield diff.a_path, b_blob, a_blob else: for item in end_commit.tree.traverse(): if item.type == "blob": yield item.path, b"", item.data_stream.read()
def get_commit_diff(commit: git.Commit) -> List[git.Diff]: """Get modified files of the given commit. Args: commit: Commit to get the diff of. Returns: List of git.Diff containing information about the modified files in the given commit. """ if len(commit.parents) == 1: return commit.parents[0].diff(commit, create_patch=True) elif len(commit.parents) == 0: # First commit in the repo return commit.diff(git.NULL_TREE, create_patch=True) else: # Probably a merge commit, we can't do much about it return []
def reset(test_viewer: TestViewer) -> Experiment: """ 将工作目录中的文件恢复到某个commit 恢复快照的 git 流程: git branch experiment git add . & git commit -m ... // 保证文件最新,防止冲突报错,这一步由 Experiment() 代为完成 git checkout <commit-id> // 恢复文件到 <commit-id> git checkout -b reset // 将当前状态附到新的临时分支 reset 上 git branch experiment // 切换回 experiment 分支 git add . & git commit -m ... // 将当前状态重新提交到最新 // 此时experiment 中最新的commit 为恢复的<commit-id> git branch -D reset // 删除临时分支 git branch master // 最终回到原来分支,保证除文件变动外git状态完好 :param test_viewer: TestViewer :return: """ repo = test_viewer.repo commit = Commit(repo, hex_to_bin(test_viewer.json_info['commit_hash'])) old_path = os.getcwd() os.chdir(commit.tree.abspath) exp = Experiment('Reset') repo = commit.repo # type:Repo with branch(commit.repo, _GITKEY.thexp_branch) as new_branch: repo.git.checkout(commit.hexsha) repo.git.checkout('-b', 'reset') repo.head.reference = new_branch repo.git.add('.') ncommit = repo.index.commit("Reset from {}".format(commit.hexsha)) repo.git.branch('-d', 'reset') exp.regist_plugin( 'reset', { 'test_name': test_viewer.test_name, # 从哪个状态恢复 'from': exp.commit.hexsha, # reset 运行时的快照 'where': commit.hexsha, # 恢复到哪一次 commit,是恢复前的保存的状态 'to': ncommit.hexsha, # 对恢复后的状态再次进行提交,此时 from 和 to 两次提交状态应该完全相同 }) exp.end() os.chdir(old_path) return exp
def commit(request, commit_hexsha): binsha = binascii.unhexlify(commit_hexsha) commit = Commit(repo, binsha) details = { 'hexsha': commit.hexsha, 'author': commit.author.name, 'message': commit.message, 'authored_datetime': commit.authored_datetime, 'files': [{ 'filename': key, 'changes': value } for key, value in commit.stats.files.items()], 'author_email': commit.author.email } return JsonResponse({'commit': details})
def get_git_info(self, path): unique_authors = [] seen_authors = [] last_commit_date = "" # print("get_git_info for " + path) for c in Commit.iter_items(self.localrepo, self.localrepo.head, path): if not last_commit_date: # Use the last commit and get the date last_commit_date = time.strftime("%Y-%m-%d", time.gmtime(c.authored_date)) c.author.email = c.author.email.lower() if not (c.author.email in self.authors): # Not in cache: let's ask GitHub self.authors[c.author.email] = {} # First, search by email print("Search by email: " + c.author.email) info = self.get_gituser_info( c.author.email, \ { 'query': '{ search(type: USER, query: "in:email ' + c.author.email + '", first: 1) { edges { node { ... on User { login name url } } } } }' }) if info: self.authors[c.author.email] = info else: # If not found, search by name print(" User not found by email, search by name: " + c.author.name) info = self.get_gituser_info( c.author.name, \ { 'query': '{ search(type: USER, query: "in:name ' + c.author.name + '", first: 1) { edges { node { ... on User { login name url } } } } }' }) if info: self.authors[c.author.email] = info else: # If not found, use local git info only and gravatar avatar self.authors[c.author.email] = { 'login':'', \ 'name':c.author.name if c.author.name else '', \ 'url':'', \ 'avatar':'https://www.gravatar.com/avatar/' + hashlib.md5(c.author.email.encode('utf-8')).hexdigest() + '?d=identicon' } if c.author.email not in seen_authors: seen_authors.append(c.author.email) unique_authors.append(self.authors[c.author.email]) #print(" Author: "+ self.authors[c.author.email]['name'] + " ("+ str(self.authors[c.author.email]['email'])+ ")") return unique_authors, last_commit_date
def __setstate__(self, state: dict): from gitdb.util import hex_to_bin from git import Commit self._start_time = state['_start_time'] self._time_fmt = state['_time_fmt'] self._exp_name = state['_exp_name'] self._exp_dir = state['_exp_dir'] self._test_dir = state['_test_dir'] self._project_dir = state['_project_dir'] self._hold_dirs = state['_hold_dirs'] self._plugins = state['_plugins'] self._tags = state['_tags'] self._exc_dict = state.get('_exc_dict', None) self._end_state = state['_end_state'] self._in_main = state['_in_main'] self._repo = None self._commit = Commit(self.repo, hex_to_bin(state['_commit'])) self._config = globs
def create_rpmbuild_content(repo, target, config): rpm_prefix = config['rpm']['prefix'] for branch in repo.branches: # We only want environment branches, not manifest branches. if not branch.name.startswith(manifest_branch_prefix): manifest_branch_name = manifest_branch_prefix + branch.name # If there is no equivalent manifest branch, we need to # skip this environment. if manifest_branch_name not in repo.branches: continue branch.checkout() labelled_tags = tags_by_label(os.path.join(repo.working_dir, 'labels')) # Get number of commits to determine the version of the env rpm. commit_num = len(list(Commit.iter_items(repo, branch.commit))) # Keep track of the labels which have tags - its those we want. for label, tag in labelled_tags.items(): create_rpmbuild_for_tag(repo, tag, target, config) fname = '{}-env-{}-label-{}.spec'.format(rpm_prefix, branch.name, label) with open(os.path.join(target, 'SPECS', fname), 'w') as fh: fh.write(generate.render_env(branch.name, label, repo, config, tag, commit_num))
def get_files_changed_between_commits(commit_a: Commit, commit_b: Commit)-> (Set[str], Set[str]): """Determine what files have been added or modified between commits b and a Those files should be added to a_files and if they are present in commit b, added to b_files :param commit_a: :param commit_b: :return: a pair of sets, the first set is the files in commit a the second set is the files in commit b ":rtype (Set[str], Set[str]): """ diffs = commit_b.diff(other=commit_a) a_files = set() # type: Set[str] b_files = set() # type: Set[str] for diff in diffs: if diff.new_file or (diff.a_blob and diff.b_blob and diff.a_blob != diff.b_blob): a_files.add(diff.a_path) if not diff.new_file: b_files.add(diff.b_path) return a_files, b_files
def newcommit(repo, message, date, name=None, email=None): """Creates a commit object with a custom date. :param repo: Repo object the commit should be part of :param tree: Tree object :param message: Commit message. It may be an empty string if no message is provided. :param date: Date in seconds, as an Int :return: Commit object representing the new commit :note: Additional information about the committer and Author are taken from the git configuration """ tree = repo.index.write_tree() try: parents = [repo.head.commit] except ValueError: parents = [] # Committer and Author info cr = repo.config_reader() if name == None or email == None: actor = Actor.committer(cr) else: actor = Actor(name, email) committer = actor author = actor # Date # offset = altzone # 3600*offsethours offset = 0 # UTC author_time, author_offset = date, offset committer_time, committer_offset = date, offset # assume utf8 encoding enc_section, enc_option = Commit.conf_encoding.split('.') conf_encoding = cr.get_value(enc_section, enc_option, Commit.default_encoding) # Create New Commit new_commit = Commit(repo, Commit.NULL_BIN_SHA, tree, author, author_time, author_offset, committer, committer_time, committer_offset, message, parents, conf_encoding) stream = StringIO() new_commit._serialize(stream) streamlen = stream.tell() stream.seek(0) istream = repo.odb.store(IStream(Commit.type, streamlen, stream)) new_commit.binsha = istream.binsha # Advance HEAD to the new commit automatically. # need late import here, importing git at the very beginning throws. import git.refs try: repo.head.set_commit(new_commit, logmsg="commit: %s" % message) except ValueError: # head is not yet set to the ref our HEAD points to # Happens on first commit import git.refs master = git.refs.Head.create(repo, repo.head.ref, new_commit, logmsg="commit (initial): %s" % message) repo.head.set_reference(master, logmsg='commit: Switching to %s' % master) # END handle empty repositories return new_commit
def test_equality(self): commit1 = Commit(self.rorepo, Commit.NULL_BIN_SHA) commit2 = Commit(self.rorepo, Commit.NULL_BIN_SHA) commit3 = Commit(self.rorepo, "\1" * 20) assert_equal(commit1, commit2) assert_not_equal(commit2, commit3)
def commit(self, commit, message): """Commits files given a commit message and a given commit""" self.repo.git.commit() class CommitFile(object): """Holds some information about a file in addition to its diff""" def __init__(self): self.isUntracked = None self.isRenamed = None self.diff = None self.lineNumbers = None #self. def setDiff(self, diff): """""" self.diff = diff if __name__ == "__main__": x = GitManager('') print x.grabUntrackedFiles() print x.grabAllFilesToBeCommited() commit = Commit.new(x.repo, x.repo.head.ref) print commit print commit.author print commit.committer print dir(commit.stats) print commit.stats.files #print x.createCommitForPartialFiles() #print commit.diff(None, None) #print x.repo.commit().diff(None, None)[1].a_blob.path
def test_list(self): # This doesn't work anymore, as we will either attempt getattr with bytes, or compare 20 byte string # with actual 20 byte bytes. This usage makes no sense anyway assert isinstance(Commit.list_items(self.rorepo, '0.1.5', max_count=5)[ '5117c9c8a4d3af19a9958677e45cda9269de1541'], Commit)