Everything Great About Git
Last updated: Mar 28, 2020
IMAGE GALLERY (1)
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
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 --
- 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
- 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.
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
- 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
git checkout <branch>
git rebase master
# 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