git_curate 1.0.0 → 1.1.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7dc878f7afe05d52530f703159c8148c1e717b448c4464235fc5d98474f2b7d3
4
- data.tar.gz: f7c99506b5e110f4fa8a371f6451be20001eb30f9eaec43b281d36dc0a9ef6e3
3
+ metadata.gz: 17d14ef21b3dceacc1b65f9d2ce51238b1f2841f1a0815afdc302ca97875c109
4
+ data.tar.gz: 246e45f78b57dd14cef91610ef09e3944f82b8559184248327a99759fd99b1bd
5
5
  SHA512:
6
- metadata.gz: 1f8218d0dae58c980c9e83037f07d76b78ee0a62936dc42d9643a610b247896d399e3eb820f721c43f490d2d913ae017757893ab7738c6e18a40da51046d03e3
7
- data.tar.gz: 7f298ae39612aa6400113721b4fc4c93ae774bc0478de5973af480520fa48e9f305d896555a25d43c8ebd2847befbb2b2616083b8e4997c352ffdbc0fd45aca0
6
+ metadata.gz: 5bd2a261e13944e2ef578ffd97e33719c9a191c11d8b7de5885ab75c980255df6fc52321863052b6c6d3c3a56e8690e77794ee56af914e3391da03d1e7312ce3
7
+ data.tar.gz: 0a79e2356319b7b31a454416bdc366b7924b85966c534bb6e122824279a4a459dc65daa6369780bd53342d53c28c2caacc06b9ebb92edbe0c78593f09ba2f450
@@ -1,7 +1,7 @@
1
- sudo: false
2
1
  language: ruby
3
2
  rvm:
4
- - 2.4.9
3
+ - 2.4.10
5
4
  - 2.5.8
6
5
  - 2.6.6
7
- - 2.7.1
6
+ - 2.7.2
7
+ - 3.0.0
@@ -1,5 +1,38 @@
1
1
  # Changelog
2
2
 
3
+ ### v1.1.2
4
+
5
+ * Dependency version upgrades
6
+ * Include Ruby v3 in automated tests
7
+
8
+ ### v1.1.1
9
+
10
+ * Dependency version upgrades
11
+
12
+ ### v1.1.0
13
+
14
+ #### Change that may be breaking for an obscure use case
15
+
16
+ * Output more helpful message in case there are no deletable branches when `git curate` run without `-l`/`--list` flag.
17
+
18
+ This will be a breaking change but only in the unlikely event that the output of `git curate` is being piped
19
+ through or processed by another program when run in _interactive_ (non-`--list`) mode.
20
+
21
+ _New behaviour when there are no deletable branches:_
22
+ Outputs `There are no local branches that can be deleted.`
23
+
24
+ _Old behaviour when there are no deletable branches:_
25
+ Outputs (irrelevantly and confusingly) the legend of interactive commands, followed by the message
26
+ `No branches deleted.`
27
+
28
+ ### v1.0.2
29
+
30
+ * Fix incorrect status-vs-upstream when commit subject begins with square-bracket-enclosed string.
31
+
32
+ ### v1.0.1
33
+
34
+ * Fix `fatal: bad revision '+'` error on encountering multiple worktrees.
35
+
3
36
  ### v1.0.0
4
37
 
5
38
  * Remove support for Ruby < v2.4.9.
data/README.md CHANGED
@@ -3,6 +3,7 @@
3
3
  [![Gem Version][GV img]][Gem Version]
4
4
  [![Build Status][BS img]][Build Status]
5
5
  [![Coverage Status][CS img]][Coverage Status]
6
+ [![Awesome][AR img]][Awesome Ruby]
6
7
 
7
8
  <img src="https://raw.githubusercontent.com/matt-harvey/git_curate/master/assets/demo.gif" width="1000" alt="Demo" />
8
9
 
@@ -10,7 +11,7 @@
10
11
 
11
12
  After a while, my local repo becomes cluttered with branches, and `git branch` outputs an awkwardly
12
13
  long list. I want to delete some of those branches to bring that list back under control; but I
