Squashing complete history before a certain tag

Following scenario: I have a repo with a large history (migrated from SVN which was used since 2006) and want to push the newer history to an external server.

I have a tag, say mytag and want to delete all commits that occurred before that tag but want to keep the history that occurred since this tag.

  • Visual Studio 2013 Update 3 Process taking up 30% CPU for a long time after commit
  • Is there any way to continue Git clone from the point where it failed?
  • git change origin of a branch (rebase)
  • Print commit message of a given commit in git
  • mercurial log format with file-statuses
  • Is it possible to keep an unversioned file in a git repository
  • I tried to do it like in the accepted answer of Rebase many commits to one in Git. What am I doing wrong?, but this results in endless conflict resolving.

    I just want to throw away the history while being able to merge my local repo (that still holds the large history) to the remote repo (with the short history).

    How do I achive that?

  • Cocoapods setup stuck on pod setup command on terminal
  • Hudson Git Plugin not working on windows
  • Git: auto pull from repository?
  • git reset --hard HEAD leaves untracked files behind
  • Integrating MsBuild with Git
  • Completely replace Fork with origin (github)
  • 2 Solutions collect form web for “Squashing complete history before a certain tag”

    Update: note that in the below I’m assuming that mytag only has one parent commit, otherwise it’s a bit more complicated.

    First, let’s assume that you only have one root commit and that it’s f414f31. (If you need to find all the root commits you can do that with the first command in this answer.)

    To be safe, let’s create a new branch for this operation, so your branch master is left as it was, just in case the results aren’t as you would like.

    git checkout -b new-master

    Reset this branch to the root commit:

    git reset --hard f414f31

    Now change the working tree and the index to be the same as the commit just before mytag:

    git merge --squash mytag^

    Then create a commit from the index – if you want to rewrite the root commit, you can do that with git commit --amend, but I would prefer to keep one commit in common between your old and new histories, so I’d just do:

    git commit

    Now what you need to do is to replay all your work since (and including) mytag on top of that commit. This is what git rebase is intended for, but by default it will linearize all the history that you’re trying to replay. If have you many merge commits in the history since mytag, that may be the reason that you see many conflicts.

    So, if you don’t mind the history being linearized and you can fix the conflicts (possibly with the help of git rerere) you could just do:

    git rebase --onto new-master mytag^ master

    However, if there are merges in that history, and you would prefer to keep them, you could try adding the -p (--preserve-merges) option, which will try to recreate them:

    git rebase -p --onto new-master mytag^ master

    You ask a further question in the comments below about the case where you have two root commits. In that case, you could just pick one of them, and use git commit --amend after the squashed merge to create a completely new root commit for the rewritten history.

    If you want to rewrite/delete history, then you are looking for git filter-branch. Here’s a nice thread that discusses how to remove commits. The $drop variable would be the commit before your mytag.

    Git Baby is a git and github fan, let's start git clone.