git-improved 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGES.md +13 -0
- data/README.md +198 -134
- data/git-improved.gemspec +2 -2
- data/lib/git-improved.rb +115 -16
- data/test/action_test.rb +85 -1
- data/test/shared.rb +5 -0
- metadata +11 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2617ea60b8914d34c0b4781f2f81ddbc0daeb9db2400dfb5c55238a93a34d006
|
4
|
+
data.tar.gz: 95d621dde81968cc258c21e9caf33318a83ba61235af844bd774258e815d6e38
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c51a5861bd3f6b02aac5528ee029a603bccafeee258044a109b9ceb5aac711c4195fdf3c8dec49ca5b767de7d8f479484abe75dfd963cf3e8fcd2811797c3e19
|
7
|
+
data.tar.gz: 633c0228ba23a7e9cb42e76201d596a84d90056637686d43c12971f54e28a6fa6febc37864c6e8ad8331463d25e1c1dc5ab809b681940c85b16abe6907be1b63
|
data/CHANGES.md
CHANGED
@@ -2,6 +2,19 @@ ChangeLog
|
|
2
2
|
=========
|
3
3
|
|
4
4
|
|
5
|
+
Release 0.2.0 (2024-09-30)
|
6
|
+
--------------------------
|
7
|
+
|
8
|
+
|
9
|
+
* [enhance] New action `file:rename:all` added.
|
10
|
+
* [enhance] New action `commit:unmerge` added.
|
11
|
+
* [enhance] Action `file:track` supports `-s, --autoskip` option.
|
12
|
+
* [enhance] Action `file:list` supports `-F changed` option.
|
13
|
+
* [enhance] Action `file:delete` supports `-f, --force` option.
|
14
|
+
* [enhance] Action `file:rename` supports `-f, --force` option.
|
15
|
+
|
16
|
+
|
17
|
+
|
5
18
|
Release 0.1.0 (2023-11-26)
|
6
19
|
--------------------------
|
7
20
|
|
data/README.md
CHANGED
@@ -8,13 +8,45 @@ It provides a much better interface than Git.
|
|
8
8
|
|
9
9
|
* Intuitive
|
10
10
|
* Easy to understand
|
11
|
-
*
|
11
|
+
* Categorized commands
|
12
|
+
|
13
|
+
Command comparison:
|
14
|
+
|
15
|
+
| Git Improved | Git |
|
16
|
+
| --------------------- | ------------------------------------- |
|
17
|
+
| `gi` | `git status -sb .` |
|
18
|
+
| `gi sw <branch>` | `git checkout <branch>` |
|
19
|
+
| `gi fork <branch>` | `git checkout -b <branch>` |
|
20
|
+
| `gi join` | `git checkout -; git merge <branch>` |
|
21
|
+
| `gi pick .` | `git add -i .` |
|
22
|
+
| `gi track <newfile>` | `git add <newfile>` |
|
23
|
+
| `gi stage <file>` | `git add <file>` |
|
24
|
+
| `gi staged` | `git diff --cached` |
|
25
|
+
| `gi unstage` | `git reset HEAD` |
|
26
|
+
| `gi commit:rollback` | `git reset HEAD^` |
|
27
|
+
| `gi file:restore` | `git reset --hard` |
|
28
|
+
| `gi cc "<comment>"` | `git commit -m "<comment>"` |
|
29
|
+
| `gi correct` | `git commit --ammend` |
|
30
|
+
| `gi fixup <commit>` | `git commit --fixup=<commit>` |
|
31
|
+
| `gi changes` | `git diff` |
|
32
|
+
| `gi branches` | `git branch -a` |
|
33
|
+
| `gi commits` | `git log -p` |
|
34
|
+
| `gi tags` | `git tag -l` |
|
35
|
+
| `gi tag:upload` | `git push --tags` |
|
36
|
+
| `gi hist` | `git git log --oneline --graph ...` |
|
37
|
+
| `gi histedit` | `git rebase -i` |
|
38
|
+
| `gi histedit:resume` | `git rebase --continue` |
|
39
|
+
| `gi histedit:cancel` | `git rebase --abort` |
|
40
|
+
| ...(and more)... | .... |
|
41
|
+
|
42
|
+
GitImproved is also an example program of [Benry-CmdApp](https://kwatch.github.io/benry-ruby/benry-cmdapp.html) framework.
|
43
|
+
Benry-CmdApp is a framework for commad-line applications which take sub-commands (like `git`, `docker`, `npm`, etc).
|
12
44
|
|
13
45
|
Links:
|
14
46
|
|
15
47
|
* Document: <https://kwatch.github.io/git-improved/>
|
16
48
|
* GitHub: <https://github.com/kwatch/git-improved>
|
17
|
-
* Changes: <https://github.com/kwatch/git-improved/CHANGES.md>
|
49
|
+
* Changes: <https://github.com/kwatch/git-improved/blob/main/CHANGES.md>
|
18
50
|
|
19
51
|
|
20
52
|
### Table of Contents
|
@@ -38,7 +70,7 @@ Links:
|
|
38
70
|
* [Status](#status)
|
39
71
|
* [Sync](#sync)
|
40
72
|
* [Tag](#tag)
|
41
|
-
* [
|
73
|
+
* [Customizing Configurations](#customizing-configurations)
|
42
74
|
* [License and Copyright](#license-and-copyright)
|
43
75
|
|
44
76
|
<!-- /TOC -->
|
@@ -51,7 +83,7 @@ GitImproved requires Ruby >= 2.3.
|
|
51
83
|
```console
|
52
84
|
$ gem install git-improved
|
53
85
|
$ gi --version
|
54
|
-
|
86
|
+
0.2.0
|
55
87
|
```
|
56
88
|
|
57
89
|
|
@@ -61,6 +93,8 @@ $ gi --version
|
|
61
93
|
## help
|
62
94
|
$ gi -h | less # help message
|
63
95
|
$ gi -l | less # list actions
|
96
|
+
$ gi : # list top-level categories of actions
|
97
|
+
$ gi commit: # list actions under 'commit' category
|
64
98
|
$ gi -h commit:create # help of an action
|
65
99
|
|
66
100
|
## create a repo
|
@@ -83,7 +117,7 @@ $ gi cc "update README file" # commit changes
|
|
83
117
|
|
84
118
|
## upload changes
|
85
119
|
$ gi repo:remote:seturl github:yourname/mysample
|
86
|
-
$ gi
|
120
|
+
$ gi upload # upload local commits to remote repo
|
87
121
|
```
|
88
122
|
|
89
123
|
|
@@ -93,215 +127,245 @@ $ gi push # upload local commits to remote repo
|
|
93
127
|
### Branch
|
94
128
|
|
95
129
|
```
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
branch:
|
100
|
-
branch:
|
101
|
-
branch:
|
102
|
-
branch:
|
103
|
-
|
104
|
-
branch:join : merge current branch into previous or other branch
|
105
|
-
|
106
|
-
branch:
|
107
|
-
|
108
|
-
branch:
|
109
|
-
|
110
|
-
branch:
|
111
|
-
branch:
|
112
|
-
branch:
|
113
|
-
branch:
|
114
|
-
branch:
|
115
|
-
|
116
|
-
|
117
|
-
branch:
|
118
|
-
|
119
|
-
|
130
|
+
$ gi branch:
|
131
|
+
Actions:
|
132
|
+
branch:checkout : create a new local branch from a remote branch
|
133
|
+
branch:create : create a new branch, not switch to it
|
134
|
+
branch:current : show current branch name
|
135
|
+
branch:delete : delete a branch
|
136
|
+
branch:echo : print CURR/PREV/PARENT branch name
|
137
|
+
branch:fork : create a new branch and switch to it
|
138
|
+
branch:join : merge current branch into previous or other branch
|
139
|
+
branch:list : list branches
|
140
|
+
branch:merge : merge previous or other branch into current branch
|
141
|
+
branch:parent : show parent branch name (EXPERIMENTAL)
|
142
|
+
branch:previous : show previous branch name
|
143
|
+
branch:rebase : rebase (move) current branch on top of other branch
|
144
|
+
branch:rename : rename the current branch to other name
|
145
|
+
branch:reset : change commit-id of current HEAD
|
146
|
+
branch:switch : switch to previous or other branch
|
147
|
+
branch:update : git pull && git stash && git rebase && git stash pop
|
148
|
+
branch:upstream : print upstream repo name of current branch
|
149
|
+
|
150
|
+
Aliases:
|
151
|
+
branch : alias for 'branch:create'
|
152
|
+
fork : alias for 'branch:fork'
|
153
|
+
join : alias for 'branch:join'
|
154
|
+
branches : alias for 'branch:list'
|
155
|
+
merge : alias for 'branch:merge'
|
156
|
+
sw : alias for 'branch:switch'
|
157
|
+
switch : alias for 'branch:switch'
|
158
|
+
update : alias for 'branch:update'
|
120
159
|
```
|
121
160
|
|
122
161
|
|
123
162
|
### Commit
|
124
163
|
|
125
164
|
```
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
commit:
|
130
|
-
|
131
|
-
commit:fixup : correct the previous commit
|
132
|
-
|
133
|
-
commit:
|
134
|
-
commit:
|
135
|
-
commit:
|
136
|
-
|
165
|
+
$ gi commit:
|
166
|
+
Actions:
|
167
|
+
commit:apply : apply a commit to curr branch (known as 'cherry-pick')
|
168
|
+
commit:correct : correct the last commit
|
169
|
+
commit:create : create a new commit
|
170
|
+
commit:fixup : correct the previous commit
|
171
|
+
commit:revert : create a new commit which reverts the target commit
|
172
|
+
commit:rollback : cancel recent commits up to the target commit-id
|
173
|
+
commit:show : show commits in current branch
|
174
|
+
commit:unmerge : rollback merge commit
|
175
|
+
|
176
|
+
Aliases:
|
177
|
+
correct : alias for 'commit:correct'
|
178
|
+
cc : alias for 'commit:create'
|
179
|
+
commit : alias for 'commit:create'
|
180
|
+
fixup : alias for 'commit:fixup'
|
181
|
+
commits : alias for 'commit:show'
|
182
|
+
unmerge : alias for 'commit:unmerge'
|
137
183
|
```
|
138
184
|
|
139
185
|
|
140
186
|
### Config
|
141
187
|
|
142
188
|
```
|
143
|
-
|
144
|
-
|
145
|
-
config:
|
189
|
+
$ gi config:
|
190
|
+
Actions:
|
191
|
+
config : list/get/set/delete config values
|
192
|
+
config:alias : list/get/set/delete aliases of 'git' (not of 'gi')
|
193
|
+
config:setuser : set user name and email
|
146
194
|
```
|
147
195
|
|
148
196
|
|
149
197
|
### File
|
150
198
|
|
151
199
|
```
|
152
|
-
file:
|
153
|
-
|
154
|
-
|
155
|
-
file:
|
156
|
-
file:
|
157
|
-
file:
|
158
|
-
|
159
|
-
file:move : move files into a directory
|
160
|
-
file:rename : rename a file or directory to new name
|
161
|
-
file:
|
162
|
-
file:
|
163
|
-
|
200
|
+
$ gi file:
|
201
|
+
Actions:
|
202
|
+
file:blame : print commit-id, author, and timestap of each line
|
203
|
+
file:changes : show changes of files
|
204
|
+
file:delete : delete files or directories
|
205
|
+
file:egrep : find by pattern
|
206
|
+
file:list : list (un)tracked/changed/ignored/missing files
|
207
|
+
file:move : move files into a directory
|
208
|
+
file:rename : rename a file or directory to new name
|
209
|
+
file:rename:all : rename multi files by pattern
|
210
|
+
file:restore : restore files (= clear changes)
|
211
|
+
file:track : register files into the repository
|
212
|
+
|
213
|
+
Aliases:
|
214
|
+
changes : alias for 'file:changes'
|
215
|
+
files : alias for 'file:list'
|
216
|
+
register : alias for 'file:track'
|
217
|
+
track : alias for 'file:track'
|
164
218
|
```
|
165
219
|
|
166
220
|
|
167
221
|
### Help
|
168
222
|
|
169
223
|
```
|
170
|
-
|
224
|
+
$ gi help:
|
225
|
+
Actions:
|
226
|
+
help : print help message (of action if specified)
|
171
227
|
```
|
172
228
|
|
173
229
|
|
174
230
|
### History
|
175
231
|
|
176
232
|
```
|
177
|
-
|
178
|
-
|
179
|
-
history:
|
180
|
-
history:edit:
|
181
|
-
history:edit:
|
182
|
-
history:edit:
|
183
|
-
|
184
|
-
history:notuploaded : show commits not uploaded yet
|
233
|
+
$ gi history:
|
234
|
+
Actions:
|
235
|
+
history : show commit history in various format
|
236
|
+
history:edit:cancel : cancel (or abort) `git rebase -i`
|
237
|
+
history:edit:resume : resume (= conitnue) suspended `git rebase -i`
|
238
|
+
history:edit:skip : skip current commit and resume
|
239
|
+
history:edit:start : start `git rebase -i` to edit commit history
|
240
|
+
history:notuploaded : show commits not uploaded yet
|
241
|
+
|
242
|
+
Aliases:
|
243
|
+
hist : alias for 'history -F graph'
|
244
|
+
histedit : alias for 'history:edit:start'
|
185
245
|
```
|
186
246
|
|
187
247
|
|
188
248
|
### Misc
|
189
249
|
|
190
250
|
```
|
191
|
-
misc:
|
251
|
+
$ gi misc:
|
252
|
+
Actions:
|
253
|
+
misc:initfile : generate a init file, or print to stdout if no args
|
192
254
|
```
|
193
255
|
|
194
256
|
|
195
257
|
### Repo
|
196
258
|
|
197
259
|
```
|
198
|
-
|
199
|
-
|
200
|
-
repo:
|
201
|
-
repo:
|
202
|
-
repo:
|
260
|
+
$ gi repo:
|
261
|
+
Actions:
|
262
|
+
repo:clone : copy a repository ('github:<user>/<repo>' is available)
|
263
|
+
repo:create : create a new directory and initialize it as a git repo
|
264
|
+
repo:init : initialize git repository with empty initial commit
|
265
|
+
repo:remote : list/get/set/delete remote repository
|
266
|
+
repo:remote:origin : get/set/delete origin (= default remote repository)
|
203
267
|
```
|
204
268
|
|
205
269
|
|
206
270
|
### Staging
|
207
271
|
|
208
272
|
```
|
209
|
-
|
210
|
-
|
211
|
-
staging:
|
212
|
-
|
213
|
-
staging:edit : edit changes in staging area
|
214
|
-
staging:show : show changes in staging area
|
215
|
-
|
273
|
+
$ gi staging:
|
274
|
+
Actions:
|
275
|
+
staging:add : add changes of files into staging area
|
276
|
+
staging:clear : delete all changes in staging area
|
277
|
+
staging:edit : edit changes in staging area
|
278
|
+
staging:show : show changes in staging area
|
279
|
+
|
280
|
+
Aliases:
|
281
|
+
stage : alias for 'staging:add'
|
282
|
+
pick : alias for 'staging:add -p'
|
283
|
+
unstage : alias for 'staging:clear'
|
284
|
+
staged : alias for 'staging:show'
|
216
285
|
```
|
217
286
|
|
218
287
|
|
219
288
|
### Stash
|
220
289
|
|
221
290
|
```
|
222
|
-
|
223
|
-
|
224
|
-
stash:
|
225
|
-
stash:
|
226
|
-
stash:
|
291
|
+
$ gi stash:
|
292
|
+
Actions:
|
293
|
+
stash:drop : delete latest changes from stash
|
294
|
+
stash:list : list stash history
|
295
|
+
stash:pop : restore latest changes from stash
|
296
|
+
stash:put : save current changes into stash
|
297
|
+
stash:show : show changes on stash
|
227
298
|
```
|
228
299
|
|
229
300
|
|
230
301
|
### Status
|
231
302
|
|
232
303
|
```
|
233
|
-
|
234
|
-
|
235
|
-
status:
|
236
|
-
status:
|
237
|
-
status:
|
304
|
+
$ gi status:
|
305
|
+
Actions:
|
306
|
+
status:compact : show status in compact format
|
307
|
+
status:default : show status in default format
|
308
|
+
status:here : same as 'stats:compact .'
|
309
|
+
status:info : show various infomation of current status
|
310
|
+
|
311
|
+
Aliases:
|
312
|
+
status : alias for 'status:compact'
|
238
313
|
```
|
239
314
|
|
240
315
|
|
241
316
|
### Sync
|
242
317
|
|
243
318
|
```
|
244
|
-
|
245
|
-
|
246
|
-
sync:
|
247
|
-
|
248
|
-
sync:push : upload commits to remote
|
249
|
-
|
319
|
+
$ gi sync
|
320
|
+
Actions:
|
321
|
+
sync:both : download and upload commits
|
322
|
+
sync:pull : download commits from remote and apply them to local
|
323
|
+
sync:push : upload commits to remote
|
324
|
+
|
325
|
+
Aliases:
|
326
|
+
sync : alias for 'sync:both'
|
327
|
+
dl : alias for 'sync:pull'
|
328
|
+
download : alias for 'sync:pull'
|
329
|
+
pull : alias for 'sync:pull'
|
330
|
+
push : alias for 'sync:push'
|
331
|
+
up : alias for 'sync:push'
|
332
|
+
upload : alias for 'sync:push'
|
250
333
|
```
|
251
334
|
|
252
335
|
|
253
336
|
### Tag
|
254
337
|
|
255
338
|
```
|
256
|
-
tag
|
257
|
-
|
258
|
-
tag:
|
259
|
-
tag:
|
260
|
-
tag:
|
261
|
-
|
262
|
-
tag:
|
339
|
+
$ gi tag:
|
340
|
+
Actions:
|
341
|
+
tag : list/show/create/delete tags
|
342
|
+
tag:create : create a new tag
|
343
|
+
tag:delete : delete a tag
|
344
|
+
tag:download : download tags
|
345
|
+
tag:list : list tags
|
346
|
+
tag:upload : upload tags
|
347
|
+
|
348
|
+
Aliases:
|
349
|
+
tags : alias for 'tag:list'
|
263
350
|
```
|
264
351
|
|
265
352
|
|
266
|
-
|
353
|
+
|
354
|
+
## Customizing Configurations
|
267
355
|
|
268
356
|
```
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
sw : alias for 'branch:switch'
|
275
|
-
switch : alias for 'branch:switch'
|
276
|
-
update : alias for 'branch:update'
|
277
|
-
correct : alias for 'commit:correct'
|
278
|
-
cc : alias for 'commit:create'
|
279
|
-
commit : alias for 'commit:create'
|
280
|
-
fixup : alias for 'commit:fixup'
|
281
|
-
commits : alias for 'commit:show'
|
282
|
-
changes : alias for 'file:changes'
|
283
|
-
files : alias for 'file:list'
|
284
|
-
register : alias for 'file:track'
|
285
|
-
track : alias for 'file:track'
|
286
|
-
hist : alias for 'history -F graph'
|
287
|
-
histedit : alias for 'history:edit:start'
|
288
|
-
pick : alias for 'staging:add -p'
|
289
|
-
stage : alias for 'staging:add'
|
290
|
-
unstage : alias for 'staging:clear'
|
291
|
-
staged : alias for 'staging:show'
|
292
|
-
status : alias for 'status:compact'
|
293
|
-
sync : alias for 'sync:both'
|
294
|
-
dl : alias for 'sync:pull'
|
295
|
-
download : alias for 'sync:pull'
|
296
|
-
pull : alias for 'sync:pull'
|
297
|
-
push : alias for 'sync:push'
|
298
|
-
up : alias for 'sync:push'
|
299
|
-
upload : alias for 'sync:push'
|
300
|
-
tags : alias for 'tag:list'
|
357
|
+
## create an init file
|
358
|
+
$ gi misc:initfile > ~/.gi_init.rb
|
359
|
+
|
360
|
+
## set an environment variable
|
361
|
+
$ export GI_INITFILE=~/.gi_init.rb
|
301
362
|
```
|
302
363
|
|
364
|
+
For details, see the output of `gi misc:initfile`.
|
365
|
+
|
366
|
+
|
303
367
|
|
304
368
|
## License and Copyright
|
305
369
|
|
306
370
|
* $License: MIT License $
|
307
|
-
* $Copyright: copyright(c) 2023 kwatch@gmail.com $
|
371
|
+
* $Copyright: copyright(c) 2023-2024 kwatch@gmail.com $
|
data/git-improved.gemspec
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |spec|
|
4
4
|
spec.name = "git-improved"
|
5
|
-
spec.version = "$Release: 0.
|
5
|
+
spec.version = "$Release: 0.2.0 $".split()[1]
|
6
6
|
spec.author = "kwatch"
|
7
7
|
spec.email = "kwatch@gmail.com"
|
8
8
|
spec.platform = Gem::Platform::RUBY
|
@@ -28,7 +28,7 @@ END
|
|
28
28
|
#spec.extra_rdoc_files = ["README.md", "CHANGES.md"]
|
29
29
|
|
30
30
|
spec.required_ruby_version = ">= 2.3"
|
31
|
-
spec.add_runtime_dependency "benry-cmdapp" , "~> 1"
|
31
|
+
spec.add_runtime_dependency "benry-cmdapp" , "~> 1.1", ">= 1.1.2"
|
32
32
|
spec.add_runtime_dependency "benry-unixcommand" , "~> 1"
|
33
33
|
spec.add_development_dependency "oktest" , "~> 1"
|
34
34
|
end
|
data/lib/git-improved.rb
CHANGED
@@ -3,8 +3,8 @@
|
|
3
3
|
# frozen_string_literal: true
|
4
4
|
|
5
5
|
###
|
6
|
-
### $Release: 0.
|
7
|
-
### $Copyright: copyright(c) 2023 kwatch@gmail.com $
|
6
|
+
### $Release: 0.2.0 $
|
7
|
+
### $Copyright: copyright(c) 2023-2024 kwatch@gmail.com $
|
8
8
|
### $License: MIT License $
|
9
9
|
###
|
10
10
|
|
@@ -207,6 +207,21 @@ END
|
|
207
207
|
return remote
|
208
208
|
end
|
209
209
|
|
210
|
+
def merge_commit?(commit)
|
211
|
+
## ref: https://stackoverflow.com/questions/3824050/
|
212
|
+
#output = `git cat-file -p #{commit}`
|
213
|
+
#header = output.split(/\n\n/)[0]
|
214
|
+
#parent_commits = header.scan(/^parent (.*)/).flatten()
|
215
|
+
#return parent_commits.length > 1
|
216
|
+
output = `git show -s --format=%p #{commit}`
|
217
|
+
return output.split().length > 1
|
218
|
+
end
|
219
|
+
|
220
|
+
def changes_exist?()
|
221
|
+
output = `git status -s -uno`
|
222
|
+
return ! output.strip().empty?
|
223
|
+
end
|
224
|
+
|
210
225
|
def color_mode?
|
211
226
|
return $stdout.tty?
|
212
227
|
end
|
@@ -629,10 +644,11 @@ END
|
|
629
644
|
##
|
630
645
|
category "file:" do
|
631
646
|
|
632
|
-
@action.("list (un)tracked/ignored/missing files")
|
647
|
+
@action.("list (un)tracked/changed/ignored/missing files")
|
633
648
|
@option.(:filtertype, "-F <filtertype>", "one of:", detail: <<~END)
|
634
|
-
- tracked :
|
635
|
-
- untracked :
|
649
|
+
- tracked : tracked files only (default)
|
650
|
+
- untracked : not-tracked files only
|
651
|
+
- changed : changed files only
|
636
652
|
- ignored : ignored files by '.gitignore'
|
637
653
|
- missing : tracked but missing files
|
638
654
|
END
|
@@ -660,6 +676,11 @@ END
|
|
660
676
|
puts output.each_line().grep(/^\?\? /)
|
661
677
|
end
|
662
678
|
|
679
|
+
def __file__list__changed(path, full)
|
680
|
+
paths = path ? [path] : []
|
681
|
+
git "status", "-s", "-uno", *paths
|
682
|
+
end
|
683
|
+
|
663
684
|
def __file__list__ignored(path, full)
|
664
685
|
opt = full ? "--ignored=matching" : "--ignored"
|
665
686
|
echoback "git status -s #{opt} #{path} | grep '^!! '"
|
@@ -678,16 +699,26 @@ END
|
|
678
699
|
@action.("register files into the repository", important: true)
|
679
700
|
@option.(:force, "-f, --force", "allow to track ignored files")
|
680
701
|
@option.(:recursive, "-r, --recursive", "track files under directories")
|
702
|
+
@option.(:autoskip, "-s, --autoskip", "skip already tracked files")
|
681
703
|
#@option.(:allow_empty_dir, "-e, --allow-empty-dir", "create '.gitkeep' to track empty directory")
|
682
|
-
def track(file, *file2, force: false, recursive: false)
|
704
|
+
def track(file, *file2, force: false, recursive: false, autoskip: false)
|
683
705
|
files = [file] + file2
|
684
|
-
files.
|
706
|
+
tracked_files, untracked_files = files.partition {|x|
|
685
707
|
output = `git ls-files -- #{x}`
|
686
|
-
output.empty?
|
687
|
-
|
708
|
+
! output.empty?
|
709
|
+
}
|
710
|
+
if autoskip
|
711
|
+
! untracked_files.empty? or
|
712
|
+
raise action_error("Missing untracked files.")
|
713
|
+
files = untracked_files
|
714
|
+
else
|
715
|
+
tracked_files.empty? or
|
716
|
+
raise action_error("#{tracked_files[0]}: Already tracked.")
|
688
717
|
end
|
689
718
|
files.each do |x|
|
690
|
-
if File.
|
719
|
+
if File.symlink?(x)
|
720
|
+
# ok
|
721
|
+
elsif File.directory?(x)
|
691
722
|
recursive or
|
692
723
|
raise action_error("#{x}: File expected, but is a directory (specify `-r` or `--recursive` otpion to track files under the directory).")
|
693
724
|
end
|
@@ -716,17 +747,71 @@ END
|
|
716
747
|
end
|
717
748
|
|
718
749
|
@action.("rename a file or directory to new name")
|
719
|
-
|
720
|
-
|
721
|
-
|
722
|
-
|
750
|
+
@option.(:force, "-f, --force", "rename even if new file or dir exists")
|
751
|
+
def rename(old_file, new_file, force: false)
|
752
|
+
opts = []
|
753
|
+
if force
|
754
|
+
opts << "-f"
|
755
|
+
else
|
756
|
+
! File.exist?(new_file) or
|
757
|
+
raise action_error("#{new_file}: Already exist.")
|
758
|
+
end
|
759
|
+
git "mv", *opts, old_file, new_file
|
760
|
+
end
|
761
|
+
|
762
|
+
@action.("rename multiple files by pattern")
|
763
|
+
@option.(:force, "-f, --force", "rename even if new file or dir exists")
|
764
|
+
def rename__all(old_pattern, new_pattern, file, *file_, force: false)
|
765
|
+
opts = []
|
766
|
+
if opts
|
767
|
+
opts << "-f"
|
768
|
+
end
|
769
|
+
files = [file, *file_]
|
770
|
+
! files.empty? or
|
771
|
+
raise action_error("No files nor directories.")
|
772
|
+
#
|
773
|
+
begin
|
774
|
+
old_rexp = Regexp.compile(old_pattern)
|
775
|
+
rescue => exc
|
776
|
+
raise action_error("#{old_pattern}: Invalid regular expression.")
|
777
|
+
end
|
778
|
+
#
|
779
|
+
pairs = []
|
780
|
+
files.each do |old_file|
|
781
|
+
new_file = old_file.gsub(old_rexp, new_pattern)
|
782
|
+
pairs << [old_file, new_file]
|
783
|
+
puts "#{old_file} => #{new_file}"
|
784
|
+
new_file != old_file or
|
785
|
+
raise action_error("#{new_file}: New name is same as old name.")
|
786
|
+
force || ! File.exist?(new_file) or
|
787
|
+
raise action_error("#{new_file}: Already exist.")
|
788
|
+
end
|
789
|
+
#
|
790
|
+
puts ""
|
791
|
+
print "Are you sure to rename above files? [Y/n]: "
|
792
|
+
answer_yes = (
|
793
|
+
case $stdin.gets.strip()
|
794
|
+
when "" ; true
|
795
|
+
when /\Ay/i ; true
|
796
|
+
when /\An/i ; false
|
797
|
+
else ; false
|
798
|
+
end
|
799
|
+
)
|
800
|
+
return unless answer_yes
|
801
|
+
#
|
802
|
+
pairs.each do |old_file, new_file|
|
803
|
+
git "mv", *opts, old_file, new_file
|
804
|
+
end
|
723
805
|
end
|
724
806
|
|
725
807
|
@action.("delete files or directories")
|
726
808
|
@option.(:recursive, "-r, --recursive", "delete files recursively.")
|
727
|
-
|
809
|
+
@option.(:force , "-f, --force" , "delete files forcedly.")
|
810
|
+
def delete(file, *file2, recursive: false, force: false)
|
728
811
|
files = [file] + file2
|
729
|
-
opts =
|
812
|
+
opts = []
|
813
|
+
opts << "-r" if recursive
|
814
|
+
opts << "-f" if force
|
730
815
|
git "rm", *opts, *files
|
731
816
|
end
|
732
817
|
|
@@ -909,6 +994,19 @@ END
|
|
909
994
|
end
|
910
995
|
end
|
911
996
|
|
997
|
+
@action.("rollback merge commit")
|
998
|
+
def unmerge()
|
999
|
+
#; [!8aa2p] fails if HEAD is not a merge commit.
|
1000
|
+
merge_commit?("HEAD") or
|
1001
|
+
raise action_error("HEAD is not a merge commit.")
|
1002
|
+
#; [!qfo66] fails if any changed files exist.
|
1003
|
+
! changes_exist?() or
|
1004
|
+
raise action_error("There are changes not committed yet."\
|
1005
|
+
" Put them into stash before unmerging.")
|
1006
|
+
#; [!mtaem] rollback merge commit
|
1007
|
+
run_once "commit:rollback", restore: true
|
1008
|
+
end
|
1009
|
+
|
912
1010
|
end
|
913
1011
|
|
914
1012
|
define_alias("commit" , "commit:create")
|
@@ -917,6 +1015,7 @@ END
|
|
917
1015
|
define_alias("fixup" , "commit:fixup")
|
918
1016
|
define_alias("commits" , "commit:show")
|
919
1017
|
#define_alias("rollback", "commit:rollback")
|
1018
|
+
define_alias("unmerge" , "commit:unmerge")
|
920
1019
|
|
921
1020
|
|
922
1021
|
##
|
data/test/action_test.rb
CHANGED
@@ -747,6 +747,55 @@ Oktest.scope do
|
|
747
747
|
end
|
748
748
|
end
|
749
749
|
|
750
|
+
topic 'commit:unmerge' do
|
751
|
+
def _prepare(n)
|
752
|
+
file = "file#{n}.tmp"
|
753
|
+
writefile(file, "A\n")
|
754
|
+
system! "git stage ."
|
755
|
+
system! "git commit -qm 'commit A'"
|
756
|
+
cid1 = get_commit_id("HEAD")
|
757
|
+
system! "git checkout -q -b b#{n}"
|
758
|
+
writefile(file, "AA\n")
|
759
|
+
system! "git stage ."
|
760
|
+
system! "git commit -qm 'commit B'"
|
761
|
+
system! "git checkout -q -"
|
762
|
+
system! "git merge -q -m 'ok' --no-ff b#{n}"
|
763
|
+
cid2 = get_commit_id("HEAD")
|
764
|
+
ok {cid2} != cid1
|
765
|
+
return cid1, cid2
|
766
|
+
end
|
767
|
+
spec "[!mtaem] rollback merge commit" do
|
768
|
+
cid1, cid2 = _prepare("4963")
|
769
|
+
output, sout = main "commit:unmerge"
|
770
|
+
cid3 = get_commit_id("HEAD")
|
771
|
+
ok {cid3} != cid2
|
772
|
+
ok {cid3} == cid1
|
773
|
+
ok {sout} == "[gi]$ git reset --hard HEAD^\n"
|
774
|
+
ok {output} == "HEAD is now at #{cid1} commit A\n"
|
775
|
+
end
|
776
|
+
spec "[!8aa2p] fails if HEAD is not a merge commit." do
|
777
|
+
_prepare("6033")
|
778
|
+
main "commit:unmerge"
|
779
|
+
output, sout, serr, status = main! "commit:unmerge"
|
780
|
+
ok {output} == ""
|
781
|
+
ok {sout} == ""
|
782
|
+
ok {status} == 1
|
783
|
+
ok {serr} != ""
|
784
|
+
ok {serr.split("\n").first} == "[ERROR] HEAD is not a merge commit."
|
785
|
+
end
|
786
|
+
spec "[!qfo66] fails if any changed files exist." do
|
787
|
+
_prepare("5014")
|
788
|
+
file = "file5014.tmp"
|
789
|
+
writefile(file, "B\n")
|
790
|
+
output, sout, serr, status = main! "commit:unmerge"
|
791
|
+
ok {output} == ""
|
792
|
+
ok {sout} == ""
|
793
|
+
ok {status} == 1
|
794
|
+
ok {serr} != ""
|
795
|
+
ok {serr.split("\n").first} == "[ERROR] There are changes not committed yet. Put them into stash before unmerging."
|
796
|
+
end
|
797
|
+
end
|
798
|
+
|
750
799
|
}
|
751
800
|
|
752
801
|
|
@@ -926,7 +975,7 @@ Oktest.scope do
|
|
926
975
|
before do
|
927
976
|
_reset_all_commits()
|
928
977
|
end
|
929
|
-
spec "list (un)tracked/ignored/missing files" do
|
978
|
+
spec "list (un)tracked/changed/ignored/missing files" do
|
930
979
|
file1 = "file1154.txt"
|
931
980
|
file2 = "file1154.css"
|
932
981
|
file3 = "file1154.json"
|
@@ -938,6 +987,7 @@ Oktest.scope do
|
|
938
987
|
system! "git add #{file1}"
|
939
988
|
system! "git add #{file2}"
|
940
989
|
system! "git commit -q -m 'add #{file1} and #{file2}'"
|
990
|
+
writefile(file2, "BB\n")
|
941
991
|
writefile(".gitignore", "*~\n")
|
942
992
|
at_end { rm_rf ".gitignore" }
|
943
993
|
## tracked
|
@@ -955,6 +1005,12 @@ Oktest.scope do
|
|
955
1005
|
?? file1154.json
|
956
1006
|
END
|
957
1007
|
ok {output} == ""
|
1008
|
+
## changed
|
1009
|
+
output, sout = main "file:list", "-F", "changed"
|
1010
|
+
ok {sout} == <<~'END'
|
1011
|
+
[gi]$ git status -s -uno .
|
1012
|
+
END
|
1013
|
+
ok {output} == " M file1154.css\n"
|
958
1014
|
## ignored
|
959
1015
|
output, sout = main "file:list", "-F", "ignored"
|
960
1016
|
ok {sout} == <<~'END'
|
@@ -1026,6 +1082,34 @@ Oktest.scope do
|
|
1026
1082
|
end
|
1027
1083
|
end
|
1028
1084
|
|
1085
|
+
topic 'file:rename:all' do
|
1086
|
+
spec "rename multiple files by pattern" do
|
1087
|
+
file = "file5190"
|
1088
|
+
dummy_file(file+"a.tmp", "A\n")
|
1089
|
+
dummy_file(file+"b.tmp", "B\n")
|
1090
|
+
at_end { Dir.glob(file+"*.*").each {|x| File.unlink(x) } }
|
1091
|
+
system! "git add #{file}a.tmp #{file}b.tmp"
|
1092
|
+
system! "git commit -q -m 'add files'"
|
1093
|
+
#
|
1094
|
+
ok {file+"a.tmp"}.file_exist?
|
1095
|
+
ok {file+"b.tmp"}.file_exist?
|
1096
|
+
ok {file+"a.txt"}.not_exist?
|
1097
|
+
ok {file+"b.txt"}.not_exist?
|
1098
|
+
output, sout = main "file:rename:all", '\.tmp$', '.txt', file+"a.tmp", file+"b.tmp", stdin: "y"
|
1099
|
+
ok {file+"a.tmp"}.not_exist?
|
1100
|
+
ok {file+"b.tmp"}.not_exist?
|
1101
|
+
ok {file+"a.txt"}.file_exist?
|
1102
|
+
ok {file+"b.txt"}.file_exist?
|
1103
|
+
ok {sout} == "file5190a.tmp => file5190a.txt\n"\
|
1104
|
+
"file5190b.tmp => file5190b.txt\n"\
|
1105
|
+
"\n"\
|
1106
|
+
"Are you sure to rename above files? [Y/n]: "\
|
1107
|
+
"[gi]$ git mv -f file5190a.tmp file5190a.txt\n"\
|
1108
|
+
"[gi]$ git mv -f file5190b.tmp file5190b.txt\n"
|
1109
|
+
ok {output} == ""
|
1110
|
+
end
|
1111
|
+
end
|
1112
|
+
|
1029
1113
|
topic 'file:restore' do
|
1030
1114
|
before do
|
1031
1115
|
system! "git reset -q --hard HEAD"
|
data/test/shared.rb
CHANGED
@@ -84,6 +84,11 @@ Oktest.global_scope do
|
|
84
84
|
return `git branch --show-current`.strip()
|
85
85
|
end
|
86
86
|
|
87
|
+
def get_commit_id(name="HEAD", width: 7)
|
88
|
+
commit_id = `git rev-parse #{name}`.strip()
|
89
|
+
return commit_id[0...width]
|
90
|
+
end
|
91
|
+
|
87
92
|
def _reset_all_commits()
|
88
93
|
system! "git reset -q --hard #{$initial_commit_id}"
|
89
94
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: git-improved
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- kwatch
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2024-09-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: benry-cmdapp
|
@@ -16,14 +16,20 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '1'
|
19
|
+
version: '1.1'
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 1.1.2
|
20
23
|
type: :runtime
|
21
24
|
prerelease: false
|
22
25
|
version_requirements: !ruby/object:Gem::Requirement
|
23
26
|
requirements:
|
24
27
|
- - "~>"
|
25
28
|
- !ruby/object:Gem::Version
|
26
|
-
version: '1'
|
29
|
+
version: '1.1'
|
30
|
+
- - ">="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 1.1.2
|
27
33
|
- !ruby/object:Gem::Dependency
|
28
34
|
name: benry-unixcommand
|
29
35
|
requirement: !ruby/object:Gem::Requirement
|
@@ -90,7 +96,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
90
96
|
- !ruby/object:Gem::Version
|
91
97
|
version: '0'
|
92
98
|
requirements: []
|
93
|
-
rubygems_version: 3.4.
|
99
|
+
rubygems_version: 3.4.19
|
94
100
|
signing_key:
|
95
101
|
specification_version: 4
|
96
102
|
summary: Improved interface for Git command
|