Beispiel #1
0
// 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.")
	}
}
Beispiel #2
0
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
}
Beispiel #3
0
// 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.")
	}
}
Beispiel #4
0
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
	})
}