Git Practical Beginner's Guide
All articles from this blog can ONLY be redistributed on an Attribution-NonCommercial-NoDerivs basis. Please credit the source, thank you.
Twitter:@kelvinshen
Blog:Kelvin Shen's Blog
Branching Strategy/Model/Flow
GitFlow is a popular git flow strategy. It is a solid start point and can work with CI/CD flows well.
Source: https://datasift.github.io/gitflow/IntroducingGitFlow.html
Theory
Stages
Changes in a git repository can potentially in the following stages:
Indexed -> Staged -> Committed -> Pushed or Pulled to remote
Concept: HEAD
HEAD means the current branch. To check where the HEAD is point, you can use the following command.
Unix style command
cat .git/HEAD
OR
Windows style command
type .git/HEAD
Scenarios
Get the latest code from an existing remote branch
The fetch command is for getting the latest of repo’s branch structure. For example, if your colleagues have commited and pushed new branches.
git fetch
git switch "target-branch"
git pull
Even better, you can do the following.
git pull origin source-branch-name
git pull origin master #for example, do this on the target branch
However, I got burnt with the following command. Because it didn’t prompt for conflicts, and left a lot of rubbish in my code base.
git merge origin source-branch-name
Create new branch
git switch -c "feature/[feature-name]"
The git checkout commend is retiring.
git checkout -b "feature/[feature-name]"
Undo indexed changes
git clean
git clean -df #remove untracked directories and files.
Undo staged changes
git checkout -- .
Reset - Undo commited changes with reset
The following command set is for undo the latest commit and it will also keep the change at your local repo unstaged.
git add .
git commit -m "yolo"
git push
git reset --soft HEAD~1
git commit -m "maybe not"
git push
Rebase
The following command will go to the head of the origin/main branch. Then apply all commits from the “feature/yolo” branch on the top.
git switch feature/yolo
git rebase origin/main
WorkTree
This is a very useful command. It allows you to have multiple branches available locally in parallel. So you can multitask or compare code in different branches.
git workfree add [local file path] [git branch name]
git worktree add "../yolo" feature/yolo
git worktree remove feature/yolo
Rename your branch
git checkout <old_name>
git branch -m <new_name>
git push origin -u <new_name>
git push origin --delete <old_name>
Reference(s)
https://linuxize.com/post/how-to-rename-local-and-remote-git-branch/
Revert a commit already pushed to a remote repository
“People generally avoid history rewiriting, for a good reason: it will fundamentally diverge your repository from anyone who cloned or forked it. People cannot just pull your rewritten history as usual. If they have local changes, they have to do some work to get in sync again; work which requires a bit more knowledge on how Git works to do it properly.”
Reference(s)
https://christoph.ruegg.name/blog/git-howto-revert-a-commit-already-pushed-to-a-remote-reposit.html
tag
Deployment https://stackoverflow.com/questions/18216991/create-a-tag-in-a-github-repository
stash
Scenarios
You are working on a feature branch and your team lead asked your to fix a bug with urgency. So you need to stash you current work and switch context.
# your are working on new features on branch A
# Save WIP changes
git stash
git swith bugfixes/branch-b
# fix bugs in the branch b
git stash pop
Scenario: Stash your work with meaningful comment.
I recommend stage this way over the default git stash
git stash save "remove semi-colon from schema"
git stash list
git stash pop stash@{2}
Other useful git stash parameters
git stash save --keep-index #All changes already added to the index (staged) are left intact
git stash save --keep-index --include-untracked
git stash --all #stash untracked files and ignored files.
git stash drop
Reference(s)
https://opensource.com/article/21/4/git-stash
switch vs checkout
git switch “branch-name” = git checkout “branch-name”
git restore “path-to-a-file” = git checkout “path-to-a-file”
git switch command parameters
-c, --create <branch> #create and switch to a new branch
-m, --merge #perform a 3-way merge with the new branch
push
The following three commands are doing the same thing. the “-u” parameter name stands for upstream.
git push -u origin feature/yolo
git push -u origin
git push
remote prune
Scenario: remove the local branches that are not on the remote any more.
git branch -vv #Check local remote branches mapping
git branch -r #List all remote branches
git remote prune origin
Scenario: delete all local branches that are already merged into master
git branch --merged main | grep -v '^[ *]*main$' | xargs git branch -d
Local Git Repository Configuration
Why Configure user.name and user.email?
These settings are crucial for identifying who contributes to a Git repository’s commits. This is particularly important in open-source projects where proper attribution is essential. While it’s technically possible to fake this information, technical measures (like commit signing) and legal frameworks exist to protect authenticity.
Repository-Specific Configuration
If you work on multiple projects across platforms, each with different aliases or email addresses, configuring these settings per repository is essential. This ensures that each commit is correctly attributed to the right identity.
To configure user.name and user.email for a specific repository, navigate to the repository’s root directory and execute:
cd /path/to/your/repository
git config user.name "Your Name"
git config user.email "your.email@example.com"
Replace “Your Name” and “your.email@example.com” with your actual name and email address for that repository.
How to configure the settings globally
To set a default name and email for all repositories on your system, use the following commands:
git config --global user.name "Your Name"
git config --global user.email "your.email@example.com"
Reference(s)
https://stackoverflow.com/questions/13064613/how-to-prune-local-tracking-branches-that-do-not-exist-on-remote-anymore
Tools
Fork
A light weight tool and great for visualization.
Pretty Prompt
How to setup
Please check out this brilliant article from almighty Scott Hanselman.
Prompt status abbreviation explained
The local branch is behind
The local branch is ahead
The merge conflict
Committed and pushed
PoshGit
I couldn’t say better than Phil Haack. So here is a link to his PoshGit blog post.
References
Sources
What is Git HEAD? https://stackoverflow.com/questions/10228760/how-do-i-fix-a-git-detached-head https://stackoverflow.com/questions/2304087/what-is-head-in-git
How to check current HEAD? https://stackoverflow.com/questions/25879039/cat-git-head-command-in-windows
What is the difference between soft and hard reset? https://stackoverflow.com/questions/3528245/whats-the-difference-between-git-reset-mixed-soft-and-hard/3528483#3528483