# RE: What's in git.git

6 messages from 2006-02-09 to 2006-02-14. Participants: Luck, Tony, Junio C Hamano, Ryan Anderson.
Thread: https://gitlist.dev/t/3279

## Luck, Tony, 2006-02-09 23:49

Subject: RE: What's in git.git
Message-ID: <B8E391BBE9FE384DAA4C5C003888BE6F05AA1FB3@scsmsx401.amr.corp.intel.com>
URL: https://gitlist.dev/e/B8E391BBE9FE384DAA4C5C003888BE6F05AA1FB3%40scsmsx401.amr.corp.intel.com

```
Looks very close to what I want.

> git checkout topic
> git format-patch --stdout origin > topic-diff

 topic-diff contains each commit as a separate message

> $VISUAL topic-diff
> # Fix comments

 so this needs some skill & care to rearrange the pieces
 and end up with legal input to git-am

Perhaps I'd like to have:

 git diff SHA-where-I-branched..HEAD

but I don't see the way to compute the SHA-where-I-branched

-Tony

```

## Junio C Hamano, 2006-02-10 00:28

Subject: Re: What's in git.git
Message-ID: <7v8xsk5a6k.fsf@assigned-by-dhcp.cox.net>
URL: https://gitlist.dev/e/7v8xsk5a6k.fsf%40assigned-by-dhcp.cox.net
In-Reply-To: <B8E391BBE9FE384DAA4C5C003888BE6F05AA1FB3@scsmsx401.amr.corp.intel.com>

```
"Luck, Tony" <tony.luck@intel.com> writes:

> Looks very close to what I want.
>
>> git checkout topic
>> git format-patch --stdout origin > topic-diff
>
>  topic-diff contains each commit as a separate message
>
>> $VISUAL topic-diff
>> # Fix comments
>
>  so this needs some skill & care to rearrange the pieces
>  and end up with legal input to git-am
>
> Perhaps I'd like to have:
>
>  git diff SHA-where-I-branched..HEAD
>
> but I don't see the way to compute the SHA-where-I-branched
>
> -Tony

If what you want to end up with is a single commit, that is
easy.

If your topic branch is only "fork from master and never
re-merge with master but just pile new commits on top of the
tip, single strand of pearls" kind,

        git-merge-base master topic

would find the 'x' commit, where you forked from:

                           "master"
        ---x---o---o---o---o
            \
             o---o---o---o
                          "topic"

If you have "my topic will conflict with a change recently done
in master so let's merge up from master to resolve conflict
before going further" kind of merge commit on your topic branch,
then you cannot have a single two-tree diff easily anyway, but
in such a case, the following steps would work.

                           "master"
        ---o---o---o---o---o
            \       \
             o---o---*---o
                          "topic"

  (1) First merge "master" into "topic":

        $ git checkout topic
        $ git pull . master

                           "master"
        ---o---o---o---o---o
            \       \       \ 
             o---o---*---o---*
                             "topic"

      which would give you the rightmost '*' merge.

  (2) Extract diff from "master" to '*':

        $ git diff HEAD^2 HEAD >P.diff

      HEAD^1 is previous "topic" head and HEAD^2 is what you
      merged ("master").

  (3) Pick commits only on "topic" branch but not on "master"

        $ git rev-list --pretty --no-merges master..topic >P.log

      This will pick up the three 'o' commits on the lower
      development track and show their commit log message.


  (4) Reset the "topic" branch to "master", and do the squashed
      commit:

	$ git reset --hard master
        $ git apply --index P.diff
        $ git commit -F P.log -e

This obviously would work equally well for single strand of
pearls case.  Maybe you can package the above up, and send in a
patch to add "git-squash" command?

```

## Junio C Hamano, 2006-02-10 00:35

