# [PATCH] revert/cherry-pick: allow starting from dirty work tree.

4 messages from 2007-11-13 to 2007-11-14. Participants: Junio C Hamano, Johannes Schindelin, Jakub Narebski.
Thread: https://gitlist.dev/t/10854

## Junio C Hamano, 2007-11-13 21:16

Subject: [PATCH] revert/cherry-pick: allow starting from dirty work tree.
Message-ID: <7vd4udsv6b.fsf@gitster.siamese.dyndns.org>
URL: https://gitlist.dev/e/7vd4udsv6b.fsf%40gitster.siamese.dyndns.org

```
There is no reason to forbid a dirty work tree when reverting or
cherry-picking a change, as long as the index is clean.

The scripted version used to allow it:

    case "$no_commit" in
    t)
    	# We do not intend to commit immediately.  We just want to
    	# merge the differences in.
    	head=$(git-write-tree) ||
    		die "Your index file is unmerged."
    	;;
    *)
    	head=$(git-rev-parse --verify HEAD) ||
    		die "You do not have a valid HEAD"
    	files=$(git-diff-index --cached --name-only $head) || exit
    	if [ "$files" ]; then
    		die "Dirty index: cannot $me (dirty: $files)"
    	fi
    	;;
    esac

but C rewrite tightened the check, probably by mistake.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 builtin-revert.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/builtin-revert.c b/builtin-revert.c
index cef7147..f704197 100644
--- a/builtin-revert.c
+++ b/builtin-revert.c
@@ -272,7 +272,7 @@ static int revert_or_cherry_pick(int argc, const char **argv)
 		if (get_sha1("HEAD", head))
 			die ("You do not have a valid HEAD");
 		wt_status_prepare(&s);
-		if (s.commitable || s.workdir_dirty)
+		if (s.commitable)
 			die ("Dirty index: cannot %s", me);
 		discard_cache();
 	}
-- 
1.5.3.5.1728.g34b3e

```

## Johannes Schindelin, 2007-11-13 23:37

Subject: Re: [PATCH] revert/cherry-pick: allow starting from dirty work tree.
Message-ID: <Pine.LNX.4.64.0711132154370.4362@racer.site>
URL: https://gitlist.dev/e/Pine.LNX.4.64.0711132154370.4362%40racer.site
In-Reply-To: <7vd4udsv6b.fsf@gitster.siamese.dyndns.org>

```
Hi,

On Tue, 13 Nov 2007, Junio C Hamano wrote:

> There is no reason to forbid a dirty work tree when reverting or
> cherry-picking a change, as long as the index is clean.
> 
> The scripted version used to allow it:
> 
>     case "$no_commit" in
>     t)
>     	# We do not intend to commit immediately.  We just want to
>     	# merge the differences in.
>     	head=$(git-write-tree) ||
>     		die "Your index file is unmerged."
>     	;;
>     *)
>     	head=$(git-rev-parse --verify HEAD) ||
>     		die "You do not have a valid HEAD"
>     	files=$(git-diff-index --cached --name-only $head) || exit
>     	if [ "$files" ]; then
>     		die "Dirty index: cannot $me (dirty: $files)"
>     	fi
>     	;;
>     esac
> 
> but C rewrite tightened the check, probably by mistake.

Probably.  Thanks.

While we're at cherry-pick: Two days ago I had to rebase in a dirty 
working directory.  Why?  Because one of the submodules was not yet ready 
to be committed to the superproject.

And you cannot easily stash away a submodule.

Now, my quick and dirty solution was to hack a GIT_IGNORE_SUBMODULES 
patch: 
http://repo.or.cz/w/git/mingw/4msysgit.git?a=commitdiff;h=9ef6b6bff4e368934c4262af13b0a309be19ebd4

But the more fundamental question is: should we eventually have a mode in 
cherry-pick (or for that matter, apply!) which can change the submodule?  
And if so, how to go about it?

I could imagine that in this case, both apply and cherry-pick should call 
submodule with a to-be-created subcommand to reset the named submodule to 
a given commit, given the current commit (to avoid races, just as with 
update-ref <ref> <newsha1> <oldsha1>).  Of course, this subcommand would 
fail if the submodule's working directory is dirty.

Thoughts?

Ciao,
Dscho

```

## Jakub Narebski, 2007-11-14 00:21

Subject: Re: [PATCH] revert/cherry-pick: allow starting from dirty work tree.
Message-ID: <fhdf2o$v60$1@ger.gmane.org>
URL: https://gitlist.dev/e/fhdf2o%24v60%241%40ger.gmane.org
In-Reply-To: <Pine.LNX.4.64.0711132154370.4362@racer.site>

```
Johannes Schindelin wrote:

> While we're at cherry-pick: Two days ago I had to rebase in a dirty 
> working directory.  Why?  Because one of the submodules was not yet ready 
> to be committed to the superproject.
> 
> And you cannot easily stash away a submodule.

git stash --recursive (to be written)? ;-)

-- 
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git

```

## Junio C Hamano, 2007-11-14 01:05

Subject: Re: [PATCH] revert/cherry-pick: allow starting from dirty work tree.
Message-ID: <7vy7d1prfw.fsf@gitster.siamese.dyndns.org>
URL: https://gitlist.dev/e/7vy7d1prfw.fsf%40gitster.siamese.dyndns.org
In-Reply-To: <Pine.LNX.4.64.0711132154370.4362@racer.site>

```
Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:

> But the more fundamental question is: should we eventually have a mode in 
> cherry-pick (or for that matter, apply!) which can change the submodule?  
> And if so, how to go about it?

I think that would be handled in exactly the same way as
switching between two branches that bind different commits at
the submodule path.

Your work tree and index knows commit X is at the path, an
operation wants to have commit Y at the path as its result.

What's next?

It does not make much difference what that "an operation" is.
It can be apply, cherry-pick, revert, merge, or branch
switching.  I think they can and should follow the same rules.

The most important rule is not to lose local changes, be they in
the index or in the work tree.  So "an operation" would error
out if the index does not match HEAD at such a path, and the
work tree does not match the index.

The implementation of "work tree does not match the index" is
different when you are talking about a regular blob vs a
submodule.  For a blob you know what we do.  For a submodule, I
would imagine that we would check if both the index matches the
HEAD and the work tree matches the index in the submodule
(this would go recursively).

And after making sure we won't lose local changes, we switch the
submodule directory from commit X to commit Y.  Most likely
detaching the HEAD with "cd sub && git checkout Y^0" or
something like that.

Then probably there will be an option added to loosen that "work
tree matches the index" check and uses "-m" option to the
checkout in the submodule directory.

More tricky is what to do with a submodule that would disappear,
though.  For that, we would want .git/subprojects/foo.git/ trick
we have discussed in the past or something similar.

```
