func exportGitImportBzrAndPush( gitRev, gitBranch, bzrBranch, url string) { // FIXME: use locks tmpGitBranch := "__git_import/" + gitBranch tmpBzrBranch := filepath.FromSlash(path.Join(bzrRepo, tmpGitBranch)) // create all temp files we will need later tmpBzrMarks, err := ioutil.TempFile(tmpDir, "bzr_marks") must(err) defer os.Remove(tmpBzrMarks.Name()) tmpBzrMarks.Close() tmpGitMarks, err := ioutil.TempFile(tmpDir, "git_marks") must(err) defer os.Remove(tmpGitMarks.Name()) tmpGitMarks.Close() // create a temp branch in git must(git.NewBranch(tmpGitBranch, gitRev)) defer git.RemoveBranch(tmpGitBranch) // export data into bzr log.Info("Exporting data from git") defer os.RemoveAll(tmpBzrBranch) exportSize, err := RunPipe( git.Export(tmpGitBranch, gitMarks, tmpGitMarks.Name()), bzr.Import(bzrRepo, bzrMarks, tmpBzrMarks.Name())) if exportSize == 0 { log.Info("Empty export. Creating bzr branch using marks") b, err := loadMarks(bzrMarks) must(err) g, err := loadMarks(gitMarks) must(err) mark, ok := g.byRev[gitRev] if !ok { log.Panicf("Can't find revision %q in the git marks file", gitRev) } brev, ok := b.byMark[mark] if !ok { log.Panicf("Can't find mark %d in bzr marks file", mark) } must(bzr.NewBranch(tmpBzrBranch, brev)) } log.Info("Pushing into bzr") must(bzr.Push(tmpBzrBranch, url)) log.Info("Finalizing") must(bzr.PullOverwrite(tmpBzrBranch, bzrBranch)) if exportSize != 0 { must(os.Rename(tmpBzrMarks.Name(), bzrMarks)) must(os.Rename(tmpGitMarks.Name(), gitMarks)) } }
func updateHookCmd(args []string) { // command-line flags fs := flag.NewFlagSet("update-hook", flag.ExitOnError) help := fs.Bool("h", false, "show usage message") fs.Usage = func() { updateHookUsage(fs) } fs.Parse(args) if *help { fs.Usage() os.Exit(0) } if fs.NArg() != 3 || fs.Arg(0) == "" || fs.Arg(1) == "" || fs.Arg(2) == "" { fs.Usage() os.Exit(2) } const emptyRef = "0000000000000000000000000000000000000000" // FIXME: should it make an exception for tags? if fs.Arg(1) == emptyRef { panic(fmt.Errorf("Creation of new references is not supported")) } if fs.Arg(2) == emptyRef { panic(fmt.Errorf("Deletion of reference is not supported")) } // FIXME: locking // trim "/refs/heads/" prefix from git reference const prefix = "refs/heads/" var gitBranch string if !strings.HasPrefix(fs.Arg(0), prefix) { log.Errorf("Unexpected reference name %q", fs.Arg(0)) os.Exit(1) } gitBranch = fs.Arg(0)[len(prefix):] // find corresponding bzr branch branchConfig, err := loadBranchConfig() must(err) var bzrBranch, url string if c, ok := branchConfig.byGitName[gitBranch]; !ok { log.Errorf("Unknown branch %q", gitBranch) os.Exit(1) } else { bzrBranch = c.Bzr url = c.Url } // now let's try to update bazaar branch to reduce the possibility of diverged branches updated := cloneAndExportBzrImportGit( url, checkIfBranchUpdated(bzrBranch), // FIXME: move this bit into function func(marksUpdated bool, tmpGitMarks, tmpBzrMarks, tmpGitBranch, tmpBzrBranch string) { must(bzr.PullOverwrite(tmpBzrBranch, bzrBranch)) must(git.RenameBranch(tmpGitBranch, gitBranch)) if marksUpdated { must(os.Rename(tmpBzrMarks, bzrMarks)) must(os.Rename(tmpGitMarks, gitMarks)) } }) if updated { log.Error("These branches have diverged") os.Exit(1) } if !checkFastForward(fs.Arg(1), fs.Arg(2)) { log.Error("Not fast-forward push") os.Exit(1) } // export git -> import bzr & push it exportGitImportBzrAndPush(fs.Arg(2), gitBranch, bzrBranch, url) }