git-maintain 0.6.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG +14 -0
- data/README.md +52 -5
- data/bin/git-maintain +1 -1
- data/lib/addons/RDMACore.rb +64 -11
- data/lib/branch.rb +58 -19
- data/lib/common.rb +22 -10
- data/lib/repo.rb +110 -14
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 417458e3750d9bcd3c32ec5ee53927fbfea2cd699673f72d50ec31a9cc1bb432
|
4
|
+
data.tar.gz: f95702ebdc24c0978b29627cfde6742fcf9ffe817d26609e895c12001cdc194c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7682468b42e62b9513ae9227bef2af4e1e01e9078a1c46648382efaa895f2152e5bbe18488e1c2e45b0fad524be09d77e953bfb48f6f49e2a34cd72e2590d0f4
|
7
|
+
data.tar.gz: 954f1f014760fa1c02b1ebead5f093115da8dada78bfea1d041d527a41d37727aad9ba06f0d94e4d926c2fb725da4dc2c61cd4b5cbafe2093c8510d2d54e820a
|
data/CHANGELOG
CHANGED
@@ -1,3 +1,17 @@
|
|
1
|
+
------------------
|
2
|
+
0.7.0 (2019-05-29)
|
3
|
+
------------------
|
4
|
+
|
5
|
+
* Add summary command
|
6
|
+
* push and push_stable now push all the selected branch at once
|
7
|
+
* Add maintain.autofetch setting in gitconfig to enable/disable autofetch
|
8
|
+
* Support 'errored' status in travis
|
9
|
+
* Fix 'steal' command for commits containing double quotes
|
10
|
+
* Fixes for rdma-core release procedure
|
11
|
+
* Support send-email for release annoucenement
|
12
|
+
* Fix support for interactive editor (ie vim)
|
13
|
+
* Support repo specific action options
|
14
|
+
|
1
15
|
------------------
|
2
16
|
0.6.0 (2019-03-21)
|
3
17
|
------------------
|
data/README.md
CHANGED
@@ -30,10 +30,10 @@ The idea is to script most of the maintenance tasks so the maintainer can focus
|
|
30
30
|
- Load git-maintain-completion.sh for shell completion
|
31
31
|
|
32
32
|
## Remote setup
|
33
|
-
- the 'github' remote should be your own WIP github to test out branches before submitting to the official repo.
|
33
|
+
- the 'github' remote should be your own WIP github to test out branches before submitting to the official repo.
|
34
34
|
Also know as the 'Validation' repo. It can be switched to another remote by setting maintain.valid-repo=xxx in your gitconfig
|
35
35
|
- the 'origin' remote should be the official repo in read-only mode to avoid any accidental pushes
|
36
|
-
- the 'stable' remote should be the official repo in RW mode
|
36
|
+
- the 'stable' remote should be the official repo in RW mode.
|
37
37
|
Also know as the 'Stable' repo. It can be switched to another remote by setting maintain.stable-repo=xxx in your gitconfig
|
38
38
|
|
39
39
|
## Stealing commits
|
@@ -41,10 +41,10 @@ The idea is to script most of the maintenance tasks so the maintainer can focus
|
|
41
41
|
The steal feature uses was shamelessly copied it from https://git.kernel.org/pub/scm/linux/kernel/git/sashal/stable-tools.git/tree/
|
42
42
|
|
43
43
|
## Making releases
|
44
|
-
The release process being very specific to each project, the release command does nothing by default.
|
44
|
+
The release process being very specific to each project, the release command does nothing by default.
|
45
45
|
However the behaviour can be overriden for specific repo (detected by repo name)
|
46
46
|
|
47
|
-
Check the lib/addons/RDMACore.rb for an example.
|
47
|
+
Check the lib/addons/RDMACore.rb for an example.
|
48
48
|
In this case, the release command bump the version in all the appropriate files (after computing the previous and next version numbers), commit and tags the commit.
|
49
49
|
|
50
50
|
|
@@ -119,9 +119,36 @@ v\1
|
|
119
119
|
|
120
120
|
Note that this value can be overriden by the stable-base.XXX value if needed
|
121
121
|
|
122
|
+
To verify your setup, you can run 'git maintain summary' which will show you your configured values and the matching local and upstrema branches that git-maintain sees
|
123
|
+
```
|
124
|
+
$ git maintain summary
|
125
|
+
# INFO: Configuration summary:
|
126
|
+
# INFO: Stable remote: stable
|
127
|
+
# INFO: Validation remote: github
|
128
|
+
# INFO:
|
129
|
+
# INFO: Branch config:
|
130
|
+
# INFO: Local branch format: /dev\/stable-v([0-9]*)/
|
131
|
+
# INFO: Remote stable branch format: stable-v\1
|
132
|
+
# INFO: Remote stable base format: v\1
|
133
|
+
# INFO:
|
134
|
+
# INFO: Local branches:
|
135
|
+
# INFO: dev/stable-v15/master -> stable/stable-v15
|
136
|
+
# INFO: dev/stable-v16/master -> stable/stable-v16
|
137
|
+
# INFO: dev/stable-v17/master -> stable/stable-v17
|
138
|
+
# INFO: dev/stable-v18/master -> stable/stable-v18
|
139
|
+
# INFO: dev/stable-v19/master -> stable/stable-v19
|
140
|
+
# INFO: dev/stable-v20/master -> stable/stable-v20
|
141
|
+
# INFO: dev/stable-v21/master -> stable/stable-v21
|
142
|
+
# INFO: dev/stable-v22/master -> stable/stable-v22
|
143
|
+
# INFO:
|
144
|
+
# INFO: Upstream branches:
|
145
|
+
# INFO: <MISSING> -> stable/stable-v23
|
146
|
+
```
|
147
|
+
|
122
148
|
Also, once you set these parameters, you can have git-maintain create all branches for you by running
|
123
|
-
|
149
|
+
```
|
124
150
|
$ git maintain create
|
151
|
+
# INFO: Creating missing dev/stable-v23/master from stable/stable-v23
|
125
152
|
```
|
126
153
|
## Day-to-day workflow
|
127
154
|
|
@@ -227,3 +254,23 @@ Review your email, send it and your day is over !
|
|
227
254
|
|
228
255
|
Enjoy, and feel free to report bugs, missing features and/or send patches
|
229
256
|
|
257
|
+
## Git config settings
|
258
|
+
|
259
|
+
This is a summary of all the settings that can be set in the git config:
|
260
|
+
|
261
|
+
- `maintain.autofetch`: Enable/Disable auto fetching.
|
262
|
+
Can be overriden by the --[no-]fetch option on the CLI.
|
263
|
+
If unset, autofetch is enabled
|
264
|
+
- `maintain.branch-format`: Local branch name space that also extracts the version.
|
265
|
+
Example: dev\/stable-v([0-9]*) will allow all branch names dev/stable-vXXX/foo to be used against stable branch with version XXX
|
266
|
+
- `maintain.stable-branch-format`: Name of the stable branch generated with the version extracted by the `maintain.branch-format` regexp.
|
267
|
+
Example: stable-v\1 will track dev/stable-vXXX/foo against <STABLE_REPO>/stable-vXXX
|
268
|
+
- `maintain.stable-base-format`: Name of the tag from which the stable branch was forked from generated with the version extracted by the `maintain.branch-format` regexp.
|
269
|
+
Example: v\1 will be mark vXXX has the fork tag for branch <STABLE_REPO>/stable-vXXX and local branch dev/stable-vXXX/foo
|
270
|
+
This settings is only needed when using `git maintain steal` command
|
271
|
+
This rule can be overriden by a specific entry in gitconfig:
|
272
|
+
`stable-base.dev---stable-vXXX vYY-ZZ`
|
273
|
+
As git does not allow `/` in gitconfig they are to be replaced by `---`
|
274
|
+
- `maintain.mail-format`: Specify how release annoucement emails are sent. Can be:
|
275
|
+
- `imap_send`: Store prepared email in an IMAP folder. See `main git-imap-send` for more infos. This is the default value.
|
276
|
+
- `send_email`: Generates a file which is compatible with git send-email
|
data/bin/git-maintain
CHANGED
@@ -20,7 +20,7 @@ actionParser.separator ""
|
|
20
20
|
actionParser.separator "Options:"
|
21
21
|
actionParser.on("-h", "--help", "Display usage.") { |val| puts actionParser.to_s; exit 0 }
|
22
22
|
actionParser.separator "Possible actions:"
|
23
|
-
GitMaintain::getActionAttr("ACTION_HELP").each(){|x|
|
23
|
+
GitMaintain::getActionAttr("ACTION_HELP").sort.each(){|x|
|
24
24
|
actionParser.separator "\t " + x
|
25
25
|
}
|
26
26
|
rest = actionParser.order!(ARGV);
|
data/lib/addons/RDMACore.rb
CHANGED
@@ -2,14 +2,49 @@ module GitMaintain
|
|
2
2
|
class RDMACoreBranch < Branch
|
3
3
|
REPO_NAME = "rdma-core"
|
4
4
|
|
5
|
+
def self.set_opts(action, optsParser, opts)
|
6
|
+
opts[:rel_type] = nil
|
7
|
+
|
8
|
+
case action
|
9
|
+
when :release
|
10
|
+
optsParser.on("--major", "Release a major version.") {
|
11
|
+
opts[:rel_type] = :major }
|
12
|
+
optsParser.on("--stable", "Release a stable version.") {
|
13
|
+
opts[:rel_type] = :stable }
|
14
|
+
end
|
15
|
+
end
|
16
|
+
def self.check_opts(opts)
|
17
|
+
if opts[:action] == :release then
|
18
|
+
if opts[:rel_type] == nil then
|
19
|
+
raise "No release type specified use --stable or --major"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
5
23
|
def release(opts)
|
6
24
|
prev_ver=@repo.runGit("show HEAD:CMakeLists.txt | egrep \"[sS][eE][tT]\\\\(PACKAGE_VERSION\"").
|
7
25
|
chomp().gsub(/[sS][eE][tT]\(PACKAGE_VERSION\s*"([0-9.]*)".*$/, '\1')
|
8
26
|
ver_nums = prev_ver.split(".")
|
9
27
|
new_ver = (ver_nums[0 .. -2] + [ver_nums[-1].to_i() + 1 ]).join(".")
|
10
|
-
|
28
|
+
rel_ver = new_ver
|
29
|
+
commit_msg = "Bump to version"
|
11
30
|
|
12
|
-
|
31
|
+
if opts[:rel_type] == :major
|
32
|
+
new_ver = ([ ver_nums[0].to_i() + 1] + ver_nums[1 .. -1]).join(".")
|
33
|
+
rel_ver = prev_ver
|
34
|
+
prev_ver = ([ ver_nums[0].to_i() - 1] + ver_nums[1 .. -1]).join(".")
|
35
|
+
ver_nums = prev_ver.split(".")
|
36
|
+
commit_msg ="Update library version to be"
|
37
|
+
end
|
38
|
+
|
39
|
+
git_prev_ver = "v" + prev_ver
|
40
|
+
# Older tags might do have the terminal minor version (.0) for major releases
|
41
|
+
@repo.runGit("rev-parse --verify --quiet #{git_prev_ver}")
|
42
|
+
if $? != 0 then
|
43
|
+
# Try without the minor version number
|
44
|
+
git_prev_ver = "v" + ver_nums[0 .. -2].join(".")
|
45
|
+
end
|
46
|
+
|
47
|
+
puts "Preparing #{opts[:rel_type].to_s} release #{prev_ver} => #{rel_ver}"
|
13
48
|
rep = GitMaintain::checkLog(opts, @local_branch, git_prev_ver, "release")
|
14
49
|
if rep != "y" then
|
15
50
|
puts "Skipping release"
|
@@ -20,18 +55,30 @@ module GitMaintain
|
|
20
55
|
tag_path=`mktemp`.chomp()
|
21
56
|
puts tag_path
|
22
57
|
tag_file = File.open(tag_path, "w+")
|
23
|
-
tag_file.puts "rdma-core-#{
|
58
|
+
tag_file.puts "rdma-core-#{rel_ver}:"
|
24
59
|
tag_file.puts ""
|
25
60
|
tag_file.puts "Updates from version #{prev_ver}"
|
26
|
-
|
27
|
-
|
61
|
+
if opts[:rel_type] == :stable then
|
62
|
+
tag_file.puts " * Backport fixes:"
|
63
|
+
end
|
64
|
+
tag_file.puts `git log HEAD ^#{git_prev_ver} --no-merges --format=' * %s'`
|
28
65
|
tag_file.close()
|
29
66
|
|
67
|
+
if opts[:rel_type] == :major
|
68
|
+
# For major, tag the current version first
|
69
|
+
@repo.runGitInteractive("tag -a -s v#{rel_ver} --edit -F #{tag_path}")
|
70
|
+
if $? != 0 then
|
71
|
+
raise("Failed to tag branch #{local_branch}")
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
30
75
|
# Update version number in relevant files
|
31
|
-
@repo.run("sed -i -e 's/\\(Version:[[:space:]]*\\)[0-9.]
|
76
|
+
@repo.run("sed -i -e 's/\\(Version:[[:space:]]*\\)[0-9.]\\+/\\1#{new_ver}/g' redhat/rdma-core.spec suse/rdma-core.spec")
|
32
77
|
@repo.run("sed -i -e 's/\\([sS][eE][tT](PACKAGE_VERSION[[:space:]]*\"\\)[0-9.]*\"/\\1#{new_ver}\"/g' CMakeLists.txt")
|
33
78
|
|
34
|
-
|
79
|
+
case opts[:rel_type]
|
80
|
+
when :stable
|
81
|
+
@repo.run("cat <<EOF > debian/changelog.new
|
35
82
|
rdma-core (#{new_ver}-1) unstable; urgency=low
|
36
83
|
|
37
84
|
* New upstream release.
|
@@ -41,16 +88,22 @@ rdma-core (#{new_ver}-1) unstable; urgency=low
|
|
41
88
|
$(cat debian/changelog)
|
42
89
|
EOF
|
43
90
|
mv debian/changelog.new debian/changelog")
|
91
|
+
when :major
|
92
|
+
@repo.run("sed -i -e 's/^rdma-core (#{rel_ver}-1)/rdma-core (#{new_ver}-1)/' debian/changelog")
|
93
|
+
end
|
44
94
|
|
45
95
|
# Add and commit
|
46
96
|
@repo.runGit("add redhat/rdma-core.spec suse/rdma-core.spec CMakeLists.txt debian/changelog")
|
47
|
-
@repo.
|
97
|
+
@repo.runGitInteractive("commit -m '#{commit_msg} #{new_ver}' --verbose --edit --signoff")
|
48
98
|
if $? != 0 then
|
49
99
|
raise("Failed to commit on branch #{local_branch}")
|
50
100
|
end
|
51
|
-
|
52
|
-
if
|
53
|
-
|
101
|
+
|
102
|
+
if opts[:rel_type] == :stable
|
103
|
+
@repo.runGitInteractive("tag -a -s v#{rel_ver} --edit -F #{tag_path}")
|
104
|
+
if $? != 0 then
|
105
|
+
raise("Failed to tag branch #{local_branch}")
|
106
|
+
end
|
54
107
|
end
|
55
108
|
`rm -f #{tag_path}`
|
56
109
|
end
|
data/lib/branch.rb
CHANGED
@@ -54,7 +54,7 @@ module GitMaintain
|
|
54
54
|
opts[:no_travis] = false
|
55
55
|
opts[:all] = false
|
56
56
|
opts[:check_only] = false
|
57
|
-
opts[:
|
57
|
+
opts[:fetch] = nil
|
58
58
|
opts[:watch] = false
|
59
59
|
|
60
60
|
optsParser.on("-v", "--base-version [MIN_VER]", Integer, "Older release to consider.") {
|
@@ -70,8 +70,8 @@ module GitMaintain
|
|
70
70
|
end
|
71
71
|
|
72
72
|
if NO_FETCH_ACTIONS.index(action) == nil
|
73
|
-
optsParser.on("--no-fetch", "
|
74
|
-
|val| opts[:
|
73
|
+
optsParser.on("--[no-]fetch", "Enable/Disable fetch of stable repo.") {
|
74
|
+
|val| opts[:fetch] = val}
|
75
75
|
end
|
76
76
|
|
77
77
|
case action
|
@@ -122,9 +122,13 @@ module GitMaintain
|
|
122
122
|
def self.execAction(opts, action)
|
123
123
|
repo = Repo::load()
|
124
124
|
travis = TravisChecker::load(repo)
|
125
|
+
opts[:repo] = repo
|
126
|
+
opts[:travis] = travis
|
127
|
+
brClass = GitMaintain::getClass(self, repo.name)
|
125
128
|
|
126
|
-
if NO_FETCH_ACTIONS.index(action) == nil && opts[:
|
127
|
-
repo
|
129
|
+
if NO_FETCH_ACTIONS.index(action) == nil && opts[:fetch] != false then
|
130
|
+
GitMaintain::log(:INFO, "Fetching stable repo")
|
131
|
+
repo.stableUpdate(opts[:fetch])
|
128
132
|
end
|
129
133
|
|
130
134
|
branchList=[]
|
@@ -154,13 +158,24 @@ module GitMaintain
|
|
154
158
|
|
155
159
|
loop do
|
156
160
|
system("clear; date") if opts[:watch] != false
|
161
|
+
|
162
|
+
res=[]
|
163
|
+
|
164
|
+
# Iterate concerned on all branches
|
157
165
|
branchList.each(){|branch|
|
158
166
|
if NO_CHECKOUT_ACTIONS.index(action) == nil then
|
159
167
|
GitMaintain::log(:INFO, "Working on #{branch.verbose_name}")
|
160
168
|
branch.checkout()
|
161
169
|
end
|
162
|
-
branch.send(action, opts)
|
170
|
+
res << branch.send(action, opts)
|
163
171
|
}
|
172
|
+
|
173
|
+
# Run epilogue (if it exists)
|
174
|
+
begin
|
175
|
+
brClass.send(action.to_s() + "_epilogue", opts, res)
|
176
|
+
rescue NoMethodError => e
|
177
|
+
end
|
178
|
+
|
164
179
|
break if opts[:watch] == false
|
165
180
|
sleep(opts[:watch])
|
166
181
|
travis.emptyCache()
|
@@ -189,10 +204,15 @@ module GitMaintain
|
|
189
204
|
@head = @repo.runGit("rev-parse --verify --quiet #{@local_branch}")
|
190
205
|
@remote_ref = "#{@repo.stable_repo}/#{@remote_branch}"
|
191
206
|
@stable_head = @repo.runGit("rev-parse --verify --quiet #{@remote_ref}")
|
192
|
-
|
207
|
+
case @branch_type
|
208
|
+
when :std
|
209
|
+
@stable_base = @repo.findStableBase(@local_branch)
|
210
|
+
when :user_specified
|
211
|
+
@stable_base = @remote_ref
|
212
|
+
end
|
193
213
|
end
|
194
214
|
attr_reader :version, :local_branch, :head, :remote_branch, :remote_ref, :stable_head,
|
195
|
-
:verbose_name, :exists
|
215
|
+
:verbose_name, :exists, :stable_base
|
196
216
|
|
197
217
|
def log(lvl, str)
|
198
218
|
GitMaintain::log(lvl, str)
|
@@ -222,7 +242,7 @@ module GitMaintain
|
|
222
242
|
opts[:commits].each(){|commit|
|
223
243
|
prev_head=@repo.runGit("rev-parse HEAD")
|
224
244
|
log(:INFO, "Applying #{@repo.getCommitHeadline(commit)}")
|
225
|
-
@repo.
|
245
|
+
@repo.runGitInteractive("cherry-pick #{commit}")
|
226
246
|
if $? != 0 then
|
227
247
|
log(:WARNING, "Cherry pick failure. Starting bash for manual fixes. Exit shell to continue")
|
228
248
|
@repo.runBash()
|
@@ -295,7 +315,7 @@ module GitMaintain
|
|
295
315
|
|
296
316
|
rep = GitMaintain::checkLog(opts, merge_branch, @local_branch, "merge")
|
297
317
|
if rep == "y" then
|
298
|
-
@repo.
|
318
|
+
@repo.runGitInteractive("merge #{merge_branch}")
|
299
319
|
if $? != 0 then
|
300
320
|
log(:WARNING, "Merge failure. Starting bash for manual fixes. Exit shell to continue")
|
301
321
|
@repo.runBash()
|
@@ -312,8 +332,17 @@ module GitMaintain
|
|
312
332
|
log(:INFO, "Nothing to push")
|
313
333
|
return
|
314
334
|
end
|
335
|
+
return "#{@local_branch}:#{@local_branch}"
|
336
|
+
end
|
337
|
+
|
338
|
+
def self.push_epilogue(opts, branches)
|
339
|
+
# Compact to remove empty entries
|
340
|
+
branches.compact!()
|
341
|
+
|
342
|
+
return if branches.length == 0
|
315
343
|
|
316
|
-
|
344
|
+
opts[:repo].runGit("push #{opts[:push_force] == true ? "-f" : ""} "+
|
345
|
+
"#{opts[:repo].valid_repo} #{branches.join(" ")}")
|
317
346
|
end
|
318
347
|
|
319
348
|
# Monitor the build status on Travis
|
@@ -325,7 +354,7 @@ module GitMaintain
|
|
325
354
|
suff= " started at #{@travis.getValidTS(head)}"
|
326
355
|
end
|
327
356
|
log(:INFO, "Status for v#{@version}: " + st + suff)
|
328
|
-
if st == "failed" && opts[:watch] == false
|
357
|
+
if (st == "failed" || st == "errored") && opts[:watch] == false
|
329
358
|
rep = "y"
|
330
359
|
suff=""
|
331
360
|
while rep == "y"
|
@@ -364,13 +393,21 @@ module GitMaintain
|
|
364
393
|
|
365
394
|
rep = GitMaintain::checkLog(opts, @local_branch, @remote_ref, "submit")
|
366
395
|
if rep == "y" then
|
367
|
-
|
396
|
+
return "#{@local_branch}:#{@remote_branch}"
|
368
397
|
else
|
369
398
|
log(:INFO, "Skipping push to stable")
|
370
399
|
return
|
371
400
|
end
|
372
401
|
end
|
373
402
|
|
403
|
+
|
404
|
+
def self.push_stable_epilogue(opts, branches)
|
405
|
+
# Compact to remove empty entries
|
406
|
+
branches.compact!()
|
407
|
+
|
408
|
+
return if branches.length == 0
|
409
|
+
opts[:repo].runGit("push #{opts[:repo].stable_repo} #{branches.join(" ")}")
|
410
|
+
end
|
374
411
|
# Monitor the build status of the stable branch on Travis
|
375
412
|
def monitor_stable(opts)
|
376
413
|
st = @travis.getStableState(@stable_head)
|
@@ -458,13 +495,13 @@ module GitMaintain
|
|
458
495
|
|
459
496
|
# Grab the subject, since commit sha1 is different between branches we
|
460
497
|
# have to look it up based on subject.
|
461
|
-
subj=@repo.
|
498
|
+
subj=@repo.getCommitSubj(commit)
|
462
499
|
if $? != 0 then
|
463
500
|
return false
|
464
501
|
end
|
465
502
|
|
466
503
|
# Try and find if there's a commit with given subject the hard way
|
467
|
-
@repo.runGit("log --pretty=\"%H\" -F --grep \"#{subj}\" "+
|
504
|
+
@repo.runGit("log --pretty=\"%H\" -F --grep \"#{subj.gsub("\"", '\\"')}\" "+
|
468
505
|
"#{@stable_base}..HEAD").split("\n").each(){|cmt|
|
469
506
|
cursubj=@repo.runGit("log -1 --format=\"%s\" #{cmt}")
|
470
507
|
if cursubj = subj then
|
@@ -512,7 +549,7 @@ module GitMaintain
|
|
512
549
|
end
|
513
550
|
|
514
551
|
def pick_one(commit)
|
515
|
-
@repo.
|
552
|
+
@repo.runGitInteractive("cherry-pick --strategy=recursive -Xpatience -x #{commit} &> /dev/null")
|
516
553
|
return if $? == 0
|
517
554
|
if @repo.runGit("status -uno --porcelain | wc -l") == "0" then
|
518
555
|
@repo.runGit("reset --hard")
|
@@ -522,7 +559,7 @@ module GitMaintain
|
|
522
559
|
# That didn't work? Let's try that with every variation of the commit
|
523
560
|
# in other stable trees.
|
524
561
|
@repo.find_alts(commit).each(){|alt_commit|
|
525
|
-
@repo.
|
562
|
+
@repo.runGitInteractive("cherry-pick --strategy=recursive -Xpatience -x #{alt_commit} &> /dev/null")
|
526
563
|
if $? == 0 then
|
527
564
|
return
|
528
565
|
end
|
@@ -530,7 +567,7 @@ module GitMaintain
|
|
530
567
|
}
|
531
568
|
# Still no? Let's go back to the original commit and hand it off to
|
532
569
|
# the user.
|
533
|
-
@repo.
|
570
|
+
@repo.runGitInteractive("cherry-pick --strategy=recursive -Xpatience -x #{commit} &> /dev/null")
|
534
571
|
raise CherryPickErrorException.new("Failed to cherry pick commit #{commit}", commit)
|
535
572
|
return false
|
536
573
|
end
|
@@ -571,7 +608,7 @@ module GitMaintain
|
|
571
608
|
end
|
572
609
|
|
573
610
|
def steal_one(opts, commit)
|
574
|
-
subj=@repo.
|
611
|
+
subj=@repo.getCommitSubj(commit)
|
575
612
|
subj.gsub!(/"/, '\"')
|
576
613
|
msg=''
|
577
614
|
|
@@ -585,8 +622,10 @@ module GitMaintain
|
|
585
622
|
return true
|
586
623
|
end
|
587
624
|
|
625
|
+
log(:VERBOSE, "Found relevant commit #{@repo.getCommitHeadline(commit)}")
|
588
626
|
if is_in_tree?(orig_cmt) == true
|
589
627
|
# Commit is already in the stable branch, skip
|
628
|
+
log(:VERBOSE, "Commit is already in tree")
|
590
629
|
return true
|
591
630
|
end
|
592
631
|
|
data/lib/common.rb
CHANGED
@@ -59,21 +59,21 @@ module GitMaintain
|
|
59
59
|
end
|
60
60
|
module_function :registerCustom
|
61
61
|
|
62
|
-
def
|
63
|
-
return @@custom_classes[repo_name]
|
64
|
-
end
|
65
|
-
module_function :getCustom
|
66
|
-
|
67
|
-
def loadClass(default_class, repo_name, *more)
|
62
|
+
def getClass(default_class, repo_name = File.basename(Dir.pwd()))
|
68
63
|
custom = @@custom_classes[repo_name]
|
69
64
|
if custom != nil && custom[default_class] != nil then
|
70
65
|
log(:DEBUG,"Detected custom #{default_class} class for repo '#{repo_name}'")
|
71
|
-
return custom[default_class]
|
66
|
+
return custom[default_class]
|
72
67
|
else
|
73
68
|
log(:DEBUG,"Detected NO custom #{default_class} classes for repo '#{repo_name}'")
|
74
|
-
return default_class
|
69
|
+
return default_class
|
75
70
|
end
|
76
71
|
end
|
72
|
+
module_function :getClass
|
73
|
+
|
74
|
+
def loadClass(default_class, repo_name, *more)
|
75
|
+
return GitMaintain::getClass(default_class, repo_name).new(*more)
|
76
|
+
end
|
77
77
|
module_function :loadClass
|
78
78
|
|
79
79
|
# Check that the constructor was called through loadClass
|
@@ -97,8 +97,14 @@ module GitMaintain
|
|
97
97
|
def setOpts(action, optsParser, opts)
|
98
98
|
ACTION_CLASS.each(){|x|
|
99
99
|
next if x::ACTION_LIST.index(action) == nil
|
100
|
-
|
101
|
-
|
100
|
+
if x.singleton_methods().index(:set_opts) != nil then
|
101
|
+
x.set_opts(action, optsParser, opts)
|
102
|
+
end
|
103
|
+
# Try to add repo specific opts
|
104
|
+
y = getClass(x)
|
105
|
+
if x != y && y.singleton_methods().index(:set_opts) != nil then
|
106
|
+
y.set_opts(action, optsParser, opts)
|
107
|
+
end
|
102
108
|
break
|
103
109
|
}
|
104
110
|
end
|
@@ -108,6 +114,12 @@ module GitMaintain
|
|
108
114
|
ACTION_CLASS.each(){|x|
|
109
115
|
next if x.singleton_methods().index(:check_opts) == nil
|
110
116
|
x.check_opts(opts)
|
117
|
+
|
118
|
+
# Try to add repo specific opts
|
119
|
+
y = getClass(x)
|
120
|
+
if x != y && y.singleton_methods().index(:check_opts) != nil then
|
121
|
+
y.check_opts(opts)
|
122
|
+
end
|
111
123
|
}
|
112
124
|
end
|
113
125
|
module_function :checkOpts
|
data/lib/repo.rb
CHANGED
@@ -6,11 +6,13 @@ module GitMaintain
|
|
6
6
|
|
7
7
|
ACTION_LIST = [
|
8
8
|
:list_branches,
|
9
|
+
:summary,
|
9
10
|
# Internal commands for completion
|
10
11
|
:list_suffixes, :submit_release
|
11
12
|
]
|
12
13
|
ACTION_HELP = [
|
13
14
|
"* submit_release: Push the to stable and create the release packages",
|
15
|
+
"* summary: Displays a summary of the configuration and the branches git-maintain sees"
|
14
16
|
]
|
15
17
|
|
16
18
|
def self.load(path=".")
|
@@ -47,10 +49,11 @@ module GitMaintain
|
|
47
49
|
if path == nil
|
48
50
|
@path = Dir.pwd()
|
49
51
|
end
|
52
|
+
@name = File.basename(@path)
|
50
53
|
|
51
|
-
@valid_repo =
|
54
|
+
@valid_repo = getGitConfig("maintain.valid-repo")
|
52
55
|
@valid_repo = @@VALID_REPO if @valid_repo == ""
|
53
|
-
@stable_repo =
|
56
|
+
@stable_repo = getGitConfig("maintain.stable-repo")
|
54
57
|
@stable_repo = @@STABLE_REPO if @stable_repo == ""
|
55
58
|
|
56
59
|
@remote_valid=runGit("remote -v | egrep '^#{@valid_repo}' | grep fetch |
|
@@ -58,10 +61,22 @@ module GitMaintain
|
|
58
61
|
@remote_stable=runGit("remote -v | egrep '^#{@stable_repo}' | grep fetch |
|
59
62
|
awk '{ print $2}' | sed -e 's/.*://' -e 's/\\.git//'")
|
60
63
|
|
61
|
-
@
|
64
|
+
@auto_fetch = getGitConfig("maintain.autofetch")
|
65
|
+
case @auto_fetch
|
66
|
+
when ""
|
67
|
+
@auto_fetch = nil
|
68
|
+
when "true", "yes", "on"
|
69
|
+
@auto_fetch = true
|
70
|
+
when "false", "no", "off"
|
71
|
+
@auto_fetch = false
|
72
|
+
else
|
73
|
+
raise("Invalid value '#{@auto_fetch}' in git config for maintain.autofetch")
|
74
|
+
end
|
75
|
+
|
76
|
+
@branch_format_raw = getGitConfig("maintain.branch-format")
|
62
77
|
@branch_format = Regexp.new(/#{@branch_format_raw}/)
|
63
|
-
@stable_branch_format =
|
64
|
-
@stable_base_format =
|
78
|
+
@stable_branch_format = getGitConfig("maintain.stable-branch-format")
|
79
|
+
@stable_base_format = getGitConfig("maintain.stable-base-format")
|
65
80
|
|
66
81
|
@stable_base_patterns=
|
67
82
|
runGit("config --get-regexp stable-base | egrep '^stable-base\.' | "+
|
@@ -70,8 +85,22 @@ module GitMaintain
|
|
70
85
|
m[y[0]] = y[1]
|
71
86
|
m
|
72
87
|
}
|
88
|
+
|
89
|
+
@mail_format = getGitConfig("maintain.mail-format")
|
90
|
+
if @mail_format == "" then
|
91
|
+
@mail_format = :imap_send
|
92
|
+
else
|
93
|
+
# Check that the format is valid
|
94
|
+
case @mail_format
|
95
|
+
when "imap_send", "send_email"
|
96
|
+
else
|
97
|
+
raise("Invalid mail-format #{@mail_format}")
|
98
|
+
end
|
99
|
+
|
100
|
+
@mail_format = @mail_format.to_sym()
|
101
|
+
end
|
73
102
|
end
|
74
|
-
attr_reader :path, :remote_valid, :remote_stable, :valid_repo, :stable_repo
|
103
|
+
attr_reader :path, :name, :remote_valid, :remote_stable, :valid_repo, :stable_repo
|
75
104
|
|
76
105
|
def log(lvl, str)
|
77
106
|
GitMaintain::log(lvl, str)
|
@@ -83,11 +112,18 @@ module GitMaintain
|
|
83
112
|
def runSystem(cmd)
|
84
113
|
return system("cd #{@path} && #{cmd}")
|
85
114
|
end
|
115
|
+
|
86
116
|
def runGit(cmd)
|
87
117
|
log(:DEBUG, "Called from #{caller[1]}")
|
88
118
|
log(:DEBUG, "Running git command '#{cmd}'")
|
89
119
|
return `git --work-tree=#{@path} #{cmd}`.chomp()
|
90
120
|
end
|
121
|
+
def runGitInteractive(cmd)
|
122
|
+
log(:DEBUG, "Called from #{caller[1]}")
|
123
|
+
log(:DEBUG, "Running interactive git command '#{cmd}'")
|
124
|
+
return system("git --work-tree=#{@path} #{cmd}")
|
125
|
+
end
|
126
|
+
|
91
127
|
def runGitImap(cmd)
|
92
128
|
return `export GIT_ASKPASS=$(dirname $(dirname $(which git)))/lib/git-core/git-gui--askpass;
|
93
129
|
if [ ! -f $GIT_ASKPASS ]; then
|
@@ -97,6 +133,9 @@ module GitMaintain
|
|
97
133
|
export GIT_ASKPASS=/usr/lib/ssh/ssh-askpass;
|
98
134
|
fi; git --work-tree=#{@path} imap-send #{cmd}`
|
99
135
|
end
|
136
|
+
def getGitConfig(entry)
|
137
|
+
return runGit("config #{entry} 2> /dev/null").chomp()
|
138
|
+
end
|
100
139
|
|
101
140
|
def runBash()
|
102
141
|
runSystem("bash")
|
@@ -111,8 +150,13 @@ module GitMaintain
|
|
111
150
|
def getCommitHeadline(sha)
|
112
151
|
return runGit("show --format=oneline --no-patch --no-decorate #{sha}")
|
113
152
|
end
|
153
|
+
def getCommitSubj(sha)
|
154
|
+
return runGit("log -1 --pretty=\"%s\" #{sha}")
|
155
|
+
end
|
114
156
|
|
115
|
-
def stableUpdate()
|
157
|
+
def stableUpdate(fetch=nil)
|
158
|
+
fetch = @auto_fetch if fetch == nil
|
159
|
+
return if fetch == false
|
116
160
|
log(:VERBOSE, "Fetching stable updates...")
|
117
161
|
runGit("fetch #{@stable_repo}")
|
118
162
|
end
|
@@ -173,9 +217,9 @@ module GitMaintain
|
|
173
217
|
mail_path=`mktemp`.chomp()
|
174
218
|
mail = File.open(mail_path, "w+")
|
175
219
|
mail.puts "From " + runGit("rev-parse HEAD") + " " + `date`.chomp()
|
176
|
-
mail.puts "From: " +
|
177
|
-
" <" +
|
178
|
-
mail.puts "To: " +
|
220
|
+
mail.puts "From: " + getGitConfig("user.name") +
|
221
|
+
" <" + getGitConfig("user.email") +">"
|
222
|
+
mail.puts "To: " + getGitConfig("patch.target")
|
179
223
|
mail.puts "Date: " + `date -R`.chomp()
|
180
224
|
|
181
225
|
if new_tags.length > 4 then
|
@@ -187,8 +231,8 @@ module GitMaintain
|
|
187
231
|
else
|
188
232
|
mail.puts "Subject: [ANNOUNCE] " + File.basename(@path) + " " +
|
189
233
|
(new_tags.length > 1 ?
|
190
|
-
(new_tags[0 .. -2].join(", ") + " and " + new_tags[-1] + " have
|
191
|
-
(new_tags.join(" ") + " has
|
234
|
+
(new_tags[0 .. -2].join(", ") + " and " + new_tags[-1] + " have") :
|
235
|
+
(new_tags.join(" ") + " has")) +
|
192
236
|
" been tagged/released"
|
193
237
|
mail.puts ""
|
194
238
|
end
|
@@ -210,7 +254,14 @@ module GitMaintain
|
|
210
254
|
mail.puts "https://github.com/#{@remote_stable}/releases"
|
211
255
|
mail.close()
|
212
256
|
|
213
|
-
|
257
|
+
case @mail_format
|
258
|
+
when :imap_send
|
259
|
+
puts runGitImap("< #{mail_path}")
|
260
|
+
when :send_email
|
261
|
+
run("cp #{mail_path} announce-release.eml")
|
262
|
+
log(:INFO, "Generated annoucement email in #{@path}/announce-release.eml")
|
263
|
+
end
|
264
|
+
run("rm -f #{mail_path}")
|
214
265
|
end
|
215
266
|
|
216
267
|
log(:WARNING, "Last chance to cancel before submitting")
|
@@ -255,7 +306,52 @@ module GitMaintain
|
|
255
306
|
def submit_release(opts)
|
256
307
|
submitReleases(opts)
|
257
308
|
end
|
258
|
-
|
309
|
+
def summary(opts)
|
310
|
+
log(:INFO, "Configuration summary:")
|
311
|
+
log(:INFO, "Stable remote: #{@@STABLE_REPO}")
|
312
|
+
log(:INFO, "Validation remote: #{@@VALID_REPO}")
|
313
|
+
log(:INFO, "")
|
314
|
+
log(:INFO, "Branch config:")
|
315
|
+
log(:INFO, "Local branch format: /#{@branch_format_raw}/")
|
316
|
+
log(:INFO, "Remote stable branch format: #{@stable_branch_format}")
|
317
|
+
log(:INFO, "Remote stable base format: #{@stable_base_format}")
|
318
|
+
|
319
|
+
if @stable_base_patterns.length > 0 then
|
320
|
+
log(:INFO, "")
|
321
|
+
log(:INFO, "Stable base rules:")
|
322
|
+
@stable_base_patterns.each(){|name, base|
|
323
|
+
log(:INFO, "\t#{name} -> #{base}")
|
324
|
+
}
|
325
|
+
end
|
326
|
+
brList = getBranchList(opts[:br_suff])
|
327
|
+
brStList = getStableBranchList()
|
328
|
+
|
329
|
+
if brList.length > 0 then
|
330
|
+
log(:INFO, "")
|
331
|
+
log(:INFO, "Local branches:")
|
332
|
+
brList.each(){|br|
|
333
|
+
branch = Branch.load(self, br, nil, opts[:branch_suff])
|
334
|
+
localBr = branch.local_branch
|
335
|
+
stableBr = @@STABLE_REPO + "/" + branch.remote_branch
|
336
|
+
stableBase = branch.stable_base
|
337
|
+
runGit("rev-parse --verify --quiet #{stableBr}")
|
338
|
+
stableBr = "<MISSING>" if $? != 0
|
339
|
+
log(:INFO, "\t#{localBr} -> #{stableBr} (#{stableBase})")
|
340
|
+
brStList.delete(br)
|
341
|
+
}
|
342
|
+
end
|
343
|
+
|
344
|
+
if brStList.length > 0 then
|
345
|
+
log(:INFO, "")
|
346
|
+
log(:INFO, "Upstream branches:")
|
347
|
+
brStList.each(){|br|
|
348
|
+
branch = Branch.load(self, br, nil, opts[:branch_suff])
|
349
|
+
stableBr = @@STABLE_REPO + "/" + branch.remote_branch
|
350
|
+
stableBase = branch.stable_base
|
351
|
+
log(:INFO, "\t<MISSING> -> #{stableBr} (#{stableBase})")
|
352
|
+
}
|
353
|
+
end
|
354
|
+
end
|
259
355
|
def find_alts(commit)
|
260
356
|
alts=[]
|
261
357
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: git-maintain
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nicolas Morey-Chaisemartin
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-05-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: github-release
|