llvm.org GIT mirror llvm / b8f8fa1
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 Peter Collingbourne 2 years ago
1 changed file(s) with 169 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
0 //===- git-r.go - svn revisions to git revisions --------------------------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This is a small program for mapping svn revisions to git revisions in the
10 // monorepo.
11 //
12 // To set up:
13 // 1) http://llvm.org/docs/GettingStarted.html#for-developers-to-work-with-a-git-monorepo
14 // and make sure to follow the instructions for fetching commit notes.
15 // 2) go build
16 // 3) cp git-r ~/bin
17 //
18 // To use:
19 // $ git r 1
20 // 09c4b68e68c4fcff64b00e1ac077c4f4a524cbcc
21 //
22 //===----------------------------------------------------------------------===//
23
24 package main
25
26 import (
27 "bufio"
28 "bytes"
29 "encoding/gob"
30 "fmt"
31 "log"
32 "os"
33 "os/exec"
34 "strconv"
35 "strings"
36 )
37
38 func git(args ...string) (*bytes.Buffer, error) {
39 cmd := exec.Command("git", args...)
40
41 var b bytes.Buffer
42 cmd.Stdout = &b
43 err := cmd.Run()
44
45 return &b, err
46 }
47
48 func mkrevmap() []string {
49 revs, err := git("grep", "git-svn-rev", "refs/notes/commits")
50 if err != nil {
51 panic(err)
52 }
53
54 var revmap []string
55
56 scanner := bufio.NewScanner(revs)
57 for scanner.Scan() {
58 // refs/notes/commits:00/0b/d4acb454290301c140a1d9c4f7a45aa2fa9c:git-svn-rev: 37235
59
60 bits := strings.Split(scanner.Text(), ":")
61 gitrev := strings.Replace(bits[1], "/", "", -1)
62 svnrev := bits[3][1:]
63
64 svnrevn, err := strconv.Atoi(svnrev)
65 if err != nil {
66 panic(err)
67 }
68
69 if svnrevn >= len(revmap) {
70 newrevmap := make([]string, svnrevn+1)
71 copy(newrevmap, revmap)
72 revmap = newrevmap
73 }
74 revmap[svnrevn] = gitrev
75 }
76
77 return revmap
78 }
79
80 type revmap struct {
81 Noterev string
82 Revs []string
83 }
84
85 func writerevmap(path string, rmap *revmap, svnrev int) {
86 noterevbuf, err := git("rev-parse", "refs/notes/commits")
87 if err != nil {
88 fmt.Fprintf(os.Stderr, "%s: could not find refs/notes/commits, see instructions:\n", os.Args[0])
89 fmt.Fprintln(os.Stderr, "http://llvm.org/docs/GettingStarted.html#for-developers-to-work-with-a-git-monorepo")
90 os.Exit(1)
91 }
92 noterev := noterevbuf.String()
93 noterev = noterev[:len(noterev)-1]
94
95 if rmap == nil || rmap.Noterev != noterev {
96 var newrmap revmap
97 newrmap.Revs = mkrevmap()
98 newrmap.Noterev = noterev
99
100 f, err := os.Create(path)
101 if err != nil {
102 panic(err)
103 }
104
105 enc := gob.NewEncoder(f)
106 err = enc.Encode(newrmap)
107 if err != nil {
108 os.Remove(path)
109 panic(err)
110 }
111
112 rmap = &newrmap
113 }
114
115 if svnrev >= len(rmap.Revs) || rmap.Revs[svnrev] == "" {
116 fmt.Fprintf(os.Stderr, "%s: %d: unknown revision\n", os.Args[0], svnrev)
117 os.Exit(1)
118 }
119
120 fmt.Println(rmap.Revs[svnrev])
121 }
122
123 func main() {
124 if len(os.Args) != 2 {
125 fmt.Fprintf(os.Stderr, "%s: expected a single argument\n", os.Args[0])
126 os.Exit(1)
127 }
128 svnrev, err := strconv.Atoi(os.Args[1])
129 if err != nil {
130 fmt.Fprintf(os.Stderr, "%s: %s: expected an integer argument\n", os.Args[0], os.Args[1])
131 os.Exit(1)
132 }
133
134 gitdirbuf, err := git("rev-parse", "--git-common-dir")
135 if err != nil {
136 fmt.Fprintf(os.Stderr, "%s: not in a git repository\n", os.Args[0])
137 os.Exit(1)
138 }
139
140 gitdir := gitdirbuf.String()
141 gitdir = gitdir[:len(gitdir)-1]
142 err = os.Chdir(gitdir)
143 if err != nil {
144 panic(err)
145 }
146
147 mappath := "git-svn-revmap-cache"
148 f, err := os.Open(mappath)
149 if err != nil {
150 writerevmap(mappath, nil, svnrev)
151 return
152 }
153
154 dec := gob.NewDecoder(f)
155 var rmap revmap
156 err = dec.Decode(&rmap)
157 if err != nil {
158 writerevmap(mappath, nil, svnrev)
159 return
160 }
161
162 if svnrev < len(rmap.Revs) && rmap.Revs[svnrev] != "" {
163 fmt.Println(rmap.Revs[svnrev])
164 return
165 }
166
167 writerevmap(mappath, &rmap, svnrev)
168 }