示例#1
0
文件: git.go 项目: php-coder/origin
// Clone clones a git repository to a specific target directory
func (h *stiGit) Clone(source, target string, c api.CloneConfig) error {
	if util.UsingCygwinGit {
		var err error
		target, err = util.ToSlashCygwin(target)
		if err != nil {
			return err
		}
	}

	// NOTE, we don NOT pass in both stdout and stderr, because
	// with running with --quiet, and no output heading to stdout, hangs were occurring with the coordination
	// of underlying channel management in the Go layer when dealing with the Go Cmd wrapper around
	// git, sending of stdout/stderr to the Pipes created here, and the glog routines sent to pipeToLog
	//
	// It was agreed that we wanted to keep --quiet and no stdout output ....leaving stderr only since
	// --quiet does not suppress that anyway reduced the frequency of the hang, but it still occurred.
	// the pipeToLog method has been left for now for historical purposes, but if this implemenetation
	// of git clone holds, we'll want to delete that at some point.

	cloneArgs := append([]string{"clone"}, cloneConfigToArgs(c)...)
	cloneArgs = append(cloneArgs, []string{source, target}...)
	errReader, errWriter, _ := os.Pipe()
	opts := util.CommandOpts{Stderr: errWriter}
	err := h.RunWithOptions(opts, "git", cloneArgs...)
	errWriter.Close()
	if err != nil {
		out, _ := ioutil.ReadAll(errReader)
		// If we captured errors via stderr, print them out.
		if len(out) > 0 {
			glog.Errorf("Clone failed: source %s, target %s,  with output %s", source, target, out)
		}
		return err
	}
	return nil
}
示例#2
0
文件: git.go 项目: php-coder/origin
// CreateLocalGitDirectoryWithSubmodule creates a git directory with a submodule
func CreateLocalGitDirectoryWithSubmodule(t *testing.T) string {
	cr := util.NewCommandRunner()

	submodule := CreateLocalGitDirectory(t)
	defer os.RemoveAll(submodule)

	if util.UsingCygwinGit {
		var err error
		submodule, err = util.ToSlashCygwin(submodule)
		if err != nil {
			t.Fatal(err)
		}
	}

	dir := CreateEmptyLocalGitDirectory(t)
	err := cr.RunWithOptions(util.CommandOpts{Dir: dir}, "git", "submodule", "add", submodule, "submodule")
	if err != nil {
		t.Fatal(err)
	}

	return dir
}
示例#3
0
文件: clone.go 项目: php-coder/origin
// Download downloads the application source code from the Git repository
// and checkout the Ref specified in the config.
func (c *Clone) Download(config *api.Config) (*api.SourceInfo, error) {
	targetSourceDir := filepath.Join(config.WorkingDir, api.Source)
	config.WorkingSourceDir = targetSourceDir

	ok, err := c.ValidCloneSpec(config.Source)
	if err != nil {
		return nil, err
	}
	if !ok {
		glog.Errorf("Clone.Download was passed an invalid source %s", config.Source)
		return nil, fmt.Errorf("invalid source %s", config.Source)
	}

	ref := "HEAD"
	if config.Ref != "" {
		ref = config.Ref
	}

	if strings.HasPrefix(config.Source, "file://") {
		s := strings.TrimPrefix(config.Source, "file://")

		if util.UsingCygwinGit {
			var err error
			s, err = util.ToSlashCygwin(s)
			if err != nil {
				glog.V(0).Infof("error: Cygwin path conversion failed: %v", err)
				return nil, err
			}
		}
		config.Source = "file://" + s
	}

	if len(config.ContextDir) > 0 {
		targetSourceDir = filepath.Join(config.WorkingDir, api.ContextTmp)
		glog.V(1).Infof("Downloading %q (%q) ...", config.Source, config.ContextDir)
	} else {
		glog.V(1).Infof("Downloading %q ...", config.Source)
	}

	if !config.IgnoreSubmodules {
		glog.V(2).Infof("Cloning sources into %q", targetSourceDir)
	} else {
		glog.V(2).Infof("Cloning sources (ignoring submodules) into %q", targetSourceDir)
	}

	cloneConfig := api.CloneConfig{Quiet: true}
	err = c.Clone(config.Source, targetSourceDir, cloneConfig)
	if err != nil {
		glog.V(0).Infof("error: git clone failed: %v", err)
		return nil, err
	}

	err = c.Checkout(targetSourceDir, ref)
	if err != nil {
		return nil, err
	}
	glog.V(1).Infof("Checked out %q", ref)
	if !config.IgnoreSubmodules {
		err = c.SubmoduleUpdate(targetSourceDir, true, true)
		if err != nil {
			return nil, err
		}
		glog.V(1).Infof("Updated submodules for %q", ref)
	}

	// Record Git's knowledge about file permissions
	if runtime.GOOS == "windows" {
		filemodes, err := c.LsTree(filepath.Join(targetSourceDir, config.ContextDir), ref, true)
		if err != nil {
			return nil, err
		}
		for _, filemode := range filemodes {
			c.Chmod(filepath.Join(targetSourceDir, config.ContextDir, filemode.Name()), os.FileMode(filemode.Mode())&os.ModePerm)
		}
	}

	info := c.GetInfo(targetSourceDir)
	if len(config.ContextDir) > 0 {
		originalTargetDir := filepath.Join(config.WorkingDir, api.Source)
		c.RemoveDirectory(originalTargetDir)
		path := filepath.Join(targetSourceDir, config.ContextDir)
		err := c.CopyContents(path, originalTargetDir)
		if err != nil {
			return nil, err
		}
		c.RemoveDirectory(targetSourceDir)
	}

	if len(config.ContextDir) > 0 {
		info.ContextDir = config.ContextDir
	}

	return info, nil
}