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] [<stash>]
+git stash apply [--index] [-q | --quiet] [--label-ours=<label>] [--label-theirs=<label>] [--label-base=<label>] [<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>]
(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`::
#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] [<stash>]")
+ N_("git stash apply [--index] [-q | --quiet] [--label-ours=<label>] [--label-theirs=<label>] [--label-base=<label>] [<stash>]")
#define BUILTIN_STASH_BRANCH_USAGE \
N_("git stash branch <branchname> [<stash>]")
#define BUILTIN_STASH_STORE_USAGE \
die(_("could not write index"));
}
-static int do_apply_stash(const char *prefix, struct stash_info *info,
- int index, int quiet)
+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)
{
int clean, ret;
int has_index = index;
init_ui_merge_options(&o, the_repository);
- o.branch1 = "Updated upstream";
- o.branch2 = "Stashed changes";
- o.ancestor = "Stash base";
+ o.branch1 = label_ours ? label_ours : "Updated upstream";
+ o.branch2 = label_theirs ? label_theirs : "Stashed changes";
+ o.ancestor = label_base ? label_base : "Stash base";
if (oideq(&info->b_tree, &c_tree))
o.branch1 = "Version stash was based on";
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()
};
if (get_stash_info(&info, argc, argv))
goto cleanup;
- ret = do_apply_stash(prefix, &info, index, quiet);
+ ret = do_apply_stash_with_labels(prefix, &info, index, quiet,
+ label_ours, label_theirs, label_base);
cleanup:
free_stash_info(&info);
return ret;
)
'
+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 &&
int size, int i, int style,
xdmerge_t *m, char *dest, int marker_size)
{
- 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 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 needs_cr = is_cr_needed(xe1, xe2, m);
if (marker_size <= 0)