All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] Teach checkout the -n|--dry-run option
@ 2011-05-06 22:12 Jens Lehmann
  2011-05-06 22:49 ` Junio C Hamano
  0 siblings, 1 reply; 9+ messages in thread
From: Jens Lehmann @ 2011-05-06 22:12 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Git Mailing List

This option can be used to determine if checking out a branch or commit
would touch files which are modified in the work tree. It doesn't change
the work tree contents or the index, so it can only tell if the checkout
would succeed using trivial merges.

It can neither be used when checking out only certain paths nor together
with the '-m' option.

Signed-off-by: Jens Lehmann <Jens.Lehmann@web.de>
---

This is a repost of a RFC patch from Sep 04, 2010 I did not receive any
responses upon:

I need this new option for the recursive submodule checkout. Denying a
checkout inside a submodule just because it has modifications is a too
limiting condition (and it is way too expensive to check the whole tree,
just looking at those paths going to be changed by the checkout should
be much faster, especially for large submodules).

IMO the same behavior that applies for a checkout in the superproject
should apply for the checkout inside the submodule: no local changes
may be overwritten by the checkout (and the HEAD must match the commit
recorded in the superproject, but that is handled elsewhere).

To be able to test that, I added the -n|--dry-run option to checkout.
I think I found all relevant places, but a few more eyeballs are highly
appreciated as I am not very familiar with this part of the code.

A thing I'm not so sure about is the output of show_local_changes(),
with -n it doesn't show the changes as they would have been *after* the
- not executed - checkout but *without* having done it.
Is that a problem here?

 Documentation/git-checkout.txt |   15 ++++++++++++---
 builtin/checkout.c             |   20 +++++++++++++++-----
 t/t2018-checkout-branch.sh     |   23 +++++++++++++++++++++++
 3 files changed, 50 insertions(+), 8 deletions(-)

diff --git a/Documentation/git-checkout.txt b/Documentation/git-checkout.txt
index 1063f69..ae58762 100644
--- a/Documentation/git-checkout.txt
+++ b/Documentation/git-checkout.txt
@@ -8,9 +8,9 @@ git-checkout - Checkout a branch or paths to the working tree
 SYNOPSIS
 --------
 [verse]
-'git checkout' [-q] [-f] [-m] [<branch>]
-'git checkout' [-q] [-f] [-m] [--detach] [<commit>]
-'git checkout' [-q] [-f] [-m] [[-b|-B|--orphan] <new_branch>] [<start_point>]
+'git checkout' [-q] [-f] [-m|-n] [<branch>]
+'git checkout' [-q] [-f] [-m|-n] [--detach] [<commit>]
+'git checkout' [-q] [-f] [-m|-n] [[-b|-B|--orphan] <new_branch>] [<start_point>]
 'git checkout' [-f|--ours|--theirs|-m|--conflict=<style>] [<tree-ish>] [--] <paths>...
 'git checkout' --patch [<tree-ish>] [--] [<paths>...]

@@ -79,6 +79,13 @@ OPTIONS
 When checking out paths from the index, do not fail upon unmerged
 entries; instead, unmerged entries are ignored.

+-n::
+--dry-run::
+	Don't really checkout the file(s), just check if it would succeed
+	using only trivial merges. Using this option will not touch the work
+	tree or the index. The command will fail when the checkout would change
+	locally modified files. This option can not be used together with `-m`.
+
 --ours::
 --theirs::
 	When checking out paths from the index, check out stage #2
@@ -167,6 +174,8 @@ 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 does not work together with '-n'.

 --conflict=<style>::
 	The same as --merge option above, but changes the way the
diff --git a/builtin/checkout.c b/builtin/checkout.c
index 38632fc..01175d1 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -33,6 +33,7 @@ struct checkout_opts {
 	int force_detach;
 	int writeout_stage;
 	int writeout_error;
+	int dry_run;

 	/* not set by parse_options */
 	int branch_exists;
@@ -373,6 +374,8 @@ static int merge_working_tree(struct checkout_opts *opts,

 	resolve_undo_clear();
 	if (opts->force) {
+		if (opts->dry_run)
+			return 0;
 		ret = reset_tree(new->commit->tree, opts, 1);
 		if (ret)
 			return ret;
@@ -397,7 +400,7 @@ static int merge_working_tree(struct checkout_opts *opts,

 		/* 2-way merge to the new branch */
 		topts.initial_checkout = is_cache_unborn();
-		topts.update = 1;
+		topts.update = !opts->dry_run;
 		topts.merge = 1;
 		topts.gently = opts->merge && old->commit;
 		topts.verbose_update = !opts->quiet;
@@ -471,8 +474,8 @@ static int merge_working_tree(struct checkout_opts *opts,
 		}
 	}

-	if (write_cache(newfd, active_cache, active_nr) ||
-	    commit_locked_index(lock_file))
+	if (!opts->dry_run && (write_cache(newfd, active_cache, active_nr) ||
+			       commit_locked_index(lock_file)))
 		die(_("unable to write new index file"));

 	if (!opts->force && !opts->quiet)
@@ -732,7 +735,7 @@ static int switch_branches(struct checkout_opts *opts, struct branch_info *new)
 	}

 	ret = merge_working_tree(opts, &old, new);
-	if (ret)
+	if (ret || opts->dry_run)
 		return ret;

 	if (!opts->quiet && !old.path && old.commit && new->commit != old.commit)
@@ -941,6 +944,7 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
 		OPT_BOOLEAN('m', "merge", &opts.merge, "perform a 3-way merge with the new branch"),
 		OPT_STRING(0, "conflict", &conflict_style, "style",
 			   "conflict style (merge or diff3)"),
+		OPT_BOOLEAN('n', "dry-run", &opts.dry_run, "show if the checkout would fail because it touches locally modified files"),
 		OPT_BOOLEAN('p', "patch", &patch_mode, "select hunks interactively"),
 		{ OPTION_BOOLEAN, 0, "guess", &dwim_new_local_branch, NULL,
 		  "second guess 'git checkout no-such-branch'",
@@ -967,7 +971,7 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
 	if (opts.new_branch_force)
 		opts.new_branch = opts.new_branch_force;

-	if (patch_mode && (opts.track > 0 || opts.new_branch
+	if (patch_mode && (opts.track > 0 || opts.new_branch || opts.dry_run
 			   || opts.new_branch_log || opts.merge || opts.force
 			   || opts.force_detach))
 		die (_("--patch is incompatible with all other options"));
@@ -1008,6 +1012,9 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
 	if (opts.force && opts.merge)
 		die(_("git checkout: -f and -m are incompatible"));

+	if (opts.merge && opts.dry_run)
+		die("git checkout: -m and -n are incompatible");
+
 	/*
 	 * Extract branch name from command line arguments, so
 	 * all that is left is pathspecs.
@@ -1060,6 +1067,9 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
 		if (1 < !!opts.writeout_stage + !!opts.force + !!opts.merge)
 			die(_("git checkout: --ours/--theirs, --force and --merge are incompatible when\nchecking out of the index."));

+		if (opts.dry_run)
+			die("git checkout: updating paths is incompatible with -n.");
+
 		return checkout_paths(source_tree, pathspec, &opts);
 	}

diff --git a/t/t2018-checkout-branch.sh b/t/t2018-checkout-branch.sh
index fa69016..61c82ef 100755
--- a/t/t2018-checkout-branch.sh
+++ b/t/t2018-checkout-branch.sh
@@ -169,4 +169,27 @@ test_expect_success 'checkout -f -B to an existing branch with mergeable changes
 	test_must_fail test_dirty_mergeable
 '

+test_expect_success 'checkout -n/--dry-run does not change work tree or index' '
+	echo precious >expect &&
+	echo precious >file1 &&
+	test_must_fail git checkout -n branch1 &&
+	test_cmp expect file1 &&
+	git checkout --dry-run -f branch1 &&
+	test_cmp expect file1 &&
+	test_must_fail git checkout -b new_branch --dry-run branch1 &&
+	test_cmp expect file1 &&
+	git checkout -b new_branch -n -f branch1 &&
+	test_cmp expect file1 &&
+	git checkout -f branch1 &&
+	git status -s -uno > actual &&
+	! test -s actual &&
+	git checkout -n HEAD^ &&
+	git status -s -uno > actual &&
+	! test -s actual
+'
+
+test_expect_success 'checkout -n/--dry-run is not allowed when checking out only certain paths' '
+	test_must_fail git checkout -n branch1 file1 &&
+	test_must_fail git checkout -n HEAD file1
+'
 test_done
-- 
1.7.5.1.174.g799a9

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH] Teach checkout the -n|--dry-run option
  2011-05-06 22:12 [PATCH] Teach checkout the -n|--dry-run option Jens Lehmann
@ 2011-05-06 22:49 ` Junio C Hamano
  2011-05-07 19:24   ` Junio C Hamano
  0 siblings, 1 reply; 9+ messages in thread
From: Junio C Hamano @ 2011-05-06 22:49 UTC (permalink / raw)
  To: Jens Lehmann; +Cc: Git Mailing List

Jens Lehmann <Jens.Lehmann@web.de> writes:

> This option can be used to determine if checking out a branch or commit
> would touch files which are modified in the work tree. It doesn't change
> the work tree contents or the index, so it can only tell if the checkout
> would succeed using trivial merges.

I hated this patch when I saw it the first time.  I thought you were
joking and let it pass. But now you brought it again, I hate it even more
now.

I do not see a merit in contaminating the checkout Porcelain with a half
baked [*1*] "dry-run" code, when your ultimate motive to use it in
submodule script and exercise only a small portion of checkout codepaths.
You are only interested in branch switching, and not other things the
Porcelain can do, like checking out a path out of the index or a tree, or
re-checking out a conflicted path out of the index.

In other words, can't the check you need in submodule be scripted around
the specific plumbing responsible for the branch switching, which is:

    $ git read-tree -m HEAD $other_branch

> @@ -397,7 +400,7 @@ static int merge_working_tree(struct checkout_opts *opts,
>
>  		/* 2-way merge to the new branch */
>  		topts.initial_checkout = is_cache_unborn();
> -		topts.update = 1;
> +		topts.update = !opts->dry_run;
>  		topts.merge = 1;
>  		topts.gently = opts->merge && old->commit;
>  		topts.verbose_update = !opts->quiet;

What you are doing in this part of your patch is exactly that two-tree
form of the "read-tree -m", no?


[Footnote]

*1* Look at how many places you say "are incompatible" when you really
mean "I didn't bother to think deeply enough about implementing this
combination".

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] Teach checkout the -n|--dry-run option
  2011-05-06 22:49 ` Junio C Hamano
