]> git.ipfire.org Git - thirdparty/git.git/commitdiff
Revert "Merge branch 'hn/git-checkout-m-with-stash' into next"
authorJunio C Hamano <gitster@pobox.com>
Tue, 14 Apr 2026 20:34:01 +0000 (13:34 -0700)
committerJunio C Hamano <gitster@pobox.com>
Tue, 14 Apr 2026 20:34:01 +0000 (13:34 -0700)
This reverts commit b4e5a964fa85a84a9328647486c250706ad6501d, reversing
changes made to 0e6c98f313ae3e75cedad7125c9b4ab3ba1065c2, as the topic
is still getting rerolled.

14 files changed:
Documentation/git-checkout.adoc
Documentation/git-stash.adoc
Documentation/git-switch.adoc
builtin/checkout.c
builtin/stash.c
sequencer.c
sequencer.h
t/t3420-rebase-autostash.sh
t/t3903-stash.sh
t/t7201-co.sh
t/t7600-merge.sh
xdiff-interface.c
xdiff-interface.h
xdiff/xmerge.c

index 70dd211ee3d12f51ad1c5d382aea6f114e576f3a..43ccf47cf6de285aedd4e448ee862b57b054714c 100644 (file)
@@ -251,19 +251,20 @@ working tree, by copying them from elsewhere, extracting a tarball, etc.
        are different between the current branch and the branch to
        which you are switching, the command refuses to switch
        branches in order to preserve your modifications in context.
-       With this option, the conflicting local changes are
-       automatically stashed before the switch and reapplied
-       afterwards.  If the local changes do not overlap with the
-       differences between branches, the switch proceeds without
-       stashing.  If reapplying the stash results in conflicts, the
-       entry is saved to the stash list.  Resolve the conflicts
-       and run `git stash drop` when done, or clear the working
-       tree (e.g. with `git reset --hard`) before running `git stash
-       pop` later to re-apply your changes.
+       However, with this option, a three-way merge between the current
+       branch, your working tree contents, and the new branch
+       is done, and you will be on the new branch.
++
+When a merge conflict happens, the index entries for conflicting
+paths are left unmerged, and you need to resolve the conflicts
+and mark the resolved paths with `git add` (or `git rm` if the merge
+should result in deletion of the path).
 +
 When checking out paths from the index, this option lets you recreate
 the conflicted merge in the specified paths.  This option cannot be
 used when checking out paths from a tree-ish.
++
+When switching branches with `--merge`, staged changes may be lost.
 
 `--conflict=<style>`::
        The same as `--merge` option above, but changes the way the
@@ -577,44 +578,39 @@ $ git checkout mytopic
 error: You have local changes to 'frotz'; not switching branches.
 ------------
 
-You can give the `-m` flag to the command, which would carry your local
-changes to the new branch:
+You can give the `-m` flag to the command, which would try a
+three-way merge:
 
 ------------
 $ git checkout -m mytopic
-Switched to branch 'mytopic'
+Auto-merging frotz
 ------------
 
-After the switch, the local modifications are reapplied and are _not_
+After this three-way merge, the local modifications are _not_
 registered in your index file, so `git diff` would show you what
 changes you made since the tip of the new branch.
 
 === 3. Merge conflict
 
-When the `--merge` (`-m`) option is in effect and the locally
-modified files overlap with files that need to be updated by the
-branch switch, the changes are stashed and reapplied after the
-switch.  If this process results in conflicts, a stash entry is saved
-and made available in `git stash list`:
+When a merge conflict happens during switching branches with
+the `-m` option, you would see something like this:
 
 ------------
 $ git checkout -m mytopic
-Your local changes are stashed, however, applying it to carry
-forward your local changes resulted in conflicts:
+Auto-merging frotz
+ERROR: Merge conflict in frotz
+fatal: merge program failed
+------------
 
- - You can try resolving them now.  If you resolved them
-   successfully, discard the stash entry with "git stash drop".
+At this point, `git diff` shows the changes cleanly merged as in
+the previous example, as well as the changes in the conflicted
+files.  Edit and resolve the conflict and mark it resolved with
+`git add` as usual:
 
- - Alternatively you can "git reset --hard" if you do not want
-   to deal with them right now, and later "git stash pop" to
-   recover your local changes.
 ------------
-
-You can try resolving the conflicts now.  Edit the conflicting files
-and mark them resolved with `git add` as usual, then run `git stash
-drop` to discard the stash entry.  Alternatively, you can clear the
-working tree with `git reset --hard` and recover your local changes
-later with `git stash pop`.
+$ edit frotz
+$ git add frotz
+------------
 
 CONFIGURATION
 -------------
index 50bb89f48362a42388d20dcccdeb6d0eacc9c57c..b05c990ecd875903a8f97abe6ee392a9bcc7959c 100644 (file)
@@ -12,7 +12,7 @@ git stash list [<log-options>]
 git stash show [-u | --include-untracked | --only-untracked] [<diff-options>] [<stash>]
 git stash drop [-q | --quiet] [<stash>]
 git stash pop [--index] [-q | --quiet] [<stash>]
