This commit is contained in:
Lunny Xiao
2026-05-12 16:45:58 -07:00
parent 09bba53aec
commit 4266720a2e
4 changed files with 195 additions and 32 deletions
+31 -19
View File
@@ -6,6 +6,8 @@ package git
import (
"encoding/base64"
"fmt"
"os"
"os/exec"
"strings"
"unicode"
@@ -17,34 +19,28 @@ import (
// TeaCreateBranch creates a new branch in the repo, tracking from another branch.
func (r TeaRepo) TeaCreateBranch(localBranchName, remoteBranchName, remoteName string) error {
// save in .git/config to assign remote for future pulls
localBranchRefName := git_plumbing.NewBranchReferenceName(localBranchName)
err := r.CreateBranch(&git_config.Branch{
Name: localBranchName,
Merge: git_plumbing.NewBranchReferenceName(remoteBranchName),
Remote: remoteName,
})
if err != nil {
if _, err := r.Reference(localBranchRefName, true); err == nil {
return git.ErrBranchExists
} else if err != nil && err != git_plumbing.ErrReferenceNotFound {
return err
}
// serialize the branch to .git/refs/heads
remoteBranchRefName := git_plumbing.NewRemoteReferenceName(remoteName, remoteBranchName)
remoteBranchRef, err := r.Storer.Reference(remoteBranchRefName)
if err != nil {
return err
}
localHashRef := git_plumbing.NewHashReference(localBranchRefName, remoteBranchRef.Hash())
return r.Storer.SetReference(localHashRef)
return runGitCommand("branch", "--track", localBranchName, fmt.Sprintf("%s/%s", remoteName, remoteBranchName))
}
// TeaCheckout checks out the given branch in the worktree.
func (r TeaRepo) TeaCheckout(ref git_plumbing.ReferenceName) error {
tree, err := r.Worktree()
if err != nil {
return err
args := []string{"checkout"}
if ref.IsRemote() {
args = append(args, "--detach", ref.String())
} else if ref.IsBranch() {
args = append(args, ref.Short())
} else {
args = append(args, ref.String())
}
return tree.Checkout(&git.CheckoutOptions{Branch: ref})
return runGitCommand(args...)
}
// TeaDeleteLocalBranch removes the given branch locally
@@ -293,3 +289,19 @@ func isASCII(s string) bool {
}
return true
}
func runGitCommand(args ...string) error {
cmd := exec.Command("git", args...)
cmd.Env = os.Environ()
output, err := cmd.CombinedOutput()
if err == nil {
return nil
}
msg := strings.TrimSpace(string(output))
if msg == "" {
return fmt.Errorf("git %s: %w", strings.Join(args, " "), err)
}
return fmt.Errorf("git %s: %w: %s", strings.Join(args, " "), err, msg)
}