@@ -3,7 +3,7 @@ defmodule GitWork.Commands.Init do
33 Convert an existing normal git repository into the worktree-based layout.
44 """
55
6- alias GitWork.Git
6+ alias GitWork . { Git , Project }
77
88 def help do
99 """
@@ -36,7 +36,7 @@ defmodule GitWork.Commands.Init do
3636
3737 cond do
3838 File . dir? ( bare_dir ) ->
39- { :error , "already initialized (found .bare/)" }
39+ do_repair ( dir , git_dir , bare_dir )
4040
4141 not File . dir? ( git_dir ) ->
4242 { :error , "not a git repository (no .git/ directory)" }
@@ -58,6 +58,60 @@ defmodule GitWork.Commands.Init do
5858 end
5959 end
6060
61+ defp do_repair ( dir , git_dir , bare_dir ) do
62+ with :ok <- ensure_gitdir_pointer ( dir , git_dir ) ,
63+ :ok <- configure_bare ( bare_dir ) ,
64+ { :ok , branch } <- Project . head_branch ( dir ) ,
65+ :ok <- ensure_worktree_dir ( dir , branch ) do
66+ { :ok , Project . worktree_path ( dir , branch ) }
67+ end
68+ end
69+
70+ defp ensure_gitdir_pointer ( dir , git_dir ) do
71+ cond do
72+ File . dir? ( git_dir ) ->
73+ { :error , "found .git directory; not a git-work root" }
74+
75+ File . regular? ( git_dir ) ->
76+ case File . read ( git_dir ) do
77+ { :ok , "gitdir: ./.bare\n " } ->
78+ :ok
79+
80+ { :ok , _ } ->
81+ write_gitdir_pointer ( dir )
82+
83+ { :error , reason } ->
84+ { :error , "failed to read .git pointer: #{ reason } " }
85+ end
86+
87+ true ->
88+ write_gitdir_pointer ( dir )
89+ end
90+ end
91+
92+ defp ensure_worktree_dir ( dir , branch ) do
93+ worktree_dir = Project . worktree_path ( dir , branch )
94+
95+ if File . dir? ( worktree_dir ) do
96+ :ok
97+ else
98+ bare_dir = Project . bare_path ( dir )
99+
100+ case Git . cmd ( [ "worktree" , "add" , worktree_dir , branch ] , cd: bare_dir ) do
101+ { :ok , _ } ->
102+ :ok
103+
104+ { :error , _msg } ->
105+ _ = Git . cmd ( [ "worktree" , "prune" ] , cd: bare_dir )
106+
107+ case Git . cmd ( [ "worktree" , "add" , worktree_dir , branch ] , cd: bare_dir ) do
108+ { :ok , _ } -> :ok
109+ { :error , msg2 } -> { :error , "failed to recreate worktree: #{ msg2 } " }
110+ end
111+ end
112+ end
113+ end
114+
61115 defp do_init_steps ( dir , branch , stashed? , git_dir , bare_dir ) do
62116 with :ok <- move_git_to_bare ( git_dir , bare_dir ) ,
63117 :ok <- configure_bare ( bare_dir ) ,
0 commit comments