@@ -25,7 +25,11 @@ defmodule Mix.SCM.Git do
2525 end
2626
2727 def accepts_options ( _app , opts ) do
28- opts = sparse_opts ( opts )
28+ opts =
29+ opts
30+ |> Keyword . put ( :checkout , opts [ :dest ] )
31+ |> sparse_opts ( )
32+
2933 cond do
3034 gh = opts [ :github ] ->
3135 opts
@@ -42,7 +46,7 @@ defmodule Mix.SCM.Git do
4246
4347 def checked_out? ( opts ) do
4448 # Are we inside a Git repository?
45- git_dest ( opts )
49+ opts [ :checkout ]
4650 |> Path . join ( ".git/HEAD" )
4751 |> File . regular?
4852 end
@@ -53,7 +57,7 @@ defmodule Mix.SCM.Git do
5357
5458 cond do
5559 lock_rev = get_lock_rev ( lock , opts ) ->
56- File . cd! ( git_dest ( opts ) , fn ->
60+ File . cd! ( opts [ :checkout ] , fn ->
5761 % { origin: origin , rev: rev } = get_rev_info ( )
5862 if get_lock_repo ( lock ) == origin and lock_rev == rev do
5963 :ok
@@ -79,129 +83,100 @@ defmodule Mix.SCM.Git do
7983
8084 def checkout ( opts ) do
8185 assert_git! ( )
82-
83- path = git_dest ( opts )
84- location = opts [ :git ]
85-
86- _ = File . rm_rf! ( path )
87-
88- fun =
89- if opts [ :sparse ] do
90- sparse_check ( git_version ( ) )
91- File . mkdir_p! ( path )
92- fn -> init_sparse ( opts ) end
93- else
94- git! ( ~s( clone --no-checkout --progress "#{ location } " "#{ path } ") )
95- fn -> do_checkout ( opts ) end
96- end
97-
98- File . cd! path , fun
86+ path = opts [ :checkout ]
87+ File . rm_rf! ( path )
88+ File . mkdir_p! ( path )
89+ File . cd! ( path , fn ->
90+ git! ( "init --quiet" )
91+ git! ( "--git-dir=.git remote add origin \" #{ opts [ :git ] } \" " )
92+ checkout ( path , opts )
93+ end )
9994 end
10095
10196 def update ( opts ) do
10297 assert_git! ( )
98+ path = opts [ :checkout ]
99+ File . cd! path , fn -> checkout ( path , opts ) end
100+ end
103101
104- File . cd! git_dest ( opts ) , fn ->
105- sparse_toggle ( opts )
102+ defp checkout ( _path , opts ) do
103+ # Set configuration
104+ sparse_toggle ( opts )
105+ update_origin ( opts [ :git ] )
106106
107- location = opts [ :git ]
108- update_origin ( location )
107+ # Fetch external data
108+ command = IO . iodata_to_binary ( [ "--git-dir=.git fetch --force --quiet" ,
109+ progress_switch ( git_version ( ) ) ,
110+ tags_switch ( opts [ :tag ] ) ] )
111+ git! ( command )
109112
110- command = IO . iodata_to_binary ( [ "-- git-dir=.git fetch --force" ,
111- progress_switch ( git_version ( ) ) ,
112- tags_switch ( opts [ :tag ] ) ] )
113+ # Migrate the git repo
114+ rev = get_lock_rev ( opts [ :lock ] , opts ) || get_opts_rev ( opts )
115+ git! ( "--git-dir=.git checkout --quiet #{ rev } " )
113116
114- git! ( command )
115- do_checkout ( opts )
117+ if opts [ :submodules ] do
118+ git! ( "--git-dir=.git submodule update --init --recursive" )
116119 end
120+
121+ # Get the new repo lock
122+ get_lock ( opts )
117123 end
118124
119125 defp sparse_opts ( opts ) do
120126 if opts [ :sparse ] do
121127 dest = Path . join ( opts [ :dest ] , opts [ :sparse ] )
122- opts
123- |> Keyword . put ( :git_dest , opts [ :dest ] )
124- |> Keyword . put ( :dest , dest )
128+ Keyword . put ( opts , :dest , dest )
125129 else
126130 opts
127131 end
128132 end
129133
134+ defp sparse_toggle ( opts ) do
135+ cond do
136+ sparse = opts [ :sparse ] ->
137+ sparse_check ( git_version ( ) )
138+ git! ( "--git-dir=.git config core.sparsecheckout true" )
139+ File . write! ( ".git/info/sparse-checkout" , sparse )
140+ File . exists? ( ".git/info/sparse-checkout" ) ->
141+ File . write! ( ".git/info/sparse-checkout" , "*" )
142+ git! ( "--git-dir=.git read-tree -mu HEAD" )
143+ git! ( "--git-dir=.git config core.sparsecheckout false" )
144+ File . rm ( ".git/info/sparse-checkout" )
145+ true ->
146+ :ok
147+ end
148+ end
149+
130150 defp sparse_check ( version ) do
131151 unless { 1 , 7 , 0 } <= version do
132- version =
133- version
134- |> Tuple . to_list
135- |> Enum . join ( "." )
152+ version = version |> Tuple . to_list |> Enum . join ( "." )
136153 Mix . raise "Git >= 1.7.0 is required to use sparse checkout. " <>
137- "You are running version #{ version } "
154+ "You are running version #{ version } "
138155 end
139156 end
140157
141- defp sparse_toggle ( opts ) do
142- git! ( "config core.sparsecheckout #{ opts [ :sparse ] != nil } " )
143- end
144-
145-
146158 defp progress_switch ( version ) when { 1 , 7 , 1 } <= version , do: " --progress"
147159 defp progress_switch ( _ ) , do: ""
148160
149161 defp tags_switch ( nil ) , do: ""
150162 defp tags_switch ( _ ) , do: " --tags"
151163
152- defp git_dest ( opts ) do
153- if opts [ :git_dest ] do
154- opts [ :git_dest ]
155- else
156- opts [ :dest ]
157- end
158- end
159-
160164 ## Helpers
161165
162166 defp validate_git_options ( opts ) do
163167 err = "You should specify only one of branch, ref or tag, and only once. " <>
164168 "Error on Git dependency: #{ opts [ :git ] } "
165169 validate_single_uniq ( opts , [ :branch , :ref , :tag ] , err )
166-
167- err = "You should specify only one sparse path. " <>
168- "Error on Git dependency: #{ opts [ :git ] } "
169- validate_single_uniq ( opts , [ :sparse ] , err )
170170 end
171171
172172 defp validate_single_uniq ( opts , take , error ) do
173173 case Keyword . take ( opts , take ) do
174- [ ] -> opts
174+ [ ] -> opts
175175 [ _ ] -> opts
176176 _ -> Mix . raise error
177177 end
178178 end
179179
180- defp init_sparse ( opts ) do
181- git! ( "init --quiet" )
182- git! ( "remote add origin #{ opts [ :git ] } --fetch" )
183- sparse_toggle ( opts )
184-
185- sparse_info =
186- File . cwd!
187- |> Path . join ( ".git/info/sparse-checkout" )
188-
189- File . write ( sparse_info , opts [ :sparse ] )
190-
191- do_checkout ( opts )
192- end
193-
194- defp do_checkout ( opts ) do
195- rev = get_lock_rev ( opts [ :lock ] , opts ) || get_opts_rev ( opts )
196- git! ( "--git-dir=.git checkout --quiet #{ rev } " )
197-
198- if opts [ :submodules ] do
199- git! ( "--git-dir=.git submodule update --init --recursive" )
200- end
201-
202- get_lock ( opts )
203- end
204-
205180 defp get_lock ( opts ) do
206181 % { rev: rev } = get_rev_info ( )
207182 { :git , opts [ :git ] , rev , get_lock_opts ( opts ) }
@@ -217,13 +192,7 @@ defmodule Mix.SCM.Git do
217192 defp get_lock_rev ( _ , _ ) , do: nil
218193
219194 defp get_lock_opts ( opts ) do
220- lock_opts = Keyword . take ( opts , [ :branch , :ref , :tag ] )
221- lock_opts =
222- if opts [ :sparse ] do
223- lock_opts ++ [ sparse: opts [ :sparse ] ]
224- else
225- lock_opts
226- end
195+ lock_opts = Keyword . take ( opts , [ :branch , :ref , :tag , :sparse ] )
227196
228197 if opts [ :submodules ] do
229198 lock_opts ++ [ submodules: true ]
0 commit comments