func crossReleaseChanges(cmd *c.Command, args []string) {
	dev.MustFindCrowbar()
	if len(args) != 2 {
		log.Fatalf("%s takes exactly 2 release names!")
	}
	releases := new([2]dev.Release)
	// Translate command line parameters.
	// releases[0] will be the release with changes, and
	// releases[1] will be the base release.
	for i, name := range args {
		switch name {
		case "current":
			releases[i] = dev.CurrentRelease()
		case "parent":
			if i == 0 {
				log.Fatalf("parent can only be the second arg to %s\n", cmd.Name())
			}
			releases[1] = releases[0].Parent()
			if releases[1] == nil {
				log.Fatalf("%s does not have a parent release.\n", releases[0].Name())
			}
		default:
			releases[i] = dev.GetRelease(name)
		}
	}
	dev.CrossReleaseChanges(releases[0], releases[1])
}
func showRelease(cmd *c.Command, args []string) {
	dev.MustFindCrowbar()
	if len(args) == 0 {
		dev.ShowRelease(dev.CurrentRelease())
	} else {
		for _, rel := range args {
			dev.ShowRelease(dev.GetRelease(rel))
		}
	}
}
func remoteChanges(cmd *c.Command, args []string) {
	dev.MustFindCrowbar()
	switch len(args) {
	case 0:
		dev.RemoteChanges(dev.CurrentRelease())
	case 1:
		dev.RemoteChanges(dev.GetRelease(args[0]))
	default:
		log.Fatalf("%s takes 0 or 1 release name!\n", cmd.Name())
	}
}
func builds(cmd *c.Command, args []string) {
	dev.MustFindCrowbar()
	res := make([]string, 0, 20)
	if len(args) == 0 {
		for build := range dev.CurrentRelease().Builds() {
			res = append(res, dev.CurrentRelease().Name()+"/"+build)
		}
	} else {
		for _, release := range args {
			for build := range dev.GetRelease(release).Builds() {
				res = append(res, release+"/"+build)
			}
		}
	}
	sort.Strings(res)
	for _, build := range res {
		fmt.Println(build)
	}
}