summaryrefslogtreecommitdiff
path: root/builtin
diff options
context:
space:
mode:
authorLibravatar Nguyễn Thái Ngọc Duy <pclouds@gmail.com>2019-03-19 16:39:10 +0700
committerLibravatar Junio C Hamano <gitster@pobox.com>2019-03-21 12:07:41 +0900
commita7256debd4b6ba9f6ccb94c0958ef48cdd8cb664 (patch)
treeae02f9142f207d27c8ab68c77e9f259b5db4c911 /builtin
parentmingw: allow building with an MSYS2 runtime v3.x (diff)
downloadtgif-a7256debd4b6ba9f6ccb94c0958ef48cdd8cb664.tar.xz
checkout.txt: note about losing staged changes with --merge
If you have staged changes in path A and perform 'checkout --merge' (which could result in conflicts in a totally unrelated path B), changes in A will be gone. Which is unexpected. We are supposed to keep all changes, or kick and scream otherwise. This is the result of how --merge is implemented, from the very first day in 1be0659efc (checkout: merge local modifications while switching branches., 2006-01-12): 1. a merge is done, unmerged entries are collected 2. a hard switch to a new branch is done, then unmerged entries added back There is no trivial fix for this. Going with 3-way merge one file at a time loses rename detection. Going with 3-way merge by trees requires teaching the algorithm to pick up staged changes. And even if we detect staged changes with --merge and abort for safety, an option to continue --merge is very weird. Such an option would keep worktree changes, but drop staged changes. Because the problem has been with us since the introduction of --merge and everybody has been pretty happy (except Phillip, who found this problem), I'll just take a note here to acknowledge it and wait for merge wizards to come in and work their magic. There may be a way forward [1]. [1] CABPp-BFoL_U=bzON4SEMaQSKU2TKwnOgNqjt5MUaOejTKGUJxw@mail.gmail.com Reported-by: Phillip Wood <phillip.wood@dunelm.org.uk> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'builtin')
-rw-r--r--builtin/checkout.c9
1 files changed, 9 insertions, 0 deletions
diff --git a/builtin/checkout.c b/builtin/checkout.c
index 24b8593b93..a56fa534f1 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -676,6 +676,8 @@ static int merge_working_tree(const struct checkout_opts *opts,
struct tree *result;
struct tree *work;
struct merge_options o;
+ struct strbuf sb = STRBUF_INIT;
+
if (!opts->merge)
return 1;
@@ -686,6 +688,13 @@ static int merge_working_tree(const struct checkout_opts *opts,
if (!old_branch_info->commit)
return 1;
+ if (repo_index_has_changes(the_repository,
+ get_commit_tree(old_branch_info->commit),
+ &sb))
+ warning(_("staged changes in the following files may be lost: %s"),
+ sb.buf);
+ strbuf_release(&sb);
+
/* Do more real merge */
/*