Beispiel #1
0
func copyTree(srcdir, dstdir string, src, dst *commit.Commit, p Progress) ([]commit.Entry, error, []error) {
	var errs []error
	var success []commit.Entry
	okdirs := map[string]bool{}

	if p != nil {
		p.SetProgress(2, 4, "Prepare copy: open "+dstdir)
	}

	c, err := commit.OpenDirAppend(dstdir)
	if err != nil {
		return success, err, errs
	}
	defer c.Close()

	if p != nil {
		p.SetProgress(2, 4, "Prepare copy: compute how many files to copy")
	}

	numfiles := len(src.Entries)
	if p != nil {
		numfiles = 0
		for _, s := range src.Entries {
			if wantCopy(s, src, dst) {
				numfiles = numfiles + 1
			}
		}
	}

	if p != nil {
		p.SetProgress(2, numfiles+4, fmt.Sprintf("Prepare copy: starting copy for %d files...", numfiles))
	}

	for _, s := range src.Entries {
		// Cannot copy, skip
		if !wantCopy(s, src, dst) {
			continue
		}

		// Find destination file name
		var d commit.Entry = commit.Entry(s)
		_, conflict := dst.ByPath[s.Path]
		if conflict {
			d.Path = commit.FindConflictFileName(s, dst)
			if d.Path == "" {
				continue
			}
		}

		srcpath := filepath.Join(srcdir, s.Path)
		dstpath := filepath.Join(dstdir, d.Path)

		if p != nil {
			p.SetProgress(len(success)+3, numfiles+4, "Copy "+d.Path)
		}

		// Create parent dirs
		err, ers := makeParentDirs(srcdir, dstdir, s.Path, okdirs)
		errs = append(errs, ers...)
		if err != nil {
			return success, err, errs
		}

		// Copy file
		err, ers = CopyFileNoReplace(srcpath, dstpath)
		errs = append(errs, ers...)
		if err != nil {
			return success, err, errs
		}

		// In case of conflicts, mark the file as a conflict
		if conflict {
			errs = append(errs, repo.MarkConflict(filepath.Join(dstdir, s.Path), dstpath)...)
		}

		// Add to commit file
		err = c.Add(d)
		if err != nil {
			errs = append(errs, err)
		}

		success = append(success, d)
	}
	return success, nil, errs
}