git rebase

This allows you to copy commits/branch to another commit/branch directly. You’re taking all the changes that were committed on a branch and replaying it on another. This creates a nice linear sequence of commits as the two parallel (merge combines two endpoints) commits seem like they were done sequentially. This especially helps when you’re contributing to project (all they’ll have to do is a fast-forward). The caveat is that all commits on the way to the rebase target are applied, even if they were just used for debugging purposes, etc.

If you use the interactive version (-i), you could pick and reorder the commits you want. This is great if you don’t quite know which commits you want to apply and would like to see some metadata on them.
git rebase -i HEAD~3 –aboveAll

Rebase also allows you to edit previous commit messages (reword), combine multiple commits (squash), split commits (edit), and delete/revert commits.

Don’t rebase commits that have been pushed publicly as others may have already based work on those commits. If it’s necessary makes sure git pull –rebase is used.

If you want to replay changes from a topic branch that’s branched off another topic branch you could use git rebase –onto master topic1 topic 2 where will replay only the changes to topic2 not common to topic1 to master.

vs. Merge

Merge will give you a record of exactly what happened during the entire history. Rebase will clean up that story so that it’s easier for developers to see how the project was created. Rebase locally to clean up the story before you push. Never rebase after you’ve pushed.

git cherry-pick

You could specify which commits you want to apply to your current HEAD. You have to know which commit hashes you want. For example, if you have 3 commits above the master branch, you could apply just the last commit by running git cherry-pick [hash of 3rd commit]. This way, only the 3rd commit gets applied to the master.

git reset

Moves a branch reference backwards in time to a specific commit. This works for local branches but not remote branches (to which you use revert instead). It’s as if the commit never happened.

git revert

This creates a new commit with the reversed changes. You could push these changes out to others.

git reflog

This log is updated when the HEAD gets updated. This usually happens with:

  • Switching branches
  • Pulling in new changes
  • Adding new commits
  • Rewrites to history

This command will show you the history of your local repository. If you performed a destructive command like reset and want to recover commits, you could find the hash of this commit with git-reflog.

git-reflog-1 git-reflog-2 git-reflog-3

You could always use git reset –hard [commit hash]  to revert accidentally changes.

git fsck

This is Git’s file system checker, which makes sure that every available object is reachable and valid. When references like branches are deleted, the objects (e.g., Commit objects) aren’t usually deleted but aren’t reachable.

This is useful (as with reflog) to recover deleted branches, but especially useful with recovering remote branches.

git-fsck

 git stash

Keep in mind when modifying or adding new files on different branches, if there isn’t a commit, those changes will “propagate” to other branches if you switch. When you’re working on a branch and you’re not quite finish but need to move onto another branch, git stash will take all the changes in your working tree and index and “stashes.” You’ll run git stash apply  to “unstash” the changes.  Keep in mind it is applied to the current branch.

When you perform a stash, it’s a merge commit. Git keeps track of the state of the index/staging-area and the working tree. Keep in mind that the index and working tree could contain changes to the same file. So essentially there are two commits when you stash. With these two commits, Git is able to “unstash” your changes.

# This command will run "apply" and a "drop" to keep your stash list clean.
git stash pop

git-stash

git describe

All this command does is show you the most recent annotated tag that is reachable from a commit. This may be useful for build and release scripts and also to find out which version a change was introduced.

This command takes a reference or commit hash and response with the most recent tag. If there was a commit after the tag, the tag will be followed by the number of commits and a letter “g” with the new commit hash.

git-describe-1 git-describe-2

git rev-parse

To find out which commit object a tag or branch points to.

git-rev-parse

git bisect

This command is great when you want to find out which commit introduced a breaking change. bisect performs a binary search to help you pinpoint which commit is bad. All you have to do is tell it which commit was bad, a commit that’s good, and it’ll automatically checkout the commits in between and have you test them. Once you’re finished git bisect reset.

git-bisect