# How to create a new commit with the content of some commit?

10 messages from 2009-05-12 to 2009-05-13. Participants: Ping Yin, Junio C Hamano, Tomas Carnecky, Jeff King, Sitaram Chamarty.
Thread: https://gitlist.dev/t/19313

## Ping Yin, 2009-05-12 14:35

Subject: How to create a new commit with the content of some commit?
Message-ID: <46dff0320905120735l501dcaf4ia8197d24b7684cfe@mail.gmail.com>
URL: https://gitlist.dev/e/46dff0320905120735l501dcaf4ia8197d24b7684cfe%40mail.gmail.com

```
a----b
 \----c

Given the graph above, I want to create a commit b1 on top of c, where
b1 and b have the same content. i.e.

a----b
 \----c----b1    ( content(b) == content(b1) )

If there are no untracked files in the working directory, i can do

git checkout b
git reset c
git add .
git commit -m "the copy of b"

Is there any simpler way? And if there are untracked files in the
working directory, how to do it?



Ping Yin

```

## Ping Yin, 2009-05-12 15:47

Subject: Re: How to create a new commit with the content of some commit?
Message-ID: <46dff0320905120847wae71bday4d4a890b00abc222@mail.gmail.com>
URL: https://gitlist.dev/e/46dff0320905120847wae71bday4d4a890b00abc222%40mail.gmail.com
In-Reply-To: <46dff0320905120735l501dcaf4ia8197d24b7684cfe@mail.gmail.com>

```
On Tue, May 12, 2009 at 10:35 PM, Ping Yin <pkufranky@gmail.com> wrote:
> a----b
>  \----c
>
> Given the graph above, I want to create a commit b1 on top of c, where
> b1 and b have the same content. i.e.
>
> a----b
>  \----c----b1    ( content(b) == content(b1) )

More precisely, b1 and b point to the same tree object

```

## Junio C Hamano, 2009-05-12 15:59

Subject: Re: How to create a new commit with the content of some commit?
Message-ID: <7vhbzq8g7u.fsf@alter.siamese.dyndns.org>
URL: https://gitlist.dev/e/7vhbzq8g7u.fsf%40alter.siamese.dyndns.org
In-Reply-To: <46dff0320905120735l501dcaf4ia8197d24b7684cfe@mail.gmail.com>

```
Ping Yin <pkufranky@gmail.com> writes:

> a----b
>  \----c
>
> Given the graph above, I want to create a commit b1 on top of c, where
> b1 and b have the same content. i.e.
>
> a----b
>  \----c----b1    ( content(b) == content(b1) )

On "c", you can:

    git read-tree -m -u b
    git commit

I think with newer git you can say

    git reset --merge b
    git commit

instead, to save some typing.

```

## Tomas Carnecky, 2009-05-12 16:04

Subject: Re: How to create a new commit with the content of some commit?
Message-ID: <83048193-FBD1-4D14-9CC9-B95BD08C67F7@dbservice.com>
URL: https://gitlist.dev/e/83048193-FBD1-4D14-9CC9-B95BD08C67F7%40dbservice.com
In-Reply-To: <46dff0320905120847wae71bday4d4a890b00abc222@mail.gmail.com>

```

On May 12, 2009, at 5:47 PM, Ping Yin wrote:

> On Tue, May 12, 2009 at 10:35 PM, Ping Yin <pkufranky@gmail.com>  
> wrote:
>> a----b
>>  \----c
>>
>> Given the graph above, I want to create a commit b1 on top of c,  
>> where
>> b1 and b have the same content. i.e.
>>
>> a----b
>>  \----c----b1    ( content(b) == content(b1) )
>
> More precisely, b1 and b point to the same tree object

git checkout c
git cherry-pick b

tom

```

## Jeff King, 2009-05-12 16:07

Subject: Re: How to create a new commit with the content of some commit?
Message-ID: <20090512160749.GA29566@coredump.intra.peff.net>
URL: https://gitlist.dev/e/20090512160749.GA29566%40coredump.intra.peff.net
In-Reply-To: <46dff0320905120735l501dcaf4ia8197d24b7684cfe@mail.gmail.com>

