Skip to content

Commit e0fb3f6

Browse files
Add worktree listing
Signed-off-by: Ofir Petrushka <hatkyinc@gmail.com>
1 parent 4bef5ab commit e0fb3f6

File tree

16 files changed

+141
-2
lines changed

16 files changed

+141
-2
lines changed

lib/git.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
require 'git/stashes'
2222
require 'git/version'
2323
require 'git/working_directory'
24+
require 'git/worktree'
25+
require 'git/worktrees'
2426

2527
lib = Git::Lib.new(nil, nil)
2628
unless lib.meets_required_version?

lib/git/base/factory.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,12 @@ def branches
1515
Git::Branches.new(self)
1616
end
1717

18+
# returns a Git::worktrees object of all the Git::Worktrees
19+
# objects for this repo
20+
def worktrees
21+
Git::Worktrees.new(self)
22+
end
23+
1824
def commit_tree(tree = nil, opts = {})
1925
Git::Object::Commit.new(self, self.lib.commit_tree(tree, opts))
2026
end

lib/git/lib.rb

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,26 @@ def branches_all
308308
arr
309309
end
310310

311+
def worktrees_all
312+
arr = []
313+
directory = ''
314+
# Output example for `worktree list --porcelain`:
315+
# worktree /code/public/ruby-git
316+
# HEAD 4bef5abbba073c77b4d0ccc1ffcd0ed7d48be5d4
317+
# branch refs/heads/master
318+
#
319+
# worktree /tmp/worktree-1
320+
# HEAD b8c63206f8d10f57892060375a86ae911fad356e
321+
# detached
322+
#
323+
command_lines('worktree',['list', '--porcelain']).each do |w|
324+
s = w.split("\s")
325+
directory = s[1] if s[0] == 'worktree'
326+
arr << [directory, s[1]] if s[0] == 'HEAD'
327+
end
328+
arr
329+
end
330+
311331
def list_files(ref_dir)
312332
dir = File.join(@git_dir, 'refs', ref_dir)
313333
files = []

lib/git/worktree.rb

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
require 'git/path'
2+
3+
module Git
4+
5+
class Worktree < Path
6+
7+
attr_accessor :full, :dir, :gcommit
8+
9+
def initialize(base, dir, gcommit)
10+
@full = dir + ' ' + gcommit
11+
@base = base
12+
@dir = dir
13+
@gcommit = gcommit
14+
end
15+
16+
def gcommit
17+
@gcommit ||= @base.gcommit(@full)
18+
@gcommit
19+
end
20+
21+
def to_a
22+
[@full]
23+
end
24+
25+
def to_s
26+
@full
27+
end
28+
end
29+
end

lib/git/worktrees.rb

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
module Git
2+
# object that holds all the available worktrees
3+
class Worktrees
4+
5+
include Enumerable
6+
7+
def initialize(base)
8+
@worktrees = {}
9+
10+
@base = base
11+
12+
# Array contains [dir, git_hash]
13+
@base.lib.worktrees_all.each do |w|
14+
@worktrees[w[0]] = Git::Worktree.new(@base, w[0], w[1])
15+
end
16+
end
17+
18+
# array like methods
19+
20+
def size
21+
@worktrees.size
22+
end
23+
24+
def each(&block)
25+
@worktrees.values.each(&block)
26+
end
27+
28+
def [](worktree_name)
29+
@worktrees.values.inject(@worktrees) do |worktrees, worktree|
30+
worktrees[worktree.full] ||= worktree
31+
worktrees
32+
end[worktree_name.to_s]
33+
end
34+
35+
def to_s
36+
out = ''
37+
@worktrees.each do |k, b|
38+
out << b.to_s << "\n"
39+
end
40+
out
41+
end
42+
end
43+
end
44+

tests/files/working/dot_git/index

0 Bytes
Binary file not shown.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
0000000000000000000000000000000000000000 5e53019b3238362144c2766f02a2c00d91fcc023 Scott Chacon <schacon@gmail.com> 1596189348 +1000 branch: Created from HEAD
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
5e53019b3238362144c2766f02a2c00d91fcc023
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
935badc874edd62a8629aaf103418092c73f0a56
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
5e53019b3238362144c2766f02a2c00d91fcc023

0 commit comments

Comments
 (0)