-git stash apply [--index] [-q | --quiet] [--label-ours=<label>] [--label-theirs=<label>] [--label-base=<label>] [<stash>]
+git stash apply [--index] [-q | --quiet] [<stash>]
 git stash branch <branchname> [<stash>]
 git stash [push] [-p | --patch] [-S | --staged] [-k | --[no-]keep-index] [-q | --quiet]
             [-u | --include-untracked] [-a | --all] [(-m | --message) <message>]
@@ -195,15 +195,6 @@ the index's ones. However, this can fail, when you have conflicts
 (which are stored in the index, where you therefore can no longer
 apply the changes as they were originally).
 
-`--label-ours=<label>`::
-`--label-theirs=<label>`::
-`--label-base=<label>`::
-       These options are only valid for the `apply` command.
-+
-Use the given labels in conflict markers instead of the default
-"Updated upstream", "Stashed changes", and "Stash base".
-`--label-base` only has an effect with merge.conflictStyle=diff3.
-
 `-k`::
 `--keep-index`::
 `--no-keep-index`::
index ee58a4d0fde38a70a69c80ee4f280029c4b5117e..87707e92652064c7385826d0d3515a1b99969e48 100644 (file)
@@ -123,19 +123,18 @@ variable.
 
 `-m`::
 `--merge`::
-       If you have local modifications to one or more files that
-       are different between the current branch and the branch to
-       which you are switching, the command normally refuses to
-       switch branches in order to preserve your modifications in
-       context.  However, with this option, the conflicting local
-       changes are automatically stashed before the switch and
-       reapplied afterwards.  If the local changes do not overlap
-       with the differences between branches, the switch proceeds
-       without stashing.  If reapplying the stash results in
-       conflicts, the entry is saved to the stash list.  Resolve
-       the conflicts and run `git stash drop` when done, or clear
-       the working tree (e.g. with `git reset --hard`) before
-       running `git stash pop` later to re-apply your changes.
+       If you have local modifications to one or more files that are
+       different between the current branch and the branch to which
+       you are switching, the command refuses to switch branches in
+       order to preserve your modifications in context.  However,
+       with this option, a three-way merge between the current
+       branch, your working tree contents, and the new branch is
+       done, and you will be on the new branch.
++
+When a merge conflict happens, the index entries for conflicting
+paths are left unmerged, and you need to resolve the conflicts
+and mark the resolved paths with `git add` (or `git rm` if the merge
+should result in deletion of the path).
 
 `--conflict=<style>`::
        The same as `--merge` option above, but changes the way the
@@ -218,15 +217,15 @@ $ git switch mytopic
 error: You have local changes to 'frotz'; not switching branches.
 ------------
 
-You can give the `-m` flag to the command, which would carry your local
-changes to the new branch:
+You can give the `-m` flag to the command, which would try a three-way
+merge:
 
 ------------
 $ git switch -m mytopic
-Switched to branch 'mytopic'
+Auto-merging frotz
 ------------
 
-After the switch, the local modifications are reapplied and are _not_
+After this three-way merge, the local modifications are _not_
 registered in your index file, so `git diff` would show you what
 changes you made since the tip of the new branch.
 
index 4671ff3804aea15a19a2464368e196316f47c6d0..ac0186a33e559a0ae2e6a9e63ae53373c58d3c1a 100644 (file)
@@ -17,6 +17,7 @@
 #include "merge-ll.h"
 #include "lockfile.h"
 #include "mem-pool.h"
+#include "merge-ort-wrappers.h"
 #include "object-file.h"
 #include "object-name.h"
 #include "odb.h"
@@ -29,7 +30,6 @@
 #include "repo-settings.h"
 #include "resolve-undo.h"
 #include "revision.h"
-#include "sequencer.h"
 #include "setup.h"
 #include "strvec.h"
 #include "submodule.h"