Subject: Re: What's in git.git
Message-ID: <7v3bis59un.fsf@assigned-by-dhcp.cox.net>
URL: https://gitlist.dev/e/7v3bis59un.fsf%40assigned-by-dhcp.cox.net
In-Reply-To: <7v8xsk5a6k.fsf@assigned-by-dhcp.cox.net>

```
Junio C Hamano <junkio@cox.net> writes:

> "Luck, Tony" <tony.luck@intel.com> writes:
>
>> Looks very close to what I want.
>>
>>> git checkout topic
>>> git format-patch --stdout origin > topic-diff
>>
>>  topic-diff contains each commit as a separate message
>>
>>> $VISUAL topic-diff
>>> # Fix comments
>>
>>  so this needs some skill & care to rearrange the pieces
>>  and end up with legal input to git-am
>>
>> Perhaps I'd like to have:
>>
>>  git diff SHA-where-I-branched..HEAD
>>
>> but I don't see the way to compute the SHA-where-I-branched
>>
>> -Tony
>
> If what you want to end up with is a single commit, that is
> easy.
>
> If your topic branch is only "fork from master and never
> re-merge with master but just pile new commits on top of the
> tip, single strand of pearls" kind,
>
>         git-merge-base master topic
>
> would find the 'x' commit, where you forked from:
>
>                            "master"
>         ---x---o---o---o---o
>             \
>              o---o---o---o
>                           "topic"
>
> If you have "my topic will conflict with a change recently done
> in master so let's merge up from master to resolve conflict
> before going further" kind of merge commit on your topic branch,
> then you cannot have a single two-tree diff easily anyway, but
> in such a case, the following steps would work.
>
>                            "master"
>         ---o---o---o---o---o
>             \       \
>              o---o---*---o
>                           "topic"
>
>   (1) First merge "master" into "topic":
>
>         $ git checkout topic
>         $ git pull . master
>
>                            "master"
>         ---o---o---o---o---o
>             \       \       \ 
>              o---o---*---o---*
>                              "topic"
>
>       which would give you the rightmost '*' merge.
>
>   (2) Extract diff from "master" to '*':
>
>         $ git diff HEAD^2 HEAD >P.diff
>
>       HEAD^1 is previous "topic" head and HEAD^2 is what you
>       merged ("master").
>
>   (3) Pick commits only on "topic" branch but not on "master"
>
>         $ git rev-list --pretty --no-merges master..topic >P.log
>
>       This will pick up the three 'o' commits on the lower
>       development track and show their commit log message.
>
>
>   (4) Reset the "topic" branch to "master", and do the squashed
>       commit:
>
> 	$ git reset --hard master
>         $ git apply --index P.diff
>         $ git commit -F P.log -e
>
> This obviously would work equally well for single strand of
> pearls case.  Maybe you can package the above up, and send in a
> patch to add "git-squash" command?

I am stupid.  (4) can be done a lot more easily.  Do not do step
(2) -- you do not need a diff at all.  But do do step (3) to get
the logs.  Then:

	$ git reset --soft master
        $ git commit -F P.log -e

What --soft reset does is to keep the index and the working tree
as is, but just change the current branch head to point at the
named commit.  So, immediately after the above soft reset, your
commit ancestry graph looks like this:

                            "master"
         ---o---o---o---o---o
                            "topic"

and the last commit finally would give you:


                            "master"
         ---o---o---o---o---o
                             \
                              o
                              "topic"

```

## Ryan Anderson, 2006-02-10 00:40

Subject: Re: What's in git.git
Message-ID: <20060210004040.GB2866@mythryan2.michonline.com>
URL: https://gitlist.dev/e/20060210004040.GB2866%40mythryan2.michonline.com
In-Reply-To: <B8E391BBE9FE384DAA4C5C003888BE6F05AA1FB3@scsmsx401.amr.corp.intel.com>

