forked from OSchip/llvm-project
utils: Add a git-r utility for mapping svn revisions to git revisions in the monorepo.
llvm-svn: 305598
This commit is contained in:
parent
32614fcf42
commit
f6ca97284c
|
@ -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)
|
||||
}
|
Loading…
Reference in New Issue