Git

Source Control

Git is a tool to track changes in a working directory(repository), a perfect tool to control the version of developement in local enviroment. While GitHub is an online repository platform allowing developers to save, share and deploy codes online.

Online Git Platform

GitHub

GitLab

BitBucket

FeatureGitHubGitLabBitbucket
Free ReposUnlimitedUnlimitedLimited to 5 users
CI/CDGitHub ActionsBuilt-inPipelines
Self-HostingNoYesYes
IntegrationWidely supportedGitLab-exclusiveAtlassian tools
Best ForOpen-source projects, team collaborationEnterprises and teams focused on DevOps workflowsTeams using Atlassian tools

Workflow and Concept

Three trees maintained by git

  1. Working Directory: to be added to Index
  2. Index(staging area): to be commited to HEAD
  3. HEAD: a current pointer in branch

origin: default name of remote repository when cloned, main: mainline branch of project, master: legacy name of main. To make different code from main branch, ALWAYS create a new branch and merge after completion. Checkout switches working directory to the target branch.

Getting Started

git init    # Create git repository
git add .   # Stash
git commit -m "Initial Commit Message"

Branching and Merging

# Create a branch
git branch <branch_name>
# Move to a branch
git checkout <branch_name>
# Create and switch to new branch
git checkout -b <branch_name>
# Delete unused branch
git branch -d <branch_name>

# Merge HEAD to a branch
git merge <branch_name>

Rebase moves entire branch in HEAD to begin on the tip of a branch. It is better for a cleaner linear history. But are not suitable for beginer and collaboration.

git rebase <branch_name>

Detach is a way to move a HEAD to previous commit.

git checkout <commit_id>
# Move to the parent of branch_name
git checkout <branch_name>^
# Move to the second parent of branch_name
git checkout <branch_name>^2
# Move to the n-th parent of branch name
git checkout <branch_name>~n

# Force the first branch to the parent of second branch. Unable to work on current branch. The moved branch will lost it's commit
git branch -f <branch_name> <branch_name>^

Reset reverse the changes by moving a branch to its parent. But it only works on local. While revert reverse the change, it will add a new commit so that the branch is now the same as its previous parent. This is recommended for collaborative work.

git reset HEAD~1
git revert HEAD

If there was unresolvable merge, git will show the conflict. Edit the files to resolve conflict.

# After resolving conflict
git add <filename>
# Preview before merging
git diff <source_branch> <target_branch>

# Cherry-pick picks the commits to be added into HEAD
git cherry-pick <commit1> <commit2>
# Interactive rebase: pick the arrangement of a branch into a new branch
git rebase -i HEAD~4
git rebase <destination_branch> <source_branch>

Pushing and Pulling

# Fetch and merge remote changes to stay synced
git pull
# Remove references to branches that no longer exist on the remote
git fetch --prune
git pull --rebase

# Update a remote branch
git push origin <branch_name>
# Update all remote branch
git push --all origin
# Delete a remote branch
git push origin --delete <branch_name>

Tagging

Tags for software release. The code is the first 10 characters of commit id. View log for commit id details.

git tag 1.0.0 1b2e1d63ff

Logging

git log
git log --author=bob
git log --pretty=oneline
git log --graph --oneline --decorate --all
git log --name-status
git log --help

Replace local changes

# Replace these files into previos update
git checkout -- <filename>
# Forget local and use newest from server
git fetch origin
git reset --hard origin/master

Hints

# built-in git GUI
gitk
# use colorful git output
git config color.ui true
# show log on just one line per commit
git config format.pretty oneline
# use interactive adding
git add -i

Reference: git-guide Visual Tutorial: Learning Git

GitHub

To use GitHub, create a repository on Github and copy the repository link https://github.com/username/repository.git.

git remote add origin https://github.com/username/repository.git
git push -u origin master

GitHub repository have its own branch based on GitHub users. On each branch of user, the repository have its own branch. After a user fork a GitHub repository, that user can open a Pull Request to merge the fork back to the original branch and is to be reviewed by the original author.

Git on VS Code

VS Vode comes with a pre-built git UI system. It will detect a git repository on the opened folder and display on Source Control. Here are some common functions:

  1. Click commit and insert the message to update graph tree. Conflict resolver will appear automatically if needed.
  2. Create and checkout branch on More Action...
  3. Press Fetch From All Remotes and click SYNC to update to latest remote repository

Alternately, Git Graph extension is also quite intuitive and easy to manage git visually.