package main import ( "errors" "flag" "fmt" "os" "dehub.dev/src/dehub.git" "gopkg.in/src-d/go-git.v4/plumbing" ) type repo struct { bare bool *dehub.Repo } func (r *repo) initFlags(flag *flag.FlagSet) { flag.BoolVar(&r.bare, "bare", false, "If set then the repo being opened will be expected to be bare") } func (r *repo) openRepo() error { var err error if r.Repo, err = dehub.OpenRepo(".", dehub.OpenBare(r.bare)); err != nil { wd, _ := os.Getwd() return fmt.Errorf("opening repo at %q: %w", wd, err) } return nil } // softReset resets to HEAD^ (or to an orphaned index, if HEAD has no parents), // returning the old HEAD. func (r *repo) softReset(expType string) (dehub.GitCommit, error) { head, err := r.GetGitHead() if err != nil { return head, fmt.Errorf("getting HEAD commit: %w", err) } else if typ, err := head.Commit.Type(); err != nil { return head, fmt.Errorf("determining commit type of HEAD:% w", err) } else if expType != "" && typ != expType { return head, fmt.Errorf("expected HEAD to be a %q commit, but found %q", expType, typ) } branchName, branchErr := r.ReferenceToBranchName(plumbing.HEAD) numParents := head.GitCommit.NumParents() if numParents > 1 { return head, errors.New("cannot reset to parent of a commit with multiple parents") } else if numParents == 0 { // if there are no parents then HEAD is the only commit in the branch. // Don't handle ErrNoBranchReference because there's not really anything // which can be done for that; we can't set head to "no commit". // Otherwise, just remove the branch reference, HEAD will still point to // it and all of HEAD's changes will be in the index. if branchErr != nil { return head, branchErr } else if err := r.GitRepo.Storer.RemoveReference(branchName); err != nil { return head, fmt.Errorf("removing reference %q: %w", branchName, err) } return head, nil } refName := branchName if errors.Is(branchErr, dehub.ErrNoBranchReference) { refName = plumbing.HEAD } else if err != nil { return head, fmt.Errorf("resolving HEAD: %w", err) } parentHash := head.GitCommit.ParentHashes[0] newHeadRef := plumbing.NewHashReference(refName, parentHash) if err := r.GitRepo.Storer.SetReference(newHeadRef); err != nil { return head, fmt.Errorf("storing reference %q: %w", newHeadRef, err) } return head, nil }