code.gitea.io/gitea@v1.22.3/modules/git/commit_test.go (about) 1 // Copyright 2017 The Gitea Authors. All rights reserved. 2 // SPDX-License-Identifier: MIT 3 4 package git 5 6 import ( 7 "context" 8 "os" 9 "path/filepath" 10 "strings" 11 "testing" 12 13 "github.com/stretchr/testify/assert" 14 ) 15 16 func TestCommitsCount(t *testing.T) { 17 bareRepo1Path := filepath.Join(testReposDir, "repo1_bare") 18 19 commitsCount, err := CommitsCount(DefaultContext, 20 CommitsCountOptions{ 21 RepoPath: bareRepo1Path, 22 Revision: []string{"8006ff9adbf0cb94da7dad9e537e53817f9fa5c0"}, 23 }) 24 25 assert.NoError(t, err) 26 assert.Equal(t, int64(3), commitsCount) 27 } 28 29 func TestCommitsCountWithoutBase(t *testing.T) { 30 bareRepo1Path := filepath.Join(testReposDir, "repo1_bare") 31 32 commitsCount, err := CommitsCount(DefaultContext, 33 CommitsCountOptions{ 34 RepoPath: bareRepo1Path, 35 Not: "master", 36 Revision: []string{"branch1"}, 37 }) 38 39 assert.NoError(t, err) 40 assert.Equal(t, int64(2), commitsCount) 41 } 42 43 func TestGetFullCommitID(t *testing.T) { 44 bareRepo1Path := filepath.Join(testReposDir, "repo1_bare") 45 46 id, err := GetFullCommitID(DefaultContext, bareRepo1Path, "8006ff9a") 47 assert.NoError(t, err) 48 assert.Equal(t, "8006ff9adbf0cb94da7dad9e537e53817f9fa5c0", id) 49 } 50 51 func TestGetFullCommitIDError(t *testing.T) { 52 bareRepo1Path := filepath.Join(testReposDir, "repo1_bare") 53 54 id, err := GetFullCommitID(DefaultContext, bareRepo1Path, "unknown") 55 assert.Empty(t, id) 56 if assert.Error(t, err) { 57 assert.EqualError(t, err, "object does not exist [id: unknown, rel_path: ]") 58 } 59 } 60 61 func TestCommitFromReader(t *testing.T) { 62 commitString := `feaf4ba6bc635fec442f46ddd4512416ec43c2c2 commit 1074 63 tree f1a6cb52b2d16773290cefe49ad0684b50a4f930 64 parent 37991dec2c8e592043f47155ce4808d4580f9123 65 author silverwind <me@silverwind.io> 1563741793 +0200 66 committer silverwind <me@silverwind.io> 1563741793 +0200 67 gpgsig -----BEGIN PGP SIGNATURE----- 68 ` + " " + ` 69 iQIzBAABCAAdFiEEWPb2jX6FS2mqyJRQLmK0HJOGlEMFAl00zmEACgkQLmK0HJOG 70 lEMDFBAAhQKKqLD1VICygJMEB8t1gBmNLgvziOLfpX4KPWdPtBk3v/QJ7OrfMrVK 71 xlC4ZZyx6yMm1Q7GzmuWykmZQJ9HMaHJ49KAbh5MMjjV/+OoQw9coIdo8nagRUld 72 vX8QHzNZ6Agx77xHuDJZgdHKpQK3TrMDsxzoYYMvlqoLJIDXE1Sp7KYNy12nhdRg 73 R6NXNmW8oMZuxglkmUwayMiPS+N4zNYqv0CXYzlEqCOgq9MJUcAMHt+KpiST+sm6 74 FWkJ9D+biNPyQ9QKf1AE4BdZia4lHfPYU/C/DEL/a5xQuuop/zMQZoGaIA4p2zGQ 75 /maqYxEIM/yRBQpT1jlODKPJrMEgx7SgY2hRU47YZ4fj6350fb6fNBtiiMAfJbjL 76 S3Gh85E9fm3hJaNSPKAaJFYL1Ya2svuWfgHj677C56UcmYis7fhiiy1aJuYdHnSm 77 sD53z/f0J+We4VZjY+pidvA9BGZPFVdR3wd3xGs8/oH6UWaLJAMGkLG6dDb3qDLm 78 1LFZwsX8sdD32i1SiWanYQYSYMyFWr0awi4xdoMtYCL7uKBYtwtPyvq3cj4IrJlb 79 mfeFhT57UbE4qukTDIQ0Y0WM40UYRTakRaDY7ubhXgLgx09Cnp9XTVMsHgT6j9/i 80 1pxsB104XLWjQHTjr1JtiaBQEwFh9r2OKTcpvaLcbNtYpo7CzOs= 81 =FRsO 82 -----END PGP SIGNATURE----- 83 84 empty commit` 85 86 sha := &Sha1Hash{0xfe, 0xaf, 0x4b, 0xa6, 0xbc, 0x63, 0x5f, 0xec, 0x44, 0x2f, 0x46, 0xdd, 0xd4, 0x51, 0x24, 0x16, 0xec, 0x43, 0xc2, 0xc2} 87 gitRepo, err := openRepositoryWithDefaultContext(filepath.Join(testReposDir, "repo1_bare")) 88 assert.NoError(t, err) 89 assert.NotNil(t, gitRepo) 90 defer gitRepo.Close() 91 92 commitFromReader, err := CommitFromReader(gitRepo, sha, strings.NewReader(commitString)) 93 assert.NoError(t, err) 94 if !assert.NotNil(t, commitFromReader) { 95 return 96 } 97 assert.EqualValues(t, sha, commitFromReader.ID) 98 assert.EqualValues(t, `-----BEGIN PGP SIGNATURE----- 99 100 iQIzBAABCAAdFiEEWPb2jX6FS2mqyJRQLmK0HJOGlEMFAl00zmEACgkQLmK0HJOG 101 lEMDFBAAhQKKqLD1VICygJMEB8t1gBmNLgvziOLfpX4KPWdPtBk3v/QJ7OrfMrVK 102 xlC4ZZyx6yMm1Q7GzmuWykmZQJ9HMaHJ49KAbh5MMjjV/+OoQw9coIdo8nagRUld 103 vX8QHzNZ6Agx77xHuDJZgdHKpQK3TrMDsxzoYYMvlqoLJIDXE1Sp7KYNy12nhdRg 104 R6NXNmW8oMZuxglkmUwayMiPS+N4zNYqv0CXYzlEqCOgq9MJUcAMHt+KpiST+sm6 105 FWkJ9D+biNPyQ9QKf1AE4BdZia4lHfPYU/C/DEL/a5xQuuop/zMQZoGaIA4p2zGQ 106 /maqYxEIM/yRBQpT1jlODKPJrMEgx7SgY2hRU47YZ4fj6350fb6fNBtiiMAfJbjL 107 S3Gh85E9fm3hJaNSPKAaJFYL1Ya2svuWfgHj677C56UcmYis7fhiiy1aJuYdHnSm 108 sD53z/f0J+We4VZjY+pidvA9BGZPFVdR3wd3xGs8/oH6UWaLJAMGkLG6dDb3qDLm 109 1LFZwsX8sdD32i1SiWanYQYSYMyFWr0awi4xdoMtYCL7uKBYtwtPyvq3cj4IrJlb 110 mfeFhT57UbE4qukTDIQ0Y0WM40UYRTakRaDY7ubhXgLgx09Cnp9XTVMsHgT6j9/i 111 1pxsB104XLWjQHTjr1JtiaBQEwFh9r2OKTcpvaLcbNtYpo7CzOs= 112 =FRsO 113 -----END PGP SIGNATURE----- 114 `, commitFromReader.Signature.Signature) 115 assert.EqualValues(t, `tree f1a6cb52b2d16773290cefe49ad0684b50a4f930 116 parent 37991dec2c8e592043f47155ce4808d4580f9123 117 author silverwind <me@silverwind.io> 1563741793 +0200 118 committer silverwind <me@silverwind.io> 1563741793 +0200 119 120 empty commit`, commitFromReader.Signature.Payload) 121 assert.EqualValues(t, "silverwind <me@silverwind.io>", commitFromReader.Author.String()) 122 123 commitFromReader2, err := CommitFromReader(gitRepo, sha, strings.NewReader(commitString+"\n\n")) 124 assert.NoError(t, err) 125 commitFromReader.CommitMessage += "\n\n" 126 commitFromReader.Signature.Payload += "\n\n" 127 assert.EqualValues(t, commitFromReader, commitFromReader2) 128 } 129 130 func TestCommitWithEncodingFromReader(t *testing.T) { 131 commitString := `feaf4ba6bc635fec442f46ddd4512416ec43c2c2 commit 1074 132 tree ca3fad42080dd1a6d291b75acdfc46e5b9b307e5 133 parent 47b24e7ab977ed31c5a39989d570847d6d0052af 134 author KN4CK3R <admin@oldschoolhack.me> 1711702962 +0100 135 committer KN4CK3R <admin@oldschoolhack.me> 1711702962 +0100 136 encoding ISO-8859-1 137 gpgsig -----BEGIN PGP SIGNATURE----- 138 139 iQGzBAABCgAdFiEE9HRrbqvYxPT8PXbefPSEkrowAa8FAmYGg7IACgkQfPSEkrow 140 Aa9olwv+P0HhtCM6CRvlUmPaqswRsDPNR4i66xyXGiSxdI9V5oJL7HLiQIM7KrFR 141 gizKa2COiGtugv8fE+TKqXKaJx6uJUJEjaBd8E9Af9PrAzjWj+A84lU6/PgPS8hq 142 zOfZraLOEWRH4tZcS+u2yFLu3ez2Wqh1xW5LNy7xqEedMXEFD1HwSJ0+pjacNkzr 143 frp6Asyt7xRI6YmgFJZJoRsS3Ktr6rtKeRL2IErSQQyorOqj6gKrglhrhfG/114j 144 FKB1v4or0WZ1DE8iP2SJZ3n+/K1IuWAINh7MVdb7PndfBPEa+IL+ucNk5uzEE8Jd 145 G8smGxXUeFEt2cP1dj2W8EgAxuA9sTnH9dqI5aRqy5ifDjuya7Emm8sdOUvtGdmn 146 SONRzusmu5n3DgV956REL7x62h7JuqmBz/12HZkr0z0zgXkcZ04q08pSJATX5N1F 147 yN+tWxTsWg+zhDk96d5Esdo9JMjcFvPv0eioo30GAERaz1hoD7zCMT4jgUFTQwgz 148 jw4YcO5u 149 =r3UU 150 -----END PGP SIGNATURE----- 151 152 ISO-8859-1` 153 154 sha := &Sha1Hash{0xfe, 0xaf, 0x4b, 0xa6, 0xbc, 0x63, 0x5f, 0xec, 0x44, 0x2f, 0x46, 0xdd, 0xd4, 0x51, 0x24, 0x16, 0xec, 0x43, 0xc2, 0xc2} 155 gitRepo, err := openRepositoryWithDefaultContext(filepath.Join(testReposDir, "repo1_bare")) 156 assert.NoError(t, err) 157 assert.NotNil(t, gitRepo) 158 defer gitRepo.Close() 159 160 commitFromReader, err := CommitFromReader(gitRepo, sha, strings.NewReader(commitString)) 161 assert.NoError(t, err) 162 if !assert.NotNil(t, commitFromReader) { 163 return 164 } 165 assert.EqualValues(t, sha, commitFromReader.ID) 166 assert.EqualValues(t, `-----BEGIN PGP SIGNATURE----- 167 168 iQGzBAABCgAdFiEE9HRrbqvYxPT8PXbefPSEkrowAa8FAmYGg7IACgkQfPSEkrow 169 Aa9olwv+P0HhtCM6CRvlUmPaqswRsDPNR4i66xyXGiSxdI9V5oJL7HLiQIM7KrFR 170 gizKa2COiGtugv8fE+TKqXKaJx6uJUJEjaBd8E9Af9PrAzjWj+A84lU6/PgPS8hq 171 zOfZraLOEWRH4tZcS+u2yFLu3ez2Wqh1xW5LNy7xqEedMXEFD1HwSJ0+pjacNkzr 172 frp6Asyt7xRI6YmgFJZJoRsS3Ktr6rtKeRL2IErSQQyorOqj6gKrglhrhfG/114j 173 FKB1v4or0WZ1DE8iP2SJZ3n+/K1IuWAINh7MVdb7PndfBPEa+IL+ucNk5uzEE8Jd 174 G8smGxXUeFEt2cP1dj2W8EgAxuA9sTnH9dqI5aRqy5ifDjuya7Emm8sdOUvtGdmn 175 SONRzusmu5n3DgV956REL7x62h7JuqmBz/12HZkr0z0zgXkcZ04q08pSJATX5N1F 176 yN+tWxTsWg+zhDk96d5Esdo9JMjcFvPv0eioo30GAERaz1hoD7zCMT4jgUFTQwgz 177 jw4YcO5u 178 =r3UU 179 -----END PGP SIGNATURE----- 180 `, commitFromReader.Signature.Signature) 181 assert.EqualValues(t, `tree ca3fad42080dd1a6d291b75acdfc46e5b9b307e5 182 parent 47b24e7ab977ed31c5a39989d570847d6d0052af 183 author KN4CK3R <admin@oldschoolhack.me> 1711702962 +0100 184 committer KN4CK3R <admin@oldschoolhack.me> 1711702962 +0100 185 encoding ISO-8859-1 186 187 ISO-8859-1`, commitFromReader.Signature.Payload) 188 assert.EqualValues(t, "KN4CK3R <admin@oldschoolhack.me>", commitFromReader.Author.String()) 189 190 commitFromReader2, err := CommitFromReader(gitRepo, sha, strings.NewReader(commitString+"\n\n")) 191 assert.NoError(t, err) 192 commitFromReader.CommitMessage += "\n\n" 193 commitFromReader.Signature.Payload += "\n\n" 194 assert.EqualValues(t, commitFromReader, commitFromReader2) 195 } 196 197 func TestHasPreviousCommit(t *testing.T) { 198 bareRepo1Path := filepath.Join(testReposDir, "repo1_bare") 199 200 repo, err := openRepositoryWithDefaultContext(bareRepo1Path) 201 assert.NoError(t, err) 202 defer repo.Close() 203 204 commit, err := repo.GetCommit("8006ff9adbf0cb94da7dad9e537e53817f9fa5c0") 205 assert.NoError(t, err) 206 207 parentSHA := MustIDFromString("8d92fc957a4d7cfd98bc375f0b7bb189a0d6c9f2") 208 notParentSHA := MustIDFromString("2839944139e0de9737a044f78b0e4b40d989a9e3") 209 210 haz, err := commit.HasPreviousCommit(parentSHA) 211 assert.NoError(t, err) 212 assert.True(t, haz) 213 214 hazNot, err := commit.HasPreviousCommit(notParentSHA) 215 assert.NoError(t, err) 216 assert.False(t, hazNot) 217 218 selfNot, err := commit.HasPreviousCommit(commit.ID) 219 assert.NoError(t, err) 220 assert.False(t, selfNot) 221 } 222 223 func TestParseCommitFileStatus(t *testing.T) { 224 type testcase struct { 225 output string 226 added []string 227 removed []string 228 modified []string 229 } 230 231 kases := []testcase{ 232 { 233 // Merge commit 234 output: "MM\x00options/locale/locale_en-US.ini\x00", 235 modified: []string{ 236 "options/locale/locale_en-US.ini", 237 }, 238 added: []string{}, 239 removed: []string{}, 240 }, 241 { 242 // Spaces commit 243 output: "D\x00b\x00D\x00b b/b\x00A\x00b b/b b/b b/b\x00A\x00b b/b b/b b/b b/b\x00", 244 removed: []string{ 245 "b", 246 "b b/b", 247 }, 248 modified: []string{}, 249 added: []string{ 250 "b b/b b/b b/b", 251 "b b/b b/b b/b b/b", 252 }, 253 }, 254 { 255 // larger commit 256 output: "M\x00go.mod\x00M\x00go.sum\x00M\x00modules/ssh/ssh.go\x00M\x00vendor/github.com/gliderlabs/ssh/circle.yml\x00M\x00vendor/github.com/gliderlabs/ssh/context.go\x00A\x00vendor/github.com/gliderlabs/ssh/go.mod\x00A\x00vendor/github.com/gliderlabs/ssh/go.sum\x00M\x00vendor/github.com/gliderlabs/ssh/server.go\x00M\x00vendor/github.com/gliderlabs/ssh/session.go\x00M\x00vendor/github.com/gliderlabs/ssh/ssh.go\x00M\x00vendor/golang.org/x/sys/unix/mkerrors.sh\x00M\x00vendor/golang.org/x/sys/unix/syscall_darwin.go\x00M\x00vendor/golang.org/x/sys/unix/zerrors_darwin_amd64.go\x00M\x00vendor/golang.org/x/sys/unix/zerrors_darwin_arm64.go\x00M\x00vendor/golang.org/x/sys/unix/zerrors_freebsd_386.go\x00M\x00vendor/golang.org/x/sys/unix/zerrors_freebsd_amd64.go\x00M\x00vendor/golang.org/x/sys/unix/zerrors_freebsd_arm.go\x00M\x00vendor/golang.org/x/sys/unix/zerrors_freebsd_arm64.go\x00M\x00vendor/golang.org/x/sys/unix/zerrors_linux.go\x00M\x00vendor/golang.org/x/sys/unix/ztypes_darwin_amd64.go\x00M\x00vendor/golang.org/x/sys/unix/ztypes_darwin_arm64.go\x00M\x00vendor/golang.org/x/sys/unix/ztypes_dragonfly_amd64.go\x00M\x00vendor/golang.org/x/sys/unix/ztypes_freebsd_386.go\x00M\x00vendor/golang.org/x/sys/unix/ztypes_freebsd_amd64.go\x00M\x00vendor/golang.org/x/sys/unix/ztypes_freebsd_arm.go\x00M\x00vendor/golang.org/x/sys/unix/ztypes_freebsd_arm64.go\x00M\x00vendor/golang.org/x/sys/unix/ztypes_netbsd_386.go\x00M\x00vendor/golang.org/x/sys/unix/ztypes_netbsd_amd64.go\x00M\x00vendor/golang.org/x/sys/unix/ztypes_netbsd_arm.go\x00M\x00vendor/golang.org/x/sys/unix/ztypes_netbsd_arm64.go\x00M\x00vendor/modules.txt\x00", 257 modified: []string{ 258 "go.mod", 259 "go.sum", 260 "modules/ssh/ssh.go", 261 "vendor/github.com/gliderlabs/ssh/circle.yml", 262 "vendor/github.com/gliderlabs/ssh/context.go", 263 "vendor/github.com/gliderlabs/ssh/server.go", 264 "vendor/github.com/gliderlabs/ssh/session.go", 265 "vendor/github.com/gliderlabs/ssh/ssh.go", 266 "vendor/golang.org/x/sys/unix/mkerrors.sh", 267 "vendor/golang.org/x/sys/unix/syscall_darwin.go", 268 "vendor/golang.org/x/sys/unix/zerrors_darwin_amd64.go", 269 "vendor/golang.org/x/sys/unix/zerrors_darwin_arm64.go", 270 "vendor/golang.org/x/sys/unix/zerrors_freebsd_386.go", 271 "vendor/golang.org/x/sys/unix/zerrors_freebsd_amd64.go", 272 "vendor/golang.org/x/sys/unix/zerrors_freebsd_arm.go", 273 "vendor/golang.org/x/sys/unix/zerrors_freebsd_arm64.go", 274 "vendor/golang.org/x/sys/unix/zerrors_linux.go", 275 "vendor/golang.org/x/sys/unix/ztypes_darwin_amd64.go", 276 "vendor/golang.org/x/sys/unix/ztypes_darwin_arm64.go", 277 "vendor/golang.org/x/sys/unix/ztypes_dragonfly_amd64.go", 278 "vendor/golang.org/x/sys/unix/ztypes_freebsd_386.go", 279 "vendor/golang.org/x/sys/unix/ztypes_freebsd_amd64.go", 280 "vendor/golang.org/x/sys/unix/ztypes_freebsd_arm.go", 281 "vendor/golang.org/x/sys/unix/ztypes_freebsd_arm64.go", 282 "vendor/golang.org/x/sys/unix/ztypes_netbsd_386.go", 283 "vendor/golang.org/x/sys/unix/ztypes_netbsd_amd64.go", 284 "vendor/golang.org/x/sys/unix/ztypes_netbsd_arm.go", 285 "vendor/golang.org/x/sys/unix/ztypes_netbsd_arm64.go", 286 "vendor/modules.txt", 287 }, 288 added: []string{ 289 "vendor/github.com/gliderlabs/ssh/go.mod", 290 "vendor/github.com/gliderlabs/ssh/go.sum", 291 }, 292 removed: []string{}, 293 }, 294 { 295 // git 1.7.2 adds an unnecessary \x00 on merge commit 296 output: "\x00MM\x00options/locale/locale_en-US.ini\x00", 297 modified: []string{ 298 "options/locale/locale_en-US.ini", 299 }, 300 added: []string{}, 301 removed: []string{}, 302 }, 303 { 304 // git 1.7.2 adds an unnecessary \n on normal commit 305 output: "\nD\x00b\x00D\x00b b/b\x00A\x00b b/b b/b b/b\x00A\x00b b/b b/b b/b b/b\x00", 306 removed: []string{ 307 "b", 308 "b b/b", 309 }, 310 modified: []string{}, 311 added: []string{ 312 "b b/b b/b b/b", 313 "b b/b b/b b/b b/b", 314 }, 315 }, 316 } 317 318 for _, kase := range kases { 319 fileStatus := NewCommitFileStatus() 320 parseCommitFileStatus(fileStatus, strings.NewReader(kase.output)) 321 322 assert.Equal(t, kase.added, fileStatus.Added) 323 assert.Equal(t, kase.removed, fileStatus.Removed) 324 assert.Equal(t, kase.modified, fileStatus.Modified) 325 } 326 } 327 328 func TestGetCommitFileStatusMerges(t *testing.T) { 329 bareRepo1Path := filepath.Join(testReposDir, "repo6_merge") 330 331 commitFileStatus, err := GetCommitFileStatus(DefaultContext, bareRepo1Path, "022f4ce6214973e018f02bf363bf8a2e3691f699") 332 assert.NoError(t, err) 333 334 expected := CommitFileStatus{ 335 []string{ 336 "add_file.txt", 337 }, 338 []string{ 339 "to_remove.txt", 340 }, 341 []string{ 342 "to_modify.txt", 343 }, 344 } 345 346 assert.Equal(t, commitFileStatus.Added, expected.Added) 347 assert.Equal(t, commitFileStatus.Removed, expected.Removed) 348 assert.Equal(t, commitFileStatus.Modified, expected.Modified) 349 } 350 351 func Test_GetCommitBranchStart(t *testing.T) { 352 bareRepo1Path := filepath.Join(testReposDir, "repo1_bare") 353 repo, err := OpenRepository(context.Background(), bareRepo1Path) 354 assert.NoError(t, err) 355 defer repo.Close() 356 commit, err := repo.GetBranchCommit("branch1") 357 assert.NoError(t, err) 358 assert.EqualValues(t, "2839944139e0de9737a044f78b0e4b40d989a9e3", commit.ID.String()) 359 360 startCommitID, err := repo.GetCommitBranchStart(os.Environ(), "branch1", commit.ID.String()) 361 assert.NoError(t, err) 362 assert.NotEmpty(t, startCommitID) 363 assert.EqualValues(t, "9c9aef8dd84e02bc7ec12641deb4c930a7c30185", startCommitID) 364 }