git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: Junio C Hamano <gitster@pobox.com>
To: Elijah Newren <newren@gmail.com>
Cc: git@vger.kernel.org
Subject: Re: [RFC/PATCH 05/18] Add testcase for --index-only merges needing the recursive strategy
Date: Fri, 08 Apr 2016 13:14:18 -0700	[thread overview]
Message-ID: <xmqqtwjbvox1.fsf@gitster.mtv.corp.google.com> (raw)
In-Reply-To: <xmqqzit3vqma.fsf@gitster.mtv.corp.google.com> (Junio C. Hamano's message of "Fri, 08 Apr 2016 12:37:33 -0700")

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

> Elijah Newren <newren@gmail.com> writes:
>
>> +test_expect_failure '--index-only with rename/modify works in non-bare-clone' '
>> +	git checkout B^0 &&
>> +
>> +	git merge --index-only -s recursive C^0 &&
>> +
>> +	echo "Making sure the working copy was not updated" &&
>> +	test ! -f b &&
>> +	test -f a &&
>> +	test $(git rev-parse B:a) = $(git hash-object a) &&
>> +
>> +	echo "Making sure the index was updated" &&
>> +	test 1 -eq $(git ls-files -s | wc -l) &&
>> +	test $(git rev-parse B:a) = $(git rev-parse :b)
>
> The most crucial test that is missing (hence prevents reviewers from
> judging if --index-only is a good idea at all) is the test on HEAD.
> Does it record a merge between B and C and move HEAD there, i.e.
>
> 	test $(git rev-parse HEAD^1) = $(git rev-parse B) &&
> 	test $(git rev-parse HEAD^2) = $(git rev-parse C)
>
> or does it make a merge but does not advance HEAD, i.e.
>
> 	test $(git rev-parse HEAD) = $(git rev-parse B)
>
> I fear that it may give a great headache to end users if you move
> HEAD in a repository with a working tree to point at the merge
> result--how do they reconcile the difference between the working
> tree (which was based on B) and the index and HEAD (which is now
> based on the result of the merge)?  The next "git commit -a" would
> appear that it would revert the changes brought in by this merge,
> wouldn't it?

And if the expectation that is not spelled out by this new test is
that the merge does not advance HEAD, the command does not make much
sense either, because there is no way for you to find out the merge
result.

Let's step back a bit.  This may or may not be what you are aiming
at, but I think I can buy a series whose title is "merge without
working tree" if the big-picture objective of the topic were to
support this workflow:

    0. I am working on my own branch that is not 'master'.

    1. I see somebody else worked on and finished a good topic
       'en/topic'.  My work is not yet in a good shape, and I do not
       want to switch to 'master' only to merge 'en/topic' to
       'master', but 'en/topic' is so good and my urge to merge it
       to 'master' is strong.

    2. Hence I want a way to merge 'en/topic' to 'master' and
       advance the tip of 'master', without using my working tree
       (or the index or my HEAD for that matter), without disrupting
       my current state.

    3. For simplicity, I can live with it if the early version of
       that "merge en/topic to master" operation is incapable of
       handling conflicts.  Then I'd say "huh, I'd need to manually
       inspect the merge result so I'll do that later" and continue
       what I was doing, or I'd say "OK, let's really have a look",
       save what I was doing in a temporary commit and switch to
       'master' to do the usual "git merge en/topic".

    4. But it would be even better if I could give a temporary
       directory to it as a scratch-pad area, and if I was asked to
       help it resolving conflicts by editing conflicted files in
       the scratch-pad area.

In any case, what is in my current index (or HEAD) is no use for
merging en/topic into master, so the command should not care or
touch not just what is in my working tree (which gives the operation
the same requirement as your series, i.e. "do not touch or require a
working tree") but also what is in my index or where my HEAD is.

The low-level ingredients that support "git merge", namely, "git
read-tree -m COMMON OURS THEIRS", actually has a support to make
this kind of "merge without fully populated working tree" possible,
by considering the lack of working tree file an equivalent to having
an unmodified working tree file (I suspect that merge-recursive is
probably broken with this regard, as it was mostly done without
knowing that we anticipated such a need in early life of Git long
before merge-recursive was invented).  We can give an empty
"scratch-pad area" as a temporary working tree, create a temporary
index out of 'master' (in the above example), perform the usual
three-way merge with
    
    GIT_DIR=... point at the real thing ...
    GIT_INDEX_FILE=... point at a temporary file ...
    export GIT_DIR GIT_INDEX_FILE
    rm -fr /var/tmp/scratchpad && mkdir /var/tmp/scratchpad
    cd /var/tmp/scratchpad
    base=$(git merge-base master en/topic)
    git read-tree -m $base master en/topic

and run "git merge -s resolve" to drive "git merge-one-file".  This
would populate /var/tmp/scratchpad with files that are involved in
the merge, without wasting diskspace for files in 'master' that does
not change, and you can edit them, "git add" these paths, and then
do a "git write-tree" to create the tree that represents the merge
result.  You obviously need to avoid touching HEAD when recording
that tree as a merge commit and advance the tip of 'master' (as HEAD
is still on my own unrelated branch), but that part is trivial
(i.e. we have written "git commit" at least twice).

Of course, if you are not going to support merges that need manual
conflict resolution, you do not need the scratchpad and the end user
experience would be simpler (i.e. you do not have to think about how
they resolve, record the resolution, etc.)  And your "merge only in
index" topic would fit well in that picture.

But then, using the current index and the HEAD as the place to merge
into is still wrong.  I think this is better done as a separate
command, not "git merge" but perhaps something like

    $ git merge-to en/topic master

or something.  "git merge --into=master en/topic" is also a
possibility.

But as I said in the early part of this message, this may or may not
be what you are aiming at.  The above is the most sensible tangent
that I can think of that may be related to "merge only in index".

  reply	other threads:[~2016-04-08 20:14 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-04-08  6:58 [RFC/PATCH 00/18] Add --index-only option to git merge Elijah Newren
2016-04-08  6:58 ` [RFC/PATCH 01/18] Remove duplicate code Elijah Newren
2016-04-08 23:34   ` Junio C Hamano
2016-04-08  6:58 ` [RFC/PATCH 02/18] Avoid checking working copy when creating a virtual merge base Elijah Newren
2016-04-08  6:58 ` [RFC/PATCH 03/18] Document weird bug in octopus merges via testcases Elijah Newren
2016-04-08  6:58 ` [RFC/PATCH 04/18] merge-octopus: Abort if index not clean Elijah Newren
2016-04-08 19:31   ` Junio C Hamano
2016-04-08  6:58 ` [RFC/PATCH 05/18] Add testcase for --index-only merges needing the recursive strategy Elijah Newren
2016-04-08 19:37   ` Junio C Hamano
2016-04-08 20:14     ` Junio C Hamano [this message]
2016-04-08  6:58 ` [RFC/PATCH 06/18] Add testcase for --index-only merges needing an ff update Elijah Newren
2016-04-08  6:58 ` [RFC/PATCH 07/18] Add testcase for --index-only merges with the resolve strategy Elijah Newren
2016-04-08  6:58 ` [RFC/PATCH 08/18] Add testcase for --index-only merges with the octopus strategy Elijah Newren
2016-04-08  6:58 ` [RFC/PATCH 09/18] Add testcase for --index-only merges with the ours strategy Elijah Newren
2016-04-08  6:58 ` [RFC/PATCH 10/18] Add testcase for --index-only merges with the subtree strategy Elijah Newren
2016-04-08  6:58 ` [RFC/PATCH 11/18] merge: Add a new --index-only option, not yet implemented Elijah Newren
2016-04-08 22:33   ` Junio C Hamano
2016-04-08  6:58 ` [RFC/PATCH 12/18] Add --index-only support for recursive merges Elijah Newren
2016-04-08  6:58 ` [RFC/PATCH 13/18] Add --index-only support with read_tree_trivial merges, kind of Elijah Newren
2016-04-08  6:58 ` [RFC/PATCH 14/18] Add --index-only support for ff_only merges Elijah Newren
2016-04-08  6:58 ` [RFC/PATCH 15/18] merge: Pass --index-only along to external merge strategy programs Elijah Newren
2016-04-08  6:58 ` [RFC/PATCH 16/18] git-merge-one-file.sh: support --index-only option Elijah Newren
2016-04-08  6:58 ` [RFC/PATCH 17/18] git-merge-resolve.sh: " Elijah Newren
2016-04-08  6:58 ` [RFC/PATCH 18/18] git-merge-octopus.sh: " Elijah Newren
2016-04-08 13:01 ` [RFC/PATCH 00/18] Add --index-only option to git merge Michael J Gruber
2016-04-09  3:09   ` Elijah Newren
2016-04-08 18:08 ` Junio C Hamano
2016-04-09  2:35   ` Elijah Newren
2016-04-09  4:44     ` Junio C Hamano
2016-04-10  5:33 ` Elijah Newren

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: http://vger.kernel.org/majordomo-info.html

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=xmqqtwjbvox1.fsf@gitster.mtv.corp.google.com \
    --to=gitster@pobox.com \
    --cc=git@vger.kernel.org \
    --cc=newren@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).