git-maintain 0.6.0 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|