|
20 | 20 | #include "resolve-undo.h"
|
21 | 21 | #include "submodule-config.h"
|
22 | 22 | #include "submodule.h"
|
| 23 | +#include "gvfs.h" |
23 | 24 |
|
24 | 25 | static const char * const checkout_usage[] = {
|
25 | 26 | N_("git checkout [<options>] <branch>"),
|
@@ -824,10 +825,26 @@ static int switch_branches(const struct checkout_opts *opts,
|
824 | 825 | parse_commit_or_die(new->commit);
|
825 | 826 | }
|
826 | 827 |
|
827 |
| - ret = merge_working_tree(opts, &old, new, &writeout_error); |
828 |
| - if (ret) { |
829 |
| - free(path_to_free); |
830 |
| - return ret; |
| 828 | + /* |
| 829 | + * Optimize the performance of "git checkout foo" by skipping the call |
| 830 | + * to merge_working_tree. Make this as restrictive as possible, only |
| 831 | + * checkout a new branch with the current commit. Any other options force |
| 832 | + * it through the old path. |
| 833 | + */ |
| 834 | + if (!gvfs_config_is_set(GVFS_SKIP_MERGE_IN_CHECKOUT) |
| 835 | + || !old.commit || !new->commit |
| 836 | + || oidcmp(&old.commit->object.oid, &new->commit->object.oid) |
| 837 | + || !opts->new_branch || opts->new_branch_force || opts->new_orphan_branch |
| 838 | + || opts->patch_mode || opts->merge || opts->force || opts->force_detach |
| 839 | + || opts->writeout_stage || !opts->overwrite_ignore |
| 840 | + || opts->ignore_skipworktree || opts->ignore_other_worktrees |
| 841 | + || opts->new_branch_log || opts->branch_exists || opts->prefix |
| 842 | + || opts->source_tree) { |
| 843 | + ret = merge_working_tree(opts, &old, new, &writeout_error); |
| 844 | + if (ret) { |
| 845 | + free(path_to_free); |
| 846 | + return ret; |
| 847 | + } |
831 | 848 | }
|
832 | 849 |
|
833 | 850 | if (!opts->quiet && !old.path && old.commit && new->commit != old.commit)
|
|
0 commit comments