Skip to content

Commit

Permalink
Get asdi restore to work
Browse files Browse the repository at this point in the history
  • Loading branch information
nikochiko committed Jan 9, 2022
1 parent 15cd74f commit 5e09b38
Show file tree
Hide file tree
Showing 3 changed files with 125 additions and 3 deletions.
28 changes: 28 additions & 0 deletions cmd/restore.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package cmd

import (
"git.kausm.in/kaustubh/autosaved/core"
"github.com/spf13/cobra"
)

var restoreCmd = &cobra.Command{
Use: "restore commit-hash",
Short: "Restores the state of a repository to a previous checkpoint (commit). Input is commit hash that we want to restore",
Long: `Restores the state of the repository to a previous state,
whose commit Hash is given as an argument`,
Args: cobra.ExactArgs(1),
Run: restore,
}

func restore(cmd *cobra.Command, args []string) {
repoPath := "."
asdRepo, err := core.AsdRepoFromGitRepoPath(repoPath, getMinSeconds())
checkError(err)

hashString := args[0]

err = asdRepo.RestoreByCommitHash(hashString)
checkError(err)

asdFmt.Successf("Restored successfully\n")
}
4 changes: 3 additions & 1 deletion cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ var globalViper = viper.GetViper()

// rootCmd represents the base command when called without any subcommands
var rootCmd = &cobra.Command{
Use: "autosaved",
Use: "asdi",
Short: "Never lose your work. Code without worrying",
Long: `autosaved, pronounced autosave-d (for autosave daemon) is a utility written in Go to autosave progress on code projects.
Expand Down Expand Up @@ -68,6 +68,8 @@ func init() {
rootCmd.AddCommand(watchCmd)

rootCmd.AddCommand(listCmd)

rootCmd.AddCommand(restoreCmd)
}

func initConfig() {
Expand Down
96 changes: 94 additions & 2 deletions core/core.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
package core

import (
"bufio"
"errors"
"fmt"
"log"
"os"
"strings"
"time"

"github.com/fatih/color"
Expand All @@ -28,6 +31,8 @@ var (
ErrNothingToSave = errors.New("nothing to save")
ErrAutosavedBranchNotCreated = errors.New("autosaved branch for current branch hasn't been created yet")
ErrUserUnbornHead = errors.New("autosaved cannot continue with an unborn head. please make an initial commit and try again")
ErrInvalidHash = errors.New("the hash submitted is not a valid hash")
ErrUserDidNotConfirm = errors.New("user didn't confirm yes")
)

type AsdRepository struct {
Expand Down Expand Up @@ -251,9 +256,13 @@ func (asd *AsdRepository) ShouldSave() (bool, string, error) {
return false, "", err
}

if shouldSave == false {
return false, reason2, nil
}

if reason2 != "" {
if reason != "" {
reason = reason + " and" + reason2
reason = reason + " and " + reason2
} else {
reason = reason2
}
Expand Down Expand Up @@ -448,7 +457,90 @@ func (asd *AsdRepository) List(limit int) error {
return nil
}

func (asd *AsdRepository) ListOnCurrentBranch(limit int) error {
func (asd *AsdRepository) RestoreByCommitHash(hashString string) error {
if !plumbing.IsHash(hashString) {
return ErrInvalidHash
}

hash := plumbing.NewHash(hashString)

color.New(color.FgCyan).Printf("\nTip: you can run `git diff HEAD..%s` to confirm your changes\n", hash.String())

questionString := color.New(color.FgYellow).Sprintf(`Are you sure you want to restore to checkpoint %s?`, hashString[:6])

if askForConfirmation(questionString) {
return asd.restoreCheckpoint(hash)
} else {
return ErrUserDidNotConfirm
}
}

func askForConfirmation(s string) bool {
reader := bufio.NewReader(os.Stdin)

for {
fmt.Printf("%s [y/n]: ", s)

response, err := reader.ReadString('\n')
if err != nil {
log.Fatal(err)
}

response = strings.ToLower(strings.TrimSpace(response))

if response == "y" || response == "yes" {
return true
} else if response == "n" || response == "no" {
return false
}
}
}

func (asd *AsdRepository) restoreCheckpoint(commit plumbing.Hash) error {
r := asd.Repository
w, err := r.Worktree()
if err != nil {
return err
}

// make note of the current head ref
head, err := r.Head()
if err != nil {
if err == plumbing.ErrReferenceNotFound {
err = ErrUserUnbornHead
return err
}

log.Printf("error: %v\n", err)
return err
}

// force checkout to that commit
coOpts := git.CheckoutOptions{
Hash: commit,
Force: true,
}
err = w.Checkout(&coOpts)
if err != nil {
return err
}

// git reset soft
resetOpts := git.ResetOptions{
Mode: git.SoftReset,
Commit: head.Hash(),
}
err = w.Reset(&resetOpts)
if err != nil {
return err
}

// git checkout to head with keep
err = checkoutWithKeep(w, head.Name())
if err != nil {
return err
}

return nil
}

Expand Down

0 comments on commit 5e09b38

Please sign in to comment.