17
#include "merge-ll.h"
18
#include "lockfile.h"
19
#include "mem-pool.h"
20
-#include "merge-ort-wrappers.h"
20
#include "object-file.h"
21
#include "object-name.h"
22
#include "odb.h"
29
#include "repo-settings.h"
30
#include "resolve-undo.h"
31
#include "revision.h"
32
+#include "sequencer.h"
33
#include "setup.h"
34
#include "submodule.h"
35
#include "symlinks.h"
99
.auto_advance = 1, \
100
}
101
102
+#define MERGE_WORKING_TREE_UNPACK_FAILED (-2)
103
+
104
struct branch_info {
105
char *name; /* The short name used */
106
char *path; /* The full name of a real branch */
755
branch->path = strbuf_detach(&buf, NULL);
756
}
757
756
-static void init_topts(struct unpack_trees_options *topts, int merge,
758
+static void init_topts(struct unpack_trees_options *topts,
759
int show_progress, int overwrite_ignore,
758
- struct commit *old_commit)
760
+ bool quiet)
761
{
762
memset(topts, 0, sizeof(*topts));
763
topts->head_idx = -1;
769
topts->initial_checkout = is_index_unborn(the_repository->index);
770
topts->update = 1;
771
topts->merge = 1;
770
- topts->quiet = merge && old_commit;
772
+ topts->quiet = quiet;
773
topts->verbose_update = show_progress;
774
topts->fn = twoway_merge;
775
topts->preserve_ignored = !overwrite_ignore;
778
static int merge_working_tree(const struct checkout_opts *opts,
779
struct branch_info *old_branch_info,
780
struct branch_info *new_branch_info,
781
+ bool quiet,
782
int *writeout_error)
783
{
784
int ret;
829
}
830
831
/* 2-way merge to the new branch */
829
- init_topts(&topts, opts->merge, opts->show_progress,
830
- opts->overwrite_ignore, old_branch_info->commit);
832
+ init_topts(&topts, opts->show_progress,
833
+ opts->overwrite_ignore, quiet);
834
init_checkout_metadata(&topts.meta, new_branch_info->refname,
835
new_branch_info->commit ?
836
&new_branch_info->commit->object.oid :
856
ret = unpack_trees(2, trees, &topts);
857
clear_unpack_trees_porcelain(&topts);
858
if (ret == -1) {
856
- /*
857
- * Unpack couldn't do a trivial merge; either
858
- * give up or do a real merge, depending on
859
- * whether the merge flag was used.
860
- */
861
- struct tree *work;
862
- struct tree *old_tree;
863
- struct merge_options o;
864
- struct strbuf sb = STRBUF_INIT;
865
- struct strbuf old_commit_shortname = STRBUF_INIT;
866
-
867
- if (!opts->merge) {
868
- rollback_lock_file(&lock_file);
869
- return 1;
870
- }
871
-
872
- /*
873
- * Without old_branch_info->commit, the below is the same as
874
- * the two-tree unpack we already tried and failed.
875
- */
876
- if (!old_branch_info->commit) {
877
- rollback_lock_file(&lock_file);
878
- return 1;
879
- }
880
- old_tree = repo_get_commit_tree(the_repository,
881
- old_branch_info->commit);
882
-
883
- if (repo_index_has_changes(the_repository, old_tree, &sb))
884
- die(_("cannot continue with staged changes in "
885
- "the following files:\n%s"), sb.buf);
886
- strbuf_release(&sb);
887
-
888
- /* Do more real merge */
889
-
890
- /*
891
- * We update the index fully, then write the
892
- * tree from the index, then merge the new
893
- * branch with the current tree, with the old
894
- * branch as the base. Then we reset the index
895
- * (but not the working tree) to the new
896
- * branch, leaving the working tree as the
897
- * merged version, but skipping unmerged
898
- * entries in the index.
899
- */
900
-
901
- add_files_to_cache(the_repository, NULL, NULL, NULL, 0,
902
- 0, 0);
903
- init_ui_merge_options(&o, the_repository);
904
- o.verbosity = 0;
905
- work = write_in_core_index_as_tree(the_repository,
906
- the_repository->index);
907
-
908
- ret = reset_tree(new_tree,
909
- opts, 1,
910
- writeout_error, new_branch_info);
911
- if (ret) {
912
- rollback_lock_file(&lock_file);
913
- return ret;
914
- }
915
- o.ancestor = old_branch_info->name;
916
- if (!old_branch_info->name) {
917
- strbuf_add_unique_abbrev(&old_commit_shortname,
918
- &old_branch_info->commit->object.oid,
919
- DEFAULT_ABBREV);
920
- o.ancestor = old_commit_shortname.buf;
921
- }
922
- o.branch1 = new_branch_info->name;
923
- o.branch2 = "local";
924
- o.conflict_style = opts->conflict_style;
925
- ret = merge_ort_nonrecursive(&o,
926
- new_tree,
927
- work,
928
- old_tree);
929
- if (ret < 0)
930
- die(NULL);
931
- ret = reset_tree(new_tree,
932
- opts, 0,
933
- writeout_error, new_branch_info);
934
- strbuf_release(&o.obuf);
935
- strbuf_release(&old_commit_shortname);
936
- if (ret) {
937
- rollback_lock_file(&lock_file);
938
- return ret;
939
- }
859
+ rollback_lock_file(&lock_file);
860
+ return MERGE_WORKING_TREE_UNPACK_FAILED;
861
}
862
}
863
1102
struct object_id rev;
1103
int flag, writeout_error = 0;
1104
int do_merge = 1;
1105
+ int created_autostash = 0;
1106
+ struct strbuf old_commit_shortname = STRBUF_INIT;
1107
+ struct strbuf autostash_msg = STRBUF_INIT;
1108
+ const char *stash_label_base = NULL;
1109
1110
trace2_cmd_mode("branch");
1111
1143
do_merge = 0;
1144
}
1145
1146
+ if (old_branch_info.name) {
1147
+ stash_label_base = old_branch_info.name;
1148
+ } else if (old_branch_info.commit) {
1149
+ strbuf_add_unique_abbrev(&old_commit_shortname,
1150
+ &old_branch_info.commit->object.oid,
1151
+ DEFAULT_ABBREV);
1152
+ stash_label_base = old_commit_shortname.buf;
1153
+ }
1154
+
1155
if (do_merge) {
1222
- ret = merge_working_tree(opts, &old_branch_info, new_branch_info, &writeout_error);
1156
+ ret = merge_working_tree(opts, &old_branch_info, new_branch_info,
1157
+ opts->merge, &writeout_error);
1158
+ if (ret == MERGE_WORKING_TREE_UNPACK_FAILED && opts->merge) {
1159
+ strbuf_addf(&autostash_msg,
1160
+ "autostash while switching to '%s'",
1161
+ new_branch_info->name);
1162
+ create_autostash_ref(the_repository,
1163
+ "CHECKOUT_AUTOSTASH_HEAD",
1164
+ autostash_msg.buf, true);
1165
+ created_autostash = 1;
1166
+ ret = merge_working_tree(opts, &old_branch_info, new_branch_info,
1167
+ false, &writeout_error);
1168
+ }
1169
+ if (created_autostash) {
1170
+ if (opts->conflict_style >= 0) {
1171
+ struct strbuf cfg = STRBUF_INIT;
1172
+ strbuf_addf(&cfg, "merge.conflictStyle=%s",
1173
+ conflict_style_name(opts->conflict_style));
1174
+ git_config_push_parameter(cfg.buf);
1175
+ strbuf_release(&cfg);
1176
+ }
1177
+ apply_autostash_ref(the_repository,
1178
+ "CHECKOUT_AUTOSTASH_HEAD",
1179
+ new_branch_info->name,
1180
+ "local",
1181
+ stash_label_base,
1182
+ autostash_msg.buf);
1183
+ }
1184
if (ret) {
1185
branch_info_release(&old_branch_info);
1225
- return ret;
1186
+ strbuf_release(&old_commit_shortname);
1187
+ strbuf_release(&autostash_msg);
1188
+ return ret < 0 ? 1 : ret;
1189
}
1190
}
1191
1194
1195
update_refs_for_switch(opts, &old_branch_info, new_branch_info);
1196
1197
+ if (created_autostash) {
1198
+ discard_index(the_repository->index);
1199
+ if (repo_read_index(the_repository) < 0)
1200
+ die(_("index file corrupt"));
1201
+
1202
+ if (!opts->quiet && new_branch_info->commit) {
1203
+ printf(_("The following paths have local changes:\n"));
1204
+ show_local_changes(&new_branch_info->commit->object,
1205
+ &opts->diff_options);
1206
+ }
1207
+ }
1208
+
1209
ret = post_checkout_hook(old_branch_info.commit, new_branch_info->commit, 1);
1210
branch_info_release(&old_branch_info);
1211
+ strbuf_release(&old_commit_shortname);
1212
+ strbuf_release(&autostash_msg);
1213
1214
return ret || writeout_error;
1215
}