wt-status: make the require_clean_work_tree() function reusable

The function used by "git pull" to stop the user when the working tree has changes is useful in other places. Let's move it into a more prominent (and into an actually reusable) spot: wt-status.[ch]. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Johannes Schindelin committed Oct 7, 2016 at 18:08 UTC fd84986f467b2556e0675d1df00f83b3a323cf2e
3 files changed +80 -76
builtin/pull.c
+1 -76
@@ -17,6 +17,7 @@
17 #include "revision.h"
18 #include "tempfile.h"
19 #include "lockfile.h"
20 +#include "wt-status.h"
21
22 enum rebase_type {
23 REBASE_INVALID = -1,
@@ -325,82 +326,6 @@ static int git_pull_config(const char *var, const char *value, void *cb)
326 return git_default_config(var, value, cb);
327 }
328
328 -/**
329 - * Returns 1 if there are unstaged changes, 0 otherwise.
330 - */
331 -static int has_unstaged_changes(void)
332 -{
333 - struct rev_info rev_info;
334 - int result;
335 -
336 - init_revisions(&rev_info, NULL);
337 - DIFF_OPT_SET(&rev_info.diffopt, IGNORE_SUBMODULES);
338 - DIFF_OPT_SET(&rev_info.diffopt, QUICK);
339 - diff_setup_done(&rev_info.diffopt);
340 - result = run_diff_files(&rev_info, 0);
341 - return diff_result_code(&rev_info.diffopt, result);
342 -}
343 -
344 -/**
345 - * Returns 1 if there are uncommitted changes, 0 otherwise.
346 - */
347 -static int has_uncommitted_changes(void)
348 -{
349 - struct rev_info rev_info;
350 - int result;
351 -
352 - if (is_cache_unborn())
353 - return 0;
354 -
355 - init_revisions(&rev_info, NULL);
356 - DIFF_OPT_SET(&rev_info.diffopt, IGNORE_SUBMODULES);
357 - DIFF_OPT_SET(&rev_info.diffopt, QUICK);
358 - add_head_to_pending(&rev_info);
359 - diff_setup_done(&rev_info.diffopt);
360 - result = run_diff_index(&rev_info, 1);
361 - return diff_result_code(&rev_info.diffopt, result);
362 -}
363 -
364 -/**
365 - * If the work tree has unstaged or uncommitted changes, dies with the
366 - * appropriate message.
367 - */
368 -static int require_clean_work_tree(const char *action, const char *hint,
369 - int gently)
370 -{
371 - struct lock_file *lock_file = xcalloc(1, sizeof(*lock_file));
372 - int err = 0;
373 -
374 - hold_locked_index(lock_file, 0);
375 - refresh_cache(REFRESH_QUIET);
376 - update_index_if_able(&the_index, lock_file);
377 - rollback_lock_file(lock_file);
378 -
379 - if (has_unstaged_changes()) {
380 - /* TRANSLATORS: the action is e.g. "pull with rebase" */
381 - error(_("Cannot %s: You have unstaged changes."), _(action));
382 - err = 1;
383 - }
384 -
385 - if (has_uncommitted_changes()) {
386 - if (err)
387 - error(_("Additionally, your index contains uncommitted changes."));
388 - else
389 - error(_("Cannot %s: Your index contains uncommitted changes."),
390 - _(action));
391 - err = 1;
392 - }
393 -
394 - if (err) {
395 - if (hint)
396 - error("%s", hint);
397 - if (!gently)
398 - exit(128);
399 - }
400 -
401 - return err;
402 -}
403 -
329 /**
330 * Appends merge candidates from FETCH_HEAD that are not marked not-for-merge
331 * into merge_heads.
wt-status.c
+76
@@ -16,6 +16,7 @@
16 #include "strbuf.h"
17 #include "utf8.h"
18 #include "worktree.h"
19 +#include "lockfile.h"
20
21 static const char cut_line[] =
22 "------------------------ >8 ------------------------\n";
@@ -2209,3 +2210,78 @@ void wt_status_print(struct wt_status *s)
2210 break;
2211 }
2212 }
2213 +
2214 +/**
2215 + * Returns 1 if there are unstaged changes, 0 otherwise.
2216 + */
2217 +static int has_unstaged_changes(void)
2218 +{
2219 + struct rev_info rev_info;
2220 + int result;
2221 +
2222 + init_revisions(&rev_info, NULL);
2223 + DIFF_OPT_SET(&rev_info.diffopt, IGNORE_SUBMODULES);
2224 + DIFF_OPT_SET(&rev_info.diffopt, QUICK);
2225 + diff_setup_done(&rev_info.diffopt);
2226 + result = run_diff_files(&rev_info, 0);
2227 + return diff_result_code(&rev_info.diffopt, result);
2228 +}
2229 +
2230 +/**
2231 + * Returns 1 if there are uncommitted changes, 0 otherwise.
2232 + */
2233 +static int has_uncommitted_changes(void)
2234 +{
2235 + struct rev_info rev_info;
2236 + int result;
2237 +
2238 + if (is_cache_unborn())
2239 + return 0;
2240 +
2241 + init_revisions(&rev_info, NULL);
2242 + DIFF_OPT_SET(&rev_info.diffopt, IGNORE_SUBMODULES);
2243 + DIFF_OPT_SET(&rev_info.diffopt, QUICK);
2244 + add_head_to_pending(&rev_info);
2245 + diff_setup_done(&rev_info.diffopt);
2246 + result = run_diff_index(&rev_info, 1);
2247 + return diff_result_code(&rev_info.diffopt, result);
2248 +}
2249 +
2250 +/**
2251 + * If the work tree has unstaged or uncommitted changes, dies with the
2252 + * appropriate message.
2253 + */
2254 +int require_clean_work_tree(const char *action, const char *hint, int gently)
2255 +{
2256 + struct lock_file *lock_file = xcalloc(1, sizeof(*lock_file));
2257 + int err = 0;
2258 +
2259 + hold_locked_index(lock_file, 0);
2260 + refresh_cache(REFRESH_QUIET);
2261 + update_index_if_able(&the_index, lock_file);
2262 + rollback_lock_file(lock_file);
2263 +
2264 + if (has_unstaged_changes()) {
2265 + /* TRANSLATORS: the action is e.g. "pull with rebase" */
2266 + error(_("Cannot %s: You have unstaged changes."), _(action));
2267 + err = 1;
2268 + }
2269 +
2270 + if (has_uncommitted_changes()) {
2271 + if (err)
2272 + error(_("Additionally, your index contains uncommitted changes."));
2273 + else
2274 + error(_("Cannot %s: Your index contains uncommitted changes."),
2275 + _(action));
2276 + err = 1;
2277 + }
2278 +
2279 + if (err) {
2280 + if (hint)
2281 + error("%s", hint);
2282 + if (!gently)
2283 + exit(128);
2284 + }
2285 +
2286 + return err;
2287 +}
wt-status.h
+3
@@ -128,4 +128,7 @@ void status_printf_ln(struct wt_status *s, const char *color, const char *fmt, .
128 __attribute__((format (printf, 3, 4)))
129 void status_printf(struct wt_status *s, const char *color, const char *fmt, ...);
130
131 +/* The following function expects that the caller took care of reading the index. */
132 +int require_clean_work_tree(const char *action, const char *hint, int gently);
133 +
134 #endif /* STATUS_H */