package gitcmd import ( "context" "path/filepath" "testing" ) const ( wAuthor = "Alice" wAuthorEmail = "alice@example.com" ) func TestCreateOrUpdateFile_NewFile(t *testing.T) { f := newFixture(t) res, err := f.repo.CreateOrUpdateFile("main", "docs/guide.md", "# guide\n", "add guide", wAuthor, wAuthorEmail, "") if err != nil { t.Fatalf("CreateOrUpdateFile: %v", err) } if res.Commit.ID == "" { t.Fatal("empty commit sha") } if len(res.Commit.Parents) != 1 || res.Commit.Parents[0] != f.c5 { t.Errorf("parents = %v, want [%s]", res.Commit.Parents, f.c5) } blob, err := f.repo.GetBlob("main", "docs/guide.md") if err != nil { t.Fatalf("GetBlob: %v", err) } if blob.Content != "# guide\n" { t.Errorf("content = %q, want %q", blob.Content, "# guide\n") } tip, _ := f.repo.refSHA("refs/heads/main") if tip != res.Commit.ID { t.Errorf("main tip = %s, want %s", tip, res.Commit.ID) } } func TestCreateOrUpdateFile_UpdateExisting(t *testing.T) { f := newFixture(t) res, err := f.repo.CreateOrUpdateFile("main", "README.md", "new content\n", "update readme", wAuthor, wAuthorEmail, "") if err != nil { t.Fatalf("CreateOrUpdateFile: %v", err) } blob, _ := f.repo.GetBlob("main", "README.md") if blob.Content != "new content\n" { t.Errorf("content = %q, want %q", blob.Content, "new content\n") } tip, _ := f.repo.refSHA("refs/heads/main") if tip != res.Commit.ID { t.Errorf("main tip = %s, want %s", tip, res.Commit.ID) } } func TestCreateOrUpdateFile_ExpectedSHAMismatch(t *testing.T) { f := newFixture(t) _, err := f.repo.CreateOrUpdateFile("main", "x.txt", "x\n", "x", wAuthor, wAuthorEmail, "0000000000000000000000000000000000000000") if err == nil { t.Fatal("expected error on expectedSHA mismatch, got nil") } } func TestCreateOrUpdateFile_EmptyRepoFirstCommit(t *testing.T) { bare := filepath.Join(t.TempDir(), "empty.git") if err := InitBare(context.Background(), bare); err != nil { t.Fatal(err) } repo, err := OpenRepository(context.Background(), bare) if err != nil { t.Fatal(err) } res, err := repo.CreateOrUpdateFile("main", "README.md", "first\n", "initial", wAuthor, wAuthorEmail, "") if err != nil { t.Fatalf("CreateOrUpdateFile on empty repo: %v", err) } tip, _ := repo.refSHA("refs/heads/main") if tip != res.Commit.ID { t.Errorf("main tip = %s, want %s", tip, res.Commit.ID) } if len(res.Commit.Parents) != 0 { t.Errorf("root commit parents = %v, want empty", res.Commit.Parents) } blob, _ := repo.GetBlob("main", "README.md") if blob.Content != "first\n" { t.Errorf("content = %q, want %q", blob.Content, "first\n") } } func TestDeleteFile(t *testing.T) { f := newFixture(t) res, err := f.repo.DeleteFile("main", "src/main.txt", "remove main.txt", wAuthor, wAuthorEmail, "") if err != nil { t.Fatalf("DeleteFile: %v", err) } tree, err := f.repo.GetTree("main", "") if err != nil { t.Fatal(err) } if containsStr(treeNames(tree), "main.txt") { t.Errorf("src/main.txt still in tree after delete") } tip, _ := f.repo.refSHA("refs/heads/main") if tip != res.Commit.ID { t.Errorf("main tip = %s, want %s", tip, res.Commit.ID) } } func TestCreateOrUpdateFileViaTempRepo_NewFile(t *testing.T) { f := newFixture(t) res, err := f.repo.CreateOrUpdateFileViaTempRepo("main", "via-temprepo.md", "hello\n", "add via temprepo", wAuthor, wAuthorEmail, "") if err != nil { t.Fatalf("CreateOrUpdateFileViaTempRepo: %v", err) } blob, err := f.repo.GetBlob("main", "via-temprepo.md") if err != nil { t.Fatalf("GetBlob: %v", err) } if blob.Content != "hello\n" { t.Errorf("content = %q, want %q", blob.Content, "hello\n") } tip, _ := f.repo.refSHA("refs/heads/main") if tip != res.Commit.ID { t.Errorf("main tip = %s, want %s", tip, res.Commit.ID) } } func TestCreateOrUpdateFileViaTempRepo_EmptyRepoFirstCommit(t *testing.T) { bare := filepath.Join(t.TempDir(), "empty.git") if err := InitBare(context.Background(), bare); err != nil { t.Fatal(err) } repo, err := OpenRepository(context.Background(), bare) if err != nil { t.Fatal(err) } res, err := repo.CreateOrUpdateFileViaTempRepo("main", "README.md", "first\n", "initial", wAuthor, wAuthorEmail, "") if err != nil { t.Fatalf("CreateOrUpdateFileViaTempRepo on empty repo: %v", err) } tip, _ := repo.refSHA("refs/heads/main") if tip != res.Commit.ID { t.Errorf("main tip = %s, want %s", tip, res.Commit.ID) } if len(res.Commit.Parents) != 0 { t.Errorf("root commit parents = %v, want empty", res.Commit.Parents) } } func TestDeleteFileViaTempRepo(t *testing.T) { f := newFixture(t) res, err := f.repo.DeleteFileViaTempRepo("main", "src/main.txt", "remove via temprepo", wAuthor, wAuthorEmail, "") if err != nil { t.Fatalf("DeleteFileViaTempRepo: %v", err) } tree, _ := f.repo.GetTree("main", "") if containsStr(treeNames(tree), "main.txt") { t.Errorf("src/main.txt still in tree after delete") } tip, _ := f.repo.refSHA("refs/heads/main") if tip != res.Commit.ID { t.Errorf("main tip = %s, want %s", tip, res.Commit.ID) } }