Git, how to automatize history collapse with rebase

I use a combination of these 2 articles to collapse my Git history : Collapsing a git repository's history and Combine the first two commits of a Git repository?

This is the result

  • git-svn: re-link git-svn cloned repo to svn
  • Running Git through Cygwin from Windows
  • Is it possible/desirable to have multiple RStudio .Rproj projects in a single Git repo?
  • Git pull on a remote server with an unknown tag
  • Have GitHub Pages render gh-pages branch rather than Jekyll content on master branch
  • Git-CodeCommit URL issues on OS X
  • git rebase -i THE_SHA_1_OF_FIRST_COMMIT
    # change "pick" into "squash" for all commits except first one
    # :wq (if your editor is vi)
    git rebase -i THE_SHA_1_OF_FIRST_COMMIT
    # change "pick" into "edit"
    # :wq (if your editor is vi)
    git reset --soft HEAD^
    git commit --amend
    git rebase --continue
    # garbage collect
    git reflog expire --expire=1.minute refs/heads/master
    git fsck --unreachable
    git prune
    git gc
    

    This work great but as I use this quite often, I wish to automatize this in a script.
    The problem is some commands like “git rebase -i” open a file to edit and I have to do it manually (same problem for “git commit –amend”). Is there a way to automatize this process? I’m not asking for a solution ready to use, just the idea.

  • I commit three times. How can I delete the second commit only?
  • Hiding files from git— possible without adding to .gitignore?
  • How to download source in ZIP format from GitHub?
  • Git push hangs on POST git-receive-pack
  • Which git tool generated this tree view?
  • How to create a symbolic link across git branches?
  • 2 Solutions collect form web for “Git, how to automatize history collapse with rebase”

    I got it working using the command git config --global core.editor to send the list of commits to a script instead of the default editor. Feels a bit dirty (and maybe not optimized) but it works, and now I can collapse the history of my repositories within one command!

    You need 2 bash scripts.

    First script replacepick.sh, the script that’s used instead of the editor. Parses all lines and replace ‘pick’ by (argument 1) from line #(argument 2) in file (argument 3).

    #!/bin/bash
    
    # ./replacepick.sh replacewith fromindex filename
    
    REPLACEWITH=$1
    FROMINDEX=$2
    FILE=$3
    
    
    echo $FILE
    
    mathccount=0
    
    if [ -f $FILE ]
    then
        OUTPUT=$FILE.tmp
        echo "" > $OUTPUT
        cat $FILE | while read line
        do
            if [[ "$line" == pick* ]]
            then
                matchcount=$(($matchcount + 1))
                if [ $matchcount -gt $FROMINDEX ]
                then
                    echo ${line/pick/$REPLACEWITH} >> $OUTPUT
                else
                    echo $line >> $OUTPUT
                fi
            else
                echo $line >> $OUTPUT
            fi
        done
        newfilecontent=`cat $OUTPUT`
        echo $newfilecontent > $FILE
    fi
    

    And the bash script collapsehistory.sh calling the git commands :

    #!/bin/bash
    
    # Collapse all commits on second commit
    `git config --global core.editor "/Users/macbook/Documents/GitTests/replacepick.sh squash 1"`
    `git rebase -i $1`
    `git rebase --continue`
    
    # Collapse 2 commits on one
    `git config --global core.editor "/Users/macbook/Documents/GitTests/replacepick.sh edit 0"`
    `git rebase -i $1`
    
    `git reset --soft HEAD^`
    `git config --global core.editor "cat"`
    `git commit --amend`
    `git rebase --continue`
    
    # garbage collect
    `git reflog expire --expire=1.minute refs/heads/master`
    `git fsck --unreachable`
    `git prune`
    `git gc`
    
    # restore your favorite editor
    `git config --global core.editor "vi"`
    

    Then you execute /path/to/historycollapse.sh SHA1_OF_FIRST_COMMIT and you’re done! Hope it helps some of you too.

    You should look at git merge --squash which will merge and squash all the commits onto your current branch without actually making a commit. You can then check and commit.

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