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 :)
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.
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>.
So you've made
commit A with features
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
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 --continueto 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.
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
- If you use
Feature 2commit, its message will be discarded and it will be squashed into the previous
pick <hash> Feature 1 fixup <hash> Feature 2
- If you use
Feature 2commit, 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
Same as above,
git rebase -i comes pretty handy when we want to delete or reorder commits, too. To delete, just change
drop on the commit you want to get rid of. To reorder, literally reorder the lines 😛
You can specify the commit when needed by either:
- Using a commit-hash (i.e.
- Using a
HEAD~1to indicate 1 commit before current
Use these with caution, since uncommited changes in general can't be recovered from deletion.
git checkout . will update your working-tree to match the git index file, effectively discarding any unstaged 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
- Resets the index file to match
- Resets working directory to match
So, it will discard all changes, staged or unstaged. You can specify a commit, if you also want to go back in time.
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.
Thank you for reading! 🤓
If you liked this post, you can connect with me on LinkedIn.