@@ -56,18 +56,24 @@ namespace
5656 }
5757}
5858
59- void checkout_subcommand::checkout_files (
60- const repository_wrapper& repo,
61- const std::vector<std::string>& files,
62- const git_checkout_options& base_options
63- )
59+ std::vector<const char *> convert_paths_to_cstr (const std::vector<std::string>& pathspecs)
6460{
6561 std::vector<const char *> pathspec_strings;
66- pathspec_strings.reserve (files .size ());
67- for (const auto & f : files )
62+ pathspec_strings.reserve (pathspecs .size ());
63+ for (const auto & f : pathspecs )
6864 {
6965 pathspec_strings.push_back (f.c_str ());
7066 }
67+ return pathspec_strings;
68+ }
69+
70+ void checkout_subcommand::checkout_head_files (
71+ const repository_wrapper& repo,
72+ const std::vector<std::string>& pathspecs,
73+ const git_checkout_options& base_options
74+ )
75+ {
76+ std::vector<const char *> pathspec_strings = convert_paths_to_cstr (pathspecs);
7177
7278 git_checkout_options options = base_options;
7379 options.paths .strings = const_cast <char **>(pathspec_strings.data ());
@@ -76,7 +82,7 @@ void checkout_subcommand::checkout_files(
7682 throw_if_error (git_checkout_head (repo, &options));
7783}
7884
79- void checkout_subcommand::checkout_paths (
85+ void checkout_subcommand::checkout_ref_files (
8086 const repository_wrapper& repo,
8187 const std::string_view tree_ish,
8288 const std::vector<std::string>& pathspecs,
@@ -92,12 +98,7 @@ void checkout_subcommand::checkout_paths(
9298 );
9399 }
94100
95- std::vector<const char *> pathspec_strings;
96- pathspec_strings.reserve (pathspecs.size ());
97- for (const auto & p : pathspecs)
98- {
99- pathspec_strings.push_back (p.c_str ());
100- }
101+ std::vector<const char *> pathspec_strings = convert_paths_to_cstr (pathspecs);
101102
102103 git_checkout_options options = base_options;
103104 options.paths .strings = const_cast <char **>(pathspec_strings.data ());
@@ -148,15 +149,12 @@ void checkout_subcommand::run()
148149 update_head (repo, annotated_commit, target_name);
149150
150151 std::cout << " Switched to a new branch '" << target_name << " '" << std::endl;
151- return ;
152152 }
153-
154- if (!pathspecs.empty ())
153+ else if (!pathspecs.empty ())
155154 {
156- // Try tree-ish + pathspec(s)
157- if ( auto obj = repo. revparse_single (target_name) )
155+ // Validate all pathspecs before checkout so we can mimic git-like errors
156+ auto lambda_validate_paths = [](repository_wrapper& repo, const std::vector<std::string> pathspecs, std::string directory )
158157 {
159- // Validate all pathspecs before checkout so we can mimic git-like errors
160158 for (const auto & p : pathspecs)
161159 {
162160 if (!std::filesystem::exists (std::filesystem::path (directory) / p) && !repo.does_track (p))
@@ -167,27 +165,25 @@ void checkout_subcommand::run()
167165 );
168166 }
169167 }
168+ };
169+
170+ // Try tree-ish + pathspec(s)
171+ if (auto obj = repo.revparse_single (target_name))
172+ {
173+ lambda_validate_paths (repo, pathspecs, directory);
170174
171175 options.checkout_strategy = GIT_CHECKOUT_FORCE ;
172- checkout_paths (repo, target_name, pathspecs, options);
173- return ;
176+ checkout_ref_files (repo, target_name, pathspecs, options);
174177 }
175-
176178 // Else treat as files
177- for ( const auto & p : pathspecs)
179+ else
178180 {
179- if (!std::filesystem::exists (std::filesystem::path (directory) / p) && !repo.does_track (p))
180- {
181- throw git_exception (
182- " error: pathspec '" + p + " ' did not match any file(s) known to git" ,
183- git2cpp_error_code::BAD_ARGUMENT
184- );
185- }
186- }
181+ lambda_validate_paths (repo, pathspecs, directory);
187182
188- std::vector<std::string> files = m_positional_args;
189- options.checkout_strategy = GIT_CHECKOUT_FORCE ;
190- checkout_files (repo, files, options);
183+ std::vector<std::string> files = m_positional_args;
184+ options.checkout_strategy = GIT_CHECKOUT_FORCE ;
185+ checkout_head_files (repo, files, options);
186+ }
191187 return ;
192188 }
193189
@@ -209,7 +205,7 @@ void checkout_subcommand::run()
209205 }
210206
211207 options.checkout_strategy = GIT_CHECKOUT_FORCE ;
212- checkout_files (repo, file, options);
208+ checkout_head_files (repo, file, options);
213209 return ;
214210 }
215211
0 commit comments