git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Jeff King <peff@peff.net>
To: Avery Pennarun <apenwarr@gmail.com>
Cc: Jon Seymour <jon.seymour@gmail.com>,
	Git Mailing List <git@vger.kernel.org>
Subject: Re: Is there something like a git format-patch --squash?
Date: Thu, 18 Feb 2010 15:34:40 -0500	[thread overview]
Message-ID: <20100218203440.GA8110@coredump.intra.peff.net> (raw)
In-Reply-To: <32541b131002181145w44d69e9eo150d08f34273cefb@mail.gmail.com>

On Thu, Feb 18, 2010 at 02:45:54PM -0500, Avery Pennarun wrote:

> > Something like this (replace MY_START_BRANCH with your starting
> > branch, and do this in a clone of your repository so you don't destroy
> > anything by accident):
> >
> >        parent=""
> >        git rev-list --first-parent --reverse  | while read commit; do
> >                if [ -z "$parent" ]; then
> >                        git checkout -f $commit
> >                        git clean -fdx
> >                else
> >                        git diff $parent $commit | git apply --index
> >                        git commit -C $commit
> >                fi
> >                parent=$commit
> >        done
> 
> In the above, in the 'else' clause, what I really wanted was something like:
> 
>    git format-patch --stdout --squash $parent..$commit
> 
> with one big "| git am" at the end of the loop.

I don't think there is a way to do it automagically. Obviously you can
use diff (as you did) to produce the diff, but how should the many
commit messages be combined?

Worst case, you could probably do it yourself by echoing the mail
headers yourself, throwing all of the commit messages in the body, and
then doing the diff:

  me=`git var GIT_AUTHOR_IDENT | sed -e 's/>.*/>/'`
  (echo "From: $me"
   echo "Subject: Mega-squash of $commit"
   echo
   git log --format="%s%n%n%b" $parent..$commit
   echo ---
   git diff $parent $commit
  ) | git am

But that's totally untested (also, do you really need $parent? In
--first-parent --reverse, isn't it always going to be $commit^1?).

But I think you can do it without diff application by just re-using the
tree-state of each merge:

  git rev-list --first-parent --reverse $from..$to |
  last=$from
  while read commit; do
    last=`git cat-file commit $commit |
          sed '1,/^$/d' |
          git commit-tree $commit^{tree} -p $from`
  done
  git update-ref refs/heads/new $last

But that isn't tested either. :) You might need to replace
"$commit^{tree}" with an equivalent rev-parse.

-Peff

  parent reply	other threads:[~2010-02-18 20:34 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-02-18 19:45 Is there something like a git format-patch --squash? Avery Pennarun
2010-02-18 19:46 ` Avery Pennarun
2010-02-18 20:34 ` Jeff King [this message]
2010-02-18 21:56   ` Avery Pennarun

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

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20100218203440.GA8110@coredump.intra.peff.net \
    --to=peff@peff.net \
    --cc=apenwarr@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=jon.seymour@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.
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 NNTP newsgroup(s).