threads / discuss / 23678

how to squash a few commits in the past

Subject: how to squash a few commits in the past

## tl;dr

8 messages between May 3, 2010 and May 6, 2010.

replies: 7people: 4as markdown or json

Gelonida· May 3, 2010, 09:33 UTC · lore
Hi,

I posted already a similiar question about how to squash the all the commit hostory older than a certain commit into one commit.

This question is slightly different.
I'm having a git repository.
Suddenly I noticed, that git pull became rather slow.

The reason: One of the team members accidentally commited a very huge file together with some useful sources. a few commits later he noticed his error and removed the huge file.

The plan would be:
- create a new git repository without the huge file
- let everybody clone the new repository and continue working.

I thought, that I could squash the commit adding the file, removing the file and the commits in between into one commit.

How could I do this?
Thanks a lot for your help.
Michael J Gruber· May 3, 2010, 10:09 UTC · re: Gelonida · lore

Re: how to squash a few commits in the past

Gelonida venit, vidit, dixit 03.05.2010 11:33:
Show 29 quoted lines
> Hi,
> 
> 
> 
> I posted already a similiar question about how to squash the all the commit
> hostory older than a certain commit into one commit.
> 
> 
> This question is slightly different.
> 
> 
> I'm having a git repository.
> 
> Suddenly I noticed, that git pull became rather slow.
> 
> The reason:
> One of the team members accidentally commited a very huge file together with
> some useful sources.
> a few commits later he noticed his error and removed the huge file.
> 
> 
> 
> The plan would be:
> - create a new git repository without the huge file
> - let everybody clone the new repository and continue working.
> 
> 
> I thought, that I could squash the commit adding the file, removing the file and
> the commits in between into one commit.

You don't need to squash the commits in between. Use git rebase -i A^ if A is the commit introducing the large file. Then, either edit that first commit (to not add the file) or reorder so that the removal commit is squashed into A.

If everything looks fine people can pull and rebase. Note that in the source repository, there will still be a large "blob" until you prune and repack.

Michael
Gelonida· May 3, 2010, 20:45 UTC · re: Michael J Gruber · lore

Re: how to squash a few commits in the past

Hi Michael,
Michael J Gruber wrote:
Show 15 quoted lines
> Gelonida venit, vidit, dixit 03.05.2010 11:33:
>>
>>
>> The plan would be:
>> - create a new git repository without the huge file
>> - let everybody clone the new repository and continue working.
>>
>>
>> I thought, that I could squash the commit adding the file, removing the file and
>> the commits in between into one commit.
> 
> You don't need to squash the commits in between. Use git rebase -i A^ if
> A is the commit introducing the large file. Then, either edit that first
> commit (to not add the file) or reorder so that the removal commit is
> squashed into A.
I seem to misunderstand your suggestion.

git rebase -i 740ebdf9b^ returns following output

> fatal: Needed a single revision
> Invalid base
what am I missing?
Gelonida· May 3, 2010, 20:55 UTC · re: Gelonida · lore

Re: how to squash a few commits in the past

Hi,
Gelonida wrote:
Show 27 quoted lines
> Hi Michael,
> 
> Michael J Gruber wrote:
>> Gelonida venit, vidit, dixit 03.05.2010 11:33:
>>>
>>> The plan would be:
>>> - create a new git repository without the huge file
>>> - let everybody clone the new repository and continue working.
>>>
>>>
>>> I thought, that I could squash the commit adding the file, removing the file and
>>> the commits in between into one commit.
>> You don't need to squash the commits in between. Use git rebase -i A^ if
>> A is the commit introducing the large file. Then, either edit that first
>> commit (to not add the file) or reorder so that the removal commit is
>> squashed into A.
> 
> 
> I seem to misunderstand your suggestion.
> 
> git rebase -i 740ebdf9b^
> returns following output
>> fatal: Needed a single revision
>> Invalid base
> 
> 
> what am I missing?
In case it is relevent:

My git version: git version 1.6.3.3

Gelonida· May 3, 2010, 21:20 UTC · re: Gelonida · lore

Re: how to squash a few commits in the past