```
On Tue, May 12, 2009 at 10:35:30PM +0800, Ping Yin wrote:

> a----b
>  \----c
> 
> Given the graph above, I want to create a commit b1 on top of c, where
> b1 and b have the same content. i.e.
> 
> a----b
>  \----c----b1    ( content(b) == content(b1) )
> 
> If there are no untracked files in the working directory, i can do
> 
> git checkout b
> git reset c
> git add .
> git commit -m "the copy of b"
> 
> Is there any simpler way? And if there are untracked files in the
> working directory, how to do it?

You can just munge the index directly, and skip the working tree
entirely:

  rm .git/index
  git read-tree b
  git commit -m 'the copy of b'

You would probably want to "git checkout -f" afterwards to update the
working tree with what's in the index.

You can also do it without even touching the index by using the commit
plumbing:

  echo 'copy of b' >message
  tree=`git rev-parse b^{tree}`
  commit=`git commit-tree $tree -p c <message`
  git update-ref c $commit

-Peff

```

## Ping Yin, 2009-05-12 16:38

Subject: Re: How to create a new commit with the content of some commit?
Message-ID: <46dff0320905120938m36018b45y780126df42ed4194@mail.gmail.com>
URL: https://gitlist.dev/e/46dff0320905120938m36018b45y780126df42ed4194%40mail.gmail.com
In-Reply-To: <7vhbzq8g7u.fsf@alter.siamese.dyndns.org>

```
On Tue, May 12, 2009 at 11:59 PM, Junio C Hamano <gitster@pobox.com> wrote:
> Ping Yin <pkufranky@gmail.com> writes:
>
>> a----b
>>  \----c
>>
>> Given the graph above, I want to create a commit b1 on top of c, where
>> b1 and b have the same content. i.e.
>>
>> a----b
>>  \----c----b1    ( content(b) == content(b1) )
>
> On "c", you can:
>
>    git read-tree -m -u b
>    git commit

is -u necessary?

>
> I think with newer git you can say
>
>    git reset --merge b
>    git commit
>

When the working directory is clean, it seems "reset --hard" and
"reset --merge" behave the same. So after "git reset --merge b",  the
HEAD is moved to b, and i have nothing to commit.

```

## Ping Yin, 2009-05-12 16:43

Subject: Re: How to create a new commit with the content of some commit?
Message-ID: <46dff0320905120943j303ef104ve7bad25f1874007f@mail.gmail.com>
URL: https://gitlist.dev/e/46dff0320905120943j303ef104ve7bad25f1874007f%40mail.gmail.com
In-Reply-To: <20090512160749.GA29566@coredump.intra.peff.net>

```
On Wed, May 13, 2009 at 12:07 AM, Jeff King <peff@peff.net> wrote:
> On Tue, May 12, 2009 at 10:35:30PM +0800, Ping Yin wrote:
>
>> a----b
>>  \----c
>>
>> Given the graph above, I want to create a commit b1 on top of c, where
>> b1 and b have the same content. i.e.
>>
>> a----b
>>  \----c----b1    ( content(b) == content(b1) )
>>
>> If there are no untracked files in the working directory, i can do
>>
>> git checkout b
>> git reset c
>> git add .
>> git commit -m "the copy of b"
>>
>> Is there any simpler way? And if there are untracked files in the
>> working directory, how to do it?
>
> You can just munge the index directly, and skip the working tree
> entirely:
>
>  rm .git/index
>  git read-tree b
>  git commit -m 'the copy of b'

In a non-conflict status, "git read-tree b" will update the index to
full match the tree of b, so "rm .git/index" is unnecessary, right?


> You can also do it without even touching the index by using the commit
> plumbing:
>
>  echo 'copy of b' >message
>  tree=`git rev-parse b^{tree}`
>  commit=`git commit-tree $tree -p c <message`
>  git update-ref c $commit

Nice solution. Thank you and thank so powerful git!

Maybe a -c option can be added to git-commit-tree?

```

## Jeff King, 2009-05-12 16:51

