Everything Great About Git
Last updated: Mar 28, 2020
IMAGE GALLERY (1)
How to read git diff output?
diff --git a/content/blog/everything-great-about-git.md b/content/blog/everything-great-about-git.md
index 18123c7..00c8696 100644
--- a/content/blog/everything-great-about-git.md
+++ b/content/blog/everything-great-about-git.md
@@ -7,3 +7,3 @@ series:
- myLearning
-categories:
+categories:
- development
@@ -14,4 +14,25 @@ tags:
- bisect
+- diff
---
- Old/original file
- new file version being diffed to
100644
means that it is ordinary file and not e.g. symlink, and that it doesn’t have executable permission bit- Symbols used for both files
- the original file, starting on line 7
- has 3 lines before this diff was applied.
+
A line was added here to the first file.-
A line was removed here from the first file.- start of new hunk
@@ -start,count +start,count @@
git-flow
workflow, set of guidelines
How to view git diff
git diff
Shows the changes between the working directory and the index. This shows what has been changed, but is not staged for a commit.
git diff --cached / --staged
Shows the changes between the index and the HEAD (which is the last commit on this branch). This shows what has been added to the index and staged for a commit.
git diff HEAD
Shows all the changes between the working directory and HEAD (which includes changes in the index). This shows all the changes since the last commit, whether or not they have been staged for commit or not.
git diff myfile.txt
- If you want to see what you haven’t git added yet:
git diff --cached myfile.txt
- or if you want to see already added changes
Another exciting use-case is to check for leading and trailing whitespaces in your file
git diff --check
Check whitespaces only on python files
$ git diff --name-only HEAD~1 HEAD | grep \.py$ | \
$ xargs git diff --check HEAD~1 HEAD --
git bisect - debugging code for culprit commit
- use
git bisect
to find out when was bug was introduced? - At what time was the code still good?
- Uses binary search to drill down to bad commit
- it accepts feed backs good|bad before presenting the culprit commit
git bisect start
git bisect terms
git bisect bad <commit-id>
git bisect next (y)
git bisect good <commit-id>
git bisect log
git bisect visualize
git bisect reset
git merge vs git rebase1
- git merge introduced all commits from the feature branches2 into master with a special merge commit.
- what if? we want all the changes done in a branch as a single commit to master
git merge --squash
followed by agit commit
- goal of both merge and rebase is to put commits from feature to master branch
- git merge takes all the commits and adds them to master in a single merge commit
- rebase moves all the commits from branch on top to master branch
- rebase preserves the order of commit
- Both of these commands are designed to integrate changes from one branch into another branch—they just do it in very different ways.
- This creates a new “merge commit” in the feature branch that ties together the histories of both branches, giving you a branch structure that looks like this:
- feature branch will have an extraneous merge commit every time you need to incorporate upstream changes
- If master is very active, this can pollute your feature branch’s history quite a bit
- Follow the golden rule of rebasing
git merge --squash <feature>
# update your feature branch with changes from master before working
git checkout feature
git rebase master -i
Rebase - rewrite history
- Amend last/previous commits -
git commit --amend --no-edit
- reword older commit messages -
git rebase -i HEAD~3
to operate on last 3 commit messages. Changepick
toreword
- delete commit messages -
git rebase
and then changepick
todrop
- Reorder commit messages - run
rebase
adn change order of commits in interactive mode - Squash commit messages -
rebase
and usefixup
orsquash
- split commit messages - use
edit
thengit reset HEAD^
to unstage files and then stage/commit them in the order you want.
git checkout -b working-on-backup-branch
git rebase -i master
pick SHA <older commit message>
squash SHA <older commit message>
squash SHA <older commit message>
- rebase current branch on master. Rebase will compute diff for each commit and add it to master incrementally.
- squash 2 commit messages into the first one. Might take a while, as git recalculates everything when rewriting history.
Git Hooks
Allows us to run custom scripts whenever certain important events occur in the Git life-cycle, such as committing, merging, pushing etc3.
Some use-cases which could be achieved using hooks4
- trigger emails before commits
- Respond to a commit event by firing a code-linting job before committing
- pre to prevent the event on failure
- post to respond to a event
- prevent commit if your name and email are incorrect
Git hook sample already under /.git/hooks
directory
- /.git/hooks
- update.sample*
- applypatch-msg.sample*
- commit-msg.sample*
- fsmonitor-watchman.sample*
- post-update.sample*
- pre-applypatch.sample*
- pre-commit.sample*
- prepare-commit-msg.sample*
- pre-push.sample*
- pre-rebase.sample*
- pre-receive.sample*
Sample OSM commit-msg hook file
Save hooks in your dot-files. carry them with you wherever you go
Global hooks
Reuse your hooks in every project
git config --global core.hooksPath /path/to/global/hooks
git hooks use-cases
- Linting - Check the quality of the code before committing
- Auto generate documentation as changes are uploaded
- Spell checks
pre-commit hook checklist
- are relevant files added
- are irrelevant files removed from staging
- Review untracked files
- Would you like to lint
- Would you like to spellcheck
Work on multiple branches?
git worktree
- separate checkout in a different directory
- cheaper
- shared objects and config
How to get changes from master?
git checkout <branch>
git rebase master
How to generate and apply patches
# PATCH GENERATE
git diff 2 1 > mypatch.diff
git format-patch -1 <sha>
git format-patch -1 HEAD
# PATCH APPLY
git apply ../0001-Update-mender-artifact-number-and-add-wt-as-runtime-.patch