Example #1
0
func (repo *cliReader) RootCommit() (rootCommit string, err error) {
	cmd := exec.Command("git", "rev-list", "--max-parents=0", "HEAD")
	cmd.Dir = repo.repoPath
	output, err := cmd.Output()
	if bytes.Count(output, []byte{'\n'}) > 1 {
		log.Critical("More than one root commit present")
	}
	rootCommit = string(bytes.TrimSpace(output))
	return
}
Example #2
0
// Branches reads all branches in a git repo
func (repo *cliReader) Branches() (branches []*GitChange, err error) {
	cmd := exec.Command("git", "branch", "-v", "--abbrev=40")
	cmd.Dir = repo.repoPath
	out, err := cmd.CombinedOutput()
	if err != nil {
		return nil, err
	}
	rootCommit, err := repo.RootCommit()
	if err != nil {
		log.Critical("Unable to get root commit")
	}
	for _, m := range branchLineRE.FindAllStringSubmatch(string(out), -1) {
		branches = append(branches, &GitChange{
			RefName:    m[2],
			Current:    m[3],
			CheckedOut: m[1] == "*",
			RootCommit: rootCommit,
			RepoName:   repo.Name(),
		})
	}

	return
}
Example #3
0
// NetIO shares GitChanges on toNet with the network via a multicast group. It
// will pass on GitChanges from the network via fromNet. It uniques the daemon
// instance by changing the .Name member to be name@<host IP>/<original .Name)
func NetIO(l log.Logger, repo Repo, addr *net.UDPAddr, fromNet, toNet chan GitChange) {
	var (
		err                error
		recvConn, sendConn *net.UDPConn // UDP connections to allow us to send and	receive change updates
	)

	l.Info("Joining %v multicast(%t) group", addr, addr.IP.IsMulticast())
	if recvConn, sendConn, err = establishConnPair(addr); err != nil {
		l.Critical("Error joining listening: %s\n", addr, err)
		return
	}

	l.Info("Successfully joined %v multicast(%t) group", addr, addr.IP.IsMulticast())
	defer recvConn.Close()
	defer sendConn.Close()
	hostIp := sendConn.LocalAddr().(*net.UDPAddr).IP.String()

	term := false
	defer func() { term = true }()
	rawFromNet := make(chan []byte, 128)
	go func() {
		for !term {
			b := make([]byte, 1024)

			if n, err := recvConn.Read(b); err != nil {
				l.Critical("Cannot read socket: %s", err)
				continue
			} else {
				rawFromNet <- b[:n]
			}
		}
	}()

	for {
		select {
		case req, ok := <-toNet:
			if !ok {
				return
			}

			req.User = repo.User()
			req.HostIp = hostIp

			l.Info("Sending %+v", req)
			buf := &bytes.Buffer{}
			enc := gob.NewEncoder(buf)

			if err := enc.Encode(req); err != nil {
				l.Critical("%s", err)
				continue
			}

			l.Fine("Sending %+v", buf.Bytes())
			if _, err := sendConn.Write(buf.Bytes()); err != nil {
				l.Critical("%s", err)
				continue
			}

		case resp := <-rawFromNet:
			var change GitChange
			dec := gob.NewDecoder(bytes.NewReader(resp))

			if err := dec.Decode(&change); err != nil {
				l.Critical("%s", err)
				continue
			} else {
				l.Debug("received %+v", change)
			}

			if rootCommit, err := repo.RootCommit(); err != nil {
				log.Critical("Error getting root commit")
			} else {
				if (repo.User() != change.User) && (rootCommit == change.RootCommit) {
					fromNet <- change
				}
			}
		}
	}
}