* [PATCH v4 1/6] reset: add a few tests for "git reset --merge"
2009-12-08 7:56 [PATCH v4 0/6] "git reset --merge" related improvements Christian Couder
@ 2009-12-08 7:56 ` Christian Couder
2009-12-08 7:56 ` [PATCH v4 2/6] reset: use "unpack_trees()" directly instead of "git read-tree" Christian Couder
` (5 subsequent siblings)
6 siblings, 0 replies; 10+ messages in thread
From: Christian Couder @ 2009-12-08 7:56 UTC (permalink / raw)
To: Junio C Hamano
Cc: git, Linus Torvalds, Johannes Schindelin, Stephan Beyer,
Daniel Barkalow, Jakub Narebski, Paolo Bonzini, Johannes Sixt
Commit 9e8eceab ("Add 'merge' mode to 'git reset'", 2008-12-01),
added the --merge option to git reset, but there were no test cases
for it.
This was not a big problem because "git reset" was just forking and
execing "git read-tree", but this will change in a following patch.
So let's add a few test cases to make sure that there will be no
regression.
Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
---
t/t7110-reset-merge.sh | 94 ++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 94 insertions(+), 0 deletions(-)
create mode 100755 t/t7110-reset-merge.sh
diff --git a/t/t7110-reset-merge.sh b/t/t7110-reset-merge.sh
new file mode 100755
index 0000000..8190da1
--- /dev/null
+++ b/t/t7110-reset-merge.sh
@@ -0,0 +1,94 @@
+#!/bin/sh
+#
+# Copyright (c) 2009 Christian Couder
+#
+
+test_description='Tests for "git reset --merge"'
+
+. ./test-lib.sh
+
+test_expect_success 'creating initial files' '
+ echo "line 1" >> file1 &&
+ echo "line 2" >> file1 &&
+ echo "line 3" >> file1 &&
+ cp file1 file2 &&
+ git add file1 file2 &&
+ test_tick &&
+ git commit -m "Initial commit"
+'
+
+test_expect_success 'reset --merge is ok with changes in file it does not touch' '
+ echo "line 4" >> file1 &&
+ echo "line 4" >> file2 &&
+ test_tick &&
+ git commit -m "add line 4" file1 &&
+ git reset --merge HEAD^ &&
+ ! grep 4 file1 &&
+ grep 4 file2 &&
+ git reset --merge HEAD@{1} &&
+ grep 4 file1 &&
+ grep 4 file2
+'
+
+test_expect_success 'reset --merge discards changes added to index (1)' '
+ echo "line 5" >> file1 &&
+ git add file1 &&
+ git reset --merge HEAD^ &&
+ ! grep 4 file1 &&
+ ! grep 5 file1 &&
+ grep 4 file2 &&
+ echo "line 5" >> file2 &&
+ git add file2 &&
+ git reset --merge HEAD@{1} &&
+ ! grep 4 file2 &&
+ ! grep 5 file1 &&
+ grep 4 file1
+'
+
+test_expect_success 'reset --merge discards changes added to index (2)' '
+ echo "line 4" >> file2 &&
+ git add file2 &&
+ git reset --merge HEAD^ &&
+ ! grep 4 file2 &&
+ git reset --merge HEAD@{1} &&
+ ! grep 4 file2 &&
+ grep 4 file1
+'
+
+test_expect_success 'reset --merge fails with changes in file it touches' '
+ echo "line 5" >> file1 &&
+ test_tick &&
+ git commit -m "add line 5" file1 &&
+ sed -e "s/line 1/changed line 1/" <file1 >file3 &&
+ mv file3 file1 &&
+ test_must_fail git reset --merge HEAD^ 2>err.log &&
+ grep file1 err.log | grep "not uptodate" &&
+ git reset --hard HEAD^
+'
+
+test_expect_success 'setup 2 different branches' '
+ git branch branch1 &&
+ git branch branch2 &&
+ git checkout branch1 &&
+ echo "line 5 in branch1" >> file1 &&
+ test_tick &&
+ git commit -a -m "change in branch1" &&
+ git checkout branch2 &&
+ echo "line 5 in branch2" >> file1 &&
+ test_tick &&
+ git commit -a -m "change in branch2"
+'
+
+test_expect_success '"reset --merge HEAD^" fails with pending merge' '
+ test_must_fail git merge branch1 &&
+ test_must_fail git reset --merge HEAD^ &&
+ git reset --hard HEAD
+'
+
+test_expect_success '"reset --merge HEAD" fails with pending merge' '
+ test_must_fail git merge branch1 &&
+ test_must_fail git reset --merge HEAD &&
+ git reset --hard HEAD
+'
+
+test_done
--
1.6.5.1.gaf97d
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH v4 2/6] reset: use "unpack_trees()" directly instead of "git read-tree"
2009-12-08 7:56 [PATCH v4 0/6] "git reset --merge" related improvements Christian Couder
2009-12-08 7:56 ` [PATCH v4 1/6] reset: add a few tests for "git reset --merge" Christian Couder
@ 2009-12-08 7:56 ` Christian Couder
2009-12-08 8:45 ` Stephen Boyd
2009-12-08 7:56 ` [PATCH v4 3/6] reset: add option "--keep-local-changes" to "git reset" Christian Couder
` (4 subsequent siblings)
6 siblings, 1 reply; 10+ messages in thread
From: Christian Couder @ 2009-12-08 7:56 UTC (permalink / raw)
To: Junio C Hamano
Cc: git, Linus Torvalds, Johannes Schindelin, Stephan Beyer,
Daniel Barkalow, Jakub Narebski, Paolo Bonzini, Johannes Sixt
From: Stephan Beyer <s-beyer@gmx.net>
This patch makes "reset_index_file()" call "unpack_trees()" directly
instead of forking and execing "git read-tree". So the code is more
efficient.
And it's also easier to see which unpack_tree() options will be used,
as we don't need to follow "git read-tree"'s command line parsing
which is quite complex.
As Daniel Barkalow found, there is a difference between this new
version and the old one. The old version gives an error for
"git reset --merge" with unmerged entries and the new version does
not. But this can be seen as a bug fix, because "--merge" was the
only "git reset" option with this behavior and this behavior was
not documented.
In fact there is still an error with unmerge entries if we reset
the unmerge entries to the same state as HEAD. So the bug is not
completely fixed.
The code comes from the sequencer GSoC project:
git://repo.or.cz/git/sbeyer.git
(at commit 5a78908b70ceb5a4ea9fd4b82f07ceba1f019079)
Mentored-by: Daniel Barkalow <barkalow@iabervon.org>
Mentored-by: Christian Couder <chriscool@tuxfamily.org>
Signed-off-by: Stephan Beyer <s-beyer@gmx.net>
Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
---
builtin-reset.c | 51 +++++++++++++++++++++++++++++++++++++----------
t/t7110-reset-merge.sh | 8 ++++--
2 files changed, 45 insertions(+), 14 deletions(-)
diff --git a/builtin-reset.c b/builtin-reset.c
index 73e6022..ddb81f3 100644
--- a/builtin-reset.c
+++ b/builtin-reset.c
@@ -18,6 +18,8 @@
#include "tree.h"
#include "branch.h"
#include "parse-options.h"
+#include "unpack-trees.h"
+#include "cache-tree.h"
static const char * const git_reset_usage[] = {
"git reset [--mixed | --soft | --hard | --merge] [-q] [<commit>]",
@@ -52,29 +54,56 @@ static inline int is_merge(void)
return !access(git_path("MERGE_HEAD"), F_OK);
}
+static int parse_and_init_tree_desc(const unsigned char *sha1,
+ struct tree_desc *desc)
+{
+ struct tree *tree = parse_tree_indirect(sha1);
+ if (!tree)
+ return 1;
+ init_tree_desc(desc, tree->buffer, tree->size);
+ return 0;
+}
+
static int reset_index_file(const unsigned char *sha1, int reset_type, int quiet)
{
- int i = 0;
- const char *args[6];
+ int nr = 1;
+ int newfd;
+ struct tree_desc desc[2];
+ struct unpack_trees_options opts;
+ struct lock_file *lock = xcalloc(1, sizeof(struct lock_file));
- args[i++] = "read-tree";
+ memset(&opts, 0, sizeof(opts));
+ opts.head_idx = 1;
+ opts.src_index = &the_index;
+ opts.dst_index = &the_index;
+ opts.fn = oneway_merge;
+ opts.merge = 1;
if (!quiet)
- args[i++] = "-v";
+ opts.verbose_update = 1;
switch (reset_type) {
case MERGE:
- args[i++] = "-u";
- args[i++] = "-m";
+ opts.update = 1;
break;
case HARD:
- args[i++] = "-u";
+ opts.update = 1;
/* fallthrough */
default:
- args[i++] = "--reset";
+ opts.reset = 1;
}
- args[i++] = sha1_to_hex(sha1);
- args[i] = NULL;
- return run_command_v_opt(args, RUN_GIT_CMD);
+ newfd = hold_locked_index(lock, 1);
+
+ read_cache_unmerged();
+
+ if (parse_and_init_tree_desc(sha1, desc + nr - 1))
+ return error("Failed to find tree of %s.", sha1_to_hex(sha1));
+ if (unpack_trees(nr, desc, &opts))
+ return -1;
+ if (write_cache(newfd, active_cache, active_nr) ||
+ commit_locked_index(lock))
+ return error("Could not write new index file.");
+
+ return 0;
}
static void print_new_head_line(struct commit *commit)
diff --git a/t/t7110-reset-merge.sh b/t/t7110-reset-merge.sh
index 8190da1..6afaf73 100755
--- a/t/t7110-reset-merge.sh
+++ b/t/t7110-reset-merge.sh
@@ -79,10 +79,12 @@ test_expect_success 'setup 2 different branches' '
git commit -a -m "change in branch2"
'
-test_expect_success '"reset --merge HEAD^" fails with pending merge' '
+test_expect_success '"reset --merge HEAD^" is ok with pending merge' '
test_must_fail git merge branch1 &&
- test_must_fail git reset --merge HEAD^ &&
- git reset --hard HEAD
+ git reset --merge HEAD^ &&
+ test -z "$(git diff --cached)" &&
+ test -n "$(git diff)" &&
+ git reset --hard HEAD@{1}
'
test_expect_success '"reset --merge HEAD" fails with pending merge' '
--
1.6.5.1.gaf97d
^ permalink raw reply related [flat|nested] 10+ messages in thread* Re: [PATCH v4 2/6] reset: use "unpack_trees()" directly instead of "git read-tree"
2009-12-08 7:56 ` [PATCH v4 2/6] reset: use "unpack_trees()" directly instead of "git read-tree" Christian Couder
@ 2009-12-08 8:45 ` Stephen Boyd
2009-12-12 4:19 ` Christian Couder
0 siblings, 1 reply; 10+ messages in thread
From: Stephen Boyd @ 2009-12-08 8:45 UTC (permalink / raw)
To: Christian Couder
Cc: Junio C Hamano, git, Linus Torvalds, Johannes Schindelin,
Stephan Beyer, Daniel Barkalow, Jakub Narebski, Paolo Bonzini,
Johannes Sixt
On Tue, 2009-12-08 at 08:56 +0100, Christian Couder wrote:
> +static int parse_and_init_tree_desc(const unsigned char *sha1,
> + struct tree_desc *desc)
> +{
> + struct tree *tree = parse_tree_indirect(sha1);
> + if (!tree)
> + return 1;
> + init_tree_desc(desc, tree->buffer, tree->size);
> + return 0;
> +}
> +
>
Is there a reason why you use this function instead of
fill_tree_descriptor()?
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [PATCH v4 2/6] reset: use "unpack_trees()" directly instead of "git read-tree"
2009-12-08 8:45 ` Stephen Boyd
@ 2009-12-12 4:19 ` Christian Couder
0 siblings, 0 replies; 10+ messages in thread
From: Christian Couder @ 2009-12-12 4:19 UTC (permalink / raw)
To: Stephen Boyd
Cc: Junio C Hamano, git, Linus Torvalds, Johannes Schindelin,
Stephan Beyer, Daniel Barkalow, Jakub Narebski, Paolo Bonzini,
Johannes Sixt
On mardi 08 décembre 2009, Stephen Boyd wrote:
> On Tue, 2009-12-08 at 08:56 +0100, Christian Couder wrote:
> > +static int parse_and_init_tree_desc(const unsigned char *sha1,
> > + struct tree_desc *desc)
> > +{
> > + struct tree *tree = parse_tree_indirect(sha1);
> > + if (!tree)
> > + return 1;
> > + init_tree_desc(desc, tree->buffer, tree->size);
> > + return 0;
> > +}
> > +
>
> Is there a reason why you use this function instead of
> fill_tree_descriptor()?
I didn't know about fill_tree_descriptor(). I will use it in the next
series.
Thanks,
Christian.
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v4 3/6] reset: add option "--keep-local-changes" to "git reset"
2009-12-08 7:56 [PATCH v4 0/6] "git reset --merge" related improvements Christian Couder
2009-12-08 7:56 ` [PATCH v4 1/6] reset: add a few tests for "git reset --merge" Christian Couder
2009-12-08 7:56 ` [PATCH v4 2/6] reset: use "unpack_trees()" directly instead of "git read-tree" Christian Couder
@ 2009-12-08 7:56 ` Christian Couder
2009-12-08 7:56 ` [PATCH v4 4/6] reset: add test cases for "--keep-local-changes" option Christian Couder
` (3 subsequent siblings)
6 siblings, 0 replies; 10+ messages in thread
From: Christian Couder @ 2009-12-08 7:56 UTC (permalink / raw)
To: Junio C Hamano
Cc: git, Linus Torvalds, Johannes Schindelin, Stephan Beyer,
Daniel Barkalow, Jakub Narebski, Paolo Bonzini, Johannes Sixt
The purpose of this new option is to discard some of the
last commits but to keep current changes in the work tree
and the index.
The table below shows what happens when running
"git reset --option target" to reset the HEAD to another
commit (as a special case "target" could be the same as
HEAD) in the cases where "--merge" and
"--keep-local-changes" (abreviated --k-l-c) behave
differently.
working index HEAD target working index HEAD
----------------------------------------------------
B B A A --k-l-c B A A
--merge A A A
B B A C --k-l-c (disallowed)
--merge C C C
In this table, A, B and C are some different states of
a file. For example the first line of the table means
that if a file is in state B in the working tree and
the index, and in a different state A in HEAD and in
the target, then "git reset --keep-local-changes target"
will put the file in state B in the working tree and in
state A in the index and HEAD.
So as can be seen in the table, "--merge" discards changes
in the index, while "--keep-local-changes" does not. So
if one wants to avoid using "git stash" before and after
using "git reset" to save current changes, it is better to
use "--keep-local-changes" rather than "--merge".
The following table shows what happens on unmerged entries:
working index HEAD target working index HEAD
----------------------------------------------------
X U A B --k-l-c X B B
--merge X B B
X U A A --k-l-c X A A
--merge (disallowed)
In this table X can be any state and U means an unmerged
entry.
A following patch will add some test cases for
"--keep-local-changes", where the differences between
"--merge" and "--keep-local-changes" can also be seen.
The "--keep-local-changes" option is implemented by doing
a 2 way merge between HEAD and the reset target, and if
this succeeds by doing a mixed reset to the target.
The code comes from the sequencer GSoC project, where
such an option was developed by Stephan Beyer:
git://repo.or.cz/git/sbeyer.git
(at commit 5a78908b70ceb5a4ea9fd4b82f07ceba1f019079)
But in the sequencer project the "reset" flag was set
in the "struct unpack_trees_options" passed to
"unpack_trees()". With this flag the changes in the
working tree were discarded if the file was different
between HEAD and the reset target.
Mentored-by: Daniel Barkalow <barkalow@iabervon.org>
Mentored-by: Christian Couder <chriscool@tuxfamily.org>
Signed-off-by: Stephan Beyer <s-beyer@gmx.net>
Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
---
builtin-reset.c | 30 +++++++++++++++++++++++++-----
1 files changed, 25 insertions(+), 5 deletions(-)
diff --git a/builtin-reset.c b/builtin-reset.c
index ddb81f3..3cbc4fd 100644
--- a/builtin-reset.c
+++ b/builtin-reset.c
@@ -22,13 +22,15 @@
#include "cache-tree.h"
static const char * const git_reset_usage[] = {
- "git reset [--mixed | --soft | --hard | --merge] [-q] [<commit>]",
+ "git reset [--mixed | --soft | --hard | --merge | --keep-local-changes] [-q] [<commit>]",
"git reset [--mixed] <commit> [--] <paths>...",
NULL
};
-enum reset_type { MIXED, SOFT, HARD, MERGE, NONE };
-static const char *reset_type_names[] = { "mixed", "soft", "hard", "merge", NULL };
+enum reset_type { MIXED, SOFT, HARD, MERGE, KEEP_LOCAL_CHANGES, NONE };
+static const char *reset_type_names[] = {
+ "mixed", "soft", "hard", "merge", "keep_local_changes", NULL
+};
static char *args_to_str(const char **argv)
{
@@ -81,6 +83,7 @@ static int reset_index_file(const unsigned char *sha1, int reset_type, int quiet
if (!quiet)
opts.verbose_update = 1;
switch (reset_type) {
+ case KEEP_LOCAL_CHANGES:
case MERGE:
opts.update = 1;
break;
@@ -95,6 +98,16 @@ static int reset_index_file(const unsigned char *sha1, int reset_type, int quiet
read_cache_unmerged();
+ if (reset_type == KEEP_LOCAL_CHANGES) {
+ unsigned char head_sha1[20];
+ if (get_sha1("HEAD", head_sha1))
+ return error("You do not have a valid HEAD.");
+ if (parse_and_init_tree_desc(head_sha1, desc))
+ return error("Failed to find tree of HEAD.");
+ nr++;
+ opts.fn = twoway_merge;
+ }
+
if (parse_and_init_tree_desc(sha1, desc + nr - 1))
return error("Failed to find tree of %s.", sha1_to_hex(sha1));
if (unpack_trees(nr, desc, &opts))
@@ -238,6 +251,9 @@ int cmd_reset(int argc, const char **argv, const char *prefix)
"reset HEAD, index and working tree", HARD),
OPT_SET_INT(0, "merge", &reset_type,
"reset HEAD, index and working tree", MERGE),
+ OPT_SET_INT(0, "keep-local-changes", &reset_type,
+ "reset HEAD but keep local changes",
+ KEEP_LOCAL_CHANGES),
OPT_BOOLEAN('q', NULL, &quiet,
"disable showing new HEAD in hard reset and progress message"),
OPT_BOOLEAN('p', "patch", &patch_mode, "select hunks interactively"),
@@ -324,9 +340,13 @@ int cmd_reset(int argc, const char **argv, const char *prefix)
if (reset_type == SOFT) {
if (is_merge() || read_cache() < 0 || unmerged_cache())
die("Cannot do a soft reset in the middle of a merge.");
+ } else {
+ int err = reset_index_file(sha1, reset_type, quiet);
+ if (reset_type == KEEP_LOCAL_CHANGES)
+ err = err || reset_index_file(sha1, MIXED, quiet);
+ if (err)
+ die("Could not reset index file to revision '%s'.", rev);
}
- else if (reset_index_file(sha1, reset_type, quiet))
- die("Could not reset index file to revision '%s'.", rev);
/* Any resets update HEAD to the head being switched to,
* saving the previous head in ORIG_HEAD before. */
--
1.6.5.1.gaf97d
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH v4 4/6] reset: add test cases for "--keep-local-changes" option
2009-12-08 7:56 [PATCH v4 0/6] "git reset --merge" related improvements Christian Couder
` (2 preceding siblings ...)
2009-12-08 7:56 ` [PATCH v4 3/6] reset: add option "--keep-local-changes" to "git reset" Christian Couder
@ 2009-12-08 7:56 ` Christian Couder
2009-12-08 7:56 ` [PATCH v4 5/6] Documentation: reset: describe new " Christian Couder
` (2 subsequent siblings)
6 siblings, 0 replies; 10+ messages in thread
From: Christian Couder @ 2009-12-08 7:56 UTC (permalink / raw)
To: Junio C Hamano
Cc: git, Linus Torvalds, Johannes Schindelin, Stephan Beyer,
Daniel Barkalow, Jakub Narebski, Paolo Bonzini, Johannes Sixt
This shows that with the "--keep-local-changes" option, changes that
are both in the work tree and the index are kept in the work tree
after the reset (but discarded in the index). As with the "--merge"
option, changes that are in both the work tree and the index are
discarded after the reset.
In the case of unmerged entries, we can see that
"git reset --merge HEAD" is disallowed while it works using
"--keep-local-changes" instead.
And this shows that otherwise "--merge" and "--keep-local-changes"
have the same behavior.
Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
---
t/t7110-reset-merge.sh | 62 +++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 61 insertions(+), 1 deletions(-)
diff --git a/t/t7110-reset-merge.sh b/t/t7110-reset-merge.sh
index 6afaf73..c8f72cd 100755
--- a/t/t7110-reset-merge.sh
+++ b/t/t7110-reset-merge.sh
@@ -3,7 +3,7 @@
# Copyright (c) 2009 Christian Couder
#
-test_description='Tests for "git reset --merge"'
+test_description='Tests for "git reset" with --merge and --keep-local-changes'
. ./test-lib.sh
@@ -30,6 +30,20 @@ test_expect_success 'reset --merge is ok with changes in file it does not touch'
grep 4 file2
'
+test_expect_success 'reset --keep-local-changes is ok with changes in file it does not touch' '
+ git reset --hard HEAD^ &&
+ echo "line 4" >> file1 &&
+ echo "line 4" >> file2 &&
+ test_tick &&
+ git commit -m "add line 4" file1 &&
+ git reset --keep-local-changes HEAD^ &&
+ ! grep 4 file1 &&
+ grep 4 file2 &&
+ git reset --keep-local-changes HEAD@{1} &&
+ grep 4 file1 &&
+ grep 4 file2
+'
+
test_expect_success 'reset --merge discards changes added to index (1)' '
echo "line 5" >> file1 &&
git add file1 &&
@@ -55,6 +69,25 @@ test_expect_success 'reset --merge discards changes added to index (2)' '
grep 4 file1
'
+test_expect_success 'reset --keep-local-changes fails with changes in index in files it touches' '
+ echo "line 4" >> file2 &&
+ echo "line 5" >> file1 &&
+ git add file1 &&
+ test_must_fail git reset --keep-local-changes HEAD^ &&
+ git reset --hard HEAD
+'
+
+test_expect_success 'reset --keep-local-changes keeps changes it does not touch' '
+ echo "line 4" >> file2 &&
+ git add file2 &&
+ git reset --keep-local-changes HEAD^ &&
+ grep 4 file2 &&
+ git reset --keep-local-changes HEAD@{1} &&
+ grep 4 file2 &&
+ grep 4 file1 &&
+ git reset --hard HEAD
+'
+
test_expect_success 'reset --merge fails with changes in file it touches' '
echo "line 5" >> file1 &&
test_tick &&
@@ -66,6 +99,17 @@ test_expect_success 'reset --merge fails with changes in file it touches' '
git reset --hard HEAD^
'
+test_expect_success 'reset --keep-local-changes fails with changes in file it touches' '
+ echo "line 5" >> file1 &&
+ test_tick &&
+ git commit -m "add line 5" file1 &&
+ sed -e "s/line 1/changed line 1/" <file1 >file3 &&
+ mv file3 file1 &&
+ test_must_fail git reset --keep-local-changes HEAD^ 2>err.log &&
+ grep file1 err.log | grep "not uptodate" &&
+ git reset --hard HEAD^
+'
+
test_expect_success 'setup 2 different branches' '
git branch branch1 &&
git branch branch2 &&
@@ -87,10 +131,26 @@ test_expect_success '"reset --merge HEAD^" is ok with pending merge' '
git reset --hard HEAD@{1}
'
+test_expect_success '"reset --keep-local-changes HEAD^" is ok with pending merge' '
+ test_must_fail git merge branch1 &&
+ git reset --keep-local-changes HEAD^ &&
+ test -z "$(git diff --cached)" &&
+ test -n "$(git diff)" &&
+ git reset --hard HEAD@{1}
+'
+
test_expect_success '"reset --merge HEAD" fails with pending merge' '
test_must_fail git merge branch1 &&
test_must_fail git reset --merge HEAD &&
git reset --hard HEAD
'
+test_expect_success '"reset --keep-local-changes HEAD" is ok with pending merge' '
+ test_must_fail git merge branch1 &&
+ git reset --keep-local-changes HEAD &&
+ test -z "$(git diff --cached)" &&
+ test -n "$(git diff)" &&
+ git reset --hard HEAD
+'
+
test_done
--
1.6.5.1.gaf97d
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH v4 5/6] Documentation: reset: describe new "--keep-local-changes" option
2009-12-08 7:56 [PATCH v4 0/6] "git reset --merge" related improvements Christian Couder
` (3 preceding siblings ...)
2009-12-08 7:56 ` [PATCH v4 4/6] reset: add test cases for "--keep-local-changes" option Christian Couder
@ 2009-12-08 7:56 ` Christian Couder
2009-12-08 7:56 ` [PATCH v4 6/6] Documentation: reset: add some tables to describe the different options Christian Couder
2009-12-08 8:29 ` [PATCH v4 0/6] "git reset --merge" related improvements Junio C Hamano
6 siblings, 0 replies; 10+ messages in thread
From: Christian Couder @ 2009-12-08 7:56 UTC (permalink / raw)
To: Junio C Hamano
Cc: git, Linus Torvalds, Johannes Schindelin, Stephan Beyer,
Daniel Barkalow, Jakub Narebski, Paolo Bonzini, Johannes Sixt
Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
---
Documentation/git-reset.txt | 7 ++++++-
1 files changed, 6 insertions(+), 1 deletions(-)
diff --git a/Documentation/git-reset.txt b/Documentation/git-reset.txt
index 2d27e40..a6c080e 100644
--- a/Documentation/git-reset.txt
+++ b/Documentation/git-reset.txt
@@ -8,7 +8,7 @@ git-reset - Reset current HEAD to the specified state
SYNOPSIS
--------
[verse]
-'git reset' [--mixed | --soft | --hard | --merge] [-q] [<commit>]
+'git reset' [--mixed | --soft | --hard | --merge | --keep-local-changes] [-q] [<commit>]
'git reset' [-q] [<commit>] [--] <paths>...
'git reset' --patch [<commit>] [--] [<paths>...]
@@ -52,6 +52,11 @@ OPTIONS
and updates the files that are different between the named commit
and the current commit in the working tree.
+--keep-local-changes::
+ This does the same thing as --merge, but it keeps changes in
+ the working tree and the index or it aborts if it is not
+ possible.
+
-p::
--patch::
Interactively select hunks in the difference between the index
--
1.6.5.1.gaf97d
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH v4 6/6] Documentation: reset: add some tables to describe the different options
2009-12-08 7:56 [PATCH v4 0/6] "git reset --merge" related improvements Christian Couder
` (4 preceding siblings ...)
2009-12-08 7:56 ` [PATCH v4 5/6] Documentation: reset: describe new " Christian Couder
@ 2009-12-08 7:56 ` Christian Couder
2009-12-08 8:29 ` [PATCH v4 0/6] "git reset --merge" related improvements Junio C Hamano
6 siblings, 0 replies; 10+ messages in thread
From: Christian Couder @ 2009-12-08 7:56 UTC (permalink / raw)
To: Junio C Hamano
Cc: git, Linus Torvalds, Johannes Schindelin, Stephan Beyer,
Daniel Barkalow, Jakub Narebski, Paolo Bonzini, Johannes Sixt
This patch adds a DISCUSSION section that contains some tables to
show how the different "git reset" options work depending on the
states of the files in the working tree, the index, HEAD and the
target commit.
Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
---
Documentation/git-reset.txt | 73 +++++++++++++++++++++++++++++++++++++++++++
1 files changed, 73 insertions(+), 0 deletions(-)
diff --git a/Documentation/git-reset.txt b/Documentation/git-reset.txt
index a6c080e..8bc8808 100644
--- a/Documentation/git-reset.txt
+++ b/Documentation/git-reset.txt
@@ -72,6 +72,79 @@ linkgit:git-add[1]).
<commit>::
Commit to make the current HEAD. If not given defaults to HEAD.
+DISCUSSION
+----------
+
+The tables below show what happens when running:
+
+----------
+git reset --option target
+----------
+
+to reset the HEAD to another commit (`target`) with the different
+reset options (`--keep-local-changes` is abreviated --k-l-c)
+depending on the state of the files.
+
+ working index HEAD target working index HEAD
+ ----------------------------------------------------
+ A B C D --soft A B D
+ --mixed A D D
+ --hard D D D
+ --merge (disallowed)
+ --k-l-c (disallowed)
+
+ working index HEAD target working index HEAD
+ ----------------------------------------------------
+ A B C C --soft A B C
+ --mixed A C C
+ --hard C C C
+ --merge (disallowed)
+ --k-l-c A C C
+
+ working index HEAD target working index HEAD
+ ----------------------------------------------------
+ B B C D --soft B B D
+ --mixed B D D
+ --hard D D D
+ --merge D D D
+ --k-l-c (disallowed)
+
+ working index HEAD target working index HEAD
+ ----------------------------------------------------
+ B B C C --soft B B C
+ --mixed B C C
+ --hard C C C
+ --merge C C C
+ --k-l-c B C C
+
+In these tables, A, B, C and D are some different states of a
+file. For example, the last line of the last table means that if a
+file is in state B in the working tree and the index, and in a
+different state C in HEAD and in the target, then "git reset
+--keep-local-changes target" will put the file in state B in the
+working tree and in state C in the index and HEAD.
+
+The following tables show what happens when there are unmerged
+entries:
+
+ working index HEAD target working index HEAD
+ ----------------------------------------------------
+ X U A B --k-l-c X B B
+ --merge X B B
+ --hard B B B
+ --mixed X B B
+ --soft (disallowed)
+
+ working index HEAD target working index HEAD
+ ----------------------------------------------------
+ X U A A --k-l-c X A A
+ --merge (disallowed)
+ --hard A A A
+ --mixed X A A
+ --soft (disallowed)
+
+X means any state and U means an unmerged index.
+
Examples
--------
--
1.6.5.1.gaf97d
^ permalink raw reply related [flat|nested] 10+ messages in thread* Re: [PATCH v4 0/6] "git reset --merge" related improvements
2009-12-08 7:56 [PATCH v4 0/6] "git reset --merge" related improvements Christian Couder
` (5 preceding siblings ...)
2009-12-08 7:56 ` [PATCH v4 6/6] Documentation: reset: add some tables to describe the different options Christian Couder
@ 2009-12-08 8:29 ` Junio C Hamano
6 siblings, 0 replies; 10+ messages in thread
From: Junio C Hamano @ 2009-12-08 8:29 UTC (permalink / raw)
To: Christian Couder
Cc: git, Linus Torvalds, Johannes Schindelin, Stephan Beyer,
Daniel Barkalow, Jakub Narebski, Paolo Bonzini, Johannes Sixt
Christian Couder <chriscool@tuxfamily.org> writes:
> The new option name is "--keep-local-changes" because that's what
> Junio used in the last email of the previous discussion, but my
> opinion is that it is a bit long and so I'd like to rename it "--keep"
> or another such short name.
I vaguely recall that I mentioned something like "I still don't know what
you are going to use this for, even though I think I am starting to
understand it a bit better than before. In any case, it sounds like 'keep
local changes' rather than 'safe'".
Please don't take that as a serious suggestion of a better name.
IOW, don't mind me---come up with a name that describes what you
are doing better. But please don't blame me either ;-)
^ permalink raw reply [flat|nested] 10+ messages in thread