HomeProjects
 
  

Useful git commands to get you started

December 5, 2020

In this post I am going to swiftly share some useful git commands, which I think will make your life easier while working with git :)


Modifying commits

NOTE: Any modification will result to a new commit being created, with a different hash, thus rewriting history. Don't follow this practice for pushed commits, unless you are sure that no one has pulled your changes.


Edit a commit's message or content

You just committed your changes and realized that you made a typo in the commit message. Run:

git commit --amend

Git will open your editor, where you can change the message on the first line. Save and exit. Git will replace the old commit with a new one, applying any changes you have made.

In case you want to add more files to the commit, the process is essentialy the same. However, you need to have staged the new files before, by running git add . or git add <pathspec>.


Split one commit into multiple

So you've made commit A with features F1 and F2. And you realize that you might be better off having each feature represented in a different commit. You want to use interactive rebase for that.

  • Start an interactive rebase session for the last commit:
git rebase -i HEAD~1
  • On the editor window that will open, change the pick command to edit, save and close.

  • Do a mixed reset to clear the index file of your changes and unstage the files:

git reset HEAD^
  • At this point, you can stage and commit any files separately:
git add F1
git commit -m 'Feature 1'
git add F2
git commit -m 'Feature 2'
  • Finally, run git rebase --continue to end the session.

Another alternative would be to stage files using git add -p, which lets you track individual changes in a file. This way you can create multiple commits off of one changed file, but this is beyond this article's scope. You can check this post for more information on how patch works.


Squash multiple commits into one

Oftentimes, you might end up with commits that are too "atomic" and maybe you want to meld them into one. Interactive rebase helps us with that, too. If we now want to squash the previously split commits Feature 1 and Feature 2, we are gonna have to do the following:

git rebase -i HEAD~2

In the editor window you are going to see the commits listed in reverse order like this:

pick <hash> Feature 1
pick <hash> Feature 2

You now have two choices: You can either use fixup or squash.

  • If you use fixup on Feature 2 commit, its message will be discarded and it will be squashed into the previous Feature 1.
pick <hash> Feature 1
fixup <hash> Feature 2
  • If you use squash on Feature 2 commit, it will open a new editor window including both commits' messages, so you can decide what the final message will be.
pick <hash> Feature 1
squash <hash> Feature 2

Delete & reorder commits

Same as above, git rebase -i comes pretty handy when we want to delete or reorder commits, too. To delete, just change pick to drop on the commit you want to get rid of. To reorder, literally reorder the lines 😛


Other useful commands

You can specify the commit when needed by either:

  • Using a commit-hash (i.e. 83b99ab).

Or:

  • Using a HEAD offset (i.e. HEAD~1 to indicate 1 commit before current HEAD location).

Use these with caution, since uncommited changes in general can't be recovered from deletion.

Discard unstaged local changes

git checkout . will update your working-tree to match the git index file, effectively discarding any unstaged changes.


Discard ALL local changes

Everything is a mess and you decide to wipe every change you've made until now.

git reset --hard

This actually does three things:

  • Moves the HEAD to <commit>.
  • Resets the index file to match <commit>.
  • Resets working directory to match <commit>.

So, it will discard all changes, staged or unstaged. You can specify a commit, if you also want to go back in time.


Go back to a previous commit (without affecting changes)

While working on a feature, you might want to rewind to a previous commit, without affecting uncommitted changes made in your working tree (i.e. when you want to create a new branch from an older commit and bring your current changes). A soft reset will only move the HEAD, leaving your working directory and index file untouched.

git reset <commit> --soft

This image nicely explains visually how different git reset modes work.

git_visualized

Thank you for reading! 🤓

Emmanouil Liakos

Emmanouil Liakos

Software Engineer

 

 

© 2021. Made with ♡ by me :)