package main import ( "bufio" "fmt" "io" "os" ) type markedChange struct { mark int state string } type Marks struct { marks int changes []markedChange } func (m *Marks) Next() int { m.marks++ return m.marks } func (m *Marks) MarkChanges(changes []change) { // Make a lookup table for existing marks, and make sure we don't // reuse them. stateToMark := make(map[string]int) for _, mc := range m.changes { stateToMark[mc.state] = mc.mark if mc.mark > m.marks { m.marks = mc.mark } } for i := range changes { if mark, ok := stateToMark[changes[i].State]; ok { changes[i].mark = mark changes[i].exported = true } else { changes[i].mark = m.Next() m.changes = append(m.changes, markedChange{ mark: changes[i].mark, state: changes[i].State, }) } } } // Import loads a marks file analogous to those used by git fast-export's // --import-marks and --export-marks switches. func (m *Marks) Import(filename string) error { f, err := os.Open(filename) if err != nil { return err } defer f.Close() br := bufio.NewReader(f) for { var mc markedChange n, err := fmt.Fscanf(br, ":%d %s\n", &mc.mark, &mc.state) if err == io.ErrUnexpectedEOF && n == 0 { return nil } if err != nil { return err } m.changes = append(m.changes, mc) } } func (m *Marks) Export(filename string) error { f, err := os.Create(filename) if err != nil { return err } for _, c := range m.changes { fmt.Fprintf(f, ":%d %s\n", c.mark, c.state) } return f.Close() }