From: Igor Djordjevic <igor.d.djordjevic@gmail.com>
To: Johannes Sixt <j6t@kdbg.org>
Cc: git@vger.kernel.org, Nikolay Shustov <nikolay.shustov@gmail.com>,
Johannes Schneider <mailings@cedarsoft.com>,
Patrik Gornicz <patrik-git@mail.pgornicz.com>,
Martin Waitz <tali@admingilde.org>,
Shawn Pearce <spearce@spearce.org>, Sam Vilain <sam@vilain.net>,
Jakub Narebski <jnareb@gmail.com>
Subject: Re: [SCRIPT/RFC 0/3] git-commit --onto-parent (three-way merge, no working tree file changes)
Date: Mon, 4 Dec 2017 03:33:35 +0100 [thread overview]
Message-ID: <7ae3ffd5-147d-55d2-9630-da12c429d631@gmail.com> (raw)
In-Reply-To: <33e97533-716b-e1cc-6aa0-bf8941225319@kdbg.org>
Hi Hannes,
On 01/12/2017 18:23, Johannes Sixt wrote:
>
> > To work with `--onto-parent` and be able to commit on top of any of
> > the topic branches, you would need a situation like this instead:
> >
> > (1) ...C <- topic C
> > |
> > ...A | <- topic A
> > \|
> > ...o I <- integration
> > /|
> > ...B | <- topic B
> > |
> > ...D <- topic D
>
> This is a very, VERY exotic workflow, I would say. How would you
> construct commit I when three or more topics have conflicts?
> merge-octopus does not support this use-case.
But I`m not interested in constructing commit I in the first place,
only help working with it once it`s already there (which shouldn`t be
too uncommon in case of unrelated, non-conflicting topics) - but I
already agreed my example could have been a bit too esoteric,
distracting attention from the important part :)
I`ll continue on this further below, where you commented on those
more common scenarios.
Here, let`s try to look at the whole situation from a "patch queue"
perspective instead, starting from something like this:
(5) ---O---I <- integration <- HEAD
... and then making progress like this - first, commit A1 onto O,
starting "topicA" branch at the same time, even, maybe using syntax
like `git commit --onto-parent O -b topicA`:
(6) ---O---J <- integration <- HEAD [ J = I + A1 ]
\ /
A1 <- topicA
..., then commit B1 onto O to start "topicB" branch:
(7) B1 <- topicB
/ \
---O---K <- integration <- HEAD [ K = J + B1 ]
\ /
A1 <- topicA
..., then add one more commit (patch) onto B1:
(8) B1---B2 <- topicB
/ \
---O--------L <- integration <- HEAD [ L = K + B2 ]
\ /
A1---/ <- topicA
..., and one more, B3:
(9) B1---B2---B3 <- topicB
/ \
---O-------------M <- integration <- HEAD [ M = L + B3 ]
\ /
A1--------/ <- topicA
We can also start a new topic branch (queue), commit C1:
(10) B1---B2---B3 <- topicB
/ \
---O-------------N <- integration <- HEAD [ N = M + C1 ]
|\ /|
| A1--------/ / <- topicA
\ /
C1---------/ <- topicC
And lets make one more "topicA" related commit A2:
(11) B1---B2---B3 <- topicB
/ \
---O-------------P <- integration <- HEAD [ P = N + A2 ]
|\ /|
| A1---A2---/ / <- topicA
\ /
C1---------/ <- topicC
Notice how HEAD never leaves "integration" branch, and underlying
commit is recreated each time? It`s like a live branch we`re working
on, but we`re not actually committing to.
No branch switching (and no working tree file changes caused by it),
and we`re working on multiple topics/branches simultaneously, being
able to instantly test their mutual interaction as we go, but also
creating their separate (and "clean") histories at the same time.
I guess this would make most sense with simple topics we _could_
practically work on at the same time without making our life too
complicated - what stands for "git add --patch", too, when working on
multiple commits at the same time.
Once satisfied, of course each topic branch would need to be tested
separately, and each commit, even - all the same as with "git add
--patch" commits.
And "git add --patch" can still be used here, too, to distribute
partial changes, currently existing together inside the working tree,
to different topic branches, at the time of making the commit itself.
Does this approach make more sense in regards to "git commit
--onto-parent" functionality I`m having in mind? Or I`m dreaming too
much here...? :)
> > Once there, starting from your initial position:
> >
> > > ...A ...C <- topics A, C
> > > \ \ E
> > > ---o---o---o---o I <- integration <- HEAD
> > > / /
> > > ...B ...D <- topics B, D
> >
> > ... and doing something like `git commit --onto B --merge` would
> > yield:
> >
> > (3) ...A ...C <- topics A, C
> > \ \ E
> > ---o---o---o---o I' <- integration
> > / /|
> > ...B ...D | <- topic D
> > \ |
> > f-------' <- topic B
> >
> > ... where (I' = I + f) is still true.
>
> I am not used to this picture. I would not think that it is totally
> unacceptable, but it still has a hmm-factor.
Main idea is not to pile up uninteresting merge commits inside
(throwaway) integration branch, needlessly complicating history, but
pretend as we just made the integration merge, where fixup commit f
was already existing in its topic branch prior the merge.
> > If that`s preferred in some
> > cases, it could even look like this instead:
> >
> > (4) ...A ...C <- topics A, C
> > \ \ E I
> > ---o---o---o---o---F <- integration
> > / / /
> > ...B ...D / <- topic D
> > \ /
> > f-------' <- topic B
> >
> > ... where F(4) = I'(3), so similar situation, just that we don`t
> > discard I but post F on top of it.
>
> This is very acceptable.
And I can see logic behind this case, too (alongside that other one,
where they can both be supported, for different scenarios).
> Nevertheless, IMO, it is not the task of git-commit to re-compute a
> merge commit. It would be OK that it commits changes on top of a
> branch that is not checked out. Perhaps it would even be OK to remove
> the change from the current workspace (index and worktree), because
> it will return in the form of a merge later, but producing that merge
> is certainly not the task of git-commit.
Just to make sure we`re on the same page - you mean conceptually, or
practically? Or both...? :)
Because practically, we don`t do any merge operations/computations
(as can be seen inside the script), so we really don`t produce any
merges :)
Having a merge commit being updated as an outcome is just a
consequence of altering our history to pretend fixup commit already
existed elsewhere, being brought into our current state from there -
and that "current state" is updated accordingly to reflect the change
we made in the history that led to it.
Let`s look at a different example, no merges involved:
(12) ---A---B---C---D <- HEAD
Here, we can do `git commit --onto-parent C` to make the history look
like this:
(13) ---A---B---C---E---D' <- HEAD
..., where we practically inserted commit E between our HEAD and
commit C, causing D to be updated to D' accordingly (rebased,
practically).
Idea is the same with merges involved, updating HEAD commit to
reflect altered history.
In situation (12), we could also do `git commit --onto-parent C
--amend`, ending up with history like this instead:
(14) ---A---B---F---D' <- HEAD
..., where F is amended C, E being added to it, instead of being a
separate commit.
So there are quite some possibilities here.
But as said, I can understand a wish to have a commit elsewhere
without "merging" it in, too (changes removed from current workspace),
or "merging" it inside a separate commit (not updating existing
HEAD one).
And saying that, making the merge commit at the same time could then
be observed as no more than a shortcut, too, like being able to
create a new branch on checkout using "-b" option.
So even conceptually, it would make sense to wish for something like
this:
(15) git commit --onto B --merge
..., producing that graph (4) shown in the quote above, I would
think?
But even in that case, do note no merge is really happening, we just
alter history of our current state, where we already are.
Splitting changes out of HEAD to a commit directly preceding it, on a
different branch, and still keeping those changes in HEAD, naturally
causes our current HEAD state to have multiple parents, what is
perceived as a merge commit, even without a merge operation leading
to it.
Thus, `git commit` seems it should be up to the task, whichever
approach user opts for :)
Regards, Buga
next prev parent reply other threads:[~2017-12-04 2:33 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-11-26 22:35 [SCRIPT/RFC 0/3] git-commit --onto-parent (three-way merge, no working tree file changes) Igor Djordjevic
2017-11-26 22:36 ` [SCRIPT/RFC 1/3] setup.sh Igor Djordjevic
2017-11-26 22:36 ` [SCRIPT/RFC 2/3] git-merge-one-file--cached Igor Djordjevic
2017-11-26 22:45 ` [SCRIPT/RFC 3/3] git-commit--onto-parent.sh Igor Djordjevic
2017-11-27 21:54 ` [SCRIPT/RFC 0/3] git-commit --onto-parent (three-way merge, no working tree file changes) Johannes Sixt
2017-11-28 1:15 ` Igor Djordjevic
2017-11-29 19:11 ` Johannes Sixt
2017-11-29 23:10 ` Igor Djordjevic
2017-12-01 17:23 ` Johannes Sixt
2017-12-04 2:33 ` Igor Djordjevic [this message]
2017-12-06 18:34 ` Johannes Sixt
2017-12-06 18:40 ` Junio C Hamano
2017-12-08 0:15 ` Igor Djordjevic
2017-12-08 16:24 ` Junio C Hamano
2017-12-08 23:54 ` Igor Djordjevic
2017-12-09 2:18 ` Alexei Lozovsky
2017-12-09 3:03 ` Igor Djordjevic
2017-12-09 19:00 ` [SCRIPT/RFC 0/3] git-commit --onto-parent (three-way merge,noworking " Phillip Wood
2017-12-09 19:01 ` [SCRIPT/RFC 0/3] git-commit --onto-parent (three-way merge, noworking " Phillip Wood
2017-12-10 1:20 ` Igor Djordjevic
2017-12-10 12:22 ` [SCRIPT/RFC 0/3] git-commit --onto-parent (three-way merge,noworking " Phillip Wood
2017-12-10 23:17 ` Igor Djordjevic
2017-12-11 1:13 ` Alexei Lozovsky
2017-12-11 1:00 ` Alexei Lozovsky
2017-11-30 22:40 ` [SCRIPT/RFC 0/3] git-commit --onto-parent (three-way merge, no working " Chris Nerwert
2017-12-03 23:01 ` Igor Djordjevic
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=7ae3ffd5-147d-55d2-9630-da12c429d631@gmail.com \
--to=igor.d.djordjevic@gmail.com \
--cc=git@vger.kernel.org \
--cc=j6t@kdbg.org \
--cc=jnareb@gmail.com \
--cc=mailings@cedarsoft.com \
--cc=nikolay.shustov@gmail.com \
--cc=patrik-git@mail.pgornicz.com \
--cc=sam@vilain.net \
--cc=spearce@spearce.org \
--cc=tali@admingilde.org \
/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).