sugarjar 1.1.2 → 1.1.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +128 -20
- data/bin/sj +3 -3
- data/lib/sugarjar/commands.rb +35 -10
- data/lib/sugarjar/version.rb +1 -1
- 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: c689945af0d2bfb7b38477d19da9f58503a15b7be931ab021c4a121a07e6198c
|
4
|
+
data.tar.gz: e5fb66f22db68dce1ef31199ea688ff768d753b5df65bc8479744c010d4072c3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9979e5aa13fd2a176cc5a391b9aef8353c1ddb7e63392ab6291f1781c3a99c39f9e4415a3c8cf02720ed2e0c6683a470978ba4ded3be9f2bb993120980a34863
|
7
|
+
data.tar.gz: 81ba9f2079a9cc6a88e9052092795c722f9a48bd6f9d763ddc33dddd48fbde65049a16dca2ca66ad39d2a33f179d175a712d22517e6e8103a5089a8d26d9592d
|
data/README.md
CHANGED
@@ -123,34 +123,142 @@ to `git clone` under the hood.
|
|
123
123
|
## Work with stacked branches more easily
|
124
124
|
|
125
125
|
It's important to break changes into reviewable chunks, but working with
|
126
|
-
stacked branches can be confusing.
|
127
|
-
|
128
|
-
branch structure like:
|
126
|
+
stacked branches can be confusing. SugarJar provides several tools to make this
|
127
|
+
easier.
|
129
128
|
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
129
|
+
First, and foremost, is `feature` and `subfeature`. Regardless of stacking, the
|
130
|
+
way to create a new feature bracnh with sugarjar is with `sj feature` (or `sj
|
131
|
+
f` for short):
|
132
|
+
|
133
|
+
```shell
|
134
|
+
$ sj feature mynewthing
|
135
|
+
Created feature branch mynewthing based on origin/main
|
134
136
|
```
|
135
137
|
|
136
|
-
|
138
|
+
A "feature" in SugarJar parliance just means that the branch is always created
|
139
|
+
from "most_main" - this is usually "upstream/main", but SJ will figure out
|
140
|
+
which remote is the "upstream", even if it's "origin", and then will determine
|
141
|
+
the primary branch ("main" or for older repos "master"). It's also smart enough
|
142
|
+
to fetch that remote first to make sure you're working on the latest HEAD.
|
143
|
+
|
144
|
+
When you want to create a stacked PR, you can create "subfeature", which, at
|
145
|
+
its core is just a branch created from the current branch:
|
137
146
|
|
138
147
|
```shell
|
139
|
-
$ sj
|
140
|
-
|
141
|
-
* e545b41 (test2) test2
|
142
|
-
* c808eae (test1) test1
|
143
|
-
o 44cf9e2 (origin/master, origin/HEAD, master) Lint/gemspec cleanups
|
148
|
+
$ sj subfeature dependentnewthing
|
149
|
+
Created feature branch dependentnewthing based on mynewthing
|
144
150
|
```
|
145
151
|
|
146
|
-
|
152
|
+
If you create branches like this then sugarjar can now make several things
|
153
|
+
much easier:
|
147
154
|
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
155
|
+
* `sj up` will rebase intelligently
|
156
|
+
* After an `sj bclean` of a branch earlier in the tree, `sj up` will update
|
157
|
+
the tracked branch to "most_main"
|
158
|
+
|
159
|
+
There are two commands that will show you the state of your stacked branches:
|
160
|
+
|
161
|
+
* `sj binfo` - shows the current branch and its ancestors up to your primary branch
|
162
|
+
* `sj smartlist` (aka `sj sl`) - shows you the whole tree.
|
163
|
+
|
164
|
+
To continue with the example above, my `smartlist` might look like:
|
165
|
+
|
166
|
+
```text
|
167
|
+
$ sj sl
|
168
|
+
* 59c0522 (HEAD -> dependentnewthing) anothertest
|
169
|
+
* 6ebaa28 (mynewthing) test
|
170
|
+
o 7a0ffd0 (tag: v1.1.2, origin/main, origin/HEAD, main) Version bump (#160)
|
171
|
+
```
|
172
|
+
|
173
|
+
This is simple. Now lets make a different feature stack:
|
174
|
+
|
175
|
+
```text
|
176
|
+
$ sj feature anotherfeature
|
177
|
+
Created feature branch anotherfeature based on origin/main
|
178
|
+
# do stuff
|
179
|
+
$ sj subfeature dependent2
|
180
|
+
Created feature branch dependent2 based on anotherfeature
|
181
|
+
# do stuff
|
182
|
+
```
|
183
|
+
|
184
|
+
The `smartlist` will now show us this tree, and it's a bit more interesting:
|
185
|
+
|
186
|
+
```text
|
187
|
+
$ sj sl
|
188
|
+
* af6f143 (HEAD -> dependent2) morestuff
|
189
|
+
* 028c7f4 (anotherfeature) stuff
|
190
|
+
| * 59c0522 (dependentnewthing) anothertest
|
191
|
+
| * 6ebaa28 (mynewthing) test
|
192
|
+
|/
|
193
|
+
o 7a0ffd0 (tag: v1.1.2, origin/main, origin/HEAD, main) Version bump (#160)
|
194
|
+
```
|
195
|
+
|
196
|
+
Now, what happens if I make a change to `mynewthing`?
|
197
|
+
|
198
|
+
```text
|
199
|
+
$ sj co mynewthing
|
200
|
+
Switched to branch 'mynewthing'
|
201
|
+
Your branch is ahead of 'origin/main' by 1 commit.
|
202
|
+
(use "git push" to publish your local commits)
|
203
|
+
$ echo 'randomchange' >> README.md
|
204
|
+
$ git commit -a -m change
|
205
|
+
[mynewthing d33e082] change
|
206
|
+
1 file changed, 1 insertion(+)
|
207
|
+
$ sj sl
|
208
|
+
* d33e082 (HEAD -> mynewthing) change
|
209
|
+
| * af6f143 (dependent2) morestuff
|
210
|
+
| * 028c7f4 (anotherfeature) stuff
|
211
|
+
| | * 59c0522 (dependentnewthing) anothertest
|
212
|
+
| |/
|
213
|
+
|/|
|
214
|
+
* | 6ebaa28 test
|
215
|
+
|/
|
216
|
+
o 7a0ffd0 (tag: v1.1.2, origin/main, origin/HEAD, main) Version bump (#160)
|
217
|
+
```
|
218
|
+
|
219
|
+
We can see here now that `dependentnewthing`, is based off a commit that _used_
|
220
|
+
to be `mynewthing`, but `mynewthing` has moved. But SugarJar will handle this
|
221
|
+
all correctly when we ask it to update the branch:
|
222
|
+
|
223
|
+
```text
|
224
|
+
$ sj co dependentnewthing
|
225
|
+
Switched to branch 'dependentnewthing'
|
226
|
+
Your branch and 'mynewthing' have diverged,
|
227
|
+
and have 1 and 1 different commits each, respectively.
|
228
|
+
(use "git pull" if you want to integrate the remote branch with yours)
|
229
|
+
$ sj up
|
230
|
+
dependentnewthing rebased on mynewthing
|
231
|
+
$ sj sl
|
232
|
+
* 93ed585 (HEAD -> dependentnewthing) anothertest
|
233
|
+
* d33e082 (mynewthing) change
|
234
|
+
* 6ebaa28 test
|
235
|
+
| * af6f143 (dependent2) morestuff
|
236
|
+
| * 028c7f4 (anotherfeature) stuff
|
237
|
+
|/
|
238
|
+
o 7a0ffd0 (tag: v1.1.2, origin/main, origin/HEAD, main) Version bump (#160)
|
239
|
+
```
|
240
|
+
|
241
|
+
Now, lets say that `mynewthing` gets merged and we use `bclean` to clean it all
|
242
|
+
up, what happens then?
|
243
|
+
|
244
|
+
```text
|
245
|
+
$ sj up
|
246
|
+
The brach we were tracking is gone, resetting tracking to origin/main
|
247
|
+
dependentnewthing rebased on origin/main
|
248
|
+
```
|
249
|
+
|
250
|
+
### Creating Stacked PRs with subfeatures
|
251
|
+
|
252
|
+
When dependent branches are created with `subfeature`, when you create a PR,
|
253
|
+
SugarJar will automatically set the 'base' of the PR to the parent branch. By
|
254
|
+
default it'll prompt you about this, but you can set `pr_autostack` to `true`
|
255
|
+
in your config to tell it to always do this (or `false` to never do this):
|
256
|
+
|
257
|
+
```text
|
258
|
+
$ sj spr
|
259
|
+
Autofilling in PR from commit message
|
260
|
+
It looks like this is a subfeature, would you like to base this PR on mynewthing? [y/n] y
|
261
|
+
...
|
154
262
|
```
|
155
263
|
|
156
264
|
## Have a better lint/unittest experience!
|
data/bin/sj
CHANGED
@@ -93,8 +93,8 @@ parser = OptionParser.new do |opts|
|
|
93
93
|
|
94
94
|
opts.on(
|
95
95
|
'--[no-]pr-autofill',
|
96
|
-
'When creating a PR, auto fill the title & description from the
|
97
|
-
'
|
96
|
+
'When creating a PR, auto fill the title & description from the top ' +
|
97
|
+
'commit if we are using "gh". [default: true]',
|
98
98
|
) do |autofill|
|
99
99
|
options['pr_autofill'] = autofill
|
100
100
|
end
|
@@ -104,7 +104,7 @@ parser = OptionParser.new do |opts|
|
|
104
104
|
'When creating a PR, if this is a subfeature, should we make it a ' +
|
105
105
|
'PR on the PR for the parent feature. If not specified, we prompt ' +
|
106
106
|
'when this happens, when true always do this, when false never do ' +
|
107
|
-
'this. Only applicable when usiing "gh".',
|
107
|
+
'this. Only applicable when usiing "gh" and on branch-based PRs.',
|
108
108
|
) do |autostack|
|
109
109
|
options['pr_autostack'] = autostack
|
110
110
|
end
|
data/lib/sugarjar/commands.rb
CHANGED
@@ -334,31 +334,40 @@ class SugarJar
|
|
334
334
|
curr = current_branch
|
335
335
|
base = tracked_branch
|
336
336
|
if @pr_autofill
|
337
|
+
SugarJar::Log.info('Autofilling in PR from commit message')
|
337
338
|
num_commits = git(
|
338
339
|
'rev-list', '--count', curr, "^#{base}"
|
339
340
|
).stdout.strip.to_i
|
340
341
|
if num_commits > 1
|
341
|
-
|
342
|
-
"Not using --fill because there are #{num_commits} commits",
|
343
|
-
)
|
342
|
+
args.unshift('--fill-first')
|
344
343
|
else
|
345
|
-
SugarJar::Log.info('Autofilling in PR from commit message')
|
346
344
|
args.unshift('--fill')
|
347
345
|
end
|
348
346
|
end
|
349
347
|
if subfeature?(base)
|
348
|
+
if upstream != push_org
|
349
|
+
SugarJar::Log.warn(
|
350
|
+
'Unfortunately you cannot based one PR on another PR when' +
|
351
|
+
" using fork-based PRs. We will base this on #{most_main}." +
|
352
|
+
' This just means the PR "Changes" tab will show changes for' +
|
353
|
+
' the full stack until those other PRs are merged and this PR' +
|
354
|
+
' PR is rebased.',
|
355
|
+
)
|
350
356
|
# nil is prompt, true is always, false is never
|
351
|
-
|
357
|
+
elsif @pr_autostack.nil?
|
352
358
|
$stdout.print(
|
353
359
|
'It looks like this is a subfeature, would you like to base ' +
|
354
360
|
"this PR on #{base}? [y/n] ",
|
355
361
|
)
|
356
362
|
ans = $stdin.gets.strip
|
357
|
-
args
|
363
|
+
args.unshift('--base', base) if %w{Y y}.include?(ans)
|
358
364
|
elsif @pr_autostack
|
359
|
-
args
|
365
|
+
args.unshift('--base', base)
|
360
366
|
end
|
361
367
|
end
|
368
|
+
# <org>:<branch> is the GH API syntax for:
|
369
|
+
# look for a branch of name <branch>, from a fork in owner <org>
|
370
|
+
args.unshift('--head', "#{push_org}:#{curr}")
|
362
371
|
SugarJar::Log.trace("Running: gh pr create #{args.join(' ')}")
|
363
372
|
system(which('gh'), 'pr', 'create', *args)
|
364
373
|
else
|
@@ -482,6 +491,10 @@ class SugarJar
|
|
482
491
|
end
|
483
492
|
end
|
484
493
|
|
494
|
+
def extract_repo(repo)
|
495
|
+
File.basename(repo, '.git')
|
496
|
+
end
|
497
|
+
|
485
498
|
def forked_repo(repo, username)
|
486
499
|
repo = if repo.start_with?('http', 'git@')
|
487
500
|
File.basename(repo)
|
@@ -898,15 +911,21 @@ class SugarJar
|
|
898
911
|
end
|
899
912
|
|
900
913
|
def tracked_branch(fallback: true)
|
914
|
+
branch = nil
|
901
915
|
s = git_nofail(
|
902
916
|
'rev-parse', '--abbrev-ref', '--symbolic-full-name', '@{u}'
|
903
917
|
)
|
904
918
|
if s.error?
|
905
|
-
fallback ? most_main : nil
|
906
|
-
|
919
|
+
branch = fallback ? most_main : nil
|
920
|
+
SugarJar::Log.debug("No specific tracked branch, using #{branch}")
|
907
921
|
else
|
908
|
-
s.stdout.strip
|
922
|
+
branch = s.stdout.strip
|
923
|
+
SugarJar::Log.debug(
|
924
|
+
"Using explicit tracked branch: #{branch}, use " +
|
925
|
+
'`git branch -u` to change',
|
926
|
+
)
|
909
927
|
end
|
928
|
+
branch
|
910
929
|
end
|
911
930
|
|
912
931
|
def most_main
|
@@ -937,6 +956,12 @@ class SugarJar
|
|
937
956
|
@remote
|
938
957
|
end
|
939
958
|
|
959
|
+
# Whatever org we push to, regardless of if this is a fork or not
|
960
|
+
def push_org
|
961
|
+
url = git('remote', 'get-url', 'origin').stdout.strip
|
962
|
+
extract_org(url)
|
963
|
+
end
|
964
|
+
|
940
965
|
def branch_from_ref(ref, type = :local)
|
941
966
|
# local branches are refs/head/XXXX
|
942
967
|
# remote branches are refs/remotes/<remote>/XXXX
|
data/lib/sugarjar/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sugarjar
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.1.
|
4
|
+
version: 1.1.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Phil Dibowitz
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2025-02-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: deep_merge
|