Subject: Re: How to create a new commit with the content of some commit?
Message-ID: <20090512165103.GE29566@coredump.intra.peff.net>
URL: https://gitlist.dev/e/20090512165103.GE29566%40coredump.intra.peff.net
In-Reply-To: <46dff0320905120943j303ef104ve7bad25f1874007f@mail.gmail.com>

```
On Wed, May 13, 2009 at 12:43:33AM +0800, Ping Yin wrote:

> > You can just munge the index directly, and skip the working tree
> > entirely:
> >
> >  rm .git/index
> >  git read-tree b
> >  git commit -m 'the copy of b'
> 
> In a non-conflict status, "git read-tree b" will update the index to
> full match the tree of b, so "rm .git/index" is unnecessary, right?

For some reason, I was thinking that entries in the index that were not
in "b" would remain, but that is not actually the case. So yes, I think
you can do it without removing the index (and you are better off to do
so, since the index also contains the stat cache for your worktree, so
it is more efficient).

You can also add "-u" as Junio suggested to update the working tree
during that step, which should be more efficient.

> >  echo 'copy of b' >message
> >  tree=`git rev-parse b^{tree}`
> >  commit=`git commit-tree $tree -p c <message`
> >  git update-ref c $commit
> 
> Maybe a -c option can be added to git-commit-tree?

I doubt there is much interest in that, as commit-tree is meant to be a
low-level building block, not a user tool. If you wanted to pull the
message from another commit, you could just do:

  git cat-file commit b | sed '1,/^$/d' | git commit-tree ...

-Peff

```

## Ping Yin, 2009-05-12 16:59

Subject: Re: How to create a new commit with the content of some commit?
Message-ID: <46dff0320905120959sc69eec9h23cd8ac6b489e5b6@mail.gmail.com>
URL: https://gitlist.dev/e/46dff0320905120959sc69eec9h23cd8ac6b489e5b6%40mail.gmail.com
In-Reply-To: <20090512165103.GE29566@coredump.intra.peff.net>

```
On Wed, May 13, 2009 at 12:51 AM, Jeff King <peff@peff.net> wrote:
> On Wed, May 13, 2009 at 12:43:33AM +0800, Ping Yin wrote:
>
>> > You can just munge the index directly, and skip the working tree
>> > entirely:
>> >
>> >  rm .git/index
>> >  git read-tree b
>> >  git commit -m 'the copy of b'
>>
>> In a non-conflict status, "git read-tree b" will update the index to
>> full match the tree of b, so "rm .git/index" is unnecessary, right?
>
> For some reason, I was thinking that entries in the index that were not
> in "b" would remain, but that is not actually the case. So yes, I think
> you can do it without removing the index (and you are better off to do
> so, since the index also contains the stat cache for your worktree, so
> it is more efficient).
>
> You can also add "-u" as Junio suggested to update the working tree
> during that step, which should be more efficient.

I don't want to touch the working directory, and -m will keep the stat
cache in the index, so i think "git read-tree -m b" is the best.

```

## Sitaram Chamarty, 2009-05-13 14:36

Subject: Re: How to create a new commit with the content of some commit?
Message-ID: <slrnh0lmmv.5j5.sitaramc@sitaramc.homelinux.net>
URL: https://gitlist.dev/e/slrnh0lmmv.5j5.sitaramc%40sitaramc.homelinux.net
In-Reply-To: <83048193-FBD1-4D14-9CC9-B95BD08C67F7@dbservice.com>

```
On 2009-05-12, Tomas Carnecky <tom@dbservice.com> wrote:
>
> On May 12, 2009, at 5:47 PM, Ping Yin wrote:
>
>> On Tue, May 12, 2009 at 10:35 PM, Ping Yin <pkufranky@gmail.com>  
>> wrote:
>>> a----b
>>>  \----c
>>>
>>> Given the graph above, I want to create a commit b1 on top of c,  
>>> where
>>> b1 and b have the same content. i.e.
>>>
>>> a----b
>>>  \----c----b1    ( content(b) == content(b1) )
>>
>> More precisely, b1 and b point to the same tree object
>
> git checkout c
> git cherry-pick b

I do not think this does what was wanted.  Applying the
change from a->b onto c may not give you "b" unless a==c.

```
