Exemplo n.º 1
0
func ExampleReverse() {
	r := stringutil.Reverse("Hello, world")
	fmt.Println(r)

	r = stringutil.Reverse("Hello, 世界")
	fmt.Println(r)

	// Output:
	// dlrow ,olleH
	// 界世 ,olleH
}
Exemplo n.º 2
0
func reverseStrings(ss []string) []string {
	rs := make([]string, len(ss))
	for i := range ss {
		rs[i] = stringutil.Reverse(ss[i])
	}
	return rs
}
Exemplo n.º 3
0
func main() {

	N := 999 * 999
	var x int
Outer:
	for n := N; n > 10001; n-- {
		if strings.EqualFold(stringutil.Reverse(strconv.Itoa(n)), strconv.Itoa(n)) {
			for q := 999; q >= 100; q-- {
				if n%q == 0 {
					if n/q >= 100 && n/q < 1000 {
						x = n
						break Outer
					}
				}
			}
		}
	}

	name := os.Args[0]
	fmt.Printf("Answer to problem %v: %v\n", name[len(name)-3:], x)
}
Exemplo n.º 4
0
func main() {
	fmt.Println(stringutil.Reverse("kinow"))
}
Exemplo n.º 5
0
func main() {
	fmt.Println(stringutil.Reverse("!selpmaxe oG ,olleH"))
}
Exemplo n.º 6
0
func ExampleReverse() {
	fmt.Println(stringutil.Reverse("hello"))
	// Output: olleh
}
Exemplo n.º 7
0
func main() {
	fmt.Println(stringutil.Reverse("olleh"))
}
Exemplo n.º 8
0
func main() {
	log.SetFlags(0)
	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, usage)
		flag.PrintDefaults()
	}
	flag.Parse()
	if *flRepoTag && *flTagRepo {
		fmt.Fprintln(os.Stderr, "-repo/tag is not compatible with -tag/repo")
		os.Exit(1)
	}
	mode := modes[*flMode]
	if mode == NoMode {
		fmt.Fprintln(os.Stderr, "Unknown mode: ", *flMode)
		os.Exit(1)
	}
	remotePaths := flag.Args()
	if len(remotePaths) < 1 {
		flag.Usage()
		os.Exit(1)
	}

	nSides := len(remotePaths)
	commitInfo := make(map[git.Oid]CommitInfo)
	finalBranchInfo := make(map[string][]BranchInfo)
	roots := []*git.Commit{}
	sideNames := make([]string, nSides)
	for i, path := range remotePaths {
		sideNames[i] = filepath.Base(path)
	}
	var sideNamesTree *Tree
	switch {
	case *flRepoTag:
		sideNamesTree = StringTree(sideNames)
	case *flTagRepo:
		sideNamesTree = StringTree(reverseStrings(sideNames))
	}

	repo, err := git.InitRepository(".", false)
	e.Exit(err)
	tagList, err := repo.Tags.List()
	e.Exit(err)
	if *flTagRepo {
		tagList = reverseStrings(tagList)
	}
	var relevantTagList []string

	for i, remotePath := range remotePaths {
		// Fetch.
		remotePath, err := filepath.Abs(remotePath)
		e.Exit(err)

		name := sideNames[i]
		remoteGlob := fmt.Sprint("refs/remotes/", name, "/*")
		switch {
		case *flRepoTag:
			sideNamesTree.Insert(name, true)
		case *flTagRepo:
			sideNamesTree.Insert(stringutil.Reverse(name), true)
		}

		remote, err := repo.Remotes.Lookup(name)
		if err != nil {
			log.Printf("fetching %q (%s)", name, err)
			remote, err = repo.Remotes.Create(name, remotePath)
			e.Exit(err)
			// Use "git fetch" because libgit2 fetch is horribly slow for big local repos.
			// err = remote.Fetch(nil, nil, "")
			_ = remote
			cmd := exec.Command("git", "fetch", name)
			cmd.Stdout = os.Stdout
			cmd.Stderr = os.Stderr
			err = cmd.Run()
			e.Exit(err)
		}

		// For each commit to be rewritten, store it side number in commitInfo.
		log.Printf("walking %q", name)
		walker, err := repo.Walk()
		e.Exit(err)
		err = walker.PushGlob(remoteGlob)
		e.Exit(err)
		if *flTagRepo || *flRepoTag {
			key := name
			if *flTagRepo {
				key = stringutil.Reverse(name)
			}
			relevantTags := sideNamesTree.FilterStrings(key, tagList)
			for _, tagName := range relevantTags {
				if *flTagRepo {
					tagName = stringutil.Reverse(tagName)
				}
				ref, err := repo.References.Lookup("refs/tags/" + tagName)
				e.Exit(err)
				obj, err := ref.Peel(git.ObjectCommit)
				if err != nil {
					// Ignore tags that do not point to commits.
					continue
				}
				relevantTagList = append(relevantTagList, tagName)
				walker.Push(obj.Id())
				// Add the tag to the list of roots for rewrite.
				commit, err := repo.LookupCommit(obj.Id())
				e.Exit(err)
				roots = append(roots, commit)
			}
		}
		sharedCommitsCount := 0
		err = walker.Iterate(func(commit *git.Commit) bool {
			oid := *commit.Id()
			if _, ok := commitInfo[oid]; !ok {
				commitInfo[oid] = CommitInfo{Side: i}
			} else {
				sharedCommitsCount++
			}
			return true
		})
		e.Exit(err)
		if sharedCommitsCount > 0 {
			log.Printf("did not change side of %s", plural(sharedCommitsCount, "shared commit"))
		}

		// Update commitInfo with lists of commit branches.
		iter, err := repo.NewReferenceIteratorGlob(remoteGlob)
		e.Exit(err)
		for {
			ref, err := iter.Next()
			if git.IsErrorCode(err, git.ErrIterOver) {
				break
			}
			e.Exit(err)
			// Seed search with head commit.
			refCommit, err := repo.LookupCommit(ref.Target())
			e.Exit(err)
			roots = append(roots, refCommit)
			// Store commit branches.
			branchName, err := ref.Branch().Name()
			e.Exit(err)
			branchName = strings.TrimPrefix(branchName, name+"/")
			if mode == FinalMode && branchName != *flInterpose {
				// Add branches other than "master" for final merge.
				finalBranchInfo[branchName] = append(finalBranchInfo[branchName], BranchInfo{
					Side:   i,
					Commit: refCommit,
				})
				// Skip interposing.
				continue
			}
			walker.Reset()
			err = walker.Push(ref.Target())
			e.Exit(err)
			walker.SimplifyFirstParent()
			err = walker.Iterate(func(commit *git.Commit) bool {
				oid := *commit.Id()
				ci := commitInfo[oid]
				ci.Branches = append(ci.Branches, branchName)
				if mode == TotalMode && branchName == "master" {
					// Reduce risk of missing sibling trees
					// with our strategy that takes them
					// from the first parent by making
					// "master" the first parent.
					n := len(ci.Branches) - 1
					ci.Branches[0], ci.Branches[n] = ci.Branches[n], ci.Branches[0]
				}

				commitInfo[oid] = ci
				return true
			})
			e.Exit(err)
		}
	}

	log.Printf("composing %s (%s)", plural(nSides, "side"), plural(len(commitInfo), "commit"))
	tb, err := repo.TreeBuilder()
	e.Exit(err)
	emptyTreeOid, err := tb.Write()
	e.Exit(err)
	emptyTree, err := repo.LookupTree(emptyTreeOid)
	e.Exit(err)
	sig := &git.Signature{Name: "root", Email: "root"} // Deterministic signature.
	composedOid, err := repo.CreateCommit("", sig, sig, "", emptyTree, roots...)
	e.Exit(err)
	if *flVerbose {
		log.Println("virtual common head:", composedOid)
	}

	filterMapping := make(map[git.Oid]git.Oid) // Map old commits to new commits.
	newHeads := make(map[string]*git.Commit)   // Map new heads to new commits.

	var progress *uiprogress.Progress
	var bar *uiprogress.Bar
	if !*flVerbose {
		progress = uiprogress.New()
		progress.Out = os.Stderr
		bar = progress.AddBar(len(commitInfo))
		progress.Start()
	}

	// libgit2 chronological topological walker in fact is not chronological.
	// totalWalker, err := repo.Walk()
	totalWalker, err := NewReverseTopologicalDateOrderCommitWalker(repo)
	e.Exit(err)
	// totalWalker.Sorting(git.SortTopological | git.SortTime | git.SortReverse)
	totalWalker.Push(composedOid)
	err = totalWalker.Iterate(func(commit *git.Commit) bool {
		oid := *commit.Id()
		if oid == *composedOid {
			return true // Skip our composed oid (and immediately finish).
		}
		ci := commitInfo[oid]

		parents := []*git.Commit{}
		useParentsFrom := uint(0)
		if len(ci.Branches) > 0 {
			// Replace first parent (if any) with heads of relevant branches.
			useParentsFrom = 1
			usedHeads := map[git.Oid]bool{}
			for _, branch := range ci.Branches {
				head := newHeads[branch]
				if head != nil && !usedHeads[*head.Id()] {
					parents = append(parents, head)
					usedHeads[*head.Id()] = true
				}
			}
		}
		// Translate old parents.
		for i := useParentsFrom; i < commit.ParentCount(); i++ {
			oldParentOid := commit.Parent(uint(i)).Id()
			parentOid := filterMapping[*oldParentOid]
			newParent, err := repo.LookupCommit(&parentOid)
			if err != nil {
				e.Exit(fmt.Errorf("Error: %v parent %v in %q was not mapped yet", &oid, oldParentOid, sideNames[ci.Side]))
			}
			parents = append(parents, newParent)
		}
		// Update trees.
		var tb *git.TreeBuilder
		if len(parents) > 0 {
			parentTree, err := parents[0].Tree()
			e.Exit(err)
			tb, err = repo.TreeBuilderFromTree(parentTree)
			e.Exit(err)
		} else {
			tb, err = repo.TreeBuilder()
			e.Exit(err)
		}
		tree, err := commit.Tree()
		e.Exit(err)
		err = tb.Insert(sideNames[ci.Side], tree.Id(), int(git.FilemodeTree))
		e.Exit(err)
		newTreeID, err := tb.Write()
		e.Exit(err)
		newTree, err := repo.LookupTree(newTreeID)
		e.Exit(err)
		// Commit.
		newOid, err := repo.CreateCommit("", commit.Author(), commit.Committer(), commit.Message(), newTree, parents...)
		e.Exit(err)
		filterMapping[oid] = *newOid
		// Update cached heads.
		newCommit, err := repo.LookupCommit(newOid)
		e.Exit(err)
		for _, branch := range ci.Branches {
			newHeads[branch] = newCommit
		}

		if bar != nil {
			bar.Incr()
		}
		if *flVerbose {
			fmt.Println(commit.Committer().When, &oid, ci.Side, ci.Branches, "→", newOid, len(parents))
		}

		return true
	})
	e.Exit(err)
	if progress != nil {
		progress.Stop()
	}

	// Create finally-merged branches.
	sig, err = repo.DefaultSignature()
	e.Exit(err)
	for branchName, branchInfos := range finalBranchInfo {
		nParents := len(branchInfos)
		var commitID *git.Oid
		if nParents == 1 {
			oldOid := filterMapping[*branchInfos[0].Commit.Id()]
			commit, err := repo.LookupCommit(&oldOid)
			e.Exit(err)
			commitID = commit.Id()
		} else {
			parents := make([]*git.Commit, nParents)
			parentNames := make([]string, nParents)
			tb, err := repo.TreeBuilder()
			e.Exit(err)
			for k, branchInfo := range branchInfos {
				parentOid := filterMapping[*branchInfo.Commit.Id()]
				parentCommit, err := repo.LookupCommit(&parentOid)
				e.Exit(err)
				parents[k] = parentCommit
				name := sideNames[branchInfo.Side]
				parentNames[k] = name
				oldTree, err := branchInfo.Commit.Tree()
				e.Exit(err)
				err = tb.Insert(name, oldTree.Id(), int(git.FilemodeTree))
				e.Exit(err)
			}
			newTreeID, err := tb.Write()
			e.Exit(err)
			newTree, err := repo.LookupTree(newTreeID)
			e.Exit(err)
			message := fmt.Sprintf("Compose branch '%s' from %s", branchName, strings.Join(parentNames, ", "))
			commitID, err = repo.CreateCommit("", sig, sig, message, newTree, parents...)
			e.Exit(err)
		}
		_, err = repo.References.Create("refs/heads/"+branchName, commitID, true, "")
		e.Exit(err)
	}
	// Create heads for interposed branches.
	for headName, commit := range newHeads {
		_, err = repo.References.Create("refs/heads/"+headName, commit.Id(), true, "")
		e.Exit(err)
	}
	// Create tags.
	rewrittenTagsCount := 0
	for {
		// This loop supports rewriting tags of tags...
		rewrittenTags := false
		for _, tagName := range relevantTagList {
			ref, err := repo.References.Lookup("refs/tags/" + tagName)
			e.Exit(err)
			oldOid := *ref.Target()
			if newOid, ok := filterMapping[oldOid]; ok {
				// Lightweight tag pointing to a rewritten commit.
				commit, err := repo.LookupCommit(&newOid)
				e.Exit(err)
				_, err = repo.Tags.CreateLightweight(tagName, commit, true)
				e.Exit(err)
				rewrittenTags = true
				rewrittenTagsCount++
				if *flVerbose {
					fmt.Println("rewritten lightweight tag", tagName, &oldOid, "→", &newOid)
				}
			}
			tag, err := repo.LookupTag(&oldOid)
			if err == nil {
				// Annotated tag.
				oldOid = *tag.Target().Id()
				if newOid, ok := filterMapping[oldOid]; ok {
					commit, err := repo.LookupCommit(&newOid)
					e.Exit(err)
					// Currently git2go does not support overwriting annotated tags.
					_, err = repo.Tags.Create(tagName, commit, tag.Tagger(), tag.Message(), true)
					e.Exit(err)
					rewrittenTags = true
					rewrittenTagsCount++
					if *flVerbose {
						fmt.Println("rewritten annotated tag", tagName, &oldOid, "→", &newOid)
					}
				}
			}
		}
		if !rewrittenTags {
			break
		}
	}
	log.Printf("merged %s, interposed %s, rewritten %s",
		plural(len(finalBranchInfo), "branch"),
		plural(len(newHeads), "branch"),
		plural(rewrittenTagsCount, "tag"))
}
Exemplo n.º 9
0
func main() {
	fmt.Printf(stringutil.Reverse("Hello go"))
}
Exemplo n.º 10
0
func main() {
	fmt.Println(stringutil.Reverse("olleh"))
	fmt.Println(calc.Sum(3, 2)) // calc 패키지의 Sum 함수 사용
}