twig 1.0.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.
- data/.gitignore +3 -0
- data/.rvmrc +1 -0
- data/CONTRIBUTING.md +26 -0
- data/Gemfile +2 -0
- data/HISTORY.md +6 -0
- data/LICENSE.md +22 -0
- data/README.md +232 -0
- data/Rakefile +10 -0
- data/bin/twig +10 -0
- data/bin/twig-gh-open +41 -0
- data/bin/twig-gh-update +93 -0
- data/bin/twig-help +4 -0
- data/install +18 -0
- data/lib/twig/branch.rb +72 -0
- data/lib/twig/cli.rb +177 -0
- data/lib/twig/commit_time.rb +32 -0
- data/lib/twig/display.rb +116 -0
- data/lib/twig/options.rb +55 -0
- data/lib/twig/util.rb +9 -0
- data/lib/twig/version.rb +3 -0
- data/lib/twig.rb +119 -0
- data/spec/spec_helper.rb +1 -0
- data/spec/twig/branch_spec.rb +232 -0
- data/spec/twig/cli_spec.rb +291 -0
- data/spec/twig/commit_time_spec.rb +47 -0
- data/spec/twig/display_spec.rb +117 -0
- data/spec/twig/options_spec.rb +126 -0
- data/spec/twig/util_spec.rb +16 -0
- data/spec/twig_spec.rb +220 -0
- data/twig.gemspec +38 -0
- metadata +166 -0
data/.gitignore
ADDED
data/.rvmrc
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
rvm use ruby-1.8.7-p358@twig --create
|
data/CONTRIBUTING.md
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
How to contribute
|
2
|
+
=================
|
3
|
+
|
4
|
+
Let's make life easier for people with lots of Git branches.
|
5
|
+
|
6
|
+
Found a bug or have a suggestion? [Please open an issue][issues] or ping
|
7
|
+
[@ronalddevera on Twitter][twitter].
|
8
|
+
|
9
|
+
If you want to hack on some code, even better! Here are the basics:
|
10
|
+
|
11
|
+
1. Fork the Twig repo.
|
12
|
+
2. Check out the [**`development`** branch][dev branch]; the `master` branch is
|
13
|
+
for stable builds only.
|
14
|
+
3. Run the tests to make sure that they pass on your machine: `bundle && rake`
|
15
|
+
4. Add one or more failing tests for your feature or bug fix.
|
16
|
+
5. Write your feature or bug fix to make the test(s) pass.
|
17
|
+
6. Test the change manually:
|
18
|
+
1. `gem build twig.gemspec`
|
19
|
+
2. `gem install twig-x.y.z.gem` (fill in the current version number)
|
20
|
+
7. Push to your fork and submit a pull request.
|
21
|
+
|
22
|
+
Thanks for contributing!
|
23
|
+
|
24
|
+
[issues]: https://github.com/rondevera/twig/issues
|
25
|
+
[twitter]: https://twitter.com/ronalddevera
|
26
|
+
[dev branch]: https://github.com/rondevera/twig/commits/development
|
data/Gemfile
ADDED
data/LICENSE.md
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Ron DeVera
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,232 @@
|
|
1
|
+
Twig: Your personal Git branch assistant.
|
2
|
+
=========================================
|
3
|
+
|
4
|
+
It's hard enough trying to remember the names of all of your Git branches. You
|
5
|
+
also need those branches' issue tracker ids, issue statuses, and reminders of
|
6
|
+
what to do next with each branch. `git branch` only lists them in alphabetical
|
7
|
+
order, which just doesn't cut it.
|
8
|
+
|
9
|
+
**Twig shows you your most recent branches, and remembers branch details for
|
10
|
+
you.** It supports subcommands, like automatically fetching statuses from your
|
11
|
+
issue tracking system. It's flexible enough to fit your everyday Git workflow,
|
12
|
+
and will save you a ton of time.
|
13
|
+
|
14
|
+
Here's how Twig looks in action:
|
15
|
+
|
16
|
+
$ twig
|
17
|
+
|
18
|
+
issue status todo branch
|
19
|
+
----- ------ ---- ------
|
20
|
+
2013-01-26 18:00:21 (7m ago) 486 In progress Rebase optimize-all-the-things
|
21
|
+
2013-01-26 16:49:21 (2h ago) 268 In progress - whitespace-all-the-things
|
22
|
+
2013-01-23 18:35:21 (3d ago) 159 Shipped Test in prod * refactor-all-the-things
|
23
|
+
2013-01-22 17:12:09 (4d ago) - - - development
|
24
|
+
2013-01-20 19:45:42 (6d ago) - - - master
|
25
|
+
|
26
|
+
|
27
|
+
Installation
|
28
|
+
============
|
29
|
+
|
30
|
+
gem install twig
|
31
|
+
|
32
|
+
|
33
|
+
Usage
|
34
|
+
=====
|
35
|
+
|
36
|
+
Twig lets you get/set custom properties for each branch, and list branches
|
37
|
+
chronologically with their properties.
|
38
|
+
|
39
|
+
* `twig`: List all branches with properties, newest first
|
40
|
+
* `twig <property>`: Get a property for the current branch
|
41
|
+
* `twig <property> <value>`: Set a property for the current branch
|
42
|
+
* `twig --unset <property>`: Unset a property for the current branch
|
43
|
+
* `twig <property> -b <branch>`: Get property for any branch
|
44
|
+
* `twig <property> <value> -b <branch>`: Set property for any branch
|
45
|
+
* `twig --unset <property> -b <branch>`: Unset property for any branch
|
46
|
+
* `twig --help`: More info
|
47
|
+
|
48
|
+
|
49
|
+
Filtering branches
|
50
|
+
------------------
|
51
|
+
|
52
|
+
Twig lists all of your branches by default (newest first), but you can filter
|
53
|
+
them by name and age:
|
54
|
+
|
55
|
+
* `twig --only-branch <pattern>`:
|
56
|
+
Only list branches whose name matches a given pattern
|
57
|
+
* `twig --except-branch <pattern>`:
|
58
|
+
Don't list branches whose name matches a given pattern
|
59
|
+
* `twig --max-days-old <age>`:
|
60
|
+
Only list branches below a given age
|
61
|
+
* `twig --all`:
|
62
|
+
List all branches regardless of other filtering options
|
63
|
+
|
64
|
+
You can put your most frequently used options into `~/.twigrc`, and they'll be
|
65
|
+
automatically included when you run `twig`. Example:
|
66
|
+
|
67
|
+
# ~/.twigrc:
|
68
|
+
except-branch: staging
|
69
|
+
max-days-old: 30
|
70
|
+
|
71
|
+
|
72
|
+
Examples
|
73
|
+
--------
|
74
|
+
|
75
|
+
List your branches, and highlight the current branch:
|
76
|
+
|
77
|
+
$ twig
|
78
|
+
|
79
|
+
2013-01-26 18:07:21 (7m ago) * refactor-all-the-things
|
80
|
+
2013-01-24 17:12:09 (2d ago) development
|
81
|
+
2013-01-23 19:45:42 (3d ago) master
|
82
|
+
|
83
|
+
Remember a branch's issue tracker id:
|
84
|
+
|
85
|
+
$ git checkout my-branch
|
86
|
+
Switched to branch 'my-branch'.
|
87
|
+
|
88
|
+
$ twig issue 123
|
89
|
+
Saved property "issue" as "123" for branch "my-branch".
|
90
|
+
# Nearly any property name will do, like "bug" or "ticket".
|
91
|
+
|
92
|
+
$ twig issue
|
93
|
+
123
|
94
|
+
|
95
|
+
$ open "https://github.com/myname/myproject/issues/`twig issue`"
|
96
|
+
# Opens a browser window for this GitHub issue (in OS X).
|
97
|
+
|
98
|
+
Keep notes on what you need to do with each branch:
|
99
|
+
|
100
|
+
$ twig todo "Run tests"
|
101
|
+
Saved property "todo" as "Run tests" for branch "my-branch".
|
102
|
+
|
103
|
+
$ twig todo "Deploy" -b finished-branch
|
104
|
+
Saved property "todo" as "Deploy" for branch "finished-branch".
|
105
|
+
|
106
|
+
$ twig
|
107
|
+
|
108
|
+
todo branch
|
109
|
+
---- ------
|
110
|
+
2013-01-26 18:00:25 (7m ago) Run tests * my-branch
|
111
|
+
2013-01-23 18:35:12 (3d ago) Deploy finished-branch
|
112
|
+
2013-01-22 17:12:23 (4d ago) - master
|
113
|
+
|
114
|
+
Remember the order in which you were rebasing your stack of branches:
|
115
|
+
|
116
|
+
$ git checkout master
|
117
|
+
Switched to branch 'master'.
|
118
|
+
|
119
|
+
$ twig rebase-onto branch2 -b branch3
|
120
|
+
Saved property "rebase-onto" as "branch2" for branch "branch3".
|
121
|
+
|
122
|
+
$ twig rebase-onto branch1 -b branch2
|
123
|
+
Saved property "rebase-onto" as "branch1" for branch "branch2".
|
124
|
+
|
125
|
+
$ twig
|
126
|
+
|
127
|
+
rebase-onto branch
|
128
|
+
----------- ------
|
129
|
+
2013-01-26 18:00:25 (7m ago) branch2 branch3
|
130
|
+
2013-01-26 16:49:47 (2h ago) branch1 branch2
|
131
|
+
2013-01-23 18:35:12 (3d ago) - branch1
|
132
|
+
2013-01-22 17:12:23 (4d ago) - * master
|
133
|
+
|
134
|
+
You can set just about any custom property you need to remember for each branch.
|
135
|
+
|
136
|
+
|
137
|
+
Subcommands
|
138
|
+
===========
|
139
|
+
|
140
|
+
Twig comes with two subcommands, `gh-open` and `gh-update`, which are handy for
|
141
|
+
use with GitHub repositories.
|
142
|
+
|
143
|
+
While inside a Git repo, run `twig gh-open` to see the repo's GitHub URL, and open
|
144
|
+
a browser window if possible:
|
145
|
+
|
146
|
+
$ cd myproject
|
147
|
+
|
148
|
+
$ twig gh-open
|
149
|
+
GitHub URL: https://github.com/myname/myproject
|
150
|
+
# Also opens a browser window (OS X only).
|
151
|
+
|
152
|
+
If you're working on an issue for a GitHub repository, you can also use the
|
153
|
+
`gh-update` subcommand:
|
154
|
+
|
155
|
+
$ git checkout add-feature
|
156
|
+
Switched to branch 'add-feature'.
|
157
|
+
|
158
|
+
$ twig issue 222
|
159
|
+
Saved property "issue" as "222" for branch "add-feature".
|
160
|
+
|
161
|
+
$ twig
|
162
|
+
|
163
|
+
issue status branch
|
164
|
+
----- ------ ------
|
165
|
+
2013-01-26 18:00:25 (7m ago) 222 - * add-feature
|
166
|
+
2013-01-23 18:35:12 (3d ago) 111 - fix-bug
|
167
|
+
2013-01-22 17:12:23 (4d ago) - - master
|
168
|
+
|
169
|
+
$ twig gh-update
|
170
|
+
# Automatically looks up the GitHub issue status for each
|
171
|
+
# of your local branches, and saves it locally.
|
172
|
+
|
173
|
+
$ twig
|
174
|
+
|
175
|
+
issue status branch
|
176
|
+
----- ------ ------
|
177
|
+
2013-01-26 18:00:25 (7m ago) 222 open * add-feature
|
178
|
+
2013-01-23 18:35:12 (3d ago) 111 closed fix-bug
|
179
|
+
2013-01-22 17:12:23 (4d ago) - - master
|
180
|
+
|
181
|
+
Run `twig gh-update` periodically to keep up with GitHub issues locally.
|
182
|
+
|
183
|
+
You can write any Twig subcommand that fits your own Git workflow. To write a
|
184
|
+
Twig subcommand:
|
185
|
+
|
186
|
+
1. Write a script. Any language will do. (If you want to take advantage of
|
187
|
+
Twig's option parsing and branch processing, you'll need Ruby. See
|
188
|
+
[`bin/twig-gh-update`][twig-gh-update] for an example.)
|
189
|
+
2. Save it with the `twig-` prefix in your `$PATH`,
|
190
|
+
e.g., `~/bin/twig-my-subcommand`.
|
191
|
+
3. Make it executable: `chmod ugo+x ~/bin/twig-my-subcommand`
|
192
|
+
4. Run your subcommand: `twig my-subcommand` (with a *space* after `twig`)
|
193
|
+
|
194
|
+
[twig-gh-update]: https://github.com/rondevera/twig/blob/master/bin/twig-gh-update
|
195
|
+
|
196
|
+
Some ideas for subcommands:
|
197
|
+
|
198
|
+
* Get each branch's status for any issue tracking system that has an API,
|
199
|
+
like [JIRA](http://www.atlassian.com/software/jira/overview),
|
200
|
+
[FogBugz](http://www.fogcreek.com/fogbugz/), or
|
201
|
+
[Lighthouse](http://lighthouseapp.com/).
|
202
|
+
* Given an issue tracker id, check out that issue's branch locally. Great for
|
203
|
+
following teammates' branches, remembering their issue ids, and knowing when
|
204
|
+
they've shipped.
|
205
|
+
* Generate a formatted list of your branches from the past week. Useful for
|
206
|
+
emailing your team about what you're up to.
|
207
|
+
|
208
|
+
If you write a subcommand that others can appreciate, send a pull request or add
|
209
|
+
it to the [Twig wiki][wiki]!
|
210
|
+
|
211
|
+
|
212
|
+
More info
|
213
|
+
=========
|
214
|
+
|
215
|
+
- **Requirements:** Tested with Git 1.6.5 and Ruby 1.8.7. Probably works with
|
216
|
+
older software, but it's not guaranteed.
|
217
|
+
- **Contributing:** Found a bug or have a suggestion? [Please open an
|
218
|
+
issue][issues] or ping [@ronalddevera on Twitter][twitter]. If you want to
|
219
|
+
hack on some features or contribute a subcommand you've written, feel free to
|
220
|
+
fork and send a pull request for the **[development branch][dev branch]**.
|
221
|
+
(The master branch is for stable builds only.) See the full details in the
|
222
|
+
[Contributing][contributing] instructions.
|
223
|
+
- **History:** [History/changelog for Twig][history]
|
224
|
+
- **License:** Twig is released under the [MIT License][license].
|
225
|
+
|
226
|
+
[issues]: https://github.com/rondevera/twig/issues
|
227
|
+
[wiki]: https://github.com/rondevera/twig/wiki
|
228
|
+
[twitter]: https://twitter.com/ronalddevera
|
229
|
+
[dev branch]: https://github.com/rondevera/twig/commits/development
|
230
|
+
[contributing]: https://github.com/rondevera/twig/blob/master/CONTRIBUTING.md
|
231
|
+
[history]: https://github.com/rondevera/twig/blob/master/HISTORY.md
|
232
|
+
[license]: https://github.com/rondevera/twig/blob/master/LICENSE.md
|
data/Rakefile
ADDED
data/bin/twig
ADDED
data/bin/twig-gh-open
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# Opens a browser window for the current GitHub repo.
|
4
|
+
#
|
5
|
+
# Author: Ron DeVera <http://rondevera.com>
|
6
|
+
|
7
|
+
class TwigGithubRepo
|
8
|
+
def initialize
|
9
|
+
if origin_url.empty? || username.empty? || repository.empty?
|
10
|
+
abort_for_non_github_repo
|
11
|
+
end
|
12
|
+
|
13
|
+
yield(self)
|
14
|
+
end
|
15
|
+
|
16
|
+
def origin_url
|
17
|
+
@origin_url ||= `git config remote.origin.url`.strip
|
18
|
+
end
|
19
|
+
|
20
|
+
def origin_url_parts
|
21
|
+
@origin_url_parts ||= origin_url.split(/[\/:]/)
|
22
|
+
end
|
23
|
+
|
24
|
+
def username
|
25
|
+
@username ||= origin_url_parts[-2] || ''
|
26
|
+
end
|
27
|
+
|
28
|
+
def repository
|
29
|
+
@repo ||= origin_url_parts[-1].sub(/\.git$/, '') || ''
|
30
|
+
end
|
31
|
+
|
32
|
+
def abort_for_non_github_repo
|
33
|
+
abort 'This does not appear to be a GitHub repository.'
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
TwigGithubRepo.new do |gh_repo|
|
38
|
+
url = "https://github.com/#{gh_repo.username}/#{gh_repo.repository}"
|
39
|
+
puts "GitHub URL: #{url}"
|
40
|
+
`which open && open #{url}`
|
41
|
+
end
|
data/bin/twig-gh-update
ADDED
@@ -0,0 +1,93 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# Updates each branch with the latest issue status on GitHub.
|
4
|
+
#
|
5
|
+
# Author: Ron DeVera <http://rondevera.com>
|
6
|
+
|
7
|
+
require File.join(File.dirname(__FILE__), '..', 'lib', 'twig')
|
8
|
+
require 'rubygems'
|
9
|
+
require 'json'
|
10
|
+
require 'net/https'
|
11
|
+
require 'uri'
|
12
|
+
|
13
|
+
class TwigGithubRepo
|
14
|
+
def initialize
|
15
|
+
if origin_url.empty? || username.empty? || repository.empty?
|
16
|
+
abort_for_non_github_repo
|
17
|
+
end
|
18
|
+
|
19
|
+
yield(self)
|
20
|
+
end
|
21
|
+
|
22
|
+
def origin_url
|
23
|
+
@origin_url ||= `git config remote.origin.url`.strip
|
24
|
+
end
|
25
|
+
|
26
|
+
def origin_url_parts
|
27
|
+
@origin_url_parts ||= origin_url.split(/[\/:]/)
|
28
|
+
end
|
29
|
+
|
30
|
+
def username
|
31
|
+
@username ||= origin_url_parts[-2] || ''
|
32
|
+
end
|
33
|
+
|
34
|
+
def repository
|
35
|
+
@repo ||= origin_url_parts[-1].sub(/\.git$/, '') || ''
|
36
|
+
end
|
37
|
+
|
38
|
+
def abort_for_non_github_repo
|
39
|
+
abort 'This does not appear to be a GitHub repository.'
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
twig = Twig.new
|
44
|
+
twig.read_config_file!
|
45
|
+
twig.read_cli_options!(ARGV)
|
46
|
+
|
47
|
+
TwigGithubRepo.new do |gh_repo|
|
48
|
+
$stdout.sync = true
|
49
|
+
print 'Getting latest states for GitHub issues...'
|
50
|
+
|
51
|
+
issues = {}
|
52
|
+
issues_uri_base =
|
53
|
+
"https://api.github.com/repos/#{gh_repo.username}/#{gh_repo.repository}/issues"
|
54
|
+
issues_uris = [
|
55
|
+
URI.parse("#{issues_uri_base}?state=open"),
|
56
|
+
URI.parse("#{issues_uri_base}?state=closed")
|
57
|
+
]
|
58
|
+
|
59
|
+
begin
|
60
|
+
issues_uris.each do |issues_uri|
|
61
|
+
http = Net::HTTP.new(issues_uri.host, issues_uri.port)
|
62
|
+
http.use_ssl = true
|
63
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
64
|
+
request = Net::HTTP::Get.new(issues_uri.path + '?' + issues_uri.query)
|
65
|
+
response = http.request(request)
|
66
|
+
|
67
|
+
if response.code.to_i == 200
|
68
|
+
issues_data = JSON.parse(response.body)
|
69
|
+
issues_data.each do |issue_data|
|
70
|
+
issues[issue_data['number']] = issue_data
|
71
|
+
end
|
72
|
+
else
|
73
|
+
puts "\nERROR: Couldn't get open issues from GitHub. " <<
|
74
|
+
"(Response: #{response.code})"
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
twig.branches.each do |branch|
|
80
|
+
issue_number = branch.get_property('issue').to_i
|
81
|
+
next unless issue_number > 0
|
82
|
+
|
83
|
+
issue = issues[issue_number]
|
84
|
+
next unless issue
|
85
|
+
|
86
|
+
state = issue['state']
|
87
|
+
branch.set_property('status', state) unless state.nil? || state.empty?
|
88
|
+
|
89
|
+
print '.'
|
90
|
+
end
|
91
|
+
|
92
|
+
puts
|
93
|
+
end
|
data/bin/twig-help
ADDED
data/install
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
twig_bin_path = File.expand_path(File.dirname(__FILE__)) + '/bin/**/twig*'
|
4
|
+
twig_bins = Dir.glob(twig_bin_path)
|
5
|
+
user_bin_path = '~/bin'
|
6
|
+
|
7
|
+
twig_bins.each do |bin|
|
8
|
+
`ln -fs #{bin} #{user_bin_path}`
|
9
|
+
end
|
10
|
+
|
11
|
+
if `which twig` && $?.success?
|
12
|
+
puts 'All set! Run `twig` to list your local branches.'
|
13
|
+
puts 'For more info, run `twig --help`.'
|
14
|
+
else
|
15
|
+
puts 'Argh! Something went wrong. Please try symlinking the files in '
|
16
|
+
puts '`./bin/` to `~/bin/` and ensure that `~/bin/` is in your `$PATH`, or '
|
17
|
+
puts 'contact rondevera on GitHub.'
|
18
|
+
end
|
data/lib/twig/branch.rb
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
class Twig
|
2
|
+
class Branch
|
3
|
+
|
4
|
+
RESERVED_BRANCH_PROPERTIES = %w[merge rebase remote]
|
5
|
+
PROPERTY_NAME_FROM_GIT_CONFIG = /^branch\.[^.]+\.([^=]+)=.*$/
|
6
|
+
|
7
|
+
attr_accessor :name, :last_commit_time
|
8
|
+
|
9
|
+
def self.all_properties
|
10
|
+
@_all_properties ||= begin
|
11
|
+
config_lines = Twig.run('git config --list').split("\n")
|
12
|
+
|
13
|
+
properties = config_lines.map do |line|
|
14
|
+
# Split by rightmost `=`, allowing branch names to contain `=`:
|
15
|
+
key, value = line.match(/(.+)=(.+)/)[1..2]
|
16
|
+
|
17
|
+
key_parts = key.split('.')
|
18
|
+
key_parts.last if key_parts[0] == 'branch' && key_parts.size > 2
|
19
|
+
end.compact
|
20
|
+
|
21
|
+
properties.uniq.sort - RESERVED_BRANCH_PROPERTIES
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def initialize(name, attrs = {})
|
26
|
+
self.name = name
|
27
|
+
raise ArgumentError, '`name` is required' if name.empty?
|
28
|
+
|
29
|
+
self.last_commit_time = attrs[:last_commit_time]
|
30
|
+
end
|
31
|
+
|
32
|
+
def to_s ; name ; end
|
33
|
+
|
34
|
+
def sanitize_property(property_name)
|
35
|
+
property_name.gsub(/[ _]+/, '')
|
36
|
+
end
|
37
|
+
|
38
|
+
def get_property(property_name)
|
39
|
+
Twig.run("git config branch.#{name}.#{property_name}")
|
40
|
+
end
|
41
|
+
|
42
|
+
def set_property(property_name, value)
|
43
|
+
property_name = sanitize_property(property_name)
|
44
|
+
value = value.to_s.strip
|
45
|
+
|
46
|
+
if RESERVED_BRANCH_PROPERTIES.include?(property_name)
|
47
|
+
%{Can't modify the reserved property "#{property_name}".}
|
48
|
+
elsif value.empty?
|
49
|
+
%{Can't set a branch property to an empty string.}
|
50
|
+
else
|
51
|
+
Twig.run(%{git config branch.#{name}.#{property_name} "#{value}"})
|
52
|
+
result_body = %{property "#{property_name}" as "#{value}" for branch "#{name}".}
|
53
|
+
if $?.success?
|
54
|
+
"Saved #{result_body}"
|
55
|
+
else
|
56
|
+
"Could not save #{result_body}"
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def unset_property(property_name)
|
62
|
+
value = get_property(property_name)
|
63
|
+
if value && !value.empty?
|
64
|
+
Twig.run(%{git config --unset branch.#{name}.#{property_name}})
|
65
|
+
%{Removed property "#{property_name}" for branch "#{name}".}
|
66
|
+
else
|
67
|
+
%{The branch "#{name}" does not have the property "#{property_name}".}
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
end
|