From: Howard Miller Date: Fri, 23 Oct 2009 05:36:10 GMT Subject: Re: Any way to "flatten" a series of changes in git Message-ID: <26ae428a0910222236l58bc64b7l12c4cff09b086dac@mail.gmail.com> In-Reply-To: <200910222357.15189.jnareb@gmail.com> 2009/10/22 Jakub Narebski : > On Thu, 22 Oct 2009, Howard Miller wrote: > >> > You can use either "git merge --squash" or "git rebase --interactive" >> > (changing 'pick' to 'squash'). >> > >> >> Actually thinking some more.... I don't understand something about >> this. I don't actually want to merge or rebase with anything. I just >> want to say "make those commits a series of commits on a branch into >> just one commit with a new message". I seriously suspect I'm missing >> the point somewhere but what has that got to do with merging or >> rebasing? > > Actually using "git merge --squash" is a bit different from using > "git rebase --interactive". > > > 1. "git merge --squash" > > From documentation: > >  --squash:: >        Produce the working tree and index state as if a real >        merge happened (except for the merge information), >        but do not actually make a commit or >        move the `HEAD`, nor record `$GIT_DIR/MERGE_HEAD` to >        cause the next `git commit` command to create a merge >        commit.  This allows you to create a single commit on >        top of the current branch whose effect is the same as >        merging another branch (or more in case of an octopus). > > This means for example if you did your changes on a separate > topic branch, and you want to merge your changes into 'master' > branch, you would do > >  $ git checkout master >  $ git merge side-branch > > which would result in the following history: > > >   ---*---*---*---*---*---*---*---M         <-- master >       \                         / >        \-.---.---.---.---.---.-/           <-- side-branch > > > If you used '--squash' option to git-merge, because changes were > made in throwaway topic branch, and as you said only final result > matter, you would get: > >  $ git checkout master >  $ git merge --squash side-branch > >   ---*---*---*---*---*---*---*---M'        <-- master >       \ >        \-.---.---.---.---.---.             <-- side-branch > > > where commit M' has the same contents (the same tree) as commit M > in previous example, but is not a merge commit. > > If you simply want to squash last say 5 commits into one, you can > use "git merge --squash" for it in the following way: > >  $ git reset --hard HEAD~5 >  $ git merge --squash --no-ff HEAD@{1} > > which means basically: rewind to state 5 commits back, then merge > in changes from before rewind, squashing them.  The --no-ff is needed > because otherwise it would be fast-forward and no commit would be > created. > > > 2. "git rebase --interactive" > > The interactive rebase is meant to edit commits being rebased, but > it can be used simply to edit commits.  It includes 'squash' command > that can be used to concatenate (squash) commits. > > So to squash last say 5 commits into one, you would use > >  $ git rebase --interactive HEAD~5 > > then edit provided list of commands and commits to read something like > this: > >   pick deadbee The oneline of this commit >   squash fa1afe1 The oneline of the next commit >   ... >   squash beedead The oneline of the that commit > > i.e. replace 'pick' command by 'squash' command. > > This is a very powerfull command, and can be used for example to turn > series of say 5 commits into series of say 2 commits; not simply squashing > to a single commit, but reducing number of commits (and presumably > cleaning up those commits). > > > HTH (hope that helps) > -- > Jakub Narebski > Poland > Hi Jakub, Yes it helps a lot. What I *don't* care about (or want to do) is actually do a merge or a rebase I just want to change history. Well, that's what I thought I wanted. What I suppose I really want is the full history for *me* and a second branch with the 'reduced' history to push to my client. I suppose that's different yet again? Howard