Interactively Rebase with git
Tags: git, tutorial
Published: 2020-01-24 01:29:56

To find out why I think you should be rebaseing interactively read my first Dev.to post. 

{% link 
https://dev.to/jessekphillips/git-is-a-communication-tool--2j9k %}

I like to write articles using a different perspective than what I used to learn or read. It probably goes along with all my other tools not commonly used. I think I found a way to cover this topic differently. 

{% link https://dev.to/jessekphillips/my-old-git-processes-19k8 %} 

# What is an interactive rebase? 

It is a program, using a domain specific language with very limited scope.

# Domain of Interactive Rebase 

The interactive rebase operats with the domain of commits. What is a commit? 

Commits consist of changes to content, author, committer, and parents. The primary two which are manipulated are the content changes and parent.

# Script Structure 

The script is interpreted from top to bottom. There is no control flow or looping.

The script allows for execution pause, where the user can modify files and the script itself in the middle of script execution. 

# What Commands are in this Language 

When interactive rebase starts you are presented with the script in a text editor. At the end of the script is a comment which lists all the commands and their description.

Concider the operations utilized when committing to git. A general workflow could be as follows. 

1. Modify files
2. Add files to git
3. Commit files to git

e: `edit` - this command pauses execution after commit.

What this means is that git will write the commit to its database and await further instructions. This is most useful when combined with amend (a way of modifying the last commit).

r: `reword` - this command pauses at commit.

What this means is that git will present a text editor with the commit message. You can now modify the message associated with the changes. 

Note here that `reword` pauses earlier than `edit` however edit is used to modify files which is an earlier step than committing. Understanding amend is important to use edit at its full power.

p: `pick` - this command will utilize the entire commit and continue execution of the script.

b: `break` - this is inserted on its own line and just stops scrip execution. Use this if you are wanting to change something before the first commit of your rebase takes place, like if you want to amend a merge commit you're rebaseing onto. 

## Fixup and Squash 

I wanted to pause and call out these next two commands. I believe these are the the most important as they make history rewrite something which can be delayed. 

f: `fixup` - this command combines the changes of this commit, with the previous commit.

Recall that the scrip execution is from the start of the file, this means `fixup` is combined upward in the file. 

s: `squash` - this command pause on the commit message after combining the changes of this commit, with the previous commit. It would be like fixup-reword if commands could be combined on a commit.

I will stop here, there are additional commands which I have not made use of.

# Hidden Commands 

These are not so much commands but script modifications which are useful.

Change the parent commit. This is just a weird way of saying apply a commit in a different order. All you need to do is move the commit line in the order you desire, this functionality is critical to using `fixup` appropriately.

d: `drop`- this command removes the commit from history. It can also be done by removing the line from the script.

# Fixup Commit

I keep coming back to `fixup` because it is so useful.

```
git commit --fixup <hash>
```

This creates a new commit but it will not ask for a message, instead the commit is an instrument to fixup the commit at the provided hash.

For more details and alternatives to <hash> read [autosquashing git commits] (https://thoughtbot.com/blog/autosquashing-git-commits). Hint `:/`

The last key piece to using this is --autosquash. 

```
git rebase -i --autosquash origin/master 
```

This tells git to move the fixup and squash commits adjacent to the commit they operate on. Or configure it 

```
git config --global rebase.autosquash true
```

This tool is critical in making merge just a little easier to merge or even rebase. 

{% link https://dev.to/jessekphillips/handling-merges-464d %}

# Squash it All

Sometimes commits build up as you work through a problem and it is not orderly. In this case breaking apart commits may be easier by starting from the beginning.

```
git reset origin/master 
```

This will leave your working tree untouched and nothing committed.

Now it is time to employ a [partial commit](https://dev.to/jessekphillips/partial-commits-with-git-3g9d) to build out the more descriptive commits.