Skip to content

Commit

Permalink
git: add DeleteBranches method
Browse files Browse the repository at this point in the history
  • Loading branch information
zombiezen committed Feb 22, 2022
1 parent 359952c commit 9d322f3
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 7 deletions.
15 changes: 8 additions & 7 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

- There are several new `git.RefMutation` constructors: `SetRef`,
`SetRefIfMatches`, and `CreateRef`.
- `git.RefMutation` has a new `IsNoop` method to make it easier to check for
the zero value.
- `git.CommitOptions` and `git.AmendOptions` have a new field: `SkipHooks`.
- There are several new `git.RefMutation` constructors: `SetRef`,
`SetRefIfMatches`, and `CreateRef`.
- `git.RefMutation` has a new `IsNoop` method to make it easier to check for
the zero value.
- `git.CommitOptions` and `git.AmendOptions` have a new field: `SkipHooks`.
- New method `Git.DeleteBranches`.

### Changed

- `*client.PullStream.ListRefs` and `*client.PushStream.Refs` now return a map
of refs instead of a slice.
- `*client.PullStream.ListRefs` and `*client.PushStream.Refs` now return a map
of refs instead of a slice.

## [0.9.0][] - 2021-01-26

Expand Down
30 changes: 30 additions & 0 deletions api.go
Original file line number Diff line number Diff line change
Expand Up @@ -1021,6 +1021,36 @@ func (g *Git) NewBranch(ctx context.Context, name string, opts BranchOptions) er
return g.run(ctx, errPrefix, args)
}

// DeleteBranchOptions specifies options for a new branch.
type DeleteBranchOptions struct {
// If Force is true, then the branch will be deleted
// even if the branch has not been merged
// or if the branch does not point to a valid commit.
Force bool
}

// DeleteBranches deletes zero or more branches.
// If names is empty, then DeleteBranches returns nil without running Git.
func (g *Git) DeleteBranches(ctx context.Context, names []string, opts DeleteBranchOptions) error {
if len(names) == 0 {
return nil
}
errPrefix := "git branch --delete " + strings.Join(names, " ")
for _, name := range names {
if err := validateBranch(name); err != nil {
return fmt.Errorf("%s: %w", errPrefix, err)
}
}
args := make([]string, 0, len(names)+4)
args = append(args, "branch", "--delete")
if opts.Force {
args = append(args, "--force")
}
args = append(args, "--")
args = append(args, names...)
return g.run(ctx, errPrefix, args)
}

// NullTreeHash computes the hash of an empty tree and adds it to the
// repository. This is sometimes useful as a diff comparison target.
func (g *Git) NullTreeHash(ctx context.Context) (Hash, error) {
Expand Down
46 changes: 46 additions & 0 deletions branch_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -295,3 +295,49 @@ func TestNewBranch(t *testing.T) {
})
}
}

func TestDeleteBranches(t *testing.T) {
ctx := context.Background()
gitPath, err := findGit()
if err != nil {
t.Skip("git not found:", err)
}
env, err := newTestEnv(ctx, gitPath)
if err != nil {
t.Fatal(err)
}
defer env.cleanup()

// Create a repository with a commit and a branch "foo".
if err := env.g.Init(ctx, "."); err != nil {
t.Fatal(err)
}
const content = "Hello, World!\n"
if err := env.root.Apply(filesystem.Write("file.txt", content)); err != nil {
t.Fatal(err)
}
if err := env.g.Add(ctx, []Pathspec{"file.txt"}, AddOptions{}); err != nil {
t.Fatal(err)
}
if err := env.g.Commit(ctx, dummyContent, CommitOptions{}); err != nil {
t.Fatal(err)
}
if err := env.g.NewBranch(ctx, "foo", BranchOptions{}); err != nil {
t.Fatal(err)
}

// Delete the branch "foo".
if err := env.g.DeleteBranches(ctx, []string{"foo"}, DeleteBranchOptions{}); err != nil {
t.Error(err)
}

// Verify that "foo" no longer exists.
refs, err := env.g.ListRefs(ctx)
if err != nil {
t.Fatal(err)
}
const fooRef = Ref("refs/heads/foo")
if hash, ok := refs[fooRef]; ok {
t.Errorf("%s = %v; want missing", fooRef, hash)
}
}

0 comments on commit 9d322f3

Please sign in to comment.