Skip to content

Useful Git Commands

Hwee-Boon Yar edited this page Mar 6, 2019 · 7 revisions

Imagine that you are working on a branch called: wonderful-feature which was forked from the master branch. You have added commits in wonderful-feature, and there are new commits in master (probably because another PR has been merged).

rebase master

This command will point wonderful-feature to the HEAD of master (and thus getting all the new commits into wonderful-feature) then reapply the commits which you previously added in wonderful-feature, effectively getting your version of wonderful-feature up to date:

$ git rebase master

Sometimes, git can't merge the commits automatically and it'll prompt you to resolve them manually. You'd usually usually use git status to see which files have merge conflicts, fix them manually (look for <<< and >>>), fix the conflicts, run git add . and then git rebase --continue. Sometimes you need to perform this manual merging process a few times depending on how many commits have to be replayed and have merge conflicts.

Why?

  1. You get to test how the branch will look like (with the latest commits from master) and make sure your changes work with those
  2. Cleaner single-path history in the git commit log, you avoid those "Merge branch 'master' of..." commits which makes it hard to see where a change was made.

Pull Latest Commits into master While Working On Another Branch

This is mostly a shortcut. Useful prior to to running git rebase master. This will update your local master branch with the latest commits from the remote repo:

git fetch origin master:master

Then you can do:

git rebase master

Why?

The alternative is:

  1. git stash save
  2. git checkout master
  3. git pull origin master
  4. git checkout wonderful-feature
  5. git stash pop

Rebase Your Branch

Unlike what is commonly referred to as "rebase master", this usually means squashing/editing your commits. Assuming:

$ git log --pretty=oneline

0x0a4 //newest commit you have added to `wonderful-feature`
0x0a3
0x0a2 //1st commit you have added in `wonderful-feature`
0x0a1  //master's HEAD
...

You are preparing a PR based on wonderful-feature. Most, if not all commits should be atomic so it makes sense sometimes to clean up your history by combining some commits into 1. Assuming you want to modify commits 0x0a2, 0x0a3, 0x0a4, you'd run:

git rebase -i 0x0a1

You run it with the commit hash for the commit 1 older than the one you want to change (i.e. 1 older than 0x0a2).

You'd see this:

pick 0x0a2 WIP 1
pick 0x0a3 WIP 2
pick 0x0a4 Finished implementing a brand new feature

Edit it so that it becomes:

pick 0x0a2 WIP 1
squash 0x0a3 WIP 2
squash 0x0a4 Finished implementing a brand new feature

And git will combine 0x0a3 and 0x0a4 into 0x0a2, i.e. "squashing" them together. Once you save the file, you'd get another file where you can update the comment (so you can delete the lines with "WIP 1" and "WIP 2" and keep "Finished implementing a brand new feature" as the comment for the resulting commit).

You can also reorder commits (by just reorganising the lines around). This is especially useful if, while you are working on a feature, you realize that you can make a related change that can be submitted as a standalone PR.

Why?

Cleaner history, keeping commits atomic. You may end up with 1 or more commits (ideally 1 or at most a few for each PR), but each commit should be atomic.

Forced Push

If you have pushed to a remote repo and then rebase your local branch, you'd have to force push to the remote repo to get the changes in:

git push origin wonderful-feature --force

Don't force push a branch to a remote repo which another person is working on without coordination.

Why

This is really useful after getting feedback from a PR review session. You can fix your local branch after the review, rebase locally, then force push to keep history clean.

Commit as Another Person

git commit --author="Hwee-Boon Yar <[email protected]>"

Why?

Useful if you are working on another person's machine