Collapse git history to tags (combine commits between tags)

191 Views Asked by At

We have a fairly big (1000+ commits) repository with 7 years worth of changes and 6 released versions (each version represented by a git tag). We would like to collapse the history so that prior to last tag, all commits between two tags are collapsed into one commit, bearing the version tag. Thus reducing our repository history to some 15 commits. We would not be doing any reverts across versions. As a bonus, ideally we would like to keep all people whose commits we collapse as co-authored-by. If its important, we do not have any merges which are skipping over the tag into new version from before the tag.

From:

CHEAD
C2
C3
...
TAG6
Cx
Cy
...
TAG5
Ca
..

into

CHEAD
C2
C3
...
TAG6
TAG5
TAG4
TAG3
TAG2
TAG1

Any ideas on how to proceed?

1

There are 1 best solutions below

3
On

Collapsing by tag is easy : git log has two options --simplify-by-decoration and --decorate-refs=<pattern>, which you can use as follows :

# --graph is useful to have a clear view of parent <-> child relation,
# you may use --oneline to have a compact view, or drop it if you want the complete
# commit messages
git log --graph --oneline --simplify-by-decoration \
      --decorate-refs=refs/tags   # <- this indicates 'keep only tags'

One partial way to get "everything after TAG6, only tags before TAG6" could be to get the log in two commands :

# in a 'mylog' script :
#!/bin/bash

log_history () {
    # get all from TAG6 up to HEAD :
    git log --decorate --graph TAG6..HEAD
    # get only tags up to TAG6 :
    git log --decorate --graph --simplify-by-decoration \
        --decorate-refs=refs/tags TAG6
}

# combine the two commands, and pipe them in your pager
# if you pipe the output of 'git log', git removes the default '--decorate',
# that's why I added it in the commands above
log_history | less

The above will give you the complete list of commits you want to see ; the only missing part would be that, in the graph, the link between TAG6 and its child commit (the commit right above TAG6) will not be drawn.

I wouldn't know how to indicate the combination you describe in one single git log command.