Git Rebase

It was pointed out to me that I had a typo in my code for the SPI shift register tutorial. I had the definition wrong for the data pin used by SPI (I guess AVR is not too particular about setting MOSI as an output for master SPI mode). Since it is supposed to be a clear example I needed to fix it. But the git repository that I used has a tag to some earlier code as the simple example, then more complex code at the latest revision. I wanted to make the change throughout and for this I decided to use the Rebase command. Here’s the steps I took:

  • Check out a new clone of the repository
  • Do a hard reset to the offending commit
  • Fix the problem and commit it
  • Hard reset back to the most recent version
  • Use the Rebase command to bring that change forward in time
  • Pull from the remote repository (you’ll be told to do this if you try to push first)
  • Push back to the remote repository

Fixing tags

  • You CANNOT move a tag on the remote repository. This is a security feature.
  • Delete the old tag and make a new one at the proper commit.

First of all, I made sure that my repository was stored somewhere else (on Github) and that I checked out a new version which I could ditch if I screwed something up:

git clone
cd Shift-Registers-SPI

I used the log command to find the commit SHA which I wanted to change, moved HEAD to that using a hard reset, then made my edits and committed them:

git log
git reset --hard faae8d
nano main.c
git commit -a -m "Fixed typo (PD3 should have been PB3)"

Now I want to move head back to the most recent revision. I found the SHA for that using the reflog command, then used the rebase command with the SHA of the commit I just made. This will apply those changes forward in time to where HEAD is at right now:

git reflog
git reset --hard 7442f3e
git rebase 3709d67

When I tried to push the changes back to Github it threw this error:

git push
 ! [rejected]        master -> master (non-fast-forward)
error: failed to push some refs to ''
To prevent you from losing history, non-fast-forward updates were rejected
Merge the remote changes (e.g. 'git pull') before pushing again.  See the
'Note about fast-forwards' section of 'git push --help' for details.

The nice thing about git is that it usually tells you what you should have done. All it took was a pull, then a push:

git pull
git push origin

The code is fixed, but I need to move my tag. It turns out to be impossible to actually move a tag that you’ve pushed to a remote repository (this is apparently a security feature). I had to satisfy myself with deleting the old tag and making a new one:

git tag -d simple-shift-example
git push origin :refs/tags/simple-shift-example
git tag simple-shift-example-FIXED 3709d67
git push --tags

Voila, fixed! It was an interesting process to get through, but I still love what Git can do, even when it gets hairy!