Skip to content

Commit 2bee56b

Browse files
committed
Merge branch 'js/libify-require-clean-work-tree'
The require_clean_work_tree() helper was recreated in C when "git pull" was rewritten from shell; the helper is now made available to other callers in preparation for upcoming "rebase -i" work. * js/libify-require-clean-work-tree: wt-status: begin error messages with lower-case wt-status: teach has_{unstaged,uncommitted}_changes() about submodules wt-status: export also the has_un{staged,committed}_changes() functions wt-status: make the require_clean_work_tree() function reusable pull: make code more similar to the shell script again pull: drop confusing prefix parameter of die_on_unclean_work_tree()
2 parents e5272d3 + 4777e17 commit 2bee56b

File tree

3 files changed

+87
-68
lines changed

3 files changed

+87
-68
lines changed

builtin/pull.c

Lines changed: 3 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "revision.h"
1818
#include "tempfile.h"
1919
#include "lockfile.h"
20+
#include "wt-status.h"
2021

2122
enum rebase_type {
2223
REBASE_INVALID = -1,
@@ -325,73 +326,6 @@ static int git_pull_config(const char *var, const char *value, void *cb)
325326
return git_default_config(var, value, cb);
326327
}
327328

328-
/**
329-
* Returns 1 if there are unstaged changes, 0 otherwise.
330-
*/
331-
static int has_unstaged_changes(const char *prefix)
332-
{
333-
struct rev_info rev_info;
334-
int result;
335-
336-
init_revisions(&rev_info, prefix);
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(const char *prefix)
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, prefix);
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 void die_on_unclean_work_tree(const char *prefix)
369-
{
370-
struct lock_file *lock_file = xcalloc(1, sizeof(*lock_file));
371-
int do_die = 0;
372-
373-
hold_locked_index(lock_file, 0);
374-
refresh_cache(REFRESH_QUIET);
375-
update_index_if_able(&the_index, lock_file);
376-
rollback_lock_file(lock_file);
377-
378-
if (has_unstaged_changes(prefix)) {
379-
error(_("Cannot pull with rebase: You have unstaged changes."));
380-
do_die = 1;
381-
}
382-
383-
if (has_uncommitted_changes(prefix)) {
384-
if (do_die)
385-
error(_("Additionally, your index contains uncommitted changes."));
386-
else
387-
error(_("Cannot pull with rebase: Your index contains uncommitted changes."));
388-
do_die = 1;
389-
}
390-
391-
if (do_die)
392-
exit(1);
393-
}
394-
395329
/**
396330
* Appends merge candidates from FETCH_HEAD that are not marked not-for-merge
397331
* into merge_heads.
@@ -875,7 +809,8 @@ int cmd_pull(int argc, const char **argv, const char *prefix)
875809
die(_("Updating an unborn branch with changes added to the index."));
876810

877811
if (!autostash)
878-
die_on_unclean_work_tree(prefix);
812+
require_clean_work_tree(N_("pull with rebase"),
813+
_("please commit or stash them."), 1, 0);
879814

880815
if (get_rebase_fork_point(rebase_fork_point, repo, *refspecs))
881816
hashclr(rebase_fork_point);

wt-status.c

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "strbuf.h"
1717
#include "utf8.h"
1818
#include "worktree.h"
19+
#include "lockfile.h"
1920

2021
static const char cut_line[] =
2122
"------------------------ >8 ------------------------\n";
@@ -2206,3 +2207,80 @@ void wt_status_print(struct wt_status *s)
22062207
break;
22072208
}
22082209
}
2210+
2211+
/**
2212+
* Returns 1 if there are unstaged changes, 0 otherwise.
2213+
*/
2214+
int has_unstaged_changes(int ignore_submodules)
2215+
{
2216+
struct rev_info rev_info;
2217+
int result;
2218+
2219+
init_revisions(&rev_info, NULL);
2220+
if (ignore_submodules)
2221+
DIFF_OPT_SET(&rev_info.diffopt, IGNORE_SUBMODULES);
2222+
DIFF_OPT_SET(&rev_info.diffopt, QUICK);
2223+
diff_setup_done(&rev_info.diffopt);
2224+
result = run_diff_files(&rev_info, 0);
2225+
return diff_result_code(&rev_info.diffopt, result);
2226+
}
2227+
2228+
/**
2229+
* Returns 1 if there are uncommitted changes, 0 otherwise.
2230+
*/
2231+
int has_uncommitted_changes(int ignore_submodules)
2232+
{
2233+
struct rev_info rev_info;
2234+
int result;
2235+
2236+
if (is_cache_unborn())
2237+
return 0;
2238+
2239+
init_revisions(&rev_info, NULL);
2240+
if (ignore_submodules)
2241+
DIFF_OPT_SET(&rev_info.diffopt, IGNORE_SUBMODULES);
2242+
DIFF_OPT_SET(&rev_info.diffopt, QUICK);
2243+
add_head_to_pending(&rev_info);
2244+
diff_setup_done(&rev_info.diffopt);
2245+
result = run_diff_index(&rev_info, 1);
2246+
return diff_result_code(&rev_info.diffopt, result);
2247+
}
2248+
2249+
/**
2250+
* If the work tree has unstaged or uncommitted changes, dies with the
2251+
* appropriate message.
2252+
*/
2253+
int require_clean_work_tree(const char *action, const char *hint, int ignore_submodules, int gently)
2254+
{
2255+
struct lock_file *lock_file = xcalloc(1, sizeof(*lock_file));
2256+
int err = 0;
2257+
2258+
hold_locked_index(lock_file, 0);
2259+
refresh_cache(REFRESH_QUIET);
2260+
update_index_if_able(&the_index, lock_file);
2261+
rollback_lock_file(lock_file);
2262+
2263+
if (has_unstaged_changes(ignore_submodules)) {
2264+
/* TRANSLATORS: the action is e.g. "pull with rebase" */
2265+
error(_("cannot %s: You have unstaged changes."), _(action));
2266+
err = 1;
2267+
}
2268+
2269+
if (has_uncommitted_changes(ignore_submodules)) {
2270+
if (err)
2271+
error(_("additionally, your index contains uncommitted changes."));
2272+
else
2273+
error(_("cannot %s: Your index contains uncommitted changes."),
2274+
_(action));
2275+
err = 1;
2276+
}
2277+
2278+
if (err) {
2279+
if (hint)
2280+
error("%s", hint);
2281+
if (!gently)
2282+
exit(128);
2283+
}
2284+
2285+
return err;
2286+
}

wt-status.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,4 +128,10 @@ void status_printf_ln(struct wt_status *s, const char *color, const char *fmt, .
128128
__attribute__((format (printf, 3, 4)))
129129
void status_printf(struct wt_status *s, const char *color, const char *fmt, ...);
130130

131+
/* The following functions expect that the caller took care of reading the index. */
132+
int has_unstaged_changes(int ignore_submodules);
133+
int has_uncommitted_changes(int ignore_submodules);
134+
int require_clean_work_tree(const char *action, const char *hint,
135+
int ignore_submodules, int gently);
136+
131137
#endif /* STATUS_H */

0 commit comments

Comments
 (0)