@ 2011-05-07 19:24   ` Junio C Hamano
  2011-05-08 11:22     ` Jens Lehmann
  0 siblings, 1 reply; 9+ messages in thread
From: Junio C Hamano @ 2011-05-07 19:24 UTC (permalink / raw)
  To: Jens Lehmann; +Cc: Git Mailing List

Junio C Hamano <gitster@pobox.com> writes:

> In other words, can't the check you need in submodule be scripted around
> the specific plumbing responsible for the branch switching, which is:
>
>     $ git read-tree -m HEAD $other_branch
>
>> @@ -397,7 +400,7 @@ static int merge_working_tree(struct checkout_opts *opts,
>>
>>  		/* 2-way merge to the new branch */
>>  		topts.initial_checkout = is_cache_unborn();
>> -		topts.update = 1;
>> +		topts.update = !opts->dry_run;
>>  		topts.merge = 1;
>>  		topts.gently = opts->merge && old->commit;
>>  		topts.verbose_update = !opts->quiet;
>
> What you are doing in this part of your patch is exactly that two-tree
> form of the "read-tree -m", no?

That is, this would succeed:

	$ git reset --hard master
        $ git read-tree --index-output=rubbish -m master next
        
and these would fail:

	$ git reset --hard master
	$ echo >>Makefile
        $ git read-tree --index-output=rubbish -m master next
        error: Entry 'Makefile' not uptodate. Cannot merge.

	$ git reset --hard master
	$ echo >>Makefile
	$ git add Makefile
        $ git read-tree --index-output=rubbish -m master next
        error: Entry 'Makefile' would be overwritten by merge. Cannot merge.

Having said that, please do not discard your patch.  After sleeping on
this, I started to think that "checkout -n" might be a better interface
than using the plumbing read-tree in the longer term, especially if you
can enhance it to handle "checkout -m -n" to check if the local change can
be merged without conflicts.

But if the only question you are interested in is "can I switch to that
branch from the current state of the index and the working tree?", I would
prefer to see if the script can use "read-tree -m" approach first.

We may also want to add "read-tree -n" so that you do not have to specify
a dummy index output only to prevent from writing the real index over,
though.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] Teach checkout the -n|--dry-run option
  2011-05-07 19:24   ` Junio C Hamano
@ 2011-05-08 11:22     ` Jens Lehmann
  2011-05-08 20:50       ` Jens Lehmann
  0 siblings, 1 reply; 9+ messages in thread
From: Jens Lehmann @ 2011-05-08 11:22 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Git Mailing List

Am 07.05.2011 21:24, schrieb Junio C Hamano:
> Junio C Hamano <gitster@pobox.com> writes:
> 
>> In other words, can't the check you need in submodule be scripted around
>> the specific plumbing responsible for the branch switching, which is:
>>
>>     $ git read-tree -m HEAD $other_branch
>>
>>> @@ -397,7 +400,7 @@ static int merge_working_tree(struct checkout_opts *opts,
>>>
>>>  		/* 2-way merge to the new branch */
>>>  		topts.initial_checkout = is_cache_unborn();
>>> -		topts.update = 1;
>>> +		topts.update = !opts->dry_run;
>>>  		topts.merge = 1;
>>>  		topts.gently = opts->merge && old->commit;
>>>  		topts.verbose_update = !opts->quiet;
>>
>> What you are doing in this part of your patch is exactly that two-tree
>> form of the "read-tree -m", no?
> 
> That is, this would succeed:
> 
> 	$ git reset --hard master
>         $ git read-tree --index-output=rubbish -m master next
>         
> and these would fail:
> 
> 	$ git reset --hard master
> 	$ echo >>Makefile
>         $ git read-tree --index-output=rubbish -m master next
>         error: Entry 'Makefile' not uptodate. Cannot merge.
> 
> 	$ git reset --hard master
> 	$ echo >>Makefile
> 	$ git add Makefile
>         $ git read-tree --index-output=rubbish -m master next
>         error: Entry 'Makefile' would be overwritten by merge. Cannot merge.

Thanks for pointing me to "git read-tree -m". When I saw that a "git
checkout -n" would do exactly what I needed, I stopped looking for
alternatives (especially as I saw that adding -n there would help
other non-submodule use cases as well).

> Having said that, please do not discard your patch.  After sleeping on
> this, I started to think that "checkout -n" might be a better interface
> than using the plumbing read-tree in the longer term, especially if you
> can enhance it to handle "checkout -m -n" to check if the local change can
> be merged without conflicts.

I'll see if I can come up with a solution for the "-m -n" case (I stopped
after implementing the checkout branch case I needed to get some feedback
if this thing went into the right direction). And I assume the "git
checkout <pathspec>" case should learn -n too?

> But if the only question you are interested in is "can I switch to that
> branch from the current state of the index and the working tree?", I would
> prefer to see if the script can use "read-tree -m" approach first.

Yup, I will try that.

> We may also want to add "read-tree -n" so that you do not have to specify
> a dummy index output only to prevent from writing the real index over,
> though.

Hmm, wouldn't using "read-tree --index-output=/dev/null" be equivalent to
"read-tree -n"? But nonetheless it might make sense to add the -n option.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] Teach checkout the -n|--dry-run option
  2011-05-08 11:22     ` Jens Lehmann
