summaryrefslogtreecommitdiff
path: root/utils/git-svn
diff options
context:
space:
mode:
authorPeter Collingbourne <peter@pcc.me.uk>2017-06-16 22:15:18 +0000
committerPeter Collingbourne <peter@pcc.me.uk>2017-06-16 22:15:18 +0000
commitb8f8fa1c8c2a83165833ce5549420e22357af39d (patch)
tree52b43759f0beb0ff857c498e6365b9d8ffcd8d88 /utils/git-svn
parent3589cb5a83a8e1066d7ca7d86aa9748ae87de390 (diff)
utils: Add a git-r utility for mapping svn revisions to git revisions in the monorepo.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@305598 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'utils/git-svn')
-rw-r--r--utils/git-svn/git-r/git-r.go169
1 files changed, 169 insertions, 0 deletions
diff --git a/utils/git-svn/git-r/git-r.go b/utils/git-svn/git-r/git-r.go
new file mode 100644
index 00000000000..fb641c98fd2
--- /dev/null
+++ b/utils/git-svn/git-r/git-r.go
@@ -0,0 +1,169 @@
+//===- git-r.go - svn revisions to git revisions --------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This is a small program for mapping svn revisions to git revisions in the
+// monorepo.
+//
+// To set up:
+// 1) http://llvm.org/docs/GettingStarted.html#for-developers-to-work-with-a-git-monorepo
+// and make sure to follow the instructions for fetching commit notes.
+// 2) go build
+// 3) cp git-r ~/bin
+//
+// To use:
+// $ git r 1
+// 09c4b68e68c4fcff64b00e1ac077c4f4a524cbcc
+//
+//===----------------------------------------------------------------------===//
+
+package main
+
+import (
+ "bufio"
+ "bytes"
+ "encoding/gob"
+ "fmt"
+ "log"
+ "os"
+ "os/exec"
+ "strconv"
+ "strings"
+)
+
+func git(args ...string) (*bytes.Buffer, error) {
+ cmd := exec.Command("git", args...)
+
+ var b bytes.Buffer
+ cmd.Stdout = &b
+ err := cmd.Run()
+
+ return &b, err
+}
+
+func mkrevmap() []string {
+ revs, err := git("grep", "git-svn-rev", "refs/notes/commits")
+ if err != nil {
+ panic(err)
+ }
+
+ var revmap []string
+
+ scanner := bufio.NewScanner(revs)
+ for scanner.Scan() {
+ // refs/notes/commits:00/0b/d4acb454290301c140a1d9c4f7a45aa2fa9c:git-svn-rev: 37235
+
+ bits := strings.Split(scanner.Text(), ":")
+ gitrev := strings.Replace(bits[1], "/", "", -1)
+ svnrev := bits[3][1:]
+
+ svnrevn, err := strconv.Atoi(svnrev)
+ if err != nil {
+ panic(err)
+ }
+
+ if svnrevn >= len(revmap) {
+ newrevmap := make([]string, svnrevn+1)
+ copy(newrevmap, revmap)
+ revmap = newrevmap
+ }
+ revmap[svnrevn] = gitrev
+ }
+
+ return revmap
+}
+
+type revmap struct {
+ Noterev string
+ Revs []string
+}
+
+func writerevmap(path string, rmap *revmap, svnrev int) {
+ noterevbuf, err := git("rev-parse", "refs/notes/commits")
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "%s: could not find refs/notes/commits, see instructions:\n", os.Args[0])
+ fmt.Fprintln(os.Stderr, "http://llvm.org/docs/GettingStarted.html#for-developers-to-work-with-a-git-monorepo")
+ os.Exit(1)
+ }
+ noterev := noterevbuf.String()
+ noterev = noterev[:len(noterev)-1]
+
+ if rmap == nil || rmap.Noterev != noterev {
+ var newrmap revmap
+ newrmap.Revs = mkrevmap()
+ newrmap.Noterev = noterev
+
+ f, err := os.Create(path)
+ if err != nil {
+ panic(err)
+ }
+
+ enc := gob.NewEncoder(f)
+ err = enc.Encode(newrmap)
+ if err != nil {
+ os.Remove(path)
+ panic(err)
+ }
+
+ rmap = &newrmap
+ }
+
+ if svnrev >= len(rmap.Revs) || rmap.Revs[svnrev] == "" {
+ fmt.Fprintf(os.Stderr, "%s: %d: unknown revision\n", os.Args[0], svnrev)
+ os.Exit(1)
+ }
+
+ fmt.Println(rmap.Revs[svnrev])
+}
+
+func main() {
+ if len(os.Args) != 2 {
+ fmt.Fprintf(os.Stderr, "%s: expected a single argument\n", os.Args[0])
+ os.Exit(1)
+ }
+ svnrev, err := strconv.Atoi(os.Args[1])
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "%s: %s: expected an integer argument\n", os.Args[0], os.Args[1])
+ os.Exit(1)
+ }
+
+ gitdirbuf, err := git("rev-parse", "--git-common-dir")
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "%s: not in a git repository\n", os.Args[0])
+ os.Exit(1)
+ }
+
+ gitdir := gitdirbuf.String()
+ gitdir = gitdir[:len(gitdir)-1]
+ err = os.Chdir(gitdir)
+ if err != nil {
+ panic(err)
+ }
+
+ mappath := "git-svn-revmap-cache"
+ f, err := os.Open(mappath)
+ if err != nil {
+ writerevmap(mappath, nil, svnrev)
+ return
+ }
+
+ dec := gob.NewDecoder(f)
+ var rmap revmap
+ err = dec.Decode(&rmap)
+ if err != nil {
+ writerevmap(mappath, nil, svnrev)
+ return
+ }
+
+ if svnrev < len(rmap.Revs) && rmap.Revs[svnrev] != "" {
+ fmt.Println(rmap.Revs[svnrev])
+ return
+ }
+
+ writerevmap(mappath, &rmap, svnrev)
+}