Skip to content

Commit

Permalink
Add Repository.message
Browse files Browse the repository at this point in the history
  • Loading branch information
jorio committed Dec 30, 2023
1 parent eedf2ce commit ea36ef1
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 1 deletion.
3 changes: 2 additions & 1 deletion pygit2/decl/repository.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ int git_repository_ident(const char **name, const char **email, const git_reposi
int git_repository_set_ident(git_repository *repo, const char *name, const char *email);
int git_repository_index(git_index **out, git_repository *repo);
git_repository_state_t git_repository_state(git_repository *repo);

int git_repository_message(git_buf *out, git_repository *repo);
int git_repository_message_remove(git_repository *repo);
int git_repository_submodule_cache_all(git_repository *repo);
int git_repository_submodule_cache_clear(git_repository *repo);
45 changes: 45 additions & 0 deletions pygit2/repository.py
Original file line number Diff line number Diff line change
Expand Up @@ -957,6 +957,51 @@ def merge(self, id, favor="normal", flags=None, file_flags=None):
C.git_annotated_commit_free(commit_ptr[0])
check_error(err)

#
# Prepared message (MERGE_MSG)
#
@property
def raw_message(self) -> bytes:
"""
Retrieve git's prepared message (bytes).
See `Repository.message` for more information.
"""
buf = ffi.new('git_buf *', (ffi.NULL, 0))
try:
err = C.git_repository_message(buf, self._repo)
if err == C.GIT_ENOTFOUND:
return b''
check_error(err)
return ffi.string(buf.ptr)
finally:
C.git_buf_dispose(buf)

@property
def message(self) -> str:
"""
Retrieve git's prepared message.
Operations such as git revert/cherry-pick/merge with the -n option stop
just short of creating a commit with the changes and save their
prepared message in .git/MERGE_MSG so the next git-commit execution can
present it to the user for them to amend if they wish.
Use this function to get the contents of this file. Don't forget to
call `Repository.remove_message()` after you create the commit.
Note that the message is also removed by `Repository.state_cleanup()`.
If there is no such message, an empty string is returned.
"""
return self.raw_message.decode('utf-8')

def remove_message(self):
"""
Remove git's prepared message.
"""
err = C.git_repository_message_remove(self._repo)
check_error(err)

#
# Describe
#
Expand Down
7 changes: 7 additions & 0 deletions test/test_cherrypick.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,15 +50,22 @@ def test_cherrypick_already_something_in_index(mergerepo):

def test_cherrypick_remove_conflicts(mergerepo):
assert mergerepo.state() == RepositoryState.NONE
assert not mergerepo.message

other_branch_tip = '1b2bae55ac95a4be3f8983b86cd579226d0eb247'
mergerepo.cherrypick(other_branch_tip)

assert mergerepo.state() == RepositoryState.CHERRYPICK
assert mergerepo.message.startswith("commit to provoke a conflict")

idx = mergerepo.index
conflicts = idx.conflicts
assert conflicts is not None
conflicts['.gitignore']
del idx.conflicts['.gitignore']
with pytest.raises(KeyError): conflicts.__getitem__('.gitignore')
assert idx.conflicts is None

mergerepo.state_cleanup()
assert mergerepo.state() == RepositoryState.NONE
assert not mergerepo.message
23 changes: 23 additions & 0 deletions test/test_merge.py
Original file line number Diff line number Diff line change
Expand Up @@ -286,3 +286,26 @@ def test_merge_mergeheads(mergerepo):

mergerepo.state_cleanup()
assert mergerepo.listall_mergeheads() == [], "state_cleanup() should wipe the mergeheads"


def test_merge_message(mergerepo):
assert not mergerepo.message
assert not mergerepo.raw_message

branch_head_hex = '1b2bae55ac95a4be3f8983b86cd579226d0eb247'
mergerepo.merge(branch_head_hex)

assert mergerepo.message.startswith(f"Merge commit '{branch_head_hex}'")
assert mergerepo.message.encode('utf-8') == mergerepo.raw_message

mergerepo.state_cleanup()
assert not mergerepo.message


def test_merge_remove_message(mergerepo):
branch_head_hex = '1b2bae55ac95a4be3f8983b86cd579226d0eb247'
mergerepo.merge(branch_head_hex)

assert mergerepo.message.startswith(f"Merge commit '{branch_head_hex}'")
mergerepo.remove_message()
assert not mergerepo.message

0 comments on commit ea36ef1

Please sign in to comment.