```
On Thu, Feb 09, 2006 at 03:49:16PM -0800, Luck, Tony wrote:
> Looks very close to what I want.
> 
> > git checkout topic
> > git format-patch --stdout origin > topic-diff
> 
>  topic-diff contains each commit as a separate message
> 
> > $VISUAL topic-diff
> > # Fix comments
> 
>  so this needs some skill & care to rearrange the pieces
>  and end up with legal input to git-am

Doh, right, I was thinking "git apply" actually.  (Apply the whole thing
as  single diff - the comments from each commit in the middle should get
ignored.)

Note that I don't believe there is any need to combine the hunks, just
stick them there in order and it *should* do the right thing.

> Perhaps I'd like to have:
> 
>  git diff SHA-where-I-branched..HEAD
> 
> but I don't see the way to compute the SHA-where-I-branched

git-merge-base topic master ?

-- 

Ryan Anderson
  sometimes Pug Majere

```

## Junio C Hamano, 2006-02-10 00:46

Subject: Re: What's in git.git
Message-ID: <7vvevo3us7.fsf@assigned-by-dhcp.cox.net>
URL: https://gitlist.dev/e/7vvevo3us7.fsf%40assigned-by-dhcp.cox.net
In-Reply-To: <20060210004040.GB2866@mythryan2.michonline.com>

```
Ryan Anderson <ryan@michonline.com> writes:

> Note that I don't believe there is any need to combine the hunks, just
> stick them there in order and it *should* do the right thing.

Probably not.  I suspect it would not like two pieces of diffs
touching the same path in a batch.

Feeding one at a time is OK, though.

```

## Luck, Tony, 2006-02-14 23:10

Subject: Re: What's in git.git
Message-ID: <20060214231039.GA15680@agluck-lia64.sc.intel.com>
URL: https://gitlist.dev/e/20060214231039.GA15680%40agluck-lia64.sc.intel.com
In-Reply-To: <7v3bis59un.fsf@assigned-by-dhcp.cox.net>

```
> >   (1) First merge "master" into "topic":
> >
> >         $ git checkout topic
> >         $ git pull . master
> >
> >   (3) Pick commits only on "topic" branch but not on "master"
> >
> >         $ git rev-list --pretty --no-merges master..topic >P.log
> >
> >       This will pick up the three 'o' commits on the lower
> >       development track and show their commit log message.
> >
> >
> > This obviously would work equally well for single strand of
> > pearls case.  Maybe you can package the above up, and send in a
> > patch to add "git-squash" command?
> 
> I am stupid.  (4) can be done a lot more easily.  Do not do step
> (2) -- you do not need a diff at all.  But do do step (3) to get
> the logs.  Then:
> 
> 	$ git reset --soft master
>         $ git commit -F P.log -e

Yes, that all seems to work as advertised.  One extra wrinkle was to
preserve the author information by grepping out the last Author: line
from the log.  Here's the work-in-progress version of git-squash (I
don't have a "master" branch, so I stuck in the "mbranch" shell variable
so there is only one place for me to change ... to mbranch=linus).

Any style (or other) comments?  If not I'll package into patch format
with a manual page in a few days.

-Tony

#!/bin/sh

. git-sh-setup

branch="$1"
mbranch=master

if [ ! -f .git/refs/heads/"$branch" ]
then
	die "Can't see branch '$branch'"
fi

if [ -f .git/refs/heads/"$branch"-unsquashed ]
then
	die "Branch '$branch' has been squashed before"
fi

cp .git/refs/heads/"$branch" .git/refs/heads/"$branch"-unsquashed

git checkout "$branch" || die "Couldn't checkout '$branch'"

git pull . $mbranch || die "Can't merge $mbranch into $branch"

git-rev-list --pretty --no-merges $mbranch..$branch > /tmp/git-squash-$$

git reset --soft $mbranch

author=$(sed -n -e  '/^Author: /s///p' /tmp/git-squash-$$ | tail -1)

git commit --author "$author" -F /tmp/git-squash-$$ -e

rm -f /tmp/git-squash-$$

```
