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".
next prev parent 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).