@ 2011-05-08 20:50       ` Jens Lehmann
  2011-05-08 21:30         ` Junio C Hamano
  0 siblings, 1 reply; 9+ messages in thread
From: Jens Lehmann @ 2011-05-08 20:50 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Git Mailing List

Am 08.05.2011 13:22, schrieb Jens Lehmann:
> Am 07.05.2011 21:24, schrieb Junio C Hamano:
>> We may also want to add "read-tree -n" so that you do not have to specify
>> a dummy index output only to prevent from writing the real index over,
>> though.
> 
> Hmm, wouldn't using "read-tree --index-output=/dev/null" be equivalent to
> "read-tree -n"? But nonetheless it might make sense to add the -n option.

No idea how I could manage to test "read-tree --index-output=/dev/null"
successfully without getting an "unable to write new index file" error.

But using read-tree works for me, so what about something like this,
maybe with some more tests?

-------------8<---------------
Subject: [PATCH] Teach read-tree the -n|--dry-run option

Using this option tells read-tree to not update the index. That makes it
possible to check if updating the index would be successful without
changing it.

As using --dry-run is expected to have no side effects, this option makes
no sense together with "-u".

Signed-off-by: Jens Lehmann <Jens.Lehmann@web.de>
---
 Documentation/git-read-tree.txt |    5 +++++
 builtin/read-tree.c             |    7 +++++--
 t/t1000-read-tree-m-3way.sh     |    2 ++
 3 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/Documentation/git-read-tree.txt b/Documentation/git-read-tree.txt
index 26fdadc..a35849f 100644
--- a/Documentation/git-read-tree.txt
+++ b/Documentation/git-read-tree.txt
@@ -53,6 +53,11 @@ OPTIONS
 	trees that are not directly related to the current
 	working tree status into a temporary index file.

+-n::
+--dry-run::
+	Don't write the index file. This option isn't allowed together
+	with -u.
+
 -v::
 	Show the progress of checking files out.

diff --git a/builtin/read-tree.c b/builtin/read-tree.c
index 93c9281..693576f 100644
--- a/builtin/read-tree.c
+++ b/builtin/read-tree.c
@@ -98,7 +98,7 @@ static struct lock_file lock_file;

 int cmd_read_tree(int argc, const char **argv, const char *unused_prefix)
 {
-	int i, newfd, stage = 0;
+	int i, newfd, stage = 0, dry_run = 0;
 	unsigned char sha1[20];
 	struct tree_desc t[MAX_UNPACK_TREES];
 	struct unpack_trees_options opts;
@@ -130,6 +130,7 @@ int cmd_read_tree(int argc, const char **argv, const char *unused_prefix)
 		  PARSE_OPT_NONEG, exclude_per_directory_cb },
 		OPT_SET_INT('i', NULL, &opts.index_only,
 			    "don't check the working tree after merging", 1),
