// Revert implements got revert func Revert(c *cli.Context) { // Open the database db := util.OpenDB() defer db.Close() // Perform operations in a read-only lock err := db.View(func(tx *bolt.Tx) error { // Get the current commit sha info := tx.Bucket(util.INFO) objects := tx.Bucket(util.OBJECTS) current := info.Get(util.CURRENT) // Get the commit object and associated tree commit := types.DeserializeCommitObject(objects.Get(current)) tree := types.DeserializeTreeObject(objects.Get(commit.Tree)) for _, file := range c.Args() { fmt.Println("Reverting " + file + "...") fileData := TreeLookup(objects, tree, path.Clean(file)) ioutil.WriteFile(file, fileData, 0644) } return nil }) if err != nil { log.Fatal("Error reading from the database.") } }
func GetNewestCommit(objects *bolt.Bucket, hashes []types.Hash) int { var newest *newestCommit = nil for i, hash := range hashes { commit := types.DeserializeCommitObject(objects.Get(hash)) if newest == nil || commit.Time.After(newest.Time) { newest = new(newestCommit) newest.Index = i newest.Time = commit.Time } } return newest.Index }
// Status implements the `got status` command. func Status(c *cli.Context) { // Open the database db := util.OpenDB() defer db.Close() // Colored output yellow := ansi.ColorFunc("yellow+h:black") green := ansi.ColorFunc("green+h:black") red := ansi.ColorFunc("red+h:black") // Perform operations in a read-only lock err := db.View(func(tx *bolt.Tx) error { // Get the current commit sha info := tx.Bucket(util.INFO) objects := tx.Bucket(util.OBJECTS) current := info.Get(util.CURRENT) // Find the differences between the working directory and the tree of the current commit. differences := []Difference{} if current != nil { // Load commit object commit := types.DeserializeCommitObject(objects.Get(current)) util.DebugLog("Comparing working directory to commit '" + commit.Message + "'.") differences = TreeDiff(objects, commit.Tree, ".") } else { // Compare directory to the empty hash util.DebugLog("Comparing working directory to empty tree.") differences = TreeDiff(objects, types.EMPTY, ".") } // Print out the found differences for _, difference := range differences { line := fmt.Sprintf("%s %s", difference.Type, difference.FilePath) if difference.Type == "A" { fmt.Println(green(line)) } if difference.Type == "R" { fmt.Println(red(line)) } if difference.Type == "M" { fmt.Println(yellow(line)) } } return nil }) if err != nil { log.Fatal("Error reading from the database.") } }
func Log(c *cli.Context) { db := util.OpenDB() defer db.Close() yellow := ansi.ColorFunc("yellow+h:black") // Perform operations in a read-only lock db.View(func(tx *bolt.Tx) error { info := tx.Bucket(util.INFO) objects := tx.Bucket(util.OBJECTS) headsBytes := info.Get(util.HEADS) if headsBytes != nil { queue := types.DeserializeHashes(headsBytes) // TODO: Keep a visited set, so we don't repeat commits for len(queue) > 0 { i := GetNewestCommit(objects, queue) // Get commit and remove it from the priority queue commitSha := queue[i] commit := types.DeserializeCommitObject(objects.Get(commitSha)) queue = append(queue[:i], queue[i+1:]...) fmt.Printf(yellow("commit %s\n"), commitSha) fmt.Printf("Message: %s\n", commit.Message) fmt.Printf("Author: %s\n", commit.Author) fmt.Printf("Date: %s\n", commit.Time) if len(commit.Parents) > 0 { fmt.Printf("Parents: %s\n", commit.Parents) } fmt.Printf("Tree: %s\n", commit.Tree) fmt.Println() // Append parents of this commit to the queue queue = append(queue, commit.Parents...) } return nil } fmt.Println("There are no commits in this repository...") return nil }) }