git-status-tree 3.5.0 → 3.6.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.
Files changed (5) hide show
  1. checksums.yaml +4 -4
  2. data/VERSION +1 -1
  3. data/lib/node.rb +37 -10
  4. data/src/git_status_tree.rb +33 -1
  5. metadata +3 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b0823206680a82016025ca4859cd9d0b7baf30ec61c51e2f5201f0dceeac9d20
4
- data.tar.gz: 731c9421ae4eeffe679b3c65f2bc5816fe949aae33af6aa4082694eb8b133b66
3
+ metadata.gz: 6ae072cfbbbb61271fe7e85784ec62a447a1d0ebaca8c64849254f82b3dc70e5
4
+ data.tar.gz: 4c7980522950a903b4619c347be85332a6bf358a869a39b6d7586b8e5b9d93e4
5
5
  SHA512:
6
- metadata.gz: 050262f9aa55d5768e1a63dfa199f035f2a3cb34d519bd1f703fd2e0405cdef23c5440449e46c3087f3349360107de5045ef60a07052a9d15667905136b56f52
7
- data.tar.gz: cb498d741fbf7c4c2cf84475b0d69b0bf1857318e2ea45279dc5bc4fb54adcceb8e2fed576c66aa42e781de2cfdf7a9ba7be99a1686c4d77eb413740bd469aa7
6
+ metadata.gz: c31c32ffb0c81747f0d16f9d6b6b6f7c958a858aef6311d735cb23520cb10cfd9f7873d90952ede9581e4567f3b5dad44c6736edf1f8a87302fb5f46a0bfe112
7
+ data.tar.gz: c8aaa7af0c6954eaeb81047ad5d992866692b0bcd2630a29a07a9af58f2f0b34f2c256e80ca5fe7d0a92825805f225a277c0feabb0f9a0127d9263a186e81ba5
data/VERSION CHANGED
@@ -1 +1 @@
1
- 3.5.0
1
+ 3.6.0
data/lib/node.rb CHANGED
@@ -129,9 +129,13 @@ class Node
129
129
  end
130
130
  end
131
131
 
132
- def file? = children.nil?
132
+ def file?
133
+ children.nil?
134
+ end
133
135
 
134
- def dir? = !file?
136
+ def dir?
137
+ !file?
138
+ end
135
139
 
136
140
  def valid?
137
141
  file? ? valid_file? : valid_dir?
@@ -168,14 +172,37 @@ class Node
168
172
  end
169
173
  end
170
174
 
171
- def modified? = status.include?('M')
172
- def added? = status.include?('A')
173
- def deleted? = status.include?('D')
174
- def renamed? = status.include?('R')
175
- def copied? = status.include?('C')
176
- def unmerged? = status.include?('U')
177
- def new? = status.include?('?')
178
- def staged? = status.include?('+')
175
+ def modified?
176
+ status.include?('M')
177
+ end
178
+
179
+ def added?
180
+ status.include?('A')
181
+ end
182
+
183
+ def deleted?
184
+ status.include?('D')
185
+ end
186
+
187
+ def renamed?
188
+ status.include?('R')
189
+ end
190
+
191
+ def copied?
192
+ status.include?('C')
193
+ end
194
+
195
+ def unmerged?
196
+ status.include?('U')
197
+ end
198
+
199
+ def new?
200
+ status.include?('?')
201
+ end
202
+
203
+ def staged?
204
+ status.include?('+')
205
+ end
179
206
 
180
207
  private
181
208
 
@@ -13,7 +13,7 @@ class GitStatusTree
13
13
  def initialize(options = {})
14
14
  Node.indent = indent(options)
15
15
  Node.collapse_dirs = collapse(options)
16
- @files = `git status --porcelain#{untracked_files(options)}`.split("\n")
16
+ @files = parse_status(`git status --porcelain -z#{untracked_files(options)}`)
17
17
  @nodes = files.map { |file| Node.create_from_string file }
18
18
  @tree = nodes.reduce { |a, i| (a + i).nodes[0] }
19
19
  end
@@ -28,6 +28,38 @@ class GitStatusTree
28
28
 
29
29
  private
30
30
 
31
+ # Parse NUL-terminated `git status --porcelain -z` output into porcelain
32
+ # entry strings. Unlike the default output, -z never quotes or escapes
33
+ # paths, so names with spaces, non-ASCII characters, quotes, backslashes
34
+ # or tabs survive intact. Rename/copy entries span two NUL-separated
35
+ # tokens ("<XY> <dest>\0<orig>\0") and are reassembled into the
36
+ # "<XY> <orig> -> <dest>" form the node parser expects.
37
+ def parse_status(raw)
38
+ # Paths are emitted as raw UTF-8 bytes; tag them so names display literally.
39
+ tokens = raw.force_encoding('UTF-8').split("\0")
40
+ files = []
41
+ index = 0
42
+ while index < tokens.length
43
+ entry = tokens[index]
44
+ index += 1
45
+ next if entry.nil? || entry.empty?
46
+
47
+ if rename_or_copy?(entry)
48
+ orig = tokens[index]
49
+ index += 1
50
+ files << "#{entry[0, 3]}#{orig} -> #{entry[3..]}"
51
+ else
52
+ files << entry
53
+ end
54
+ end
55
+ files
56
+ end
57
+
58
+ def rename_or_copy?(entry)
59
+ status = entry[0, 2]
60
+ status.include?('R') || status.include?('C')
61
+ end
62
+
31
63
  def indent(options)
32
64
  indent = options[:indent] || config || 4
33
65
  indent = 2 if indent < 2
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: git-status-tree
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.5.0
4
+ version: 3.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Wolfgang Teuber
@@ -45,14 +45,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
45
45
  requirements:
46
46
  - - ">="
47
47
  - !ruby/object:Gem::Version
48
- version: '3.4'
48
+ version: '2.6'
49
49
  required_rubygems_version: !ruby/object:Gem::Requirement
50
50
  requirements:
51
51
  - - ">="
52
52
  - !ruby/object:Gem::Version
53
53
  version: '0'
54
54
  requirements: []
55
- rubygems_version: 3.6.9
55
+ rubygems_version: 4.0.10
56
56
  specification_version: 4
57
57
  summary: git status in file tree format
58
58
  test_files: []