+		OPT__DRY_RUN(&dry_run, "don't update the index"),
 		OPT_SET_INT(0, "no-sparse-checkout", &opts.skip_sparse_checkout,
 			    "skip applying sparse checkout filter", 1),
 		OPT_SET_INT(0, "debug-unpack", &opts.debug_unpack,
@@ -183,6 +184,8 @@ int cmd_read_tree(int argc, const char **argv, const char *unused_prefix)
 		die("--exclude-per-directory is meaningless unless -u");
 	if (opts.merge && !opts.index_only)
 		setup_work_tree();
+	if (opts.update && dry_run)
+		die("--dry-run contradicts -u");

 	if (opts.merge) {
 		if (stage < 2)
@@ -219,7 +222,7 @@ int cmd_read_tree(int argc, const char **argv, const char *unused_prefix)
 	if (unpack_trees(nr_trees, t, &opts))
 		return 128;

-	if (opts.debug_unpack)
+	if (opts.debug_unpack || dry_run)
 		return 0; /* do not write the index out */

 	/*
diff --git a/t/t1000-read-tree-m-3way.sh b/t/t1000-read-tree-m-3way.sh
index ca8a409..bcfb5e6 100755
--- a/t/t1000-read-tree-m-3way.sh
+++ b/t/t1000-read-tree-m-3way.sh
@@ -259,6 +259,8 @@ test_expect_success \
     "rm -f .git/index AA &&
      cp .orig-A/AA AA &&
      git update-index --add AA &&
+     git read-tree -n -m $tree_O $tree_A $tree_B &&
+     test_must_fail check_result &&
      git read-tree -m $tree_O $tree_A $tree_B &&
      check_result"

-- 
1.7.5.1.218.g8af57

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH] Teach checkout the -n|--dry-run option
  2011-05-08 20:50       ` Jens Lehmann
@ 2011-05-08 21:30         ` Junio C Hamano
  2011-05-08 21:41           ` Jens Lehmann
  2011-05-11 21:50           ` [PATCH] Teach read-tree " Jens Lehmann
  0 siblings, 2 replies; 9+ messages in thread
From: Junio C Hamano @ 2011-05-08 21:30 UTC (permalink / raw)
  To: Jens Lehmann; +Cc: Junio C Hamano, Git Mailing List

Jens Lehmann <Jens.Lehmann@web.de> writes:

> diff --git a/t/t1000-read-tree-m-3way.sh b/t/t1000-read-tree-m-3way.sh
> index ca8a409..bcfb5e6 100755
> --- a/t/t1000-read-tree-m-3way.sh
> +++ b/t/t1000-read-tree-m-3way.sh
> @@ -259,6 +259,8 @@ test_expect_success \
>      "rm -f .git/index AA &&
>       cp .orig-A/AA AA &&
>       git update-index --add AA &&
> +     git read-tree -n -m $tree_O $tree_A $tree_B &&
> +     test_must_fail check_result &&

That's a rather sloppy way to test that the command did not do anything to
compare one possible outcome, instead of verifying that the result is
identical to the original condition, no?

How about

	...
	git update_index --add AA &&
        git ls-files -s >pre-dry-run &&
        git read-tree -n -m $tree_O $tree_A $tree_B &&
        git ls-files -s >post-dry-run &&
        test_cmp pre-dry-run post-dry-run &&
        ...

We also should be checking that the command reports it is going to fail
when it should as well.  Always remember to check both sides of the coin.

>       git read-tree -m $tree_O $tree_A $tree_B &&
>       check_result"

I suspect that it would make sense to replace

	git read-tree $args && check_result

with
        
	read_tree_must_succeed $args

and

	test_must_fail git read-tree $args

with

	read_tree_must_fail $args

and implement two shell wrappers, perhaps like this.

read_tree_must_succeed () {
	git ls-files -s >pre-dry-run &&
	git read-tree -n "$@" &&
        git ls-files -s >post-dry-run &&
        test_cmp pre-dry-run post-dry-run &&
        git read-tree "$@"
}

read_tree_must_fail () {
	git ls-files -s >pre-dry-run &&
	test_must_fail git read-tree -n "$@" &&
        git ls-files -s >post-dry-run &&
	test_must_fail git read-tree "$@"
}

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] Teach checkout the -n|--dry-run option
  2011-05-08 21:30         ` Junio C Hamano
@ 2011-05-08 21:41           ` Jens Lehmann
  2011-05-11 21:50           ` [PATCH] Teach read-tree " Jens Lehmann
  1 sibling, 0 replies; 9+ messages in thread
From: Jens Lehmann @ 2011-05-08 21:41 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Git Mailing List

Am 08.05.2011 23:30, schrieb Junio C Hamano:
> Jens Lehmann <Jens.Lehmann@web.de> writes:
> 
>> diff --git a/t/t1000-read-tree-m-3way.sh b/t/t1000-read-tree-m-3way.sh
>> index ca8a409..bcfb5e6 100755
>> --- a/t/t1000-read-tree-m-3way.sh
>> +++ b/t/t1000-read-tree-m-3way.sh
>> @@ -259,6 +259,8 @@ test_expect_success \
>>      "rm -f .git/index AA &&
>>       cp .orig-A/AA AA &&
>>       git update-index --add AA &&
>> +     git read-tree -n -m $tree_O $tree_A $tree_B &&
>> +     test_must_fail check_result &&
> 
> That's a rather sloppy way to test that the command did not do anything to
> compare one possible outcome, instead of verifying that the result is
> identical to the original condition, no?
> 
> How about
> 
> 	...
> 	git update_index --add AA &&
>         git ls-files -s >pre-dry-run &&
>         git read-tree -n -m $tree_O $tree_A $tree_B &&
>         git ls-files -s >post-dry-run &&
>         test_cmp pre-dry-run post-dry-run &&
>         ...

Yeah, that is much better than my first sketch.

> We also should be checking that the command reports it is going to fail
> when it should as well.  Always remember to check both sides of the coin.
> 
>>       git read-tree -m $tree_O $tree_A $tree_B &&
>>       check_result"
> 
> I suspect that it would make sense to replace
> 
> 	git read-tree $args && check_result
> 
> with
>         
> 	read_tree_must_succeed $args
> 
> and
> 
> 	test_must_fail git read-tree $args
> 
> with
> 
> 	read_tree_must_fail $args
> 
> and implement two shell wrappers, perhaps like this.
> 
> read_tree_must_succeed () {
> 	git ls-files -s >pre-dry-run &&
> 	git read-tree -n "$@" &&
>         git ls-files -s >post-dry-run &&
>         test_cmp pre-dry-run post-dry-run &&
>         git read-tree "$@"
> }
> 
> read_tree_must_fail () {
> 	git ls-files -s >pre-dry-run &&
> 	test_must_fail git read-tree -n "$@" &&
>         git ls-files -s >post-dry-run &&
> 	test_must_fail git read-tree "$@"
> }

Thanks, will send an updated patch with better test cases soon ...

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH] Teach read-tree the -n|--dry-run option
  2011-05-08 21:30         ` Junio C Hamano
  2011-05-08 21:41           ` Jens Lehmann
@ 2011-05-11 21:50           ` Jens Lehmann
  2011-05-11 22:47             ` Junio C Hamano
  1 sibling, 1 reply; 9+ messages in thread
From: Jens Lehmann @ 2011-05-11 21:50 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Git Mailing List

Using this option tells read-tree to not update the index. That makes it
possible to check if updating the index would be successful without
changing it.

As using --dry-run is expected to have no side effects, this option makes
no sense together with "-u".

Signed-off-by: Jens Lehmann <Jens.Lehmann@web.de>
---

Now with updated tests.

 Documentation/git-read-tree.txt |    5 ++
 builtin/read-tree.c             |    7 ++-
 t/t1000-read-tree-m-3way.sh     |   96 +++++++++++++++++++++++----------------
 t/t1001-read-tree-m-2way.sh     |   48 +++++++++++--------
 t/t1002-read-tree-m-u-2way.sh   |    4 ++
 5 files changed, 98 insertions(+), 62 deletions(-)

diff --git a/Documentation/git-read-tree.txt b/Documentation/git-read-tree.txt
index 26fdadc..a35849f 100644
--- a/Documentation/git-read-tree.txt
+++ b/Documentation/git-read-tree.txt
@@ -53,6 +53,11 @@ OPTIONS
 	trees that are not directly related to the current
 	working tree status into a temporary index file.

+-n::
+--dry-run::
+	Don't write the index file. This option isn't allowed together
+	with -u.
+
 -v::
 	Show the progress of checking files out.

diff --git a/builtin/read-tree.c b/builtin/read-tree.c
index 93c9281..693576f 100644
--- a/builtin/read-tree.c
+++ b/builtin/read-tree.c
@@ -98,7 +98,7 @@ static struct lock_file lock_file;

 int cmd_read_tree(int argc, const char **argv, const char *unused_prefix)
 {
-	int i, newfd, stage = 0;
+	int i, newfd, stage = 0, dry_run = 0;
 	unsigned char sha1[20];
 	struct tree_desc t[MAX_UNPACK_TREES];
 	struct unpack_trees_options opts;
@@ -130,6 +130,7 @@ int cmd_read_tree(int argc, const char **argv, const char *unused_prefix)
 		  PARSE_OPT_NONEG, exclude_per_directory_cb },
 		OPT_SET_INT('i', NULL, &opts.index_only,
 			    "don't check the working tree after merging", 1),
+		OPT__DRY_RUN(&dry_run, "don't update the index"),
 		OPT_SET_INT(0, "no-sparse-checkout", &opts.skip_sparse_checkout,
 			    "skip applying sparse checkout filter", 1),
 		OPT_SET_INT(0, "debug-unpack", &opts.debug_unpack,
@@ -183,6 +184,8 @@ int cmd_read_tree(int argc, const char **argv, const char *unused_prefix)
 		die("--exclude-per-directory is meaningless unless -u");
 	if (opts.merge && !opts.index_only)
 		setup_work_tree();
+	if (opts.update && dry_run)
+		die("--dry-run contradicts -u");

 	if (opts.merge) {
 		if (stage < 2)
@@ -219,7 +222,7 @@ int cmd_read_tree(int argc, const char **argv, const char *unused_prefix)
 	if (unpack_trees(nr_trees, t, &opts))
 		return 128;

-	if (opts.debug_unpack)
+	if (opts.debug_unpack || dry_run)
 		return 0; /* do not write the index out */

 	/*
diff --git a/t/t1000-read-tree-m-3way.sh b/t/t1000-read-tree-m-3way.sh
index ca8a409..a386cfd 100755
--- a/t/t1000-read-tree-m-3way.sh
+++ b/t/t1000-read-tree-m-3way.sh
@@ -131,13 +131,29 @@ check_result () {
     test_cmp expected current
 }

+read_tree_must_succeed () {
+    git ls-files -s >pre-dry-run &&
+    git read-tree -n "$@" &&
+    git ls-files -s >post-dry-run &&
+    test_cmp pre-dry-run post-dry-run &&
+    git read-tree "$@"
+}
+
+read_tree_must_fail () {
+    git ls-files -s >pre-dry-run &&
+    test_must_fail git read-tree -n "$@" &&
+    git ls-files -s >post-dry-run &&
+    test_cmp pre-dry-run post-dry-run &&
+    test_must_fail git read-tree "$@"
+}
+
 # This is done on an empty work directory, which is the normal
 # merge person behaviour.
 test_expect_success \
     '3-way merge with git read-tree -m, empty cache' \
     "rm -fr [NDMALTS][NDMALTSF] Z &&
      rm .git/index &&
-     git read-tree -m $tree_O $tree_A $tree_B &&
+     read_tree_must_succeed -m $tree_O $tree_A $tree_B &&
      check_result"

 # This starts out with the first head, which is the normal
@@ -146,9 +162,9 @@ test_expect_success \
     '3-way merge with git read-tree -m, match H' \
     "rm -fr [NDMALTS][NDMALTSF] Z &&
      rm .git/index &&
-     git read-tree $tree_A &&
+     read_tree_must_succeed $tree_A &&
      git checkout-index -f -u -a &&
-     git read-tree -m $tree_O $tree_A $tree_B &&
+     read_tree_must_succeed -m $tree_O $tree_A $tree_B &&
      check_result"

 : <<\END_OF_CASE_TABLE
@@ -211,7 +227,7 @@ test_expect_success '1 - must not have an entry not in A.' "
      rm -f .git/index XX &&
      echo XX >XX &&
      git update-index --add XX &&
-     test_must_fail git read-tree -m $tree_O $tree_A $tree_B
+     read_tree_must_fail -m $tree_O $tree_A $tree_B
 "

 test_expect_success \
@@ -219,7 +235,7 @@ test_expect_success \
     "rm -f .git/index NA &&
      cp .orig-B/NA NA &&
      git update-index --add NA &&
-     git read-tree -m $tree_O $tree_A $tree_B"
+     read_tree_must_succeed -m $tree_O $tree_A $tree_B"

 test_expect_success \
     '2 - matching B alone is OK in !O && !A && B case.' \
@@ -227,14 +243,14 @@ test_expect_success \
      cp .orig-B/NA NA &&
      git update-index --add NA &&
      echo extra >>NA &&
-     git read-tree -m $tree_O $tree_A $tree_B"
+     read_tree_must_succeed -m $tree_O $tree_A $tree_B"

 test_expect_success \
     '3 - must match A in !O && A && !B case.' \
     "rm -f .git/index AN &&
      cp .orig-A/AN AN &&
      git update-index --add AN &&
-     git read-tree -m $tree_O $tree_A $tree_B &&
+     read_tree_must_succeed -m $tree_O $tree_A $tree_B &&
      check_result"

 test_expect_success \
@@ -243,7 +259,7 @@ test_expect_success \
      cp .orig-A/AN AN &&
      git update-index --add AN &&
      echo extra >>AN &&
-     git read-tree -m $tree_O $tree_A $tree_B"
+     read_tree_must_succeed -m $tree_O $tree_A $tree_B"

 test_expect_success \
     '3 (fail) - must match A in !O && A && !B case.' "
@@ -251,7 +267,7 @@ test_expect_success \
      cp .orig-A/AN AN &&
      echo extra >>AN &&
      git update-index --add AN &&
-     test_must_fail git read-tree -m $tree_O $tree_A $tree_B
+     read_tree_must_fail -m $tree_O $tree_A $tree_B
 "

 test_expect_success \
@@ -259,7 +275,7 @@ test_expect_success \
     "rm -f .git/index AA &&
      cp .orig-A/AA AA &&
      git update-index --add AA &&
-     git read-tree -m $tree_O $tree_A $tree_B &&
+     read_tree_must_succeed -m $tree_O $tree_A $tree_B &&
      check_result"

 test_expect_success \
@@ -268,7 +284,7 @@ test_expect_success \
      cp .orig-A/AA AA &&
      git update-index --add AA &&
      echo extra >>AA &&
-     test_must_fail git read-tree -m $tree_O $tree_A $tree_B
+     read_tree_must_fail -m $tree_O $tree_A $tree_B
 "

 test_expect_success \
@@ -277,7 +293,7 @@ test_expect_success \
      cp .orig-A/AA AA &&
      echo extra >>AA &&
      git update-index --add AA &&
-     test_must_fail git read-tree -m $tree_O $tree_A $tree_B
+     read_tree_must_fail -m $tree_O $tree_A $tree_B
 "

 test_expect_success \
@@ -285,7 +301,7 @@ test_expect_success \
     "rm -f .git/index LL &&
      cp .orig-A/LL LL &&
      git update-index --add LL &&
-     git read-tree -m $tree_O $tree_A $tree_B &&
+     read_tree_must_succeed -m $tree_O $tree_A $tree_B &&
      check_result"

 test_expect_success \
@@ -294,7 +310,7 @@ test_expect_success \
      cp .orig-A/LL LL &&
      git update-index --add LL &&
      echo extra >>LL &&
-     git read-tree -m $tree_O $tree_A $tree_B &&
+     read_tree_must_succeed -m $tree_O $tree_A $tree_B &&
      check_result"

 test_expect_success \
@@ -303,7 +319,7 @@ test_expect_success \
      cp .orig-A/LL LL &&
      echo extra >>LL &&
      git update-index --add LL &&
-     test_must_fail git read-tree -m $tree_O $tree_A $tree_B
+     read_tree_must_fail -m $tree_O $tree_A $tree_B
 "

 test_expect_success \
@@ -311,7 +327,7 @@ test_expect_success \
      rm -f .git/index DD &&
      echo DD >DD &&
      git update-index --add DD &&
-     test_must_fail git read-tree -m $tree_O $tree_A $tree_B
+     read_tree_must_fail -m $tree_O $tree_A $tree_B
 "

 test_expect_success \
@@ -319,7 +335,7 @@ test_expect_success \
      rm -f .git/index DM &&
      cp .orig-B/DM DM &&
      git update-index --add DM &&
-     test_must_fail git read-tree -m $tree_O $tree_A $tree_B
+     read_tree_must_fail -m $tree_O $tree_A $tree_B
 "

 test_expect_success \
@@ -327,7 +343,7 @@ test_expect_success \
      rm -f .git/index DN &&
      cp .orig-B/DN DN &&
      git update-index --add DN &&
-     test_must_fail git read-tree -m $tree_O $tree_A $tree_B
+     read_tree_must_fail -m $tree_O $tree_A $tree_B
 "

 test_expect_success \
@@ -335,7 +351,7 @@ test_expect_success \
     "rm -f .git/index MD &&
      cp .orig-A/MD MD &&
      git update-index --add MD &&
-     git read-tree -m $tree_O $tree_A $tree_B &&
+     read_tree_must_succeed -m $tree_O $tree_A $tree_B &&
      check_result"

 test_expect_success \
@@ -344,7 +360,7 @@ test_expect_success \
      cp .orig-A/MD MD &&
      git update-index --add MD &&
      echo extra >>MD &&
-     test_must_fail git read-tree -m $tree_O $tree_A $tree_B
+     read_tree_must_fail -m $tree_O $tree_A $tree_B
 "

 test_expect_success \
@@ -353,7 +369,7 @@ test_expect_success \
      cp .orig-A/MD MD &&
      echo extra >>MD &&
      git update-index --add MD &&
-     test_must_fail git read-tree -m $tree_O $tree_A $tree_B
+     read_tree_must_fail -m $tree_O $tree_A $tree_B
 "

 test_expect_success \
@@ -361,7 +377,7 @@ test_expect_success \
     "rm -f .git/index ND &&
      cp .orig-A/ND ND &&
      git update-index --add ND &&
-     git read-tree -m $tree_O $tree_A $tree_B &&
+     read_tree_must_succeed -m $tree_O $tree_A $tree_B &&
      check_result"

 test_expect_success \
@@ -370,7 +386,7 @@ test_expect_success \
      cp .orig-A/ND ND &&
      git update-index --add ND &&
      echo extra >>ND &&
-     test_must_fail git read-tree -m $tree_O $tree_A $tree_B
+     read_tree_must_fail -m $tree_O $tree_A $tree_B
 "

 test_expect_success \
@@ -379,7 +395,7 @@ test_expect_success \
      cp .orig-A/ND ND &&
      echo extra >>ND &&
      git update-index --add ND &&
-     test_must_fail git read-tree -m $tree_O $tree_A $tree_B
+     read_tree_must_fail -m $tree_O $tree_A $tree_B
 "

 test_expect_success \
@@ -387,7 +403,7 @@ test_expect_success \
     "rm -f .git/index MM &&
      cp .orig-A/MM MM &&
      git update-index --add MM &&
-     git read-tree -m $tree_O $tree_A $tree_B &&
+     read_tree_must_succeed -m $tree_O $tree_A $tree_B &&
      check_result"

 test_expect_success \
@@ -396,7 +412,7 @@ test_expect_success \
      cp .orig-A/MM MM &&
      git update-index --add MM &&
      echo extra >>MM &&
-     test_must_fail git read-tree -m $tree_O $tree_A $tree_B
+     read_tree_must_fail -m $tree_O $tree_A $tree_B
 "

 test_expect_success \
@@ -405,7 +421,7 @@ test_expect_success \
      cp .orig-A/MM MM &&
      echo extra >>MM &&
      git update-index --add MM &&
-     test_must_fail git read-tree -m $tree_O $tree_A $tree_B
+     read_tree_must_fail -m $tree_O $tree_A $tree_B
 "

 test_expect_success \
@@ -413,7 +429,7 @@ test_expect_success \
     "rm -f .git/index SS &&
      cp .orig-A/SS SS &&
      git update-index --add SS &&
-     git read-tree -m $tree_O $tree_A $tree_B &&
+     read_tree_must_succeed -m $tree_O $tree_A $tree_B &&
      check_result"

 test_expect_success \
@@ -422,7 +438,7 @@ test_expect_success \
      cp .orig-A/SS SS &&
      git update-index --add SS &&
      echo extra >>SS &&
-     git read-tree -m $tree_O $tree_A $tree_B &&
+     read_tree_must_succeed -m $tree_O $tree_A $tree_B &&
      check_result"

 test_expect_success \
@@ -431,7 +447,7 @@ test_expect_success \
      cp .orig-A/SS SS &&
      echo extra >>SS &&
      git update-index --add SS &&
-     test_must_fail git read-tree -m $tree_O $tree_A $tree_B
+     read_tree_must_fail -m $tree_O $tree_A $tree_B
 "

 test_expect_success \
@@ -439,7 +455,7 @@ test_expect_success \
     "rm -f .git/index MN &&
      cp .orig-A/MN MN &&
      git update-index --add MN &&
-     git read-tree -m $tree_O $tree_A $tree_B &&
+     read_tree_must_succeed -m $tree_O $tree_A $tree_B &&
      check_result"

 test_expect_success \
@@ -448,7 +464,7 @@ test_expect_success \
      cp .orig-A/MN MN &&
      git update-index --add MN &&
      echo extra >>MN &&
-     git read-tree -m $tree_O $tree_A $tree_B &&
+     read_tree_must_succeed -m $tree_O $tree_A $tree_B &&
      check_result"

 test_expect_success \
@@ -456,7 +472,7 @@ test_expect_success \
     "rm -f .git/index NM &&
      cp .orig-A/NM NM &&
      git update-index --add NM &&
-     git read-tree -m $tree_O $tree_A $tree_B &&
+     read_tree_must_succeed -m $tree_O $tree_A $tree_B &&
      check_result"

 test_expect_success \
@@ -465,7 +481,7 @@ test_expect_success \
      cp .orig-B/NM NM &&
      git update-index --add NM &&
      echo extra >>NM &&
-     git read-tree -m $tree_O $tree_A $tree_B &&
+     read_tree_must_succeed -m $tree_O $tree_A $tree_B &&
      check_result"

 test_expect_success \
@@ -474,7 +490,7 @@ test_expect_success \
      cp .orig-A/NM NM &&
      git update-index --add NM &&
      echo extra >>NM &&
-     test_must_fail git read-tree -m $tree_O $tree_A $tree_B
+     read_tree_must_fail -m $tree_O $tree_A $tree_B
 "

 test_expect_success \
@@ -483,7 +499,7 @@ test_expect_success \
      cp .orig-A/NM NM &&
      echo extra >>NM &&
      git update-index --add NM &&
-     test_must_fail git read-tree -m $tree_O $tree_A $tree_B
+     read_tree_must_fail -m $tree_O $tree_A $tree_B
 "

 test_expect_success \
@@ -491,7 +507,7 @@ test_expect_success \
     "rm -f .git/index NN &&
      cp .orig-A/NN NN &&
      git update-index --add NN &&
-     git read-tree -m $tree_O $tree_A $tree_B &&
+     read_tree_must_succeed -m $tree_O $tree_A $tree_B &&
      check_result"

 test_expect_success \
@@ -500,7 +516,7 @@ test_expect_success \
      cp .orig-A/NN NN &&
      git update-index --add NN &&
      echo extra >>NN &&
-     git read-tree -m $tree_O $tree_A $tree_B &&
+     read_tree_must_succeed -m $tree_O $tree_A $tree_B &&
      check_result"

 test_expect_success \
@@ -509,7 +525,7 @@ test_expect_success \
      cp .orig-A/NN NN &&
      echo extra >>NN &&
      git update-index --add NN &&
-     test_must_fail git read-tree -m $tree_O $tree_A $tree_B
+     read_tree_must_fail -m $tree_O $tree_A $tree_B
 "

 # #16
@@ -522,7 +538,7 @@ test_expect_success \
     echo E16 >F16 &&
     git update-index F16 &&
     tree1=`git write-tree` &&
-    git read-tree -m $tree0 $tree1 $tree1 $tree0 &&
+    read_tree_must_succeed -m $tree0 $tree1 $tree1 $tree0 &&
     git ls-files --stage'

 test_done
diff --git a/t/t1001-read-tree-m-2way.sh b/t/t1001-read-tree-m-2way.sh
index 680d992..ebe7c4d 100755
--- a/t/t1001-read-tree-m-2way.sh
+++ b/t/t1001-read-tree-m-2way.sh
@@ -48,6 +48,14 @@ check_cache_at () {
 	esac
 }

+read_tree_must_succeed () {
+    git ls-files -s >pre-dry-run &&
+    git read-tree -n "$@" &&
+    git ls-files -s >post-dry-run &&
+    test_cmp pre-dry-run post-dry-run &&
+    git read-tree "$@"
+}
+
 cat >bozbar-old <<\EOF
 This is a sample file used in two-way fast-forward merge
 tests.  Its second line ends with a magic word bozbar
@@ -94,7 +102,7 @@ echo '+100644 X 0	yomin' >expected
 test_expect_success \
     '4 - carry forward local addition.' \
     'rm -f .git/index &&
-     git read-tree $treeH &&
+     read_tree_must_succeed $treeH &&
      git checkout-index -u -f -q -a &&
      git update-index --add yomin &&
      read_tree_twoway $treeH $treeM &&
@@ -106,7 +114,7 @@ test_expect_success \
 test_expect_success \
     '5 - carry forward local addition.' \
     'rm -f .git/index &&
-     git read-tree $treeH &&
+     read_tree_must_succeed $treeH &&
      git checkout-index -u -f -q -a &&
      echo yomin >yomin &&
      git update-index --add yomin &&
@@ -120,7 +128,7 @@ test_expect_success \
 test_expect_success \
     '6 - local addition already has the same.' \
     'rm -f .git/index &&
-     git read-tree $treeH &&
+     read_tree_must_succeed $treeH &&
      git checkout-index -u -f -q -a &&
      git update-index --add frotz &&
      read_tree_twoway $treeH $treeM &&
@@ -131,7 +139,7 @@ test_expect_success \
 test_expect_success \
     '7 - local addition already has the same.' \
     'rm -f .git/index &&
-     git read-tree $treeH &&
+     read_tree_must_succeed $treeH &&
      git checkout-index -u -f -q -a &&
      echo frotz >frotz &&
      git update-index --add frotz &&
@@ -144,7 +152,7 @@ test_expect_success \
 test_expect_success \
     '8 - conflicting addition.' \
     'rm -f .git/index &&
-     git read-tree $treeH &&
+     read_tree_must_succeed $treeH &&
      git checkout-index -u -f -q -a &&
      echo frotz frotz >frotz &&
      git update-index --add frotz &&
@@ -153,7 +161,7 @@ test_expect_success \
 test_expect_success \
     '9 - conflicting addition.' \
     'rm -f .git/index &&
-     git read-tree $treeH &&
+     read_tree_must_succeed $treeH &&
      git checkout-index -u -f -q -a &&
      echo frotz frotz >frotz &&
      git update-index --add frotz &&
@@ -163,7 +171,7 @@ test_expect_success \
 test_expect_success \
     '10 - path removed.' \
     'rm -f .git/index &&
-     git read-tree $treeH &&
+     read_tree_must_succeed $treeH &&
      git checkout-index -u -f -q -a &&
      echo rezrov >rezrov &&
      git update-index --add rezrov &&
@@ -174,7 +182,7 @@ test_expect_success \
 test_expect_success \
     '11 - dirty path removed.' \
     'rm -f .git/index &&
-     git read-tree $treeH &&
+     read_tree_must_succeed $treeH &&
      git checkout-index -u -f -q -a &&
      echo rezrov >rezrov &&
      git update-index --add rezrov &&
@@ -184,7 +192,7 @@ test_expect_success \
 test_expect_success \
     '12 - unmatching local changes being removed.' \
     'rm -f .git/index &&
-     git read-tree $treeH &&
+     read_tree_must_succeed $treeH &&
      git checkout-index -u -f -q -a &&
      echo rezrov rezrov >rezrov &&
      git update-index --add rezrov &&
@@ -193,7 +201,7 @@ test_expect_success \
 test_expect_success \
     '13 - unmatching local changes being removed.' \
     'rm -f .git/index &&
-     git read-tree $treeH &&
+     read_tree_must_succeed $treeH &&
      git checkout-index -u -f -q -a &&
      echo rezrov rezrov >rezrov &&
      git update-index --add rezrov &&
@@ -208,7 +216,7 @@ EOF
 test_expect_success \
     '14 - unchanged in two heads.' \
     'rm -f .git/index &&
-     git read-tree $treeH &&
+     read_tree_must_succeed $treeH &&
      git checkout-index -u -f -q -a &&
      echo nitfol nitfol >nitfol &&
      git update-index --add nitfol &&
@@ -221,7 +229,7 @@ test_expect_success \
 test_expect_success \
     '15 - unchanged in two heads.' \
     'rm -f .git/index &&
-     git read-tree $treeH &&
+     read_tree_must_succeed $treeH &&
      git checkout-index -u -f -q -a &&
      echo nitfol nitfol >nitfol &&
      git update-index --add nitfol &&
@@ -235,7 +243,7 @@ test_expect_success \
 test_expect_success \
     '16 - conflicting local change.' \
     'rm -f .git/index &&
-     git read-tree $treeH &&
+     read_tree_must_succeed $treeH &&
      git checkout-index -u -f -q -a &&
      echo bozbar bozbar >bozbar &&
      git update-index --add bozbar &&
@@ -244,7 +252,7 @@ test_expect_success \
 test_expect_success \
     '17 - conflicting local change.' \
     'rm -f .git/index &&
-     git read-tree $treeH &&
+     read_tree_must_succeed $treeH &&
      git checkout-index -u -f -q -a &&
      echo bozbar bozbar >bozbar &&
      git update-index --add bozbar &&
@@ -254,7 +262,7 @@ test_expect_success \
 test_expect_success \
     '18 - local change already having a good result.' \
     'rm -f .git/index &&
-     git read-tree $treeH &&
+     read_tree_must_succeed $treeH &&
      git checkout-index -u -f -q -a &&
      cat bozbar-new >bozbar &&
      git update-index --add bozbar &&
@@ -266,7 +274,7 @@ test_expect_success \
 test_expect_success \
     '19 - local change already having a good result, further modified.' \
     'rm -f .git/index &&
-     git read-tree $treeH &&
+     read_tree_must_succeed $treeH &&
      git checkout-index -u -f -q -a &&
      cat bozbar-new >bozbar &&
      git update-index --add bozbar &&
@@ -279,7 +287,7 @@ test_expect_success \
 test_expect_success \
     '20 - no local change, use new tree.' \
     'rm -f .git/index &&
-     git read-tree $treeH &&
+     read_tree_must_succeed $treeH &&
      git checkout-index -u -f -q -a &&
      cat bozbar-old >bozbar &&
      git update-index --add bozbar &&
@@ -291,7 +299,7 @@ test_expect_success \
 test_expect_success \
     '21 - no local change, dirty cache.' \
     'rm -f .git/index &&
-     git read-tree $treeH &&
+     read_tree_must_succeed $treeH &&
      git checkout-index -u -f -q -a &&
      cat bozbar-old >bozbar &&
      git update-index --add bozbar &&
@@ -302,7 +310,7 @@ test_expect_success \
 test_expect_success \
     '22 - local change cache updated.' \
     'rm -f .git/index &&
-     git read-tree $treeH &&
+     read_tree_must_succeed $treeH &&
      git checkout-index -u -f -q -a &&
      sed -e "s/such as/SUCH AS/" bozbar-old >bozbar &&
      git update-index --add bozbar &&
@@ -401,7 +409,7 @@ test_expect_success '-m references the correct modified tree' '
 	echo a >file-a &&
 	git add file-a &&
 	git ls-tree $(git write-tree) file-a >expect &&
-	git read-tree -m HEAD initial-mod &&
+	read_tree_must_succeed -m HEAD initial-mod &&
 	git ls-tree $(git write-tree) file-a >actual &&
 	test_cmp expect actual
 '
diff --git a/t/t1002-read-tree-m-u-2way.sh b/t/t1002-read-tree-m-u-2way.sh
index a4a17e0..ad9a4e8 100755
--- a/t/t1002-read-tree-m-u-2way.sh
+++ b/t/t1002-read-tree-m-u-2way.sh
@@ -341,4 +341,8 @@ test_expect_success \
      test_cmp DFDF.out DFDFcheck.out &&
      check_cache_at DF/DF clean'

+test_expect_success \
+    '-u is not allowed with -n' \
+    'test_must_fail git read-tree -n -u -m $treeDF $treeDFDF'
+
 test_done
-- 
1.7.5.1.218.g2da34

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH] Teach read-tree the -n|--dry-run option
  2011-05-11 21:50           ` [PATCH] Teach read-tree " Jens Lehmann
@ 2011-05-11 22:47             ` Junio C Hamano
  0 siblings, 0 replies; 9+ messages in thread
From: Junio C Hamano @ 2011-05-11 22:47 UTC (permalink / raw)
  To: Jens Lehmann; +Cc: Git Mailing List

Jens Lehmann <Jens.Lehmann@web.de> writes:

> Using this option tells read-tree to not update the index. That makes it
> possible to check if updating the index would be successful without
> changing it.

Thanks for verifying the 3-way case as well.

> As using --dry-run is expected to have no side effects, this option makes
> no sense together with "-u".

I wondered if there be cases where "read-tree -m <1 to 3 trees>" will
succeed but the same command with "-u" can fail. If there were such cases,
we would need more than this patch does.

An obvious case is when you cannot write to your working tree, perhaps due
to ENOSPC or incorrect permission settings in the working tree, but I am
not worried about that. I am only worried about situations related to
version control (i.e. you may lose local changes).

I _think_ the only difference "-u" makes is that check_updates() makes
calls to checkout_entry(), and the only errors checkout_entry() would
catch are filesystem related ones. Even though there is one conditional
that says "if the cached stat does not match, you cannot checkout unless
you set .force to the checkout state", but unpack_trees() does set that
flag, so we should be safe.

Thanks.

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2011-05-11 22:48 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-05-06 22:12 [PATCH] Teach checkout the -n|--dry-run option Jens Lehmann
2011-05-06 22:49 ` Junio C Hamano
2011-05-07 19:24   ` Junio C Hamano
2011-05-08 11:22     ` Jens Lehmann
2011-05-08 20:50       ` Jens Lehmann
2011-05-08 21:30         ` Junio C Hamano
2011-05-08 21:41           ` Jens Lehmann
2011-05-11 21:50           ` [PATCH] Teach read-tree " Jens Lehmann
2011-05-11 22:47             ` Junio C Hamano

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.