5 everyday Git tricks to save time and headaches
June 18, 2020
Most developers use git everyday for uses far beyond source control.
This guide assumes intermediate knowledge of the git
bash utility.
The Tricks
Trick #1: Amended commits
While reviewing your work, it is common to find issues or improvements. It is
simple to incorporate new changes into the latest commit using git-commit
--amend
:
# Stage your changes
$ git add [...]
# Commit them to latest commit:
$ git commit --amend --no-edit
This will add the latest changes to your previous commit. If you want to make
changes to the commit message, simply omit the --no-edit
option, and git will
open your editor with commit message to edit.
I use this frequently enough that I added the following alias:
git config --global alias.cane commit --amend --no-edit
Trick #2: Patch mode (-p
): Granular browsing and actions
The patch flag -p
can be used with several git commands to varying effect.
Patched git log
Let’s take git-log
as a simple use case, here against the react git repo:
$ git log -p
commit 090c6ed7515b63c9aa7c42659973bfc179691006 (HEAD -> master, origin/master, origin/HEAD)
Author: YeonJuan <yeonjuan93@naver.com>
Date: Thu Jun 18 01:29:02 2020 +0900
[eslint-plugin-react-hooks]: handling sparse array when no-inline callback (#19145)
diff --git a/packages/eslint-plugin-react-hooks/__tests__/ESLintRuleExhaustiveDeps-test.js b/packages/eslint-plugin-react-hooks/__tests__/ESLintRuleExhaustiveDeps-test.js
index c82042839..9322952fa 100644
--- a/packages/eslint-plugin-react-hooks/__tests__/ESLintRuleExhaustiveDeps-test.js
+++ b/packages/eslint-plugin-react-hooks/__tests__/ESLintRuleExhaustiveDeps-test.js
@@ -369,6 +369,20 @@ const tests = {
}
`,
},
+ {
+ code: normalizeIndent`
+ function MyComponent({myEffect}) {
+ useEffect(myEffect, [,myEffect]);
+ }
+ `,
+ },
While usually git log
simply outputs high-level commit information, here it includes output of the changes in each commit. This is even more useful when a path is provided:
$ git log -p README.md
commit d7918f4a9b74a44aa9d665b5860db76914615f89
Author: zefeng <zefengbao@outlook.com>
Date: Sun Mar 29 22:18:15 2020 +0800
chore: npm link more directly (#18428)
diff --git a/README.md b/README.md
index a2635458c..d890a3782 100644
--- a/README.md
+++ b/README.md
@@ -16,7 +16,7 @@ React has been designed for gradual adoption from the start, and **you can use a
* [Add React to a Website](https://reactjs.org/docs/add-react-to-a-website.html) as a `<script>` tag in one minute.
* [Create a New React App](https://reactjs.org/docs/create-a-new-react-app.html) if you're looking for a powerful JavaScript toolchain.
-You can use React as a `<script>` tag from a [CDN](https://reactjs.org/docs/cdn-links.html), or as a `react` package on [npm](https://www.npmjs.com/).
+You can use React as a `<script>` tag from a [CDN](https://reactjs.org/docs/cdn-links.html), or as a `react` package on [npm](https://www.npmjs.com/package/react).
## Documentation
This is useful for tracking down when or how a particular file changed over time.
Patched git-add
Another great use of the patch flag is with git add
:
$ git add -p
diff --git a/packages/eslint-plugin-react-hooks/__tests__/ESLintRuleExhaustiveDeps-test.js b/packages/eslint-plugin-react-hooks/__tests__/ESLintRuleExhaustiveDeps-test.js
index c82042839..9322952fa 100644
--- a/packages/eslint-plugin-react-hooks/__tests__/ESLintRuleExhaustiveDeps-test.js
+++ b/packages/eslint-plugin-react-hooks/__tests__/ESLintRuleExhaustiveDeps-test.js
@@ -369,6 +369,20 @@ const tests = {
}
`,
},
+ {
+ code: normalizeIndent`
+ function MyComponent({myEffect}) {
+ useEffect(myEffect, [,myEffect]);
+ }
+ `,
+ },
+ {
+ code: normalizeIndent`
+ function MyComponent({myEffect}) {
+ useEffect(myEffect, [,myEffect,,]);
+ }
+ `,
+ },
{
code: normalizeIndent`
let local = {};
Stage this hunk [y,n,q,a,d,e,?]?
When the -p
flag is provided to git add, changes are displayed for interactive
staging. This is useful when you make many changes without making commits along
the way. You can effectively group changes into commits based on the effect,
resulting in a clean, easy-to-follow git history for posterity. Which is what
everyone wants and needs.
Other uses
The patch flag can also be used with git-checkout
and git-reset
.
Checkouts are useful to pull changes from a branch (for example, a spike branch)
into a feature branch when you want to make the changes permanent. You can event
git checkout -p stash@{0}
to checkout from a stash!
Patch can be used with git reset to reset staged changes that you do not want to
commit at this time. Or it can be used for partial --soft
and --hard
resets.
Trick #3: Travel through time with the reflog
Often times when working through some git issue with a less experienced developer, I’ll tell them that with git, we are safe. While there are several safety mechanisms within git to help you from losing your work, reflog is one that I find useful on a regular basis.
The reflog is a log of changes to the ref for git’s head
pointer. When you
change the location of HEAD with git commands like checkout
, commit
, and
reset
, the change is pushed into the reflog. Take the following example:
$ git co -b git-tricks
Switched to a new branch 'git-tricks'
$ git commit --allow-empty -m "An empty commit"
[git-tricks 92ef2ba] An empty commit
$ git reflog
92ef2ba (HEAD -> git-tricks) HEAD@{0}: commit: An empty commit
7ed0f97 (origin/master, origin/HEAD, master) HEAD@{1}: checkout: moving from
master to git-tricks
The branch checkout and commit are now in the reflog.
Reflog locations can be used as refs for commands like checkout
and reset
.
This can be useful after a botched rebase:
$ git rebase -i head~4
[ ... your bad rebase occurs ]
$ git reflog
6387db45d (HEAD) HEAD@{0}: commit (amend): Fox spelling (#19084)
d4fc2c145 HEAD@{1}: rebase -i: fast-forward
30b47103d HEAD@{2}: rebase -i (start): checkout HEAD~4
090c6ed75 (origin/master, origin/HEAD, master) HEAD@{3}: reset: moving to
origin/master
You can use the commit hash or reflog entry to simply git-reset --hard
back to
the latest safe point:
$ git reset --hard HEAD@{3}
HEAD is now at 090c6ed75 [eslint-plugin-react-hooks]: handling sparse array when no-inline callback (#19145)
And now your head
is now back to a clean state!
Trick #4: Easy branch renaming
This is a quick one. If you don’t like the name of your branch, simply rename it with:
git branch -m your-new-branch-name
Trick #5: Automatic remote branch creation with push.default
Usually, when you go to push a new branch, the following message is printed:
$ git push
fatal: The current branch git-tricks has no upstream branch.
To push the current branch and set the remote as upstream, use
git push --set-upstream origin git-tricks
You can tell git to automatically set this upstream with the following update to your git configuration:
$ git config --global push.default current
Now, when you run git push
from a new branch, the remote branch is created and
the code successfully pushed:
Counting objects: 9, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (8/8), done.
Writing objects: 100% (9/9), 3.09 KiB | 3.09 MiB/s, done.
Total 9 (delta 2), reused 0 (delta 0)
remote: Resolving deltas: 100% (2/2), completed with 2 local objects.
remote:
remote: Create a pull request for 'git-tricks' on GitHub by visiting:
remote: https://github.com/benjaminbergstein/blog/pull/new/git-tricks
remote:
To github.com:benjaminbergstein/blog.git
* [new branch] git-tricks -> git-tricks
Conclusion
There are 5 tricks for improving your everyday git workflow! Hope you found this useful.