package main import ( "errors" "flag" "fmt" "os" "dehub.dev/src/dehub.git" "gopkg.in/src-d/go-git.v4/plumbing" ) type proj struct { bare bool *dehub.Project } func (proj *proj) initFlags(flag *flag.FlagSet) { flag.BoolVar(&proj.bare, "bare", false, "If set then the project being opened will be expected to have a bare git repo") } func (proj *proj) openProj() error { var err error if proj.Project, err = dehub.OpenProject(".", dehub.OpenBareRepo(proj.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 (proj *proj) softReset(expType string) (dehub.Commit, error) { head, err := proj.GetHeadCommit() if err != nil { return head, fmt.Errorf("getting HEAD commit: %w", err) } else if typ := head.Payload.Type(); expType != "" && typ != expType { return head, fmt.Errorf("expected HEAD to be have a %q payload, but found a %q payload", expType, typ) } branchName, branchErr := proj.ReferenceToBranchName(plumbing.HEAD) numParents := head.Object.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 := proj.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.Object.ParentHashes[0] newHeadRef := plumbing.NewHashReference(refName, parentHash) if err := proj.GitRepo.Storer.SetReference(newHeadRef); err != nil { return head, fmt.Errorf("storing reference %q: %w", newHeadRef, err) } return head, nil }