Thursday, 19 January 2017

Rewriting History with Git

Well, this is basically a followup of my previous blogpost about git.

A note of warning: rewriting history can be tricky, and you should perform this only on your local Git repository on things you haven't yet pushed to a remote (public) repository.

For more detailed information on how you can work with it, see the References. Right here, right now, I'm going to provide the way I've used it in my current work.

Logs

Rewriting history is done by "rebasing" your current checkins.

It helps if you can easily retrieve your current checkins from the logs.

The following shows my last 5 checkins in my local branch.
[mrbear@localhost project]$ git log --pretty=format:"%h %s" HEAD~5..HEAD
75d7620 BUGS-0010 Make it visible whether user is using the test or the production version.
ca9217e BUGS-0010 Cache test/prod urls.
b1f93c1 BUGS-0010 Replace hardcoded urls with configuration.
46908ce BUGS-0010 Implement configuration using Gulp.
49115c3 BUGS-0010 Two ways: "gulp test" or "gulp production".
Bear in mind that the log shows the checkins from most recent (on top) to the least recent (last). Rebasing takes the checkins in the opposite order.

Squashing checkins

Let us try to squash some commits that we've made together into one single commit.
[mrbear@localhost project]$ git rebase -i HEAD~5
49115c3 BUGS-0010 Two ways: "gulp test" or "gulp production".
46908ce BUGS-0010 Implement configuration using Gulp.
b1f93c1 BUGS-0010 Replace hardcoded urls with configuration.
ca9217e BUGS-0010 Cache test/prod urls.
75d7620 BUGS-0010 Make it visible whether user is using the test or the production version.

# Rebase d5defcb..75d7620 onto d5defcb (5 command(s))
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit's log message
# x, exec = run command (the rest of the line) using shell
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#
# Note that empty commits are commented out
I've decided to squash 46908ce, so that this commit will be combined with its previous commit, the 49115c3.

I can even change the commit message and combine the two commit messages!
# This is a combination of 2 commits.
# The first commit's message is:

BUGS-0010 Implement configuration using Gulp.

# This is the 2nd commit message:

BUGS-0010 Two ways: "gulp test" or "gulp production".

# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# Date:      Thu Jan 19 14:13:50 2017 +0100
#
# rebase in progress; onto 0a98e03
# You are currently editing a commit while rebasing branch 'BUGS-0010' on '0a98e03'.
#
# Changes to be committed:
#       modified:   config.xml
#       modified:   lang.json
# Untracked files:
#       project/config.xml~
#       project/res/
#       project/www/conf/
#       project/www/i18n/
#
The output will look something like this:
[detached HEAD 5b2f880] BUGS-0010 Configuration using gulp in two ways: "gulp test" or "gulp production".
Date: Mon Jan 9 13:20:45 2017 +0100
8 files changed, 36 insertions(+), 6 deletions(-)
rename project/{ => conf}/config.xml (94%)
rename project/{www/i18n => conf}/lang.json (99%)
Successfully rebased and updated refs/heads/BUGS-0010.

Reordering checkins

Reordering the checkins, is as simple as cut&pasting the appropriate lines into a different sequence.

Removing checkins

Removing a checkin, can be done by just removing a line from the sequence. Use with caution.

References

Atlassian Git Tutorial - Rewriting history
https://www.atlassian.com/git/tutorials/rewriting-history/git-rebase-i
Git - 7.6 Git Tools - Rewriting History
https://git-scm.com/book/en/v2/Git-Tools-Rewriting-History

No comments:

Post a Comment