Hi Michael,
Gelonida wrote:
Show 24 quoted lines
> Hi Michael,
> 
> Michael J Gruber wrote:
>> Gelonida venit, vidit, dixit 03.05.2010 11:33:
>>>
>>> The plan would be:
>>> - create a new git repository without the huge file
>>> - let everybody clone the new repository and continue working.
>>>
>>>
>>> I thought, that I could squash the commit adding the file, removing the file and
>>> the commits in between into one commit.
>> You don't need to squash the commits in between. Use git rebase -i A^ if
>> A is the commit introducing the large file. Then, either edit that first
>> commit (to not add the file) or reorder so that the removal commit is
>> squashed into A.
> 
> 
> I seem to misunderstand your suggestion.
> 
> git rebase -i 740ebdf9b^
> returns following output
>> fatal: Needed a single revision
>> Invalid base

Please ignore me previous reply. It is very embarassing, but I tried it in the wrong window and therefore wrong directory.

Now I'm back to other errors. What I did was:

git rebase -i 740ebdf9^ # as a very first test I tried to modify nothing at all. # So I just quit the editor window (with about 270 entries) # where I could choose what to pick, squash or ignore

The result: the counter counts to about 50 of my 270 commits and then command aborts then

> Automatic cherry-pick failed.  After resolving the conflicts,
> mark the corrected paths with 'git add <paths>', and
> run 'git rebase --continue'
> Could not apply 67f3f6d... preparation for #241

I guess, that the problem might be. that the version tree looks roughly like this:

# first line of tree A-B-C-<forksoff>-D-E-F-G-<all_joined>-H-I-J-<forks_off>--K-

#tree continues after
K-L-<all_joined>-M-N
However, the commit, that I want to fix is commit I,
I think git gets lost somehow between J and L
Is it normal, that git gets lost wehn rebasing such a structure.
Ramkumar Ramachandra· May 5, 2010, 13:19 UTC · re: Gelonida · lore

Re: how to squash a few commits in the past

Hi,
On Mon, May 3, 2010 at 11:20 PM, Gelonida <gelonida@gmail.com> wrote:
> Is it normal, that git gets lost wehn rebasing such a structure.

While performing an interactive rebase, conflicts can often occur and this is quite normal.

>> Automatic cherry-pick failed.  After resolving the conflicts,
>> mark the corrected paths with 'git add <paths>', and
>> run 'git rebase --continue'
>> Could not apply 67f3f6d... preparation for #241

The problem and solution is described in that message. Open the file, resolve the conflict and continue the rebase operation.

-- Ram
Gelonida· May 5, 2010, 21:41 UTC · re: Ramkumar Ramachandra · lore

Re: how to squash a few commits in the past

Hi Ragu,
Ramkumar Ramachandra wrote:
Show 15 quoted lines
> Hi,
> 
> On Mon, May 3, 2010 at 11:20 PM, Gelonida <gelonida@gmail.com> wrote:
>> Is it normal, that git gets lost wehn rebasing such a structure.
> 
> While performing an interactive rebase, conflicts can often occur and
> this is quite normal.
> 
>>> Automatic cherry-pick failed.  After resolving the conflicts,
>>> mark the corrected paths with 'git add <paths>', and
>>> run 'git rebase --continue'
>>> Could not apply 67f3f6d... preparation for #241
> 
> The problem and solution is described in that message. Open the file,
> resolve the conflict and continue the rebase operation.

Yes merging manually could be a theortical solution, but I really don't understand, why I should merge anything at all.

The history is purely linear at the places where I want to squash.

These two commits precede a few more consecutive commits, traverse then a tree which forks to multiple branches, which partially cherrypick from each other and will then join again to a unique linear sequence.

If I have a history of several hundred commits and I am asked several times to merge, just because I want to squash two consecutve commits without any branches going out or in, then something (probably the way I try to attack the problem or much less likely a mysterious git bug) is kind of wrong.

I'm still looking for a solution, where I specify only the commits to be squashed and everything else stays untouched without any further userinteraction

Johannes Sixt· May 6, 2010, 06:45 UTC · re: Gelonida · lore

Re: how to squash a few commits in the past

Am 5/3/2010 11:33, schrieb Gelonida:
Show 7 quoted lines
> One of the team members accidentally commited a very huge file together with
> some useful sources.
> a few commits later he noticed his error and removed the huge file.
> 
> The plan would be:
> - create a new git repository without the huge file
> - let everybody clone the new repository and continue working.
Use 'git filter-branch':
  git filter-branch \
    --index-filter 'git rm --ignore-unmatch --cached the/huge/file' \
    --prune-empty \
    -- --all

The --prune-empty removes the commit that removed the file from the history if the removal of the/huge/file was the only thing it did.

If you have tags that must be rewritten, add "--tag-name-filter cat" to the command before "--".

Try this in a backup copy or clone first!
-- Hannes

← back to recent threads