git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: Junio C Hamano <gitster@pobox.com>
To: Yann Dirson <dirson@bertin.fr>
Cc: Andreas Schwab <schwab@linux-m68k.org>,
	Christian Couder <christian.couder@gmail.com>,
	Thomas Rast <trast@student.ethz.ch>,
	git list <git@vger.kernel.org>
Subject: Re: [BUG] Cannot push some grafted branches
Date: Tue, 18 Dec 2012 08:09:35 -0800	[thread overview]
Message-ID: <7vehinibpc.fsf@alter.siamese.dyndns.org> (raw)
In-Reply-To: <20121218120058.0c558ba5@chalon.bertin.fr> (Yann Dirson's message of "Tue, 18 Dec 2012 12:00:58 +0100")

Yann Dirson <dirson@bertin.fr> writes:

> On Mon, 17 Dec 2012 13:14:56 -0800
> Junio C Hamano <gitster@pobox.com> wrote:
>
>> Andreas Schwab <schwab@linux-m68k.org> writes:
>> 
>> > Christian Couder <christian.couder@gmail.com> writes:
>> >
>> >> Yeah, at one point I wanted to have a command that created to craft a
>> >> new commit based on an existing one.
>> >
>> > This isn't hard to do, you only have to resort to plumbing:
>> >
>> > $ git cat-file commit fef11965da875c105c40f1a9550af1f5e34a6e62 | sed s/bfae342c973b0be3c9e99d3d86ed2e6b152b4a6b/790c83cda92f95f1b4b91e2ddc056a52a99a055d/ | git hash-object -t commit --stdin -w
>> > bb45cc6356eac6c7fa432965090045306dab7026
>> 
>> Good.  I do not think an extra special-purpose command is welcome
>> here.
>
> Well, I'm not sure this is intuitive enough to be useful to the average user :)

I do not understand why you even want to go in the harder route in
the first place, only to complicate things?

All you want to do is to craft a commit object that records a
specific tree shape, has a set of parents you want, and has the log
information you want.  Once you have the commit, you can replace an
unwanted commit with it.

    ----A----B----o---- ....

           X----Y----Z---- ....

Suppose you want to pretend that X is a child of A, even though it
is not in the real life.  So you want to create a commit that 

    - has the same tree as X;
    - has A as its parent; and
    - records log and authorship of X.

and then use "git replace" to replace X, right?  How about doing it
this way?

    $ git checkout X^0 ;# detach
    $ git reset --soft A
    $ git commit -C X

The first gives you the index and the working tree that is the same
as X, the second moves HEAD while keeping the index and the working
tree so that the commit you create will be a child of A, and the
last makes that commit with the metainformation from X [*1*].  If
you want, you can even tweak the contents of the tree before making
the commit in the final step, or tweak the log message during the
final step.

Then you can take the resulting commit and replace X with it, no?

Alternatively, you can do:

    $ git checkout X^0 ;# detach
    $ git reset --soft B
    $ git commit --amend -C X

that is, find an existing commit B that has the desired set of
parents, and amend it with the same tree and the metainformation as
X.  This would even work when you want to come up with a commit that
replaces a merge.  For example, if you want to pretend that B were a
merge between A and X in the above topology, you could

    $ git checkout -b temp A
    $ git merge -s ours X ;# the recorded tree does not matter
    $ git checkout B^0 ;# detach
    $ git reset --soft temp
    $ git commit --amend -c B

which would create one merge that has the desired set of parents
(i.e. A and X) in the first two steps on temp branch, prepares the
index and the working tree to match the tree of B, and with that
tree and the metainformation from B, amends that merge.  The
resulting commit will be a merge between A and X that has the tree
of B and metainformation of B (with a chance to edit it further, as
I used -c there).

Is this not intuitive enough?


[Footnote]

*1* If you are not tweaking the tree contents, you can do this
all in the index without affecting the working tree, e.g.

    $ git checkout HEAD^0 ;# totally random state unrelated to X nor A
    $ git read-tree X ;# just update the index to match tree of X
    $ git reset --soft A ;# next commit will be child of A
    $ git commit -C X ;# and with metainformation from X

After you are done, you can "read-tree $branch" followed by
"checkout $branch" to come back to where you were.

  parent reply	other threads:[~2012-12-18 16:09 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-12-11 14:39 [BUG] Cannot push some grafted branches Yann Dirson
2012-12-11 18:15 ` Junio C Hamano
2012-12-12  8:44   ` Yann Dirson
2012-12-12 10:54     ` Yann Dirson
2012-12-12 19:57     ` Junio C Hamano
2012-12-17  7:52       ` Yann Dirson
2012-12-17  8:56         ` Junio C Hamano
2012-12-17 10:30           ` Yann Dirson
2012-12-17  8:43       ` Thomas Rast
2012-12-17 10:40         ` Yann Dirson
2012-12-17 13:43           ` Christian Couder
2012-12-17 14:02             ` Yann Dirson
2012-12-17 20:03             ` Andreas Schwab
2012-12-17 21:14               ` Junio C Hamano
2012-12-18 11:00                 ` Yann Dirson
2012-12-18 12:03                   ` Johannes Sixt
2012-12-18 12:49                     ` Thomas Rast
2012-12-18 13:41                       ` Yann Dirson
2012-12-18 14:31                         ` Thomas Rast
2012-12-18 16:24                         ` Jeff King
2012-12-19  7:13                           ` Johannes Sixt
2012-12-19 13:06                             ` Jeff King
2012-12-18 16:09                   ` Junio C Hamano [this message]
2012-12-19  8:29                     ` Yann Dirson
2012-12-19 13:12                     ` Thomas Rast
2012-12-19 20:07                       ` Junio C Hamano
2012-12-21 12:47                         ` Michael J Gruber
2012-12-21 16:58                           ` Junio C Hamano
2012-12-22 16:38                             ` Michael J Gruber

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=7vehinibpc.fsf@alter.siamese.dyndns.org \
    --to=gitster@pobox.com \
    --cc=christian.couder@gmail.com \
    --cc=dirson@bertin.fr \
    --cc=git@vger.kernel.org \
    --cc=schwab@linux-m68k.org \
    --cc=trast@student.ethz.ch \
    /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).