Example #1
0
func runRevlog(cmd *Command, w io.Writer, args []string) {
	if len(args) == 0 {
		fatalf("missing argument: revlog index file")
	}
	index, err := revlog.Open(storeName(args[0]))
	if err != nil {
		fatalf("%s", err)
	}

	if *revlogR == -1 {
		index.Dump(w)
		return
	}

	r, err := revlog.FileRevSpec(*revlogR).Lookup(index)
	if err != nil {
		fatalf("%s", err)
	}
	if !*revlogBuild {
		dh := &dataHelper{}
		d, err := r.GetData(dh)
		if dh.file != nil {
			dh.file.Close()
		}
		if err != nil {
			fatalf("%s", err)
		}
		if r.IsBase() {
			w.Write(d)
		} else {
			hunks, err := patch.Parse(d)
			if err != nil {
				fatalf("%s", err)
			}
			for _, h := range hunks {
				h.Dump(w)
			}
		}
	} else {
		fb := revlog.NewFileBuilder()
		err = fb.BuildWrite(w, r)
		if err != nil {
			fatalf("%s", err)
		}
	}
}
Example #2
0
func (p *FileBuilder) PreparePatch(r *Rec) (f *FilePatch, err error) {
	var prevPatch []patch.Hunk
	rsav := r
	dc := p.dataCache
	if dc == nil {
		dc = noCache{}
	}

	if !p.data.keepOpen {
		defer p.CloseData()
	}

	for {
		d := dc.Get(r.i)
		if d == nil {
			d, err = r.GetData(&p.data)
			if err != nil {
				err = fmt.Errorf("rev %d: get data: %v", r.i, err)
				return
			}
			dc.Store(r.i, d)
		}
		if r.IsBase() {
			f = new(FilePatch)
			if rsav.IsStartOfBranch() {
				if r == rsav {
					// The normal case, rsav is a base revision, the
					// complete meta header is at the top of the data
					f.MetaData = scanMetaData(d)
					f.MetaSkip = len(f.MetaData)
				} else if len(prevPatch) > 0 {
					baseMeta := scanMetaData(d)
					skipFirst := false

					prevPatch[0].Adjust(func(begin, end int, data []byte) []byte {
						if n := len(baseMeta); n > 0 && begin >= 2 && end <= n-2 {
							// A rare case: There is a meta header at the top of the
							// data of the base revision (already parsed into tmp), but
							// there's also the first patch that modifies some content of the
							// meta header. (For a more robust solution the patches
							// following the first one would need to be checked too
							// whether they are located within the original meta header.)
							// An example is:
							//	hgo revlog $GOROOT/.hg/store/data/test/fixedbugs/bug136.go.i
							//	file revision 1
							b := &p.metaBuf
							b.Reset()
							b.Write(baseMeta[:begin])
							b.Write(data)
							b.Write(baseMeta[end:])
							f.MetaSkip = n
							f.MetaData = b.Bytes()
							skipFirst = true
							return data[:0]
						}

						// Another rare case, rsav is an incremental revision, the
						// meta header is at the top of the first hunk.
						// Example: hgo revlog -r 1 $PLAN9/.hg/store/data/src/cmd/dd.c.i
						if begin > 0 {
							return data
						}
						f.MetaData = scanMetaData(data)
						return data[len(f.MetaData):]
					})

					if skipFirst {
						prevPatch = prevPatch[1:]
					}
				}
			}
			f.baseData = d
			f.patch = prevPatch
			f.rev = rsav
			f.fb = p
			return
		}
		hunks, err1 := patch.Parse(d)
		if err1 != nil {
			err = err1
			return
		}
		if prevPatch == nil {
			prevPatch = hunks
		} else {
			prevPatch = p.w.JoinPatches(hunks, prevPatch)
			p.swap()
		}
		r = r.Prev()
	}
	panic("not reached")

}