fork of go-git with some jj specific features
at v5.13.1 22 kB view raw
1package git 2 3import ( 4 "bytes" 5 "log" 6 "os" 7 "os/exec" 8 "path/filepath" 9 "runtime" 10 "strings" 11 "time" 12 13 fixtures "github.com/go-git/go-git-fixtures/v4" 14 "github.com/go-git/go-git/v5/plumbing" 15 "github.com/go-git/go-git/v5/plumbing/cache" 16 "github.com/go-git/go-git/v5/plumbing/object" 17 "github.com/go-git/go-git/v5/plumbing/storer" 18 "github.com/go-git/go-git/v5/storage/filesystem" 19 "github.com/go-git/go-git/v5/storage/memory" 20 21 "github.com/ProtonMail/go-crypto/openpgp" 22 "github.com/ProtonMail/go-crypto/openpgp/armor" 23 "github.com/ProtonMail/go-crypto/openpgp/errors" 24 "github.com/go-git/go-billy/v5/memfs" 25 "github.com/go-git/go-billy/v5/util" 26 . "gopkg.in/check.v1" 27) 28 29func (s *WorktreeSuite) TestCommitEmptyOptions(c *C) { 30 fs := memfs.New() 31 r, err := Init(memory.NewStorage(), fs) 32 c.Assert(err, IsNil) 33 34 w, err := r.Worktree() 35 c.Assert(err, IsNil) 36 37 util.WriteFile(fs, "foo", []byte("foo"), 0644) 38 39 _, err = w.Add("foo") 40 c.Assert(err, IsNil) 41 42 hash, err := w.Commit("foo", &CommitOptions{}) 43 c.Assert(err, IsNil) 44 c.Assert(hash.IsZero(), Equals, false) 45 46 commit, err := r.CommitObject(hash) 47 c.Assert(err, IsNil) 48 c.Assert(commit.Author.Name, Not(Equals), "") 49} 50 51func (s *WorktreeSuite) TestCommitInitial(c *C) { 52 expected := plumbing.NewHash("98c4ac7c29c913f7461eae06e024dc18e80d23a4") 53 54 fs := memfs.New() 55 storage := memory.NewStorage() 56 57 r, err := Init(storage, fs) 58 c.Assert(err, IsNil) 59 60 w, err := r.Worktree() 61 c.Assert(err, IsNil) 62 63 util.WriteFile(fs, "foo", []byte("foo"), 0644) 64 65 _, err = w.Add("foo") 66 c.Assert(err, IsNil) 67 68 hash, err := w.Commit("foo\n", &CommitOptions{Author: defaultSignature()}) 69 c.Assert(hash, Equals, expected) 70 c.Assert(err, IsNil) 71 72 assertStorageStatus(c, r, 1, 1, 1, expected) 73} 74 75func (s *WorktreeSuite) TestNothingToCommit(c *C) { 76 expected := plumbing.NewHash("838ea833ce893e8555907e5ef224aa076f5e274a") 77 78 r, err := Init(memory.NewStorage(), memfs.New()) 79 c.Assert(err, IsNil) 80 81 w, err := r.Worktree() 82 c.Assert(err, IsNil) 83 84 hash, err := w.Commit("failed empty commit\n", &CommitOptions{Author: defaultSignature()}) 85 c.Assert(hash, Equals, plumbing.ZeroHash) 86 c.Assert(err, Equals, ErrEmptyCommit) 87 88 hash, err = w.Commit("enable empty commits\n", &CommitOptions{Author: defaultSignature(), AllowEmptyCommits: true}) 89 c.Assert(hash, Equals, expected) 90 c.Assert(err, IsNil) 91} 92 93func (s *WorktreeSuite) TestNothingToCommitNonEmptyRepo(c *C) { 94 fs := memfs.New() 95 r, err := Init(memory.NewStorage(), fs) 96 c.Assert(err, IsNil) 97 98 w, err := r.Worktree() 99 c.Assert(err, IsNil) 100 101 err = util.WriteFile(fs, "foo", []byte("foo"), 0644) 102 c.Assert(err, IsNil) 103 104 w.Add("foo") 105 _, err = w.Commit("previous commit\n", &CommitOptions{Author: defaultSignature()}) 106 c.Assert(err, IsNil) 107 108 hash, err := w.Commit("failed empty commit\n", &CommitOptions{Author: defaultSignature()}) 109 c.Assert(hash, Equals, plumbing.ZeroHash) 110 c.Assert(err, Equals, ErrEmptyCommit) 111 112 _, err = w.Commit("enable empty commits\n", &CommitOptions{Author: defaultSignature(), AllowEmptyCommits: true}) 113 c.Assert(err, IsNil) 114} 115 116func (s *WorktreeSuite) TestRemoveAndCommitToMakeEmptyRepo(c *C) { 117 fs := memfs.New() 118 r, err := Init(memory.NewStorage(), fs) 119 c.Assert(err, IsNil) 120 121 w, err := r.Worktree() 122 c.Assert(err, IsNil) 123 124 err = util.WriteFile(fs, "foo", []byte("foo"), 0644) 125 c.Assert(err, IsNil) 126 127 _, err = w.Add("foo") 128 c.Assert(err, IsNil) 129 130 _, err = w.Commit("Add in Repo\n", &CommitOptions{Author: defaultSignature()}) 131 c.Assert(err, IsNil) 132 133 err = fs.Remove("foo") 134 c.Assert(err, IsNil) 135 136 _, err = w.Add("foo") 137 c.Assert(err, IsNil) 138 139 _, err = w.Commit("Remove foo\n", &CommitOptions{Author: defaultSignature()}) 140 c.Assert(err, IsNil) 141} 142 143func (s *WorktreeSuite) TestCommitParent(c *C) { 144 expected := plumbing.NewHash("ef3ca05477530b37f48564be33ddd48063fc7a22") 145 146 fs := memfs.New() 147 w := &Worktree{ 148 r: s.Repository, 149 Filesystem: fs, 150 } 151 152 err := w.Checkout(&CheckoutOptions{}) 153 c.Assert(err, IsNil) 154 155 err = util.WriteFile(fs, "foo", []byte("foo"), 0644) 156 c.Assert(err, IsNil) 157 158 _, err = w.Add("foo") 159 c.Assert(err, IsNil) 160 161 hash, err := w.Commit("foo\n", &CommitOptions{Author: defaultSignature()}) 162 c.Assert(hash, Equals, expected) 163 c.Assert(err, IsNil) 164 165 assertStorageStatus(c, s.Repository, 13, 11, 10, expected) 166} 167 168func (s *WorktreeSuite) TestCommitAmendWithoutChanges(c *C) { 169 fs := memfs.New() 170 w := &Worktree{ 171 r: s.Repository, 172 Filesystem: fs, 173 } 174 175 err := w.Checkout(&CheckoutOptions{}) 176 c.Assert(err, IsNil) 177 178 err = util.WriteFile(fs, "foo", []byte("foo"), 0644) 179 c.Assert(err, IsNil) 180 181 _, err = w.Add("foo") 182 c.Assert(err, IsNil) 183 184 prevHash, err := w.Commit("foo\n", &CommitOptions{Author: defaultSignature()}) 185 c.Assert(err, IsNil) 186 187 amendedHash, err := w.Commit("foo\n", &CommitOptions{Author: defaultSignature(), Amend: true}) 188 c.Assert(err, IsNil) 189 190 headRef, err := w.r.Head() 191 c.Assert(err, IsNil) 192 193 c.Assert(amendedHash, Equals, headRef.Hash()) 194 c.Assert(amendedHash, Equals, prevHash) 195 196 commit, err := w.r.CommitObject(headRef.Hash()) 197 c.Assert(err, IsNil) 198 c.Assert(commit.Message, Equals, "foo\n") 199 200 assertStorageStatus(c, s.Repository, 13, 11, 10, amendedHash) 201} 202 203func (s *WorktreeSuite) TestCommitAmendWithChanges(c *C) { 204 fs := memfs.New() 205 w := &Worktree{ 206 r: s.Repository, 207 Filesystem: fs, 208 } 209 210 err := w.Checkout(&CheckoutOptions{}) 211 c.Assert(err, IsNil) 212 213 util.WriteFile(fs, "foo", []byte("foo"), 0644) 214 215 _, err = w.Add("foo") 216 c.Assert(err, IsNil) 217 218 _, err = w.Commit("foo\n", &CommitOptions{Author: defaultSignature()}) 219 c.Assert(err, IsNil) 220 221 util.WriteFile(fs, "bar", []byte("bar"), 0644) 222 223 _, err = w.Add("bar") 224 c.Assert(err, IsNil) 225 226 amendedHash, err := w.Commit("bar\n", &CommitOptions{Amend: true}) 227 c.Assert(err, IsNil) 228 229 headRef, err := w.r.Head() 230 c.Assert(err, IsNil) 231 232 c.Assert(amendedHash, Equals, headRef.Hash()) 233 234 commit, err := w.r.CommitObject(headRef.Hash()) 235 c.Assert(err, IsNil) 236 c.Assert(commit.Message, Equals, "bar\n") 237 c.Assert(commit.NumParents(), Equals, 1) 238 239 stats, err := commit.Stats() 240 c.Assert(err, IsNil) 241 c.Assert(stats, HasLen, 2) 242 c.Assert(stats[0], Equals, object.FileStat{ 243 Name: "bar", 244 Addition: 1, 245 }) 246 c.Assert(stats[1], Equals, object.FileStat{ 247 Name: "foo", 248 Addition: 1, 249 }) 250 251 assertStorageStatus(c, s.Repository, 14, 12, 11, amendedHash) 252} 253 254func (s *WorktreeSuite) TestCommitAmendNothingToCommit(c *C) { 255 fs := memfs.New() 256 w := &Worktree{ 257 r: s.Repository, 258 Filesystem: fs, 259 } 260 261 err := w.Checkout(&CheckoutOptions{}) 262 c.Assert(err, IsNil) 263 264 err = util.WriteFile(fs, "foo", []byte("foo"), 0644) 265 c.Assert(err, IsNil) 266 267 _, err = w.Add("foo") 268 c.Assert(err, IsNil) 269 270 prevHash, err := w.Commit("foo\n", &CommitOptions{Author: defaultSignature()}) 271 c.Assert(err, IsNil) 272 273 _, err = w.Commit("bar\n", &CommitOptions{Author: defaultSignature(), AllowEmptyCommits: true}) 274 c.Assert(err, IsNil) 275 276 amendedHash, err := w.Commit("foo\n", &CommitOptions{Author: defaultSignature(), Amend: true}) 277 c.Log(prevHash, amendedHash) 278 c.Assert(err, Equals, ErrEmptyCommit) 279 c.Assert(amendedHash, Equals, plumbing.ZeroHash) 280} 281 282func (s *WorktreeSuite) TestAddAndCommitWithSkipStatus(c *C) { 283 expected := plumbing.NewHash("375a3808ffde7f129cdd3c8c252fd0fe37cfd13b") 284 285 fs := memfs.New() 286 w := &Worktree{ 287 r: s.Repository, 288 Filesystem: fs, 289 } 290 291 err := w.Checkout(&CheckoutOptions{}) 292 c.Assert(err, IsNil) 293 294 util.WriteFile(fs, "LICENSE", []byte("foo"), 0644) 295 util.WriteFile(fs, "foo", []byte("foo"), 0644) 296 297 err = w.AddWithOptions(&AddOptions{ 298 Path: "foo", 299 SkipStatus: true, 300 }) 301 c.Assert(err, IsNil) 302 303 hash, err := w.Commit("commit foo only\n", &CommitOptions{ 304 Author: defaultSignature(), 305 }) 306 307 c.Assert(hash, Equals, expected) 308 c.Assert(err, IsNil) 309 310 assertStorageStatus(c, s.Repository, 13, 11, 10, expected) 311} 312 313func (s *WorktreeSuite) TestAddAndCommitWithSkipStatusPathNotModified(c *C) { 314 expected := plumbing.NewHash("375a3808ffde7f129cdd3c8c252fd0fe37cfd13b") 315 expected2 := plumbing.NewHash("8691273baf8f6ee2cccfc05e910552c04d02d472") 316 317 fs := memfs.New() 318 w := &Worktree{ 319 r: s.Repository, 320 Filesystem: fs, 321 } 322 323 err := w.Checkout(&CheckoutOptions{}) 324 c.Assert(err, IsNil) 325 326 util.WriteFile(fs, "foo", []byte("foo"), 0644) 327 328 status, err := w.Status() 329 c.Assert(err, IsNil) 330 foo := status.File("foo") 331 c.Assert(foo.Staging, Equals, Untracked) 332 c.Assert(foo.Worktree, Equals, Untracked) 333 334 err = w.AddWithOptions(&AddOptions{ 335 Path: "foo", 336 SkipStatus: true, 337 }) 338 c.Assert(err, IsNil) 339 340 status, err = w.Status() 341 c.Assert(err, IsNil) 342 foo = status.File("foo") 343 c.Assert(foo.Staging, Equals, Added) 344 c.Assert(foo.Worktree, Equals, Unmodified) 345 346 hash, err := w.Commit("commit foo only\n", &CommitOptions{All: true, 347 Author: defaultSignature(), 348 }) 349 c.Assert(hash, Equals, expected) 350 c.Assert(err, IsNil) 351 352 commit1, err := w.r.CommitObject(hash) 353 c.Assert(err, IsNil) 354 355 status, err = w.Status() 356 c.Assert(err, IsNil) 357 foo = status.File("foo") 358 c.Assert(foo.Staging, Equals, Untracked) 359 c.Assert(foo.Worktree, Equals, Untracked) 360 361 assertStorageStatus(c, s.Repository, 13, 11, 10, expected) 362 363 err = w.AddWithOptions(&AddOptions{ 364 Path: "foo", 365 SkipStatus: true, 366 }) 367 c.Assert(err, IsNil) 368 369 status, err = w.Status() 370 c.Assert(err, IsNil) 371 foo = status.File("foo") 372 c.Assert(foo.Staging, Equals, Untracked) 373 c.Assert(foo.Worktree, Equals, Untracked) 374 375 hash, err = w.Commit("commit with no changes\n", &CommitOptions{ 376 Author: defaultSignature(), 377 AllowEmptyCommits: true, 378 }) 379 c.Assert(hash, Equals, expected2) 380 c.Assert(err, IsNil) 381 382 commit2, err := w.r.CommitObject(hash) 383 c.Assert(err, IsNil) 384 385 status, err = w.Status() 386 c.Assert(err, IsNil) 387 foo = status.File("foo") 388 c.Assert(foo.Staging, Equals, Untracked) 389 c.Assert(foo.Worktree, Equals, Untracked) 390 391 patch, err := commit2.Patch(commit1) 392 c.Assert(err, IsNil) 393 files := patch.FilePatches() 394 c.Assert(files, IsNil) 395 396 assertStorageStatus(c, s.Repository, 13, 11, 11, expected2) 397} 398 399func (s *WorktreeSuite) TestCommitAll(c *C) { 400 expected := plumbing.NewHash("aede6f8c9c1c7ec9ca8d287c64b8ed151276fa28") 401 402 fs := memfs.New() 403 w := &Worktree{ 404 r: s.Repository, 405 Filesystem: fs, 406 } 407 408 err := w.Checkout(&CheckoutOptions{}) 409 c.Assert(err, IsNil) 410 411 util.WriteFile(fs, "LICENSE", []byte("foo"), 0644) 412 util.WriteFile(fs, "foo", []byte("foo"), 0644) 413 414 hash, err := w.Commit("foo\n", &CommitOptions{ 415 All: true, 416 Author: defaultSignature(), 417 }) 418 419 c.Assert(hash, Equals, expected) 420 c.Assert(err, IsNil) 421 422 assertStorageStatus(c, s.Repository, 13, 11, 10, expected) 423} 424 425func (s *WorktreeSuite) TestRemoveAndCommitAll(c *C) { 426 expected := plumbing.NewHash("907cd576c6ced2ecd3dab34a72bf9cf65944b9a9") 427 428 fs := memfs.New() 429 w := &Worktree{ 430 r: s.Repository, 431 Filesystem: fs, 432 } 433 434 err := w.Checkout(&CheckoutOptions{}) 435 c.Assert(err, IsNil) 436 437 util.WriteFile(fs, "foo", []byte("foo"), 0644) 438 _, err = w.Add("foo") 439 c.Assert(err, IsNil) 440 441 _, errFirst := w.Commit("Add in Repo\n", &CommitOptions{ 442 Author: defaultSignature(), 443 }) 444 c.Assert(errFirst, IsNil) 445 446 errRemove := fs.Remove("foo") 447 c.Assert(errRemove, IsNil) 448 449 hash, errSecond := w.Commit("Remove foo\n", &CommitOptions{ 450 All: true, 451 Author: defaultSignature(), 452 }) 453 c.Assert(errSecond, IsNil) 454 455 c.Assert(hash, Equals, expected) 456 c.Assert(err, IsNil) 457 458 assertStorageStatus(c, s.Repository, 13, 11, 11, expected) 459} 460 461func (s *WorktreeSuite) TestCommitSign(c *C) { 462 fs := memfs.New() 463 storage := memory.NewStorage() 464 465 r, err := Init(storage, fs) 466 c.Assert(err, IsNil) 467 468 w, err := r.Worktree() 469 c.Assert(err, IsNil) 470 471 util.WriteFile(fs, "foo", []byte("foo"), 0644) 472 473 _, err = w.Add("foo") 474 c.Assert(err, IsNil) 475 476 key := commitSignKey(c, true) 477 hash, err := w.Commit("foo\n", &CommitOptions{Author: defaultSignature(), SignKey: key}) 478 c.Assert(err, IsNil) 479 480 // Verify the commit. 481 pks := new(bytes.Buffer) 482 pkw, err := armor.Encode(pks, openpgp.PublicKeyType, nil) 483 c.Assert(err, IsNil) 484 485 err = key.Serialize(pkw) 486 c.Assert(err, IsNil) 487 err = pkw.Close() 488 c.Assert(err, IsNil) 489 490 expectedCommit, err := r.CommitObject(hash) 491 c.Assert(err, IsNil) 492 actual, err := expectedCommit.Verify(pks.String()) 493 c.Assert(err, IsNil) 494 c.Assert(actual.PrimaryKey, DeepEquals, key.PrimaryKey) 495} 496 497func (s *WorktreeSuite) TestCommitSignBadKey(c *C) { 498 fs := memfs.New() 499 storage := memory.NewStorage() 500 501 r, err := Init(storage, fs) 502 c.Assert(err, IsNil) 503 504 w, err := r.Worktree() 505 c.Assert(err, IsNil) 506 507 util.WriteFile(fs, "foo", []byte("foo"), 0644) 508 509 _, err = w.Add("foo") 510 c.Assert(err, IsNil) 511 512 key := commitSignKey(c, false) 513 _, err = w.Commit("foo\n", &CommitOptions{Author: defaultSignature(), SignKey: key}) 514 c.Assert(err, Equals, errors.InvalidArgumentError("signing key is encrypted")) 515} 516 517func (s *WorktreeSuite) TestCommitTreeSort(c *C) { 518 fs := s.TemporalFilesystem(c) 519 520 st := filesystem.NewStorage(fs, cache.NewObjectLRUDefault()) 521 _, err := Init(st, nil) 522 c.Assert(err, IsNil) 523 524 r, _ := Clone(memory.NewStorage(), memfs.New(), &CloneOptions{ 525 URL: fs.Root(), 526 }) 527 528 w, err := r.Worktree() 529 c.Assert(err, IsNil) 530 531 mfs := w.Filesystem 532 533 err = mfs.MkdirAll("delta", 0755) 534 c.Assert(err, IsNil) 535 536 for _, p := range []string{"delta_last", "Gamma", "delta/middle", "Beta", "delta-first", "alpha"} { 537 util.WriteFile(mfs, p, []byte("foo"), 0644) 538 _, err = w.Add(p) 539 c.Assert(err, IsNil) 540 } 541 542 _, err = w.Commit("foo\n", &CommitOptions{ 543 All: true, 544 Author: defaultSignature(), 545 }) 546 c.Assert(err, IsNil) 547 548 err = r.Push(&PushOptions{}) 549 c.Assert(err, IsNil) 550 551 cmd := exec.Command("git", "fsck") 552 cmd.Dir = fs.Root() 553 cmd.Env = os.Environ() 554 buf := &bytes.Buffer{} 555 cmd.Stderr = buf 556 cmd.Stdout = buf 557 558 err = cmd.Run() 559 560 c.Assert(err, IsNil, Commentf("%s", buf.Bytes())) 561} 562 563// https://github.com/go-git/go-git/pull/224 564func (s *WorktreeSuite) TestJustStoreObjectsNotAlreadyStored(c *C) { 565 fs := s.TemporalFilesystem(c) 566 567 fsDotgit, err := fs.Chroot(".git") // real fs to get modified timestamps 568 c.Assert(err, IsNil) 569 storage := filesystem.NewStorage(fsDotgit, cache.NewObjectLRUDefault()) 570 571 r, err := Init(storage, fs) 572 c.Assert(err, IsNil) 573 574 w, err := r.Worktree() 575 c.Assert(err, IsNil) 576 577 // Step 1: Write LICENSE 578 util.WriteFile(fs, "LICENSE", []byte("license"), 0644) 579 hLicense, err := w.Add("LICENSE") 580 c.Assert(err, IsNil) 581 c.Assert(hLicense, Equals, plumbing.NewHash("0484eba0d41636ba71fa612c78559cd6c3006cde")) 582 583 hash, err := w.Commit("commit 1\n", &CommitOptions{ 584 All: true, 585 Author: defaultSignature(), 586 }) 587 c.Assert(err, IsNil) 588 c.Assert(hash, Equals, plumbing.NewHash("7a7faee4630d2664a6869677cc8ab614f3fd4a18")) 589 590 infoLicense, err := fsDotgit.Stat(filepath.Join("objects", "04", "84eba0d41636ba71fa612c78559cd6c3006cde")) 591 c.Assert(err, IsNil) // checking objects file exists 592 593 // Step 2: Write foo. 594 time.Sleep(5 * time.Millisecond) // uncool, but we need to get different timestamps... 595 util.WriteFile(fs, "foo", []byte("foo"), 0644) 596 hFoo, err := w.Add("foo") 597 c.Assert(err, IsNil) 598 c.Assert(hFoo, Equals, plumbing.NewHash("19102815663d23f8b75a47e7a01965dcdc96468c")) 599 600 hash, err = w.Commit("commit 2\n", &CommitOptions{ 601 All: true, 602 Author: defaultSignature(), 603 }) 604 c.Assert(err, IsNil) 605 c.Assert(hash, Equals, plumbing.NewHash("97c0c5177e6ac57d10e8ea0017f2d39b91e2b364")) 606 607 // Step 3: Check 608 // There is no need to overwrite the object of LICENSE, because its content 609 // was not changed. Just a write on the object of foo is required. This behaviour 610 // is fixed by #224 and tested by comparing the timestamps of the stored objects. 611 infoFoo, err := fsDotgit.Stat(filepath.Join("objects", "19", "102815663d23f8b75a47e7a01965dcdc96468c")) 612 c.Assert(err, IsNil) // checking objects file exists 613 c.Assert(infoLicense.ModTime().Before(infoFoo.ModTime()), Equals, true) // object of foo has another/greaterThan timestamp than LICENSE 614 615 infoLicenseSecond, err := fsDotgit.Stat(filepath.Join("objects", "04", "84eba0d41636ba71fa612c78559cd6c3006cde")) 616 c.Assert(err, IsNil) 617 618 log.Printf("comparing mod time: %v == %v on %v (%v)", infoLicenseSecond.ModTime(), infoLicense.ModTime(), runtime.GOOS, runtime.GOARCH) 619 c.Assert(infoLicenseSecond.ModTime(), Equals, infoLicense.ModTime()) // object of LICENSE should have the same timestamp because no additional write operation was performed 620} 621 622func (s *WorktreeSuite) TestCommitInvalidCharactersInAuthorInfos(c *C) { 623 f := fixtures.Basic().One() 624 s.Repository = s.NewRepositoryWithEmptyWorktree(f) 625 626 expected := plumbing.NewHash("e8eecef2524c3a37cf0f0996603162f81e0373f1") 627 628 fs := memfs.New() 629 storage := memory.NewStorage() 630 631 r, err := Init(storage, fs) 632 c.Assert(err, IsNil) 633 634 w, err := r.Worktree() 635 c.Assert(err, IsNil) 636 637 util.WriteFile(fs, "foo", []byte("foo"), 0644) 638 639 _, err = w.Add("foo") 640 c.Assert(err, IsNil) 641 642 hash, err := w.Commit("foo\n", &CommitOptions{Author: invalidSignature()}) 643 c.Assert(hash, Equals, expected) 644 c.Assert(err, IsNil) 645 646 assertStorageStatus(c, r, 1, 1, 1, expected) 647 648 // Check HEAD commit contains author informations with '<', '>' and '\n' stripped 649 lr, err := r.Log(&LogOptions{}) 650 c.Assert(err, IsNil) 651 652 commit, err := lr.Next() 653 c.Assert(err, IsNil) 654 655 c.Assert(commit.Author.Name, Equals, "foo bad") 656 c.Assert(commit.Author.Email, Equals, "badfoo@foo.foo") 657 658} 659 660func assertStorageStatus( 661 c *C, r *Repository, 662 treesCount, blobCount, commitCount int, head plumbing.Hash, 663) { 664 trees, err := r.Storer.IterEncodedObjects(plumbing.TreeObject) 665 c.Assert(err, IsNil) 666 blobs, err := r.Storer.IterEncodedObjects(plumbing.BlobObject) 667 c.Assert(err, IsNil) 668 commits, err := r.Storer.IterEncodedObjects(plumbing.CommitObject) 669 c.Assert(err, IsNil) 670 671 c.Assert(lenIterEncodedObjects(trees), Equals, treesCount) 672 c.Assert(lenIterEncodedObjects(blobs), Equals, blobCount) 673 c.Assert(lenIterEncodedObjects(commits), Equals, commitCount) 674 675 ref, err := r.Head() 676 c.Assert(err, IsNil) 677 c.Assert(ref.Hash(), Equals, head) 678} 679 680func lenIterEncodedObjects(iter storer.EncodedObjectIter) int { 681 count := 0 682 iter.ForEach(func(plumbing.EncodedObject) error { 683 count++ 684 return nil 685 }) 686 687 return count 688} 689 690func defaultSignature() *object.Signature { 691 when, _ := time.Parse(object.DateFormat, "Thu May 04 00:03:43 2017 +0200") 692 return &object.Signature{ 693 Name: "foo", 694 Email: "foo@foo.foo", 695 When: when, 696 } 697} 698 699func invalidSignature() *object.Signature { 700 when, _ := time.Parse(object.DateFormat, "Thu May 04 00:03:43 2017 +0200") 701 return &object.Signature{ 702 Name: "foo <bad>\n", 703 Email: "<bad>\nfoo@foo.foo", 704 When: when, 705 } 706} 707 708func commitSignKey(c *C, decrypt bool) *openpgp.Entity { 709 s := strings.NewReader(armoredKeyRing) 710 es, err := openpgp.ReadArmoredKeyRing(s) 711 c.Assert(err, IsNil) 712 713 c.Assert(es, HasLen, 1) 714 c.Assert(es[0].Identities, HasLen, 1) 715 _, ok := es[0].Identities["foo bar <foo@foo.foo>"] 716 c.Assert(ok, Equals, true) 717 718 key := es[0] 719 if decrypt { 720 err = key.PrivateKey.Decrypt([]byte(keyPassphrase)) 721 c.Assert(err, IsNil) 722 } 723 724 return key 725} 726 727const armoredKeyRing = ` 728-----BEGIN PGP PRIVATE KEY BLOCK----- 729 730lQdGBFt89QIBEAC8du0Purt9yeFuLlBYHcexnZvcbaci2pY+Ejn1VnxM7caFxRX/ 731b2weZi9E6+I0F+K/hKIaidPdcbK92UCL0Vp6F3izjqategZ7o44vlK/HfWFME4wv 732sou6lnig9ovA73HRyzngi3CmqWxSdg8lL0kIJLNzlvCFEd4Z34BnEkagklQJRymo 7330WnmLJjSnZFT5Nk7q5jrcR7ApbD98cakvgivDlUBPJCk2JFPWheCkouWPHMvLXQz 734bZXW5RFz4lJsMUWa/S3ofvIOnjG5Etnil3IA4uksS8fSDkGus998mBvUwzqX7xBh 735dK17ZEbxDdO4PuVJDkjvq618rMu8FVk5yVd59rUketSnGrehd/+vdh6qtgQC4tu1 736RldbUVAuKZGg79H61nWnvrDZmbw4eoqCEuv1+aZsM9ElSC5Ps2J0rtpHRyBndKn+ 7378Jlc/KTH04/O+FAhEv0IgMTFEm3iAq8udBhRBgu6Y4gJyn4tqy6+6ZjPUNos8GOG 738+ZJPdrgHHHfQged1ygeceN6W2AwQRet/B3/rieHf2V93uHJy/DjYUEuBhPm9nxqi 739R6ILUr97Sj2EsvLyfQO9pFpIctoNKEJmDx/C9tkFMNNlQhpsBitSdR2/wancw9ND 740iWV/J9roUdC0qns7eNSbiFe3Len8Xir7srnjAFgbGvOu9jDBUuiKGT5F3wARAQAB 741/gcDAl+0SktmjrUW8uwpvru6GeIeo5kc4rXuD7iIxH6nDl3nmjZMX7qWvp+pRTHH 7420hEDH44899PDvzclBN3ouehfFUbJ+DBy8umBiLqF8Mu2PrKjdmyv3BvnbTkqPM3m 7432Su7WmUDBhG00X07lfl8fTpZJG80onEGzGynryP/xVm4ymzoHyYGksntXLYr2HJ5 744aV6L7sL2/STsaaOVHoa/oEmVBo1+NRsTxRRUcFVLs3g0OIi6ZCeSevBdavMwf9Iv 745b5Bs/e0+GLpP71XzFpdrGcL6oGjZH/dgdeypzbGA+FHtQJqynN3qEE9eCc9cfTGL 7462zN2OtnMA28NtPVN4SnSxQIDvycWx68NZjfwLOK+gswfKpimp+6xMWSnNIRDyU9M 747w0hdNPMK9JAxm/MlnkR7x6ysX/8vrVVFl9gWOmxzJ5L4kvfMsHcV5ZFRP8OnVA6a 748NFBWIBGXF1uQC4qrXup/xKyWJOoH++cMo2cjPT3+3oifZgdBydVfHXjS9aQ/S3Sa 749A6henWyx/qeBGPVRuXWdXIOKDboOPK8JwQaGd6yazKkH9c5tDohmQHzZ6ho0gyAt 750dh+g9ZyiZVpjc6excfK/DP/RdUOYKw3Ur9652hKephvYZzHvPjTbqVkhS7JjZkVY 751rukQ64d5T0pE1B4y+If4hLFXMNQtfo0TIsATNA69jop+KFnJpLzAB+Ee33EA/HUl 752YC5EJCJaXt6kdtYFac0HvVWiz5ZuMhdtzpJfvOe+Olp/xR9nIPW3XZojQoHIZKwu 753gXeZeVMvfeoq+ymKAKNH5Np4WaUDF7Wh9VLl045jGyF5viyy61ivC0eyAzp5W1uy 754gJBZwafVma5MhmZUS2dFs0hBwBrKRzZZhN65VvfSYw6CnXp83ryUjReDvrLmqZDM 755FNpSMDKRk1+k9Wwi3m+fzLAvlxoHscJ5Any7ApsvBRbyehP8MAAG7UV3jImugTLi 756yN6FKVwziQXiC4/97oKbA1YYNjTT7Qw9gWTXvLRspn4f9997brcA9dm0M0seTjLa 757lc5hTJwJQdvPPI2klf+YgPvsD6nrP1moeWBb8irICqG1/BoE0JHPS+bqJ1J+m1iV 758kRV/+4pV2bLlXKqg1LEvqANW+1P1eM2nbbVB7EQn8ZOPIKMoCLoC1QWUPNfnemsW 759U5ynAbhsbm16PDJql0ApEgUCEDfsXTu1ui6SIO3bs/gWyD9HEmnfaYMYDKF+j+0r 760jXd4GnCxb+Yu3wV5WyewOHouzC+++h/3WcDLkOYZ9pcIbA86qT+v6b9MuTAU0D3c 761wlDv8r5J59zOcXl4HpMb2BY5F9dZn8hjgeVJRhJdij9x1TQ8qlVasSi4Eq8SiPmZ 762PZz33Pk6yn2caQ6wd47A79LXCbFQqJqA5aA6oS4DOpENGS5fh7WUZq/MTcmm9GsG 763w2gHxocASK9RCUYgZFWVYgLDuviMMWvc/2TJcTMxdF0Amu3erYAD90smFs0g/6fZ 7644pRLnKFuifwAMGMOx7jbW5tmOaSPx6XkuYvkDJeLMHoN3z/8bZEG5VpayypwFGyV 765bk/YIUWg/KM/43juDPdTvab9tZzYIjxC6on7dtYIAGjZis97XZou3KYKTaMe1VY6 766IhrnVzJ0JAHpd1prf9NUz96e1vjGdn3I61JgjNp5sWklIJEZzvaD28Eovf/LH1BO 767gYFFCvsWXaRoPHNQ5a9m7CROkLeHUFgRu5uriqHxxQHgogDznc8/3fnvDAHNpNb6 768Jnk4zaeVR3tTyIjiNM+wxUFPDNFpJWmQbSDCcPVYTbpznzVRnhqrw7q0FWZvbyBi 769YXIgPGZvb0Bmb28uZm9vPokCVAQTAQgAPgIbAwULCQgHAgYVCAkKCwIEFgIDAQIe 770AQIXgBYhBJOhf/AeVDKFRgh8jgKTlUAu/M1TBQJbfPU4BQkSzAM2AAoJEAKTlUAu 771/M1TVTIQALA6ocNc2fXz1loLykMxlfnX/XxiyNDOUPDZkrZtscqqWPYaWvJK3OiD 77232bdVEbftnAiFvJYkinrCXLEmwwf5wyOxKFmCHwwKhH0UYt60yF4WwlOVNstGSAy 773RkPMEEmVfMXS9K1nzKv/9A5YsqMQob7sN5CMN66Vrm0RKSvOF/NhhM9v8fC0QSU2 774GZNO0tnRfaS4wMnFr5L4FuDST+14F5sJT7ZEJz7HfbxXKLvvWbvqLlCYHJOdz56s 775X/eKde8eT9/LSzcmgsd7rGS2np5901kubww5jllUl1CFnk3Mdg9FTJl5u9Epuhnn 776823Jpdy1ZNbyLqZ266Z/q2HepDA7P/GqIXgWdHjwG2y1YAC4JIkA4RBbesQwqAXs 7776cX5gqRFRl5iDGEP5zclS0y5mWi/J8bLYxMYfqxs9EZtHd9DumWISi87804TEzYa 778WDijMlW7PR8QRW0vdmtYOhJZOlTnomLQx2v27iqpVXRh12J1aYVBFC+IvG1vhCf9 779FL3LzAHHEGlIoDaKJMd+Wg/Lm/f1PqqQx3lWIh9hhKh5Qx6hcuJH669JOWuEdxfo 7801so50aItG+tdDKqXflmOi7grrUURchYYKteaW2fC2SQgzDClprALI7aj9s/lDrEN 781CgLH6twOqdSFWqB/4ASDMsNeLeKX3WOYKYYMlE01cj3T1m6dpRUO 782=gIM9 783-----END PGP PRIVATE KEY BLOCK----- 784` 785 786const keyPassphrase = "abcdef0123456789"