summaryrefslogtreecommitdiff
path: root/branches.go
blob: 46ea091698aa8ba9c397b22a5da188963c3c59a8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
package gitpb

import (
	"errors"
	"fmt"
	"os"
	"path/filepath"
	"strings"

	"go.wit.com/log"
)

// returns true if 'git pull' will work
func (repo *Repo) ExistsUserBranchRemote() bool {
	branchname := repo.GetUserBranchName()
	if repo.IsBranchRemote(branchname) {
		return true
	}
	return false
}

// returns true if the user branch exists
func (repo *Repo) ExistsUserBranch() bool {
	if repo.GetUserBranchName() == "" {
		return false
	}
	branchname := repo.GetUserBranchName()
	if repo.Exists(filepath.Join(".git/refs/heads", branchname)) {
		// todo: actually use .git/config
		return true
	}
	return repo.IsBranchRemote(branchname)
}

// returns true if the devel branch exists
func (repo *Repo) ExistsDevelBranch() bool {
	if repo.GetDevelBranchName() == "" {
		return false
	}
	branchname := repo.GetDevelBranchName()
	if repo.Exists(filepath.Join(".git/refs/heads", branchname)) {
		// todo: actually use .git/config
		return true
	}
	return repo.IsBranchRemote(branchname)
}

func (repo *Repo) GetBranchHash(branchname string) string {
	if branchname == "" {
		return ""
	}
	if repo.Exists(filepath.Join(".git/refs/remotes", branchname)) {
		return readRefHash(filepath.Join(repo.FullPath, ".git/refs/remotes", branchname))
	}
	if repo.Exists(filepath.Join(".git/refs/heads", branchname)) {
		return readRefHash(filepath.Join(repo.FullPath, ".git/refs/heads", branchname))
	}
	return ""
}

func (repo *Repo) GetBranchVersion(branchname string) string {
	if branchname == repo.GetUserBranchName() {
		return "user"
	}
	if branchname == repo.GetDevelBranchName() {
		return "devel"
	}
	if branchname == repo.GetMasterBranchName() {
		return "master"
	}
	base, branchname := filepath.Split(branchname)
	if base != "" {
		if branchname == repo.GetUserBranchName() {
			return "remote user"
		}
		if branchname == repo.GetDevelBranchName() {
			return "remote devel"
		}
		if branchname == repo.GetMasterBranchName() {
			return "remote master"
		}
	}
	return ""
}

func readRefHash(filename string) string {
	data, _ := os.ReadFile(filename)
	return string(data)
}

func (repo *Repo) GetLocalBranches() []string {
	return ListFiles(filepath.Join(repo.GetFullPath(), "/.git/refs/heads"))
}

func (repo *Repo) GetRemoteBranches() []string {
	remotes := ListFiles(filepath.Join(repo.GetFullPath(), "/.git/refs/remotes"))
	return remotes
}

// git describe --tags e548b0fb6d0d14cdfb693850d592419f247dc2b1
// v0.22.61-15-gbab84d7
func (repo *Repo) GetHashName(h string) (string, error) {
	h = strings.TrimSpace(h)
	log.Info("GetHashName() is looking for", repo.GetGoPath(), h)
	cmd := []string{"git", "describe", "--tags", h}
	r, err := repo.RunStrict(cmd)
	if err != nil {
		return "", err
	}
	if len(r.Stdout) == 0 {
		return "", errors.New("git describe was empty")
	}
	return r.Stdout[0], nil
}

// lookup a hash from a tag with 'git rev-list'
func (repo *Repo) GetTagHash(t string) string {
	// git rev-list -n 1 v0.0.66
	cmd := []string{"git", "rev-list", "-n", "1", t}
	result, _ := repo.RunStrict(cmd)
	// log.Info("getLastTagVersion()", result.Stdout)

	if len(result.Stdout) == 0 {
		// log.Log(WARN, "no gitpb.LastTag() repo is broken. ignore this.", repo.GetGoPath())
		return ""
	}

	return result.Stdout[0]
}

// deletes the devel local branch if it is a subset of the remote devel branch
func (repo *Repo) DeleteLocalDevelBranch() error {
	branch := repo.GetDevelBranchName()
	remote := filepath.Join("origin", branch)

	if !repo.IsDevelRemote() {
		return fmt.Errorf("no remote branch")
	}
	b1 := repo.CountDiffObjects(branch, remote) // should be zero
	if b1 == 0 {
		cmd := []string{"git", "branch", "-D", repo.GetDevelBranchName()}
		log.Info("DEVEL IS IN REMOTE", repo.GetGoPath(), cmd)
		err := repo.RunVerbose(cmd)
		return err
	} else {
		return fmt.Errorf("local branch has patches not in remote")
	}
}