13
- can't always remember which branches I want to keep from the branch names alone; and inspecting them
14
+ can&#8217;t always remember which branches I want to keep from the branch names alone; and inspecting them
14
15
  one at a time and _then_ running `git branch -D` in a separate step, is painful.
15
16
 
16
17
  `git curate` is intended to ease this pain. It steps you through the local branches of a repo one at
@@ -26,12 +27,12 @@ a time, outputting the following information about each:
26
27
  You can then select whether to delete or keep each branch as you go.
27
28
 
28
29
  **NOTE** `git curate` does _not_ run `git fetch` prior to generating its output. If you want to
29
- be sure that the "Status vs upstream" column reflects the latest state of the upstream branches
30
+ be sure that the &ldquo;Status vs upstream&rdquo; column reflects the latest state of the upstream branches
30
31
  as per their remote repository, you should run `git fetch` first.
31
32
 
32
33
  ## Installation
33
34
 
34
- You'll need Ruby (v2.4.9 or greater) installed. Run:
35
+ You&#8217;ll need Ruby (v2.4.9 or greater) installed. Run:
35
36
 
36
37
  ```
37
38
  gem install git_curate
@@ -50,15 +51,16 @@ git curate
50
51
  This will step you through your local branches one at a time, outputting some information about
51
52
  each, and asking you whether to keep or delete each branch.
52
53
 
53
- At each branch, enter "k"&mdash;or simply press Enter&mdash;to _keep_ the branch and move to the next one;
54
- or enter "d" to select the branch for deletion.
54
+ At each branch, enter &ldquo;k&rdquo;&mdash;or simply press Enter&mdash;to _keep_ the branch and move to the next one;
55
+ or enter &ldquo;d&rdquo; to select the branch for deletion.
55
56
 
56
- Entering "e" will end the session immediately, deleting all selected branches; and "a" will
57
+ Entering &ldquo;e&rdquo; will end the session immediately, deleting all selected branches; and &ldquo;a&rdquo; will
57
58
  abort the session without deleting any branches. Once the final branch has been considered,
58
59
  any selected branches will be immediately deleted.
59
60
 
60
61
  Note the branch you are currently on will not be included in the list, as `git` does not allow you to delete
61
- the branch you're on.
62
+ the branch you&#8217;re on. (The same applies to any branches that are currently checked out in other
63
+ [worktrees](https://git-scm.com/docs/git-worktree).)
62
64
 
63
65
  If you just want to view the information about your local branches without stepping through
64
66
  them interactively, enter `git curate --list` or `git curate -l`. Your current branch _will_
@@ -75,13 +77,14 @@ To run the test suite, run `bundle exec rake spec`. For a list of other Rake tas
75
77
 
76
78
  ## License
77
79
 
78
- The gem is available as open source under the terms of the [MIT
79
- License](http://opensource.org/licenses/MIT).
80
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
80
81
 
81
82
  [Gem Version]: https://rubygems.org/gems/git_curate
82
83
  [Build Status]: https://travis-ci.org/matt-harvey/git_curate
83
84
  [Coverage Status]: https://coveralls.io/github/matt-harvey/git_curate
85
+ [Awesome Ruby]: https://awesome-ruby.com/#-git-tools
84
86
 
85
87
  [GV img]: https://img.shields.io/gem/v/git_curate.svg
86
88
  [BS img]: https://img.shields.io/travis/matt-harvey/git_curate.svg
87
89
  [CS img]: https://img.shields.io/coveralls/matt-harvey/git_curate.svg
90
+ [AR img]: https://cdn.rawgit.com/sindresorhus/awesome/d7305f38d29fed78fa85652e3a63e154dd8e8829/media/badge.svg
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.0.0
1
+ 1.1.2
@@ -29,8 +29,8 @@ Gem::Specification.new do |spec|
29
29
  spec.require_paths = ["lib"]
30
30
 
31
31
  spec.add_runtime_dependency "highline", "2.0.3"
32
- spec.add_runtime_dependency "tabulo", "2.5.0"
33
- spec.add_runtime_dependency "tty-screen", "0.7.1"
32
+ spec.add_runtime_dependency "tabulo", "2.6.2"
33
+ spec.add_runtime_dependency "tty-screen", "0.8.1"
34
34
 
35
35
  spec.add_development_dependency "bundler"
36
36
  spec.add_development_dependency "coveralls"
@@ -1,16 +1,15 @@
1
1
  module GitCurate
2
2
 
3
+ UpstreamInfo = Struct.new(:upstream, :status)
4
+
3
5
  class Branch
4
6
 
5
7
  # Regex for determining whether a "raw" branch name is the name of the current branch
6
- CURRENT_BRANCH_REGEX = /^\*\s+/
7
-
8
- # Regexes for unpacking the output of `git branch -vv`
9
- BRANCH_NAME_REGEX = /\s+/
10
- LEADING_STAR_REGEX = /^\* /
11
- REMOTE_INFO_REGEX = /^[^\s]+\s+[^\s]+\s+\[(.+?)\]/
8
+ # on this or another worktree.
9
+ CURRENT_BRANCH_REGEX = /^[+*]\s+/
12
10
 
13
- # Returns the branch name, with "* " prefixed if it's the current branch.
11
+ # Returns the branch name, with "* " prefixed if it's the current branch on the current
12
+ # worktree, or "+ " if it's the current branch on another worktree.
14
13
  attr_reader :raw_name
15
14
 
16
15
  # Returns a human-friendly string describing the status of the branch relative to the upstream branch
@@ -22,7 +21,6 @@ module GitCurate
22
21
  @proper_name ||= @raw_name.lstrip.sub(CURRENT_BRANCH_REGEX, '')
23
22
  end
24
23
 
25
- # Returns truthy if and only if this is the currently checked out branch.
26
24
  def current?
27
25
  @current ||= (@raw_name =~ CURRENT_BRANCH_REGEX)
28
26
  end
@@ -80,28 +78,40 @@ module GitCurate
80
78
  # a brief description of each branch's status relative to its upstream branch (up to
81
79
  # date, or ahead/behind).
82
80
  def self.branch_info
83
- Util.command_to_a("git branch -vv").map do |line|
84
- line_is_current_branch = (line =~ LEADING_STAR_REGEX)
85
- tidied_line = (line_is_current_branch ? line.gsub(LEADING_STAR_REGEX, "") : line)
86
- proper_branch_name = tidied_line.split(BRANCH_NAME_REGEX)[0]
87
- raw_branch_name = (line_is_current_branch ? "* #{proper_branch_name}" : proper_branch_name)
88
- remote_info = tidied_line[REMOTE_INFO_REGEX, 1]
89
- upstream_info =
90
- if remote_info.nil?
91
- "No upstream"
81
+ # Double quotes around the format string to ensure Windows compatibility.
82
+ command = 'git for-each-ref --format="%(refname:short) .. %(upstream:short) .. %(upstream:track)" refs/heads'
83
+ branches_with_remotes = Util.command_to_a(command).map do |line|
84
+ parts = line.split("..", -1).map { |s| s.strip! ; s.empty? ? nil : s }
85
+ [parts[0], UpstreamInfo.new(parts[1], parts[2])]
86
+ end.to_h
87
+
88
+ info = Util.command_to_a("git branch").map do |line|
89
+ raw_branch_name = line.strip
90
+ proper_branch_name = raw_branch_name.gsub(CURRENT_BRANCH_REGEX, "")
91
+ upstream_info = branches_with_remotes[proper_branch_name]
92
+ upstream_data =
93
+ if upstream_info.upstream
94
+ status = upstream_info.status
95
+ if status
96
+ status.gsub(/^\[/, "").gsub(/\]$/, "").capitalize
97
+ else
98
+ "Up to date"
99
+ end
92
100
  else
93
- comparison_raw = remote_info.split(":")
94
- comparison_raw.length < 2 ? "Up to date" : comparison_raw[1].strip.capitalize
101
+ "No upstream"
95
102
  end
96
- [raw_branch_name, upstream_info]
97
- end.to_h
103
+ [raw_branch_name, upstream_data]
104
+ end
105
+
106
+ info.to_h
98
107
  end
99
108
 
100
109
  def self.delete_multi(*branches)
101
110
  Util.command_output("git branch -D #{branches.map(&:proper_name).join(" ")} --")
102
111
  end
103
112
 
104
- # raw_name should start in "* " if the current branch, but should otherwise have not whitespace.
113
+ # raw_name should start in "* " if the current branch on this worktree, "+ " if it's the current
114
+ # branch on another worktree, or otherwise have no whitespace.
105
115
  def initialize(raw_name, merged:, upstream_info:)
106
116
  @raw_name = raw_name
107
117
  @merged = merged
@@ -26,17 +26,11 @@ module GitCurate
26
26
  return EXIT_FAILURE
27
27
  end
28
28
 
29
- if interactive?
30
- puts
31
- print_help
32
- puts
33
- end
34
-
35
29
  branches = Branch.local
36
30
  branches.reject!(&:current?) if interactive?
37
31
 
38
32
  table = Tabulo::Table.new(branches, border: :reduced_ascii, column_padding: 0, align_header: :left) do |t|
39
- t.add_column(:branch, header: "Branch") { |b| b.displayable_name(pad: !interactive?) }
33
+ t.add_column("Branch") { |b| b.displayable_name(pad: !interactive?) }
40
34
  t.add_column("Last commit:#{$/}Date", &:last_commit_date)
41
35
  t.add_column("#{$/}Hash", &:hash)
42
36
  t.add_column("#{$/}Author", &:last_author)
@@ -57,6 +51,15 @@ module GitCurate
57
51
  return EXIT_SUCCESS
58
52
  end
59
53
 
54
+ if branches.empty?
55
+ puts "There are no local branches that can be deleted."
56
+ return EXIT_SUCCESS
57
+ end
58
+
59
+ puts
60
+ print_help
61
+ puts
62
+
60
63
  table.each_with_index do |row, index|
61
64
  case HighLine.ask("#{row} #{prompt}").downcase
62
65
  when "d"
@@ -1,3 +1,3 @@
1
1
  module GitCurate
2
- VERSION = "1.0.0"
2
+ VERSION = "1.1.2"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: git_curate
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matthew Harvey
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-04-25 00:00:00.000000000 Z
11
+ date: 2021-01-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: highline
@@ -30,28 +30,28 @@ dependencies:
30
30
  requirements:
31
31
  - - '='
32
32
  - !ruby/object:Gem::Version
33
- version: 2.5.0
33
+ version: 2.6.2
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - '='
39
39
  - !ruby/object:Gem::Version
40
- version: 2.5.0
40
+ version: 2.6.2
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: tty-screen
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - '='
46
46
  - !ruby/object:Gem::Version
47
- version: 0.7.1
47
+ version: 0.8.1
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - '='
53
53
  - !ruby/object:Gem::Version
54
- version: 0.7.1
54
+ version: 0.8.1
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: bundler
57
57
  requirement: !ruby/object:Gem::Requirement
@@ -154,6 +154,7 @@ files:
154
154
  - README.md
155
155
  - Rakefile
156
156
  - VERSION
157
+ - assets/1920px-Topiary_Château_de_Hautefort_10.jpg
157
158
  - assets/demo.gif
158
159
  - bin/setup
159
160
  - exe/git-curate
@@ -173,7 +174,7 @@ licenses:
173
174
  metadata:
174
175
  source_code_uri: https://github.com/matt-harvey/git_curate
175
176
  changelog_uri: https://raw.githubusercontent.com/matt-harvey/git_curate/master/CHANGELOG.md
176
- post_install_message:
177
+ post_install_message:
177
178
  rdoc_options: []
178
179
  require_paths:
179
180
  - lib
@@ -189,7 +190,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
189
190
  version: '0'
190
191
  requirements: []
191
192
  rubygems_version: 3.1.2
192
- signing_key:
193
+ signing_key:
193
194
  specification_version: 4
194
195
  summary: Simple git branch curation tool
195
196
  test_files: []