fcom 0.14.1 → 0.14.2

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5cdd11f33d8f860458cfed5178fd646edbb09c816db281f5da8516f5daa6d8e5
4
- data.tar.gz: 4e08f8b334c65e51cec16e9479e01b6f13c7f62e4cd291378424027a77f40a3a
3
+ metadata.gz: 4071568074fd24d7c0a576634a4157c0435de4fd8003e06aa04ffcf638986cf6
4
+ data.tar.gz: 2a9aa2def6078ad23040f8be5b72cb8a5b847ec712487056343f555523dfce95
5
5
  SHA512:
6
- metadata.gz: cc22685bf66c9ed8b5d2bc651db8488f80f92e89353b2e9a71e33670d29ab09430b3570b6093086915f70487cd908efe8ec3570110d1938bc9be7dcca46f9c1f
7
- data.tar.gz: 365e9d0dbe2df71792554aed127a1c6c192c1f36e3fc3316a6b35834c6b51d21b1bbf9bb147a2651aadba93e29d24eb2a5983fc4af2bdf406c18865160a6d991
6
+ metadata.gz: c68874cbbfcf90422e0be737e3cef764cf6e167c9180d8fb301f99ab8fd77286bac66313d42a66d3b06cff941327447a4f21d880db939350c55bdae536243f83
7
+ data.tar.gz: 642dd889c30b45dffba2b24cd3e99f3eb91e30053997e2aa9c71441810c0f48ab4c99a55b62cecf90be64d2d6334692f1a71f422a5b186369be3a792a1813d8a
data/CHANGELOG.md CHANGED
@@ -1,3 +1,10 @@
1
+ ## v0.14.2 (2025-02-14)
2
+ - When using `--debug`, print the command used to query for renames and the parsed result.
3
+ - Track renames even across bulk renames. Fixes a bug where we might fail to track back through a rename that occurred in a commit with other renames.
4
+ - Search the git renaming history of the entire repo when filtering with a directory path. Fixes a bug wherein we failed to track renames into the specified target directory.
5
+ - Search over the diff of commits at the start of a search range, using `git rev-list`. This fixes a bug wherein sometimes a change in a commit renaming a file would not be included in the results.
6
+ - Only consider renames from outside of target directory. Fixes a bug wherein some commits could appear twice in the search results (and also performance was negatively impacted).
7
+
1
8
  ## v0.14.1 (2025-01-24)
2
9
  - Stream results progressively. ([#757](https://github.com/davidrunger/fcom/pull/757))
3
10
 
data/Gemfile CHANGED
@@ -12,7 +12,8 @@ gemspec
12
12
  group :development, :test do
13
13
  gem 'bundler', require: false
14
14
  gem 'pry'
15
- gem 'pry-byebug'
15
+ # Go back to upstream if/when https://github.com/deivid-rodriguez/pry-byebug/pull/ 428 is merged.
16
+ gem 'pry-byebug', github: 'davidrunger/pry-byebug'
16
17
  gem 'rake', require: false
17
18
  gem 'rspec', require: false
18
19
  gem 'rubocop', require: false
data/Gemfile.lock CHANGED
@@ -1,7 +1,15 @@
1
+ GIT
2
+ remote: https://github.com/davidrunger/pry-byebug
3
+ revision: 3ac27ef70a1b16a461db9f7572d3fe1a205effd4
4
+ specs:
5
+ pry-byebug (3.10.1)
6
+ pry (>= 0.13)
7
+ runger_byebug (>= 11.0)
8
+
1
9
  PATH
2
10
  remote: .
3
11
  specs:
4
- fcom (0.14.1)
12
+ fcom (0.14.2)
5
13
  activesupport (>= 6)
6
14
  memo_wise (>= 1.7)
7
15
  rainbow (>= 3.0)
@@ -27,40 +35,52 @@ GEM
27
35
  base64 (0.2.0)
28
36
  benchmark (0.4.0)
29
37
  bigdecimal (3.1.9)
30
- byebug (11.1.3)
31
38
  coderay (1.1.3)
32
39
  concurrent-ruby (1.3.5)
33
40
  connection_pool (2.5.0)
34
- diff-lcs (1.5.1)
41
+ date (3.4.1)
42
+ diff-lcs (1.6.0)
35
43
  drb (2.2.1)
36
44
  i18n (1.14.7)
37
45
  concurrent-ruby (~> 1.0)
38
- json (2.9.1)
39
- language_server-protocol (3.17.0.3)
40
- logger (1.6.5)
46
+ io-console (0.8.0)
47
+ irb (1.15.1)
48
+ pp (>= 0.6.0)
49
+ rdoc (>= 4.0.0)
50
+ reline (>= 0.4.2)
51
+ json (2.10.1)
52
+ language_server-protocol (3.17.0.4)
53
+ logger (1.6.6)
41
54
  memo_wise (1.10.0)
42
55
  method_source (1.1.0)
43
56
  minitest (5.25.4)
44
57
  parallel (1.26.3)
45
- parser (3.3.7.0)
58
+ parser (3.3.7.1)
46
59
  ast (~> 2.4.1)
47
60
  racc
61
+ pp (0.6.2)
62
+ prettyprint
63
+ prettyprint (0.2.0)
48
64
  prism (1.3.0)
49
- pry (0.14.2)
65
+ pry (0.15.2)
50
66
  coderay (~> 1.1)
51
67
  method_source (~> 1.0)
52
- pry-byebug (3.10.1)
53
- byebug (~> 11.0)
54
- pry (>= 0.13, < 0.15)
68
+ psych (5.2.3)
69
+ date
70
+ stringio
55
71
  racc (1.8.1)
56
72
  rainbow (3.1.1)
57
73
  rake (13.2.1)
74
+ rdoc (6.12.0)
75
+ psych (>= 4.0.0)
58
76
  regexp_parser (2.10.0)
77
+ reline (0.6.0)
78
+ io-console (~> 0.5)
59
79
  rspec (3.13.0)
60
80
  rspec-core (~> 3.13.0)
61
81
  rspec-expectations (~> 3.13.0)
62
82
  rspec-mocks (~> 3.13.0)
63
- rspec-core (3.13.2)
83
+ rspec-core (3.13.3)
64
84
  rspec-support (~> 3.13.0)
65
85
  rspec-expectations (3.13.3)
66
86
  diff-lcs (>= 1.2.0, < 2.0)
@@ -69,17 +89,17 @@ GEM
69
89
  diff-lcs (>= 1.2.0, < 2.0)
70
90
  rspec-support (~> 3.13.0)
71
91
  rspec-support (3.13.2)
72
- rubocop (1.71.0)
92
+ rubocop (1.71.2)
73
93
  json (~> 2.3)
74
94
  language_server-protocol (>= 3.17.0)
75
95
  parallel (~> 1.10)
76
96
  parser (>= 3.3.0.2)
77
97
  rainbow (>= 2.2.2, < 4.0)
78
98
  regexp_parser (>= 2.9.3, < 3.0)
79
- rubocop-ast (>= 1.36.2, < 2.0)
99
+ rubocop-ast (>= 1.38.0, < 2.0)
80
100
  ruby-progressbar (~> 1.7)
81
101
  unicode-display_width (>= 2.4.0, < 4.0)
82
- rubocop-ast (1.37.0)
102
+ rubocop-ast (1.38.0)
83
103
  parser (>= 3.3.1.0)
84
104
  rubocop-performance (1.23.1)
85
105
  rubocop (>= 1.48.1, < 2.0)
@@ -89,16 +109,20 @@ GEM
89
109
  rubocop-rspec (3.4.0)
90
110
  rubocop (~> 1.61)
91
111
  ruby-progressbar (1.13.0)
92
- runger_release_assistant (0.14.0)
112
+ runger_byebug (11.4.0)
113
+ irb
114
+ reline
115
+ runger_release_assistant (2.0.0)
93
116
  activesupport (>= 6)
94
117
  memo_wise (>= 1.7)
95
118
  rainbow (>= 3.0)
96
119
  slop (~> 4.8)
97
- runger_style (4.1.0)
120
+ runger_style (5.1.0)
98
121
  prism (>= 0.24.0)
99
122
  rubocop (>= 1.68.0)
100
123
  securerandom (0.4.1)
101
124
  slop (4.10.1)
125
+ stringio (3.1.2)
102
126
  tzinfo (2.0.6)
103
127
  concurrent-ruby (~> 1.0)
104
128
  unicode-display_width (3.1.4)
@@ -113,7 +137,7 @@ DEPENDENCIES
113
137
  bundler
114
138
  fcom!
115
139
  pry
116
- pry-byebug
140
+ pry-byebug!
117
141
  rake
118
142
  rspec
119
143
  rubocop
@@ -129,44 +153,53 @@ CHECKSUMS
129
153
  base64 (0.2.0) sha256=0f25e9b21a02a0cc0cea8ef92b2041035d39350946e8789c562b2d1a3da01507
130
154
  benchmark (0.4.0) sha256=0f12f8c495545e3710c3e4f0480f63f06b4c842cc94cec7f33a956f5180e874a
131
155
  bigdecimal (3.1.9) sha256=2ffc742031521ad69c2dfc815a98e426a230a3d22aeac1995826a75dabfad8cc
132
- byebug (11.1.3) sha256=2485944d2bb21283c593d562f9ae1019bf80002143cc3a255aaffd4e9cf4a35b
133
156
  coderay (1.1.3) sha256=dc530018a4684512f8f38143cd2a096c9f02a1fc2459edcfe534787a7fc77d4b
134
157
  concurrent-ruby (1.3.5) sha256=813b3e37aca6df2a21a3b9f1d497f8cbab24a2b94cab325bffe65ee0f6cbebc6
135
158
  connection_pool (2.5.0) sha256=233b92f8d38e038c1349ccea65dd3772727d669d6d2e71f9897c8bf5cd53ebfc
136
- diff-lcs (1.5.1) sha256=273223dfb40685548436d32b4733aa67351769c7dea621da7d9dd4813e63ddfe
159
+ date (3.4.1) sha256=bf268e14ef7158009bfeaec40b5fa3c7271906e88b196d958a89d4b408abe64f
160
+ diff-lcs (1.6.0) sha256=a1e7f7b272962f8fc769358ad00001b87cdcf32ba349d6c70c6b544613d2da2e
137
161
  drb (2.2.1) sha256=e9d472bf785f558b96b25358bae115646da0dbfd45107ad858b0bc0d935cb340
138
- fcom (0.14.1)
162
+ fcom (0.14.2)
139
163
  i18n (1.14.7) sha256=ceba573f8138ff2c0915427f1fc5bdf4aa3ab8ae88c8ce255eb3ecf0a11a5d0f
140
- json (2.9.1) sha256=d2bdef4644052fad91c1785d48263756fe32fcac08b96a20bb15840e96550d11
141
- language_server-protocol (3.17.0.3) sha256=3d5c58c02f44a20d972957a9febe386d7e7468ab3900ce6bd2b563dd910c6b3f
142
- logger (1.6.5) sha256=c3cfe56d01656490ddd103d38b8993d73d86296adebc5f58cefc9ec03741e56b
164
+ io-console (0.8.0) sha256=cd6a9facbc69871d69b2cb8b926fc6ea7ef06f06e505e81a64f14a470fddefa2
165
+ irb (1.15.1) sha256=d9bca745ac4207a8b728a52b98b766ca909b86ff1a504bcde3d6f8c84faae890
166
+ json (2.10.1) sha256=ddc88ad91a1baf3f0038c174f253af3b086d30dc74db17ca4259bbde982f94dc
167
+ language_server-protocol (3.17.0.4) sha256=c484626478664fd13482d8180947c50a8590484b1258b99b7aedb3b69df89669
168
+ logger (1.6.6) sha256=dd618d24e637715472732e7eed02e33cfbdf56deaad225edd0f1f89d38024017
143
169
  memo_wise (1.10.0) sha256=ae40ff8e7799697ff5d59d739b8766f76be22eba69c7c8468edb42ab83c94c3f
144
170
  method_source (1.1.0) sha256=181301c9c45b731b4769bc81e8860e72f9161ad7d66dd99103c9ab84f560f5c5
145
171
  minitest (5.25.4) sha256=9cf2cae25ac4dfc90c988ebc3b917f53c054978b673273da1bd20bcb0778f947
146
172
  parallel (1.26.3) sha256=d86babb7a2b814be9f4b81587bf0b6ce2da7d45969fab24d8ae4bf2bb4d4c7ef
147
- parser (3.3.7.0) sha256=7449011771e3e7881297859b849de26a6f4fccd515bece9520a87e7d2116119b
173
+ parser (3.3.7.1) sha256=7dbe61618025519024ac72402a6677ead02099587a5538e84371b76659e6aca1
174
+ pp (0.6.2) sha256=947ec3120c6f92195f8ee8aa25a7b2c5297bb106d83b41baa02983686577b6ff
175
+ prettyprint (0.2.0) sha256=2bc9e15581a94742064a3cc8b0fb9d45aae3d03a1baa6ef80922627a0766f193
148
176
  prism (1.3.0) sha256=b11620829831b1cb7e6c9b46c81ff8a6e36ccb3f888f164485eb7351f386273a
149
- pry (0.14.2) sha256=c4fe54efedaca1d351280b45b8849af363184696fcac1c72e0415f9bdac4334d
150
- pry-byebug (3.10.1) sha256=c8f975c32255bfdb29e151f5532130be64ff3d0042dc858d0907e849125581f8
177
+ pry (0.15.2) sha256=12d54b8640d3fa29c9211dd4ffb08f3fd8bf7a4fd9b5a73ce5b59c8709385b6b
178
+ pry-byebug (3.10.1)
179
+ psych (5.2.3) sha256=84a54bb952d14604fea22d99938348814678782f58b12648fcdfa4d2fce859ee
151
180
  racc (1.8.1) sha256=4a7f6929691dbec8b5209a0b373bc2614882b55fc5d2e447a21aaa691303d62f
152
181
  rainbow (3.1.1) sha256=039491aa3a89f42efa1d6dec2fc4e62ede96eb6acd95e52f1ad581182b79bc6a
153
182
  rake (13.2.1) sha256=46cb38dae65d7d74b6020a4ac9d48afed8eb8149c040eccf0523bec91907059d
183
+ rdoc (6.12.0) sha256=7d6f706e070bffa5d18a448f24076cbfb34923a99c1eab842aa18e6ca69f56e0
154
184
  regexp_parser (2.10.0) sha256=cb6f0ddde88772cd64bff1dbbf68df66d376043fe2e66a9ef77fcb1b0c548c61
185
+ reline (0.6.0) sha256=57620375dcbe56ec09bac7192bfb7460c716bbf0054dc94345ecaa5438e539d2
155
186
  rspec (3.13.0) sha256=d490914ac1d5a5a64a0e1400c1d54ddd2a501324d703b8cfe83f458337bab993
156
- rspec-core (3.13.2) sha256=94fbda6e4738e478f1c7532b7cc241272fcdc8b9eac03a97338b1122e4573300
187
+ rspec-core (3.13.3) sha256=25136507f4f9cf2e8977a2851e64e438b4331646054e345998714108745cdfe4
157
188
  rspec-expectations (3.13.3) sha256=0e6b5af59b900147698ea0ff80456c4f2e69cac4394fbd392fbd1ca561f66c58
158
189
  rspec-mocks (3.13.2) sha256=2327335def0e1665325a9b617e3af9ae20272741d80ac550336309a7c59abdef
159
190
  rspec-support (3.13.2) sha256=cea3a2463fd9b84b9dcc9685efd80ea701aa8f7b3decb3b3ce795ed67737dbec
160
- rubocop (1.71.0) sha256=e19679efd447346ac476122313d3788ae23c38214790bcf660e984c747608bf0
161
- rubocop-ast (1.37.0) sha256=9513ac88aaf113d04b52912533ffe46475de1362d4aa41141b51b2455827c080
191
+ rubocop (1.71.2) sha256=9a7b7501aac661a338ed7ff2a5eba78e581759e1f0d3c82362b2ca217ed3f97f
192
+ rubocop-ast (1.38.0) sha256=4fdf6792fe443a9a18acb12dbc8225d0d64cd1654e41fedb30e79c18edbb26ae
162
193
  rubocop-performance (1.23.1) sha256=f22f86a795f5e6a6180aac2c6fc172534b173a068d6ed3396d6460523e051b82
163
194
  rubocop-rake (0.6.0) sha256=56b6f22189af4b33d4f4e490a555c09f1281b02f4d48c3a61f6e8fe5f401d8db
164
195
  rubocop-rspec (3.4.0) sha256=8721c13b6a8c9530a7ac481cea9423022f946fcf72428bda8289f8b57e4d4885
165
196
  ruby-progressbar (1.13.0) sha256=80fc9c47a9b640d6834e0dc7b3c94c9df37f08cb072b7761e4a71e22cff29b33
166
- runger_release_assistant (0.14.0) sha256=7abc5eb1e0f63d8d611691bc21698d2b3b8f148a5f47cacd8dd32c21d16ee9be
167
- runger_style (4.1.0) sha256=0740ed8c194fc6dcb420b11b1fb13cebf244e8e34c1c1df05200dc0e15ce084e
197
+ runger_byebug (11.4.0) sha256=569e22ba2215f57e7f69e145fcb63be401e29fcd312f7936d813e12d0c7bbee6
198
+ runger_release_assistant (2.0.0) sha256=f4f5708291eaeef1b881208f87a494877fe768739d6e96b7293fc335b28a3865
199
+ runger_style (5.1.0) sha256=2518b1f636c87889acf3539b33fea8ab0703f3adcfac814985f4f0e91d13a400
168
200
  securerandom (0.4.1) sha256=cc5193d414a4341b6e225f0cb4446aceca8e50d5e1888743fac16987638ea0b1
169
201
  slop (4.10.1) sha256=844322b5ffcf17ed4815fdb173b04a20dd82b4fd93e3744c88c8fafea696d9c7
202
+ stringio (3.1.2) sha256=204f1828f85cdb39d57cac4abc6dc44b04505a223f131587f2e20ae3729ba131
170
203
  tzinfo (2.0.6) sha256=8daf828cc77bcf7d63b0e3bdb6caa47e2272dcfaf4fbfe46f8c3a9df087a829b
171
204
  unicode-display_width (3.1.4) sha256=8caf2af1c0f2f07ec89ef9e18c7d88c2790e217c482bfc78aaa65eadd5415ac1
172
205
  unicode-emoji (4.0.4) sha256=2c2c4ef7f353e5809497126285a50b23056cc6e61b64433764a35eff6c36532a
data/README.md CHANGED
@@ -9,6 +9,26 @@ davidrunger/fcom`, I get this output:
9
9
 
10
10
  ![](https://s3.amazonaws.com/screens.davidrunger.com/2019-12-28-20-50-09-oect2(1).png)
11
11
 
12
+ ## Table of Contents
13
+
14
+ <!--ts-->
15
+ * [Table of Contents](#table-of-contents)
16
+ * [Installation](#installation)
17
+ * [Dependencies](#dependencies)
18
+ * [Basic usage](#basic-usage)
19
+ * [Available options and examples](#available-options-and-examples)
20
+ * [The .fcom.yml config file](#the-fcomyml-config-file)
21
+ * [Example .fcom.yml config file](#example-fcomyml-config-file)
22
+ * [Performance considerations for -p/--path option](#performance-considerations-for--p--path-option)
23
+ * [Development](#development)
24
+ * [Contributing](#contributing)
25
+ * [License](#license)
26
+
27
+ <!-- Created by https://github.com/ekalinin/github-markdown-toc -->
28
+ <!-- Added by: david, at: Fri Feb 14 02:37:37 AM CST 2025 -->
29
+
30
+ <!--te-->
31
+
12
32
  ## Installation
13
33
 
14
34
  ```
@@ -27,7 +47,7 @@ This gem assumes that you have `git` and [`rg` (ripgrep)][ripgrep] installed.
27
47
  $ fcom <search string> [options]
28
48
  ```
29
49
 
30
- #### Available options and examples
50
+ ### Available options and examples
31
51
 
32
52
  After installing, execute `fcom --help` to see usage examples and available options.
33
53
 
@@ -57,7 +77,7 @@ Examples:
57
77
  -h, --help print this help information
58
78
  ```
59
79
 
60
- ## `.fcom.yml` config file
80
+ ## The `.fcom.yml` config file
61
81
  We highly recommend that you create an `.fcom.yml` file in any repository that you plan to search
62
82
  with `fcom`.
63
83
 
@@ -67,7 +87,8 @@ repo/directory.
67
87
  (You might (or might not) want to add `.fcom.yml` to your `~/.gitignore_global` file, so that this
68
88
  file is not tracked by `git`.)
69
89
 
70
- #### Example `.fcom.yml` config file
90
+ ### Example `.fcom.yml` config file
91
+
71
92
  ```yaml
72
93
  repo: githubusername/reponame
73
94
  ```
@@ -77,6 +98,14 @@ more quickly, because time will not be wasted parsing the output of `git remote
77
98
  determine the URL of the repo's remote repository (which is used to construct links to matching
78
99
  commits).
79
100
 
101
+ ## Performance considerations for `-p`/`--path` option
102
+
103
+ The performance of `fcom`'s querying and parsing of git history can significantly depend upon the `-p`/`--path` option provided (or lack thereof):
104
+
105
+ 1. **fastest:** provide a _file_ path as the `-p`/`--path` option
106
+ 2. **medium:** do not provide any `-p`/`--path` option (i.e. search the whole repository)
107
+ 3. **slowest:** provide a _subdirectory_ `-p`/`--path` option
108
+
80
109
  ## Development
81
110
 
82
111
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run
data/lib/fcom/querier.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'pp'
3
4
  require 'pty'
4
5
 
5
6
  require_relative 'options_helpers.rb'
@@ -30,16 +31,27 @@ class Fcom::Querier
30
31
 
31
32
  commands =
32
33
  filename_by_most_recent_containing_commit.map do |commit, path_at_commit|
34
+ commit_without_caret = commit.first(40)
35
+
36
+ start_of_log =
37
+ filtered_renames.
38
+ drop_while { it.first != commit_without_caret }.
39
+ detect { it.last == path_at_commit }&.
40
+ first ||
41
+ first_commit_sha
42
+
33
43
  <<~COMMAND.squish
44
+ git rev-list #{start_of_log} #{commit} |
45
+
34
46
  git log
35
47
  --format="commit %s|%H|%an|%cr (%ci)"
36
48
  --patch
37
49
  --full-diff
38
50
  --topo-order
39
51
  --no-textconv
52
+ --stdin
40
53
  #{%(--author="#{author}") if author}
41
54
  #{days_limiter}
42
- #{commit}
43
55
  --
44
56
  #{path_at_commit}
45
57
  |
@@ -104,9 +116,11 @@ class Fcom::Querier
104
116
 
105
117
  memo_wise \
106
118
  def filename_by_most_recent_containing_commit
107
- {
108
- most_recent_commit_with_file => path,
109
- }.merge(renames.transform_keys { "#{_1}^" })
119
+ [
120
+ [most_recent_commit_with_file, path],
121
+ ] + filtered_renames.map do |commit, previous_name|
122
+ ["#{commit}^", previous_name]
123
+ end
110
124
  end
111
125
 
112
126
  memo_wise \
@@ -118,25 +132,59 @@ class Fcom::Querier
118
132
  end
119
133
  end
120
134
 
135
+ # rubocop:disable Metrics/CyclomaticComplexity
136
+ # rubocop:disable Metrics/PerceivedComplexity
121
137
  memo_wise \
122
- def renames
123
- if path == Fcom::ROOT_PATH
124
- {}
125
- else
126
- command =
127
- 'git log HEAD ' \
128
- "--format=%H --name-status --follow --diff-filter=R #{days_limiter} " \
129
- "-- '#{path}'"
130
-
131
- `#{command}`.
132
- split(/\n(?=[0-9a-f]{40})/).
133
- to_h do |sha_and_name_info|
134
- sha_and_name_info.
135
- match(/(?<sha>[0-9a-f]{40})\n\nR\d+\s+(?<previous_name>\S+)?/).
136
- named_captures.
137
- values_at('sha', 'previous_name')
138
+ def filtered_renames
139
+ filtered_renames =
140
+ if path == Fcom::ROOT_PATH
141
+ []
142
+ elsif path == path_for_git_log_renames_query
143
+ # (Path is a file.)
144
+ full_renames_history_for_path_for_git_log_renames_query
145
+ else
146
+ # (Path is a non-root directory.)
147
+ already_selected = Set.new
148
+ path_with_trailing_slash = File.join(path, '/').to_s
149
+
150
+ renames_landing_in_target_directory_from_outside_of_it =
151
+ full_renames_history_for_path_for_git_log_renames_query.
152
+ select do |(_commit, previous_name, new_name)|
153
+ (
154
+ !previous_name.start_with?(path_with_trailing_slash) &&
155
+ new_name.start_with?(path_with_trailing_slash) &&
156
+ !already_selected.include?(new_name)
157
+ ).tap do |is_most_recent_rename_into_target_directory|
158
+ if is_most_recent_rename_into_target_directory
159
+ already_selected << new_name
160
+ end
161
+ end
162
+ end
163
+
164
+ traced_back_renames(renames_landing_in_target_directory_from_outside_of_it.map(&:last))
165
+ end
166
+
167
+ Fcom.logger.debug(<<~LOG)
168
+ Filtered renames:
169
+ #{filtered_renames.pretty_inspect}
170
+ LOG
171
+
172
+ filtered_renames
173
+ end
174
+ # rubocop:enable Metrics/PerceivedComplexity
175
+ # rubocop:enable Metrics/CyclomaticComplexity
176
+
177
+ def traced_back_renames(new_file_names)
178
+ new_file_names_of_interest = Set.new(new_file_names)
179
+
180
+ full_renames_history_for_path_for_git_log_renames_query.
181
+ select do |(_commit, previous_name, new_name)|
182
+ new_file_names_of_interest.include?(new_name).tap do |is_rename_of_interest|
183
+ if is_rename_of_interest
184
+ new_file_names_of_interest << previous_name
185
+ end
138
186
  end
139
- end
187
+ end
140
188
  end
141
189
 
142
190
  memo_wise \
@@ -145,4 +193,49 @@ class Fcom::Querier
145
193
  "--since=#{days}.day"
146
194
  end
147
195
  end
196
+
197
+ memo_wise \
198
+ def full_renames_history_for_path_for_git_log_renames_query
199
+ command =
200
+ 'git log HEAD ' \
201
+ "--format=%H --name-status --follow --diff-filter=R #{days_limiter} " \
202
+ "-- '#{path_for_git_log_renames_query}'"
203
+
204
+ Fcom.logger.debug("Querying renames with: #{command}")
205
+
206
+ `#{command}`.
207
+ split(/\n(?=[0-9a-f]{40})/).
208
+ flat_map do |sha_and_rename_info_lines|
209
+ sha, rename_info_lines =
210
+ sha_and_rename_info_lines.
211
+ match(/(?<sha>[0-9a-f]{40})\n\n(?<rename_info_lines>R\d+.*)/m).
212
+ named_captures.
213
+ values_at('sha', 'rename_info_lines')
214
+
215
+ rename_info_lines.lines.map do |rename_info_line|
216
+ previous_name, new_name =
217
+ rename_info_line.
218
+ match(/\AR\d+\s+(?<previous_name>\S+)\s+(?<new_name>\S+)/).
219
+ named_captures.
220
+ values_at('previous_name', 'new_name')
221
+
222
+ [sha, previous_name, new_name]
223
+ end
224
+ end.tap do |renames|
225
+ Fcom.logger.debug(<<~LOG)
226
+ Full renames history for '#{path_for_git_log_renames_query}':
227
+ #{renames.pretty_inspect}
228
+ LOG
229
+ end
230
+ end
231
+
232
+ memo_wise \
233
+ def path_for_git_log_renames_query
234
+ File.directory?(path) ? Fcom::ROOT_PATH : path
235
+ end
236
+
237
+ memo_wise \
238
+ def first_commit_sha
239
+ `git rev-list --max-parents=0 HEAD`.rstrip
240
+ end
148
241
  end
data/lib/fcom/version.rb CHANGED
@@ -2,6 +2,6 @@
2
2
 
3
3
  # rubocop:disable Style/StaticClass
4
4
  class Fcom
5
- VERSION = '0.14.1'
5
+ VERSION = '0.14.2'
6
6
  end
7
7
  # rubocop:enable Style/StaticClass
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fcom
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.14.1
4
+ version: 0.14.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Runger
8
8
  bindir: exe
9
9
  cert_chain: []
10
- date: 2025-01-25 00:00:00.000000000 Z
10
+ date: 2025-02-14 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: activesupport