|
29 | 29 |
|
30 | 30 | import pytest
|
31 | 31 |
|
32 |
| -from pygit2 import GIT_OBJ_COMMIT, Signature, Oid |
| 32 | +from pygit2 import GIT_OBJ_COMMIT, Signature, Oid, GitError |
33 | 33 | from . import utils
|
34 | 34 |
|
35 | 35 |
|
36 | 36 | COMMIT_SHA = '5fe808e8953c12735680c257f56600cb0de44b10'
|
| 37 | +COMMIT_SHA_TO_AMEND = '784855caf26449a1914d2cf62d12b9374d76ae78' # tip of the master branch |
37 | 38 |
|
38 | 39 |
|
39 | 40 | @utils.refcount
|
@@ -133,3 +134,116 @@ def test_modify_commit(barerepo):
|
133 | 134 | with pytest.raises(AttributeError): setattr(commit, 'author', author)
|
134 | 135 | with pytest.raises(AttributeError): setattr(commit, 'tree', None)
|
135 | 136 | with pytest.raises(AttributeError): setattr(commit, 'parents', None)
|
| 137 | + |
| 138 | +def test_amend_commit_metadata(barerepo): |
| 139 | + repo = barerepo |
| 140 | + commit = repo[COMMIT_SHA_TO_AMEND] |
| 141 | + assert commit.oid == repo.head.target |
| 142 | + |
| 143 | + encoding = 'iso-8859-1' |
| 144 | + amended_message = "Amended commit message.\n\nMessage with non-ascii chars: ééé.\n" |
| 145 | + amended_author = Signature( 'Jane Author', '[email protected]', 12345, 0) |
| 146 | + amended_committer = Signature( 'John Committer', '[email protected]', 12346, 0) |
| 147 | + |
| 148 | + amended_oid = repo.amend_commit( |
| 149 | + commit, 'HEAD', message=amended_message, author=amended_author, |
| 150 | + committer=amended_committer, encoding=encoding) |
| 151 | + amended_commit = repo[amended_oid] |
| 152 | + |
| 153 | + assert repo.head.target == amended_oid |
| 154 | + assert GIT_OBJ_COMMIT == amended_commit.type |
| 155 | + assert amended_committer == amended_commit.committer |
| 156 | + assert amended_author == amended_commit.author |
| 157 | + assert amended_message.encode(encoding) == amended_commit.raw_message |
| 158 | + assert commit.author != amended_commit.author |
| 159 | + assert commit.committer != amended_commit.committer |
| 160 | + assert commit.tree == amended_commit.tree # we didn't touch the tree |
| 161 | + |
| 162 | +def test_amend_commit_tree(barerepo): |
| 163 | + repo = barerepo |
| 164 | + commit = repo[COMMIT_SHA_TO_AMEND] |
| 165 | + assert commit.oid == repo.head.target |
| 166 | + |
| 167 | + tree = '967fce8df97cc71722d3c2a5930ef3e6f1d27b12' |
| 168 | + tree_prefix = tree[:5] |
| 169 | + |
| 170 | + amended_oid = repo.amend_commit(commit, 'HEAD', tree=tree_prefix) |
| 171 | + amended_commit = repo[amended_oid] |
| 172 | + |
| 173 | + assert repo.head.target == amended_oid |
| 174 | + assert GIT_OBJ_COMMIT == amended_commit.type |
| 175 | + assert commit.message == amended_commit.message |
| 176 | + assert commit.author == amended_commit.author |
| 177 | + assert commit.committer == amended_commit.committer |
| 178 | + assert commit.tree_id != amended_commit.tree_id |
| 179 | + assert Oid(hex=tree) == amended_commit.tree_id |
| 180 | + |
| 181 | +def test_amend_commit_not_tip_of_branch(barerepo): |
| 182 | + repo = barerepo |
| 183 | + |
| 184 | + # This commit isn't at the tip of the branch. |
| 185 | + commit = repo['5fe808e8953c12735680c257f56600cb0de44b10'] |
| 186 | + assert commit.oid != repo.head.target |
| 187 | + |
| 188 | + # Can't update HEAD to the rewritten commit because it's not the tip of the branch. |
| 189 | + with pytest.raises(GitError): |
| 190 | + repo.amend_commit(commit, 'HEAD', message="this won't work!") |
| 191 | + |
| 192 | + # We can still amend the commit if we don't try to update a ref. |
| 193 | + repo.amend_commit(commit, None, message="this will work") |
| 194 | + |
| 195 | +def test_amend_commit_no_op(barerepo): |
| 196 | + repo = barerepo |
| 197 | + commit = repo[COMMIT_SHA_TO_AMEND] |
| 198 | + assert commit.oid == repo.head.target |
| 199 | + |
| 200 | + amended_oid = repo.amend_commit(commit, None) |
| 201 | + assert amended_oid == commit.oid |
| 202 | + |
| 203 | +def test_amend_commit_argument_types(barerepo): |
| 204 | + repo = barerepo |
| 205 | + |
| 206 | + some_tree = repo['967fce8df97cc71722d3c2a5930ef3e6f1d27b12'] |
| 207 | + commit = repo[COMMIT_SHA_TO_AMEND] |
| 208 | + alt_commit1 = Oid(hex=COMMIT_SHA_TO_AMEND) |
| 209 | + alt_commit2 = COMMIT_SHA_TO_AMEND |
| 210 | + alt_tree = some_tree |
| 211 | + alt_refname = repo.head # try this one last, because it'll change the commit at the tip |
| 212 | + |
| 213 | + # Pass bad values/types for the commit |
| 214 | + with pytest.raises(ValueError): repo.amend_commit(None, None) |
| 215 | + with pytest.raises(TypeError): repo.amend_commit(some_tree, None) |
| 216 | + |
| 217 | + # Pass bad types for signatures |
| 218 | + with pytest.raises(TypeError): repo.amend_commit(commit, None, author="Toto") |
| 219 | + with pytest.raises(TypeError): repo.amend_commit(commit, None, committer="Toto") |
| 220 | + |
| 221 | + # Pass bad refnames |
| 222 | + with pytest.raises(ValueError): repo.amend_commit(commit, "this-ref-doesnt-exist") |
| 223 | + with pytest.raises(TypeError): repo.amend_commit(commit, repo) |
| 224 | + |
| 225 | + # Pass bad trees |
| 226 | + with pytest.raises(ValueError): repo.amend_commit(commit, None, tree="can't parse this") |
| 227 | + with pytest.raises(KeyError): repo.amend_commit(commit, None, tree="baaaaad") |
| 228 | + |
| 229 | + # Pass an Oid for the commit |
| 230 | + amended_oid = repo.amend_commit(alt_commit1, None, message="Hello") |
| 231 | + amended_commit = repo[amended_oid] |
| 232 | + assert GIT_OBJ_COMMIT == amended_commit.type |
| 233 | + assert str(amended_oid) != COMMIT_SHA_TO_AMEND |
| 234 | + |
| 235 | + # Pass a str for the commit |
| 236 | + amended_oid = repo.amend_commit(alt_commit2, None, message="Hello", tree=alt_tree) |
| 237 | + amended_commit = repo[amended_oid] |
| 238 | + assert GIT_OBJ_COMMIT == amended_commit.type |
| 239 | + assert str(amended_oid) != COMMIT_SHA_TO_AMEND |
| 240 | + assert repo[COMMIT_SHA_TO_AMEND].tree != amended_commit.tree |
| 241 | + assert alt_tree.oid == amended_commit.tree_id |
| 242 | + |
| 243 | + # Pass an actual reference object for refname |
| 244 | + # (Warning: the tip of the branch will be altered after this test!) |
| 245 | + amended_oid = repo.amend_commit(alt_commit2, alt_refname, message="Hello") |
| 246 | + amended_commit = repo[amended_oid] |
| 247 | + assert GIT_OBJ_COMMIT == amended_commit.type |
| 248 | + assert str(amended_oid) != COMMIT_SHA_TO_AMEND |
| 249 | + assert repo.head.target == amended_oid |
0 commit comments