summaryrefslogtreecommitdiff
path: root/compare.go
blob: 28fb9d171138762e3a5b7dd4287628f677138be4 (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
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
package gitpb

import (
	"strings"

	"go.wit.com/lib/ENV"
	"go.wit.com/lib/config"
	"go.wit.com/log"
)

type RepoTag struct {
	r *Repo
	t *GitTag
}

func (r *Repo) NewCompareTag(refname string) *RepoTag {
	t := r.IfRefExists(refname)
	if t == nil {
		return nil
	}
	rt := new(RepoTag)
	rt.r = r
	rt.t = t
	return rt
}

func (r *Repo) NewCompareRef(t *GitTag) *RepoTag {
	if t == nil {
		return nil
	}
	rt := new(RepoTag)
	rt.r = r
	rt.t = t
	return rt
}

func (rt *RepoTag) GetRefname() string {
	return rt.t.Refname
}

func (rt *RepoTag) GetRef() *GitTag {
	return rt.t
}

func (t1 *RepoTag) CompareBranch(t2 *RepoTag) ([]string, []string, []string, []string, error) {
	lines1, cmd1, err1 := t1.r.CountDiffObjectsNEWNEW(t1.t.Refname, t2.t.Refname)
	// log.Info("lessthan", t1.t.Refname, t2.t.Refname, count, t1.r.FullPath)
	if err1 != nil {
		// log.Info("lessthan", t1.t.Refname, t2.t.Refname, count, t1.r.FullPath, err)
		return nil, nil, cmd1, nil, err1
	}
	lines2, cmd2, err2 := t1.r.CountDiffObjectsNEWNEW(t2.t.Refname, t1.t.Refname)
	// log.Info("lessthan", t1.t.Refname, t2.t.Refname, count, t1.r.FullPath)
	if err2 != nil {
		// log.Info("lessthan", t1.t.Refname, t2.t.Refname, count, t1.r.FullPath, err)
		return nil, nil, cmd1, cmd2, err2
	}
	if (len(lines1) != 0) || (len(lines2) != 0) {
		return lines1, lines2, cmd1, cmd2, nil
	}
	return lines1, lines2, cmd1, cmd2, nil
}

func (r *Repo) CompareHashes(keepHash string, deleteHash string) ([]string, []string, []string, []string, error) {
	lines1, cmd1, err1 := r.CountDiffObjectsNEWNEW(keepHash, deleteHash)
	// log.Info("lessthan", t1.t.Refname, t2.t.Refname, count, t1.r.FullPath)
	if err1 != nil {
		// log.Info("lessthan", t1.t.Refname, t2.t.Refname, count, t1.r.FullPath, err)
		return nil, nil, cmd1, nil, err1
	}
	lines2, cmd2, err2 := r.CountDiffObjectsNEWNEW(deleteHash, keepHash)
	// log.Info("lessthan", t1.t.Refname, t2.t.Refname, count, t1.r.FullPath)
	if err2 != nil {
		// log.Info("lessthan", t1.t.Refname, t2.t.Refname, count, t1.r.FullPath, err)
		return nil, nil, cmd1, cmd2, err2
	}
	if (len(lines1) != 0) || (len(lines2) != 0) {
		return lines1, lines2, cmd1, cmd2, nil
	}
	return lines1, lines2, cmd1, cmd2, nil
}

/*
func (t1 *RepoTag) LessThanVerbose(t2 *RepoTag) []string {
	count, err := t1.r.CountDiffObjectsNew(t1.t.Refname, t2.t.Refname)
	log.Info("lessthan", t1.t.Refname, t2.t.Refname, len(count), t1.r.FullPath)
	if err != nil {
		log.Info("lessthan", t1.t.Refname, t2.t.Refname, len(count), t1.r.FullPath, err)
		return nil
	}
	if len(count) == 0 {
		return nil
	}
	return count
}

func (t1 *RepoTag) Equal(t2 *RepoTag) bool {
	return false
}
*/

// if t1 is user branch, and t2 is devel branch, true if 0
func (t1 *RepoTag) GreaterThan(t2 *RepoTag) []string {
	lines, _, err := t1.r.CountDiffObjectsNEWNEW(t2.t.Refname, t1.t.Refname)
	// log.Info("greaterthan", t1.t.Refname, t2.t.Refname, count, t1.r.FullPath, err)
	if err != nil {
		return nil
	}
	if len(lines) == 0 {
		return lines
	}
	return nil
}

func (r *Repo) GetLocalUserRef() *GitTag {
	return r.IsBranchLocal(r.GetUserBranchName())
}

func (r *Repo) GetLocalDevelRef() *GitTag {
	return r.IsBranchLocal(r.GetDevelBranchName())
}

func (r *Repo) GetLocalMasterRef() *GitTag {
	return r.IsBranchLocal(r.GetMasterBranchName())
}

// It's safe to remove a tag if the deleteHash is completely contained in the keepHash
// This determines the git PatchId's for each hash and finds out if they are there
// brute force so it can be slow, but it worth it because it works (todo: detect rare duplicate patchId's)
func (repo *Repo) SafeDelete(deleteHash string, keepHash string) error {
	// compare the branches
	hashok, hashbad, cmd1, cmd2, err := repo.CompareHashes(keepHash, deleteHash)

	if err != nil {
		// things are really really messed up. might be 'branchless' at this point (?)
		log.Printf("%-13.13s %-55.55s err='%v' %s %v\n", "CMD ERR", repo.FullPath, err, "NOT SAFE TO DELETE. Reload()?", cmd1)
		log.Printf("%-13.13s %-55.55s err='%v' %s %v\n", "CMD ERR", repo.FullPath, err, "NOT SAFE TO DELETE. Reload()?", cmd2)
		return err
	}

	// things only in the master branch (safe to ignore)
	for _, line := range hashok {
		log.Info("OK", repo.Namespace, "in keepHash", cmd1, line)
	}

	// things still only in the local branch (bad to delete)
	for _, line := range hashbad {
		// notes.addTextNote("BAD", repo, localRef.GetRef(), cmd2, line)
		log.Info("BAD", repo.Namespace, "in deleteHash", cmd2, line)
		parts := strings.Split(line, "%00") // git log doesn't actually convert %00 to NULL
		if len(parts) != 4 {
			log.Info("len", len(parts))
			panic("nope")
		}
		findThisHash := parts[0]
		log.Info(findThisHash, deleteHash, "need to figure out the patchID for this to be deleted hash")
	}

	if len(hashbad) == 0 {
		// todo: force checkout to local master branch
		// before doing this
		cmd := []string{"git", "update-ref", "-d", deleteHash}
		log.Printf("%-13.13s %-55.55s %v %s\n", "CMD OK", repo.FullPath, cmd1, "")
		log.Printf("%-13.13s %-55.55s %v %s\n", "CMD OK", repo.FullPath, cmd2, "")
		log.Printf("%-13.13s %-55.55s %v %s\n", "SAFE TO DELETE", repo.FullPath, cmd, "add --fix")
		if ENV.Get("Fix") == "true" {
			err := repo.RunVerbose(cmd)
			if err != nil {
				log.Info(deleteHash, repo.FullPath)
				s := "local user branch could not be deleted"
				config.BadExit(s, err)
			}
		}
		return config.ErrdKeyFalse("Fix")
	}

	return log.Errorf("NOT SAFE")
}