@@ -790,10 +790,8 @@ static int merge_working_tree(const struct checkout_opts *opts,
        struct tree *new_tree;
 
        repo_hold_locked_index(the_repository, &lock_file, LOCK_DIE_ON_ERROR);
-       if (repo_read_index_preload(the_repository, NULL, 0) < 0) {
-               rollback_lock_file(&lock_file);
+       if (repo_read_index_preload(the_repository, NULL, 0) < 0)
                return error(_("index file corrupt"));
-       }
 
        resolve_undo_clear_index(the_repository->index);
        if (opts->new_orphan_branch && opts->orphan_from_empty_tree) {
@@ -806,18 +804,14 @@ static int merge_working_tree(const struct checkout_opts *opts,
        } else {
                new_tree = repo_get_commit_tree(the_repository,
                                                new_branch_info->commit);
-               if (!new_tree) {
-                       rollback_lock_file(&lock_file);
+               if (!new_tree)
                        return error(_("unable to read tree (%s)"),
                                     oid_to_hex(&new_branch_info->commit->object.oid));
-               }
        }
        if (opts->discard_changes) {
                ret = reset_tree(new_tree, opts, 1, writeout_error, new_branch_info);
-               if (ret) {
-                       rollback_lock_file(&lock_file);
+               if (ret)
                        return ret;
-               }
        } else {
                struct tree_desc trees[2];
                struct tree *tree;
@@ -827,7 +821,6 @@ static int merge_working_tree(const struct checkout_opts *opts,
                refresh_index(the_repository->index, REFRESH_QUIET, NULL, NULL, NULL);
 
                if (unmerged_index(the_repository->index)) {
-                       rollback_lock_file(&lock_file);
                        error(_("you need to resolve your current index first"));
                        return 1;
                }
@@ -860,8 +853,82 @@ static int merge_working_tree(const struct checkout_opts *opts,
                ret = unpack_trees(2, trees, &topts);
                clear_unpack_trees_porcelain(&topts);
                if (ret == -1) {
-                       rollback_lock_file(&lock_file);
-                       return 1;
+                       /*
+                        * Unpack couldn't do a trivial merge; either
+                        * give up or do a real merge, depending on
+                        * whether the merge flag was used.
+                        */
+                       struct tree *work;
+                       struct tree *old_tree;
+                       struct merge_options o;
+                       struct strbuf sb = STRBUF_INIT;
+                       struct strbuf old_commit_shortname = STRBUF_INIT;
+
+                       if (!opts->merge)
+                               return 1;
+
+                       /*
+                        * Without old_branch_info->commit, the below is the same as
+                        * the two-tree unpack we already tried and failed.
+                        */
+                       if (!old_branch_info->commit)
+                               return 1;
+                       old_tree = repo_get_commit_tree(the_repository,
+                                                       old_branch_info->commit);
+
+                       if (repo_index_has_changes(the_repository, old_tree, &sb))
+                               die(_("cannot continue with staged changes in "
+                                     "the following files:\n%s"), sb.buf);
+                       strbuf_release(&sb);
+
+                       /* Do more real merge */
+
+                       /*
+                        * We update the index fully, then write the
+                        * tree from the index, then merge the new
+                        * branch with the current tree, with the old
+                        * branch as the base. Then we reset the index
+                        * (but not the working tree) to the new
+                        * branch, leaving the working tree as the
+                        * merged version, but skipping unmerged
+                        * entries in the index.
+                        */
+
+                       add_files_to_cache(the_repository, NULL, NULL, NULL, 0,
+                                       0, 0);
+                       init_ui_merge_options(&o, the_repository);
+                       o.verbosity = 0;
+                       work = write_in_core_index_as_tree(the_repository,
+                                                          the_repository->index);
+
+                       ret = reset_tree(new_tree,
+                                        opts, 1,
+                                        writeout_error, new_branch_info);
+                       if (ret)
+                               return ret;
+                       o.ancestor = old_branch_info->name;
+                       if (!old_branch_info->name) {
+                               strbuf_add_unique_abbrev(&old_commit_shortname,
+                                                        &old_branch_info->commit->object.oid,
+                                                        DEFAULT_ABBREV);
+                               o.ancestor = old_commit_shortname.buf;
+                       }
+                       o.branch1 = new_branch_info->name;
+                       o.branch2 = "local";
+                       o.conflict_style = opts->conflict_style;
+                       ret = merge_ort_nonrecursive(&o,
+                                                    new_tree,
+                                                    work,
+                                                    old_tree);
+                       if (ret < 0)
+                               die(NULL);
+                       ret = reset_tree(new_tree,
+                                        opts, 0,
+                                        writeout_error, new_branch_info);
+                       strbuf_release(&o.obuf);
+                       strbuf_release(&old_commit_shortname);
+                       if (ret)
+                               return ret;
                }
        }
 
@@ -1106,9 +1173,6 @@ static int switch_branches(const struct checkout_opts *opts,
        struct object_id rev;
        int flag, writeout_error = 0;
        int do_merge = 1;
-       int created_autostash = 0;
-       struct strbuf old_commit_shortname = STRBUF_INIT;
-       const char *stash_label_base = NULL;
 
        trace2_cmd_mode("branch");
 
@@ -1146,31 +1210,10 @@ static int switch_branches(const struct checkout_opts *opts,
                        do_merge = 0;
        }
 
-       if (old_branch_info.name)
-               stash_label_base = old_branch_info.name;
-       else if (old_branch_info.commit) {
-               strbuf_add_unique_abbrev(&old_commit_shortname,
-                                        &old_branch_info.commit->object.oid,
-                                        DEFAULT_ABBREV);
-               stash_label_base = old_commit_shortname.buf;
-       }
-
        if (do_merge) {
                ret = merge_working_tree(opts, &old_branch_info, new_branch_info, &writeout_error);
-               if (ret && opts->merge) {
-                       create_autostash_ref_silent(the_repository,
-                                                  "CHECKOUT_AUTOSTASH_HEAD");
-                       created_autostash = 1;
-                       ret = merge_working_tree(opts, &old_branch_info, new_branch_info, &writeout_error);
-               }
                if (ret) {
-                       apply_autostash_ref_with_labels(the_repository,
-                                                      "CHECKOUT_AUTOSTASH_HEAD",
-                                                      new_branch_info->name,
-                                                      "local",
-                                                      stash_label_base);
                        branch_info_release(&old_branch_info);
-                       strbuf_release(&old_commit_shortname);
                        return ret;
                }
        }
@@ -1180,29 +1223,8 @@ static int switch_branches(const struct checkout_opts *opts,
 
        update_refs_for_switch(opts, &old_branch_info, new_branch_info);
 
-       if (opts->conflict_style >= 0) {
-               struct strbuf cfg = STRBUF_INIT;
-               strbuf_addf(&cfg, "merge.conflictStyle=%s",
-                           conflict_style_name(opts->conflict_style));
-               git_config_push_parameter(cfg.buf);
-               strbuf_release(&cfg);
-       }
-       apply_autostash_ref_with_labels(the_repository, "CHECKOUT_AUTOSTASH_HEAD",
-                                      new_branch_info->name, "local",
-                                      stash_label_base);
-
-       discard_index(the_repository->index);
-       if (repo_read_index(the_repository) < 0)
-               die(_("index file corrupt"));
-
-       if (created_autostash && !opts->discard_changes && !opts->quiet &&
-           new_branch_info->commit)
-               show_local_changes(&new_branch_info->commit->object,
-                                  &opts->diff_options);
-
        ret = post_checkout_hook(old_branch_info.commit, new_branch_info->commit, 1);
        branch_info_release(&old_branch_info);
-       strbuf_release(&old_commit_shortname);
 
        return ret || writeout_error;
 }
index 00314e2b1318c9f9e5cac4f3cfd6d5a4f7732ff1..0d27b2fb1fcb67e0bde913d61e9adaf6c9a075fd 100644 (file)
@@ -44,7 +44,7 @@
 #define BUILTIN_STASH_POP_USAGE \
        N_("git stash pop [--index] [-q | --quiet] [<stash>]")
 #define BUILTIN_STASH_APPLY_USAGE \
-       N_("git stash apply [--index] [-q | --quiet] [--label-ours=<label>] [--label-theirs=<label>] [--label-base=<label>] [<stash>]")
+       N_("git stash apply [--index] [-q | --quiet] [<stash>]")
 #define BUILTIN_STASH_BRANCH_USAGE \
        N_("git stash branch <branchname> [<stash>]")
 #define BUILTIN_STASH_STORE_USAGE \
@@ -590,11 +590,8 @@ static void unstage_changes_unless_new(struct object_id *orig_tree)
                die(_("could not write index"));
 }
 
-static int do_apply_stash_with_labels(const char *prefix,
-                                     struct stash_info *info,
-                                     int index, int quiet,
-                                     const char *label_ours, const char *label_theirs,
-                                     const char *label_base)
+static int do_apply_stash(const char *prefix, struct stash_info *info,
+                         int index, int quiet)
 {
        int clean, ret;
        int has_index = index;
@@ -646,9 +643,9 @@ static int do_apply_stash_with_labels(const char *prefix,
 
        init_ui_merge_options(&o, the_repository);
 
-       o.branch1 = label_ours ? label_ours : "Updated upstream";
-       o.branch2 = label_theirs ? label_theirs : "Stashed changes";
-       o.ancestor = label_base ? label_base : "Stash base";
+       o.branch1 = "Updated upstream";
+       o.branch2 = "Stashed changes";
+       o.ancestor = "Stash base";
 
        if (oideq(&info->b_tree, &c_tree))
                o.branch1 = "Version stash was based on";
@@ -720,31 +717,17 @@ restore_untracked:
        return ret;
 }
 
-static int do_apply_stash(const char *prefix, struct stash_info *info,
-                         int index, int quiet)
-{
-       return do_apply_stash_with_labels(prefix, info, index, quiet,
-                                         NULL, NULL, NULL);
-}
-
 static int apply_stash(int argc, const char **argv, const char *prefix,
                       struct repository *repo UNUSED)
 {
        int ret = -1;
        int quiet = 0;
        int index = use_index;
-       const char *label_ours = NULL, *label_theirs = NULL, *label_base = NULL;
        struct stash_info info = STASH_INFO_INIT;
        struct option options[] = {
                OPT__QUIET(&quiet, N_("be quiet, only report errors")),
                OPT_BOOL(0, "index", &index,
                         N_("attempt to recreate the index")),
-               OPT_STRING(0, "label-ours", &label_ours, N_("label"),
-                          N_("label for the upstream side in conflict markers")),
-               OPT_STRING(0, "label-theirs", &label_theirs, N_("label"),
-                          N_("label for the stashed side in conflict markers")),
-               OPT_STRING(0, "label-base", &label_base, N_("label"),
-                          N_("label for the base in diff3 conflict markers")),
                OPT_END()
        };
 
@@ -754,8 +737,7 @@ static int apply_stash(int argc, const char **argv, const char *prefix,
        if (get_stash_info(&info, argc, argv))
                goto cleanup;
 
-       ret = do_apply_stash_with_labels(prefix, &info, index, quiet,
-                                        label_ours, label_theirs, label_base);
+       ret = do_apply_stash(prefix, &info, index, quiet);
 cleanup:
        free_stash_info(&info);
        return ret;
index 72967886d7de8458b42e2893b9c7bc8bc1a8ef82..b7d8dca47f4a58a7b67340dabea99a0f3ace86d0 100644 (file)
@@ -4657,8 +4657,7 @@ static enum todo_command peek_command(struct todo_list *todo_list, int offset)
 
 static void create_autostash_internal(struct repository *r,
                                      const char *path,
-                                     const char *refname,
-                                     bool silent)
+                                     const char *refname)
 {
        struct strbuf buf = STRBUF_INIT;
        struct lock_file lock_file = LOCK_INIT;
@@ -4703,8 +4702,7 @@ static void create_autostash_internal(struct repository *r,
                                        &oid, null_oid(the_hash_algo), 0, UPDATE_REFS_DIE_ON_ERR);
                }
 
-               if (!silent)
-                       printf(_("Created autostash: %s\n"), buf.buf);
+               printf(_("Created autostash: %s\n"), buf.buf);
                if (reset_head(r, &ropts) < 0)
                        die(_("could not reset --hard"));
                discard_index(r->index);
@@ -4716,22 +4714,15 @@ static void create_autostash_internal(struct repository *r,
 
 void create_autostash(struct repository *r, const char *path)
 {
-       create_autostash_internal(r, path, NULL, false);
+       create_autostash_internal(r, path, NULL);
 }
 
 void create_autostash_ref(struct repository *r, const char *refname)
 {
-       create_autostash_internal(r, NULL, refname, false);
+       create_autostash_internal(r, NULL, refname);
 }
 
-void create_autostash_ref_silent(struct repository *r, const char *refname)
-{
-       create_autostash_internal(r, NULL, refname, true);
-}
-
-static int apply_save_autostash_oid(const char *stash_oid, int attempt_apply,
-                                   const char *label_ours, const char *label_theirs,
-                                   const char *label_base)
+static int apply_save_autostash_oid(const char *stash_oid, int attempt_apply)
 {
        struct child_process child = CHILD_PROCESS_INIT;
        int ret = 0;
@@ -4742,12 +4733,6 @@ static int apply_save_autostash_oid(const char *stash_oid, int attempt_apply,
                child.no_stderr = 1;
                strvec_push(&child.args, "stash");
                strvec_push(&child.args, "apply");
-               if (label_ours)
-                       strvec_pushf(&child.args, "--label-ours=%s", label_ours);
-               if (label_theirs)
-                       strvec_pushf(&child.args, "--label-theirs=%s", label_theirs);
-               if (label_base)
-                       strvec_pushf(&child.args, "--label-base=%s", label_base);
                strvec_push(&child.args, stash_oid);
                ret = run_command(&child);
        }
@@ -4766,23 +4751,15 @@ static int apply_save_autostash_oid(const char *stash_oid, int attempt_apply,
                strvec_push(&store.args, stash_oid);
                if (run_command(&store))
                        ret = error(_("cannot store %s"), stash_oid);
-               else if (attempt_apply)
-                       fprintf(stderr,
-                               _("Your local changes are stashed, however, applying it to carry\n"
-                                 "forward your local changes resulted in conflicts:\n"
-                                 "\n"
-                                 " - You can try resolving them now.  If you resolved them\n"
-                                 "   successfully, discard the stash entry with \"git stash drop\".\n"
-                                 "\n"
-                                 " - Alternatively you can \"git reset --hard\" if you do not want\n"
-                                 "   to deal with them right now, and later \"git stash pop\" to\n"
-                                 "   recover your local changes.\n"));
                else
                        fprintf(stderr,
-                               _("Autostash exists; creating a new stash entry.\n"
+                               _("%s\n"
                                  "Your changes are safe in the stash.\n"
                                  "You can run \"git stash pop\" or"
-                                 " \"git stash drop\" at any time.\n"));
+                                 " \"git stash drop\" at any time.\n"),
+                               attempt_apply ?
+                               _("Applying autostash resulted in conflicts.") :
+                               _("Autostash exists; creating a new stash entry."));
        }
 
        return ret;
@@ -4800,8 +4777,7 @@ static int apply_save_autostash(const char *path, int attempt_apply)
        }
        strbuf_trim(&stash_oid);
 
-       ret = apply_save_autostash_oid(stash_oid.buf, attempt_apply,
-                                     NULL, NULL, NULL);
+       ret = apply_save_autostash_oid(stash_oid.buf, attempt_apply);
 
        unlink(path);
        strbuf_release(&stash_oid);
@@ -4820,13 +4796,11 @@ int apply_autostash(const char *path)
 
 int apply_autostash_oid(const char *stash_oid)
 {
-       return apply_save_autostash_oid(stash_oid, 1, NULL, NULL, NULL);
+       return apply_save_autostash_oid(stash_oid, 1);
 }
 
 static int apply_save_autostash_ref(struct repository *r, const char *refname,
-                                   int attempt_apply,
-                                   const char *label_ours, const char *label_theirs,
-                                   const char *label_base)
+                                   int attempt_apply)
 {
        struct object_id stash_oid;
        char stash_oid_hex[GIT_MAX_HEXSZ + 1];
@@ -4842,8 +4816,7 @@ static int apply_save_autostash_ref(struct repository *r, const char *refname,
                return error(_("autostash reference is a symref"));
 
        oid_to_hex_r(stash_oid_hex, &stash_oid);
-       ret = apply_save_autostash_oid(stash_oid_hex, attempt_apply,
-                                      label_ours, label_theirs, label_base);
+       ret = apply_save_autostash_oid(stash_oid_hex, attempt_apply);
 
        refs_delete_ref(get_main_ref_store(r), "", refname,
                        &stash_oid, REF_NO_DEREF);
@@ -4853,20 +4826,12 @@ static int apply_save_autostash_ref(struct repository *r, const char *refname,
 
 int save_autostash_ref(struct repository *r, const char *refname)
 {
-       return apply_save_autostash_ref(r, refname, 0, NULL, NULL, NULL);
+       return apply_save_autostash_ref(r, refname, 0);
 }
 
 int apply_autostash_ref(struct repository *r, const char *refname)
 {
-       return apply_save_autostash_ref(r, refname, 1, NULL, NULL, NULL);
-}
-
-int apply_autostash_ref_with_labels(struct repository *r, const char *refname,
-                                   const char *label_ours, const char *label_theirs,
-                                   const char *label_base)
-{
-       return apply_save_autostash_ref(r, refname, 1,
-                                       label_ours, label_theirs, label_base);
+       return apply_save_autostash_ref(r, refname, 1);
 }
 
 static int checkout_onto(struct repository *r, struct replay_opts *opts,
index 2c4ff17c4e6c2f663730b21737d0a79351a6aa39..a6fa670c7c1f99a8bcd68f58540ee793b67894bc 100644 (file)
@@ -230,15 +230,11 @@ void commit_post_rewrite(struct repository *r,
 
 void create_autostash(struct repository *r, const char *path);
 void create_autostash_ref(struct repository *r, const char *refname);
-void create_autostash_ref_silent(struct repository *r, const char *refname);
 int save_autostash(const char *path);
 int save_autostash_ref(struct repository *r, const char *refname);
 int apply_autostash(const char *path);
 int apply_autostash_oid(const char *stash_oid);
 int apply_autostash_ref(struct repository *r, const char *refname);
-int apply_autostash_ref_with_labels(struct repository *r, const char *refname,
-                                   const char *label_ours, const char *label_theirs,
-                                   const char *label_base);
 
 #define SUMMARY_INITIAL_COMMIT   (1 << 0)
 #define SUMMARY_SHOW_AUTHOR_DATE (1 << 1)
index e4e2cb19ce2db2856634069cad6dbb8c8c5d2abf..ad3ba6a9848f8a940a71cba1e11579d0e831a209 100755 (executable)
@@ -61,30 +61,18 @@ create_expected_failure_apply () {
        First, rewinding head to replay your work on top of it...
        Applying: second commit
        Applying: third commit
-       Your local changes are stashed, however, applying it to carry
-       forward your local changes resulted in conflicts:
-
-        - You can try resolving them now.  If you resolved them
-          successfully, discard the stash entry with "git stash drop".
-
-        - Alternatively you can "git reset --hard" if you do not want
-          to deal with them right now, and later "git stash pop" to
-          recover your local changes.
+       Applying autostash resulted in conflicts.
+       Your changes are safe in the stash.
+       You can run "git stash pop" or "git stash drop" at any time.
        EOF
 }
 
 create_expected_failure_merge () {
        cat >expected <<-EOF
        $(grep "^Created autostash: [0-9a-f][0-9a-f]*\$" actual)
-       Your local changes are stashed, however, applying it to carry
-       forward your local changes resulted in conflicts:
-
-        - You can try resolving them now.  If you resolved them
-          successfully, discard the stash entry with "git stash drop".
-
-        - Alternatively you can "git reset --hard" if you do not want
-          to deal with them right now, and later "git stash pop" to
-          recover your local changes.
+       Applying autostash resulted in conflicts.
+       Your changes are safe in the stash.
+       You can run "git stash pop" or "git stash drop" at any time.
        Successfully rebased and updated refs/heads/rebased-feature-branch.
        EOF
 }
index 00bcb1f80208e82cd8214dd381573abf5514c4e8..70879941c22f8c4c0046c7af4765f693d1de525f 100755 (executable)
@@ -1666,35 +1666,6 @@ test_expect_success 'restore untracked files even when we hit conflicts' '
        )
 '
 
-test_expect_success 'apply with custom conflict labels' '
-       git init conflict_labels &&
-       (
-               cd conflict_labels &&
-               test_commit base file &&
-               echo stashed >file &&
-               git stash push -m "stashed" &&
-               test_commit upstream file &&
-               test_must_fail git -c merge.conflictStyle=diff3 stash apply --label-ours=UP --label-theirs=STASH &&
-               test_grep "^<<<<<<< UP" file &&
-               test_grep "^||||||| Stash base" file &&
-               test_grep "^>>>>>>> STASH" file
-       )
-'
-
-test_expect_success 'apply with empty conflict labels' '
-       git init empty_labels &&
-       (
-               cd empty_labels &&
-               test_commit base file &&
-               echo stashed >file &&
-               git stash push -m "stashed" &&
-               test_commit upstream file &&
-               test_must_fail git stash apply --label-ours= --label-theirs= &&
-               test_grep "^<<<<<<<$" file &&
-               test_grep "^>>>>>>>$" file
-       )
-'
-
 test_expect_success 'stash create reports a locked index' '
        test_when_finished "rm -rf repo" &&
        git init repo &&
index 8f02a664f449febead61fdcce1ffee4497b02c2f..9bcf7c0b40461ff3341ef7b95c02867120c7f263 100755 (executable)
@@ -210,201 +210,6 @@ test_expect_success 'checkout --merge --conflict=diff3 <branch>' '
        test_cmp expect two
 '
 
-test_expect_success 'checkout --merge --conflict=zdiff3 <branch>' '
-       git checkout -f main &&
-       git reset --hard &&
-       git clean -f &&
-
-       fill a b X d e >two &&
-       git checkout --merge --conflict=zdiff3 simple &&
-
-       cat <<-EOF >expect &&
-       a
-       <<<<<<< simple
-       c
-       ||||||| main
-       b
-       c
-       d
-       =======
-       b
-       X
-       d
-       >>>>>>> local
-       e
-       EOF
-       test_cmp expect two
-'
-
-test_expect_success 'checkout -m respects merge.conflictStyle config' '
-       git checkout -f main &&
-       git reset --hard &&
-       git clean -f &&
-
-       test_config merge.conflictStyle diff3 &&
-       fill b d >two &&
-       git checkout -m simple &&
-
-       cat <<-EOF >expect &&
-       <<<<<<< simple
-       a
-       c
-       e
-       ||||||| main
-       a
-       b
-       c
-       d
-       e
-       =======
-       b
-       d
-       >>>>>>> local
-       EOF
-       test_cmp expect two
-'
-
-test_expect_success 'checkout -m skips stash when no conflict' '
-       git checkout -f main &&
-       git clean -f &&
-
-       fill 0 x y z >same &&
-       git stash list >stash-before &&
-       git checkout -m side >actual 2>&1 &&
-       test_grep ! "Created autostash" actual &&
-       git stash list >stash-after &&
-       test_cmp stash-before stash-after &&
-       fill 0 x y z >expect &&
-       test_cmp expect same
-'
-
-test_expect_success 'checkout -m skips stash with non-conflicting dirty index' '
-       git checkout -f main &&
-       git clean -f &&
-
-       fill 0 x y z >same &&
-       git add same &&
-       git checkout -m side >actual 2>&1 &&
-       test_grep ! "Created autostash" actual &&
-       fill 0 x y z >expect &&
-       test_cmp expect same
-'
-
-test_expect_success 'checkout -m stashes and applies on conflicting changes' '
-       git checkout -f main &&
-       git clean -f &&
-
-       fill 1 2 3 4 5 6 7 >one &&
-       git checkout -m side >actual 2>&1 &&
-       test_grep ! "Created autostash" actual &&
-       test_grep "Applied autostash" actual &&
-       fill 1 2 3 4 5 6 7 >expect &&
-       test_cmp expect one
-'
-
-test_expect_success 'checkout -m with mixed staged and unstaged changes' '
-       git checkout -f main &&
-       git clean -f &&
-
-       fill 0 x y z >same &&
-       git add same &&
-       fill 1 2 3 4 5 6 7 >one &&
-       git checkout -m side >actual 2>&1 &&
-       test_grep ! "Created autostash" actual &&
-       test_grep "Applied autostash" actual &&
-       fill 0 x y z >expect &&
-       test_cmp expect same &&
-       fill 1 2 3 4 5 6 7 >expect &&
-       test_cmp expect one
-'
-
-test_expect_success 'checkout -m stashes on truly conflicting changes' '
-       git checkout -f main &&
-       git clean -f &&
-
-       fill 1 2 3 4 5 >one &&
-       test_must_fail git checkout side 2>stderr &&
-       test_grep "Your local changes" stderr &&
-       git checkout -m side >actual 2>&1 &&
-       test_grep ! "Created autostash" actual &&
-       test_grep "resulted in conflicts" actual &&
-       test_grep "git stash drop" actual &&
-       git stash drop &&
-       git reset --hard
-'
-
-test_expect_success 'checkout -m produces usable stash on conflict' '
-       git checkout -f main &&
-       git clean -f &&
-
-       fill 1 2 3 4 5 >one &&
-       git checkout -m side >actual 2>&1 &&
-       test_grep "recover your local changes" actual &&
-       git checkout -f main &&
-       git stash pop &&
-       fill 1 2 3 4 5 >expect &&
-       test_cmp expect one
-'
-
-test_expect_success 'checkout -m stashes on staged conflicting changes' '
-       git checkout -f main &&
-       git clean -f &&
-
-       fill 1 2 3 4 5 >one &&
-       git add one &&
-       git checkout -m side >actual 2>&1 &&
-       test_grep ! "Created autostash" actual &&
-       test_grep "resulted in conflicts" actual &&
-       test_grep "git stash drop" actual &&
-       git stash drop &&
-       git reset --hard
-'
-
-test_expect_success 'checkout -m applies stash cleanly with non-overlapping changes in same file' '
-       git checkout -f main &&
-       git reset --hard &&
-       git clean -f &&
-
-       git checkout -b nonoverlap_base &&
-       fill a b c d >file &&
-       git add file &&
-       git commit -m "add file" &&
-
-       git checkout -b nonoverlap_child &&
-       fill a b c INSERTED d >file &&
-       git commit -a -m "insert line near end of file" &&
-
-       fill DIRTY a b c INSERTED d >file &&
-
-       git stash list >stash-before &&
-       git checkout -m nonoverlap_base 2>stderr &&
-       test_grep "Applied autostash" stderr &&
-       test_grep ! "resulted in conflicts" stderr &&
-
-       git stash list >stash-after &&
-       test_cmp stash-before stash-after &&
-
-       fill DIRTY a b c d >expect &&
-       test_cmp expect file &&
-
-       git checkout -f main &&
-       git branch -D nonoverlap_base &&
-       git branch -D nonoverlap_child
-'
-
-test_expect_success 'checkout -m -b skips stash with dirty tree' '
-       git checkout -f main &&
-       git clean -f &&
-
-       fill 0 x y z >same &&
-       git checkout -m -b newbranch >actual 2>&1 &&
-       test_grep ! "Created autostash" actual &&
-       fill 0 x y z >expect &&
-       test_cmp expect same &&
-       git checkout main &&
-       git branch -D newbranch
-'
-
 test_expect_success 'switch to another branch while carrying a deletion' '
        git checkout -f main &&
        git reset --hard &&
index cbef8a534ebedc1e1c3a6b308648669660ae6902..9838094b66ac393e550eaabba7201ff987028a98 100755 (executable)
@@ -914,7 +914,7 @@ test_expect_success 'merge with conflicted --autostash changes' '
        git diff >expect &&
        test_when_finished "test_might_fail git stash drop" &&
        git merge --autostash c3 2>err &&
-       test_grep "your local changes resulted in conflicts" err &&
+       test_grep "Applying autostash resulted in conflicts." err &&
        git show HEAD:file >merge-result &&
        test_cmp result.1-9 merge-result &&
        git stash show -p >actual &&
index 5ee2b96d0a756f4586d145f0ddaf8fd0906b10d4..f043330f2a12a00809226ce985e1c6da54ce26b1 100644 (file)
@@ -325,18 +325,6 @@ int parse_conflict_style_name(const char *value)
                return -1;
 }
 
-const char *conflict_style_name(int style)
-{
-       switch (style) {
-       case XDL_MERGE_DIFF3:
-               return "diff3";
-       case XDL_MERGE_ZEALOUS_DIFF3:
-               return "zdiff3";
-       default:
-               return "merge";
-       }
-}
-
 int git_xmerge_style = -1;
 
 int git_xmerge_config(const char *var, const char *value,
index ce54e1c0e002f8ac48467d0cf09a750bf987eff7..fbc4ceec40eff51a9d72479689b8311fc12c4d8c 100644 (file)
@@ -55,7 +55,6 @@ void xdiff_set_find_func(xdemitconf_t *xecfg, const char *line, int cflags);
 void xdiff_clear_find_func(xdemitconf_t *xecfg);
 struct config_context;
 int parse_conflict_style_name(const char *value);
-const char *conflict_style_name(int style);
 int git_xmerge_config(const char *var, const char *value,
                      const struct config_context *ctx, void *cb);
 extern int git_xmerge_style;
index 659ad4ec97346295d15b646a89935bd1aa9d7214..29dad98c496b077cfecc3eb4f446a8211f676838 100644 (file)
@@ -199,9 +199,9 @@ static int fill_conflict_hunk(xdfenv_t *xe1, const char *name1,
                              int size, int i, int style,
                              xdmerge_t *m, char *dest, int marker_size)
 {
-       int marker1_size = (name1 && *name1 ? strlen(name1) + 1 : 0);
-       int marker2_size = (name2 && *name2 ? strlen(name2) + 1 : 0);
-       int marker3_size = (name3 && *name3 ? strlen(name3) + 1 : 0);
+       int marker1_size = (name1 ? strlen(name1) + 1 : 0);
+       int marker2_size = (name2 ? strlen(name2) + 1 : 0);
+       int marker3_size = (name3 ? strlen(name3) + 1 : 0);
        int needs_cr = is_cr_needed(xe1, xe2, m);
 
        if (marker_size <= 0)