Git Overview
Git main site: git-scm.com/
Git GUI: Visual Studio Code and various others
Purpose
- To save snapshot/ commit
- Version control
- Collaborating on same file/project at the same time
- Splitting production and development code
- For example: having the main branch be the production code
- The side branch will be for current development where testing and changes can be done without affecting production build
- Once changes are done, then the side branch can be merge with the main one (through pull requests) and then delete the side branch
Git Concepts
The 4 Levels of Git
- Remote repo level: the central location of the repo
- Git Providers: GitHub, GitLab, GitBucket
- Local repo level: a copy of the repo on the local computer including any local changes made to it
- Local repo use push/pull to synch changes with remote repo
- Stage area level: the area where changes to the files/folders are made before being commited to the local repo
- Local folder level: the development code on the computer
Branches
Create a copy of same code in main repo to work on without affecting the main branch
- Use to make changes without affecting the production code (i.e. main branch)
- Example: create a branch to fix a bug/ add feature, and once it's done, commit and push it to the remote repo branch, and do a pull request to have it merged with the main one
You can only have one copy of the repo locally; if the repo have multiple branches, switching branches will change the local folders to match that branch
- i.e. Only one branch of a repo can exist in the local folder at a time
HEAD
The HEAD is the pointer to the commit you're currently working on.
- When switching branch, it will move to the last commit in that branch
- When switching branch and the branch is new, it's just a copy of the previous branch, but it's pointing to the lastest commit of the new branch
Key Files
git/: folder that has local git settings.gitconfigfile.gitconfig: global git setting file, usually in the User folder.git/config: local git setting file, in the local repo location.gitignorefile : file in repo root that tells git what to ignore by listing out the files/folders in it, like log fileslogs/will ignore everything in logs folderlog.txtwill ignore the file log.txtlogs/*.txtwill ignore all .txt files inside the log folder.gitkeepfile : git ignores empty folder, so dev use this to make git recognize an empty folder by putting a.gitkeepfile in there
Common Git Commands
git add .|filename: add all/filename changes to the staging areagit commit -m message: commit changes in staging area to local repo and tag the commit with the message- Message standard: describe changes, be in present tense, and max of 50 characters
git clone URL: clone the repo from the specified URL into the current directorygit push/pull: sync changes between local and remote repogit status: view overview of changesgit log: give history of repogit log --grep searchTerm: search through loggit log --oneline: display concise log format with only commit id and message on one linegit restore .|filename: undo changes in staging areagit revert commitId: revert the changes to the commit with the id- git does not delete history, but will add on to it by stating the changes that reverted the repo
Good Commands for Debugging
git stash: save any uncommited changes in the staging areagit stash pop: load the uncommited changes you saved back to the staging areagit switch branchName: switch to another branch, branchName, and move the current HEAD to point to the branch's last commitgit switch -c newBranch: create and switch to new branch, but since it's a new branch, it copies the main branch and all the commits you've done so fargit merge sourceBranch: merge current branch with source branchgit branch newBranch: create new branch without switching to itgit reset --hard HEAD~x|Head~commitHash: revert the current branch by 'x' commits or to the commitHashgit log --oneline: display concise log format with only commit id and message on one linegit revert commitHash: revert the changes to the commit with the idgit cherry-pick commitHash: copies the commit changes from commitHash to the current branch, but does not revert it in the old branch
Tagging
Tagging is used to mark the commits in a repo history, usually to mark releases (v1.0, v1.1, v2.0)
git tag tagName commitHash: create a lightweight tag with the name tagName for the commitHashgit tag -a tagName -m "message" commitHash: create an annotated tag that allow us to add a message to the tag (more commonly use)git tag -ln: list tag with their annotationsgit tag -ln "v1.*": filter tag so only version 1 tags are showngit tag --delete tagName: delete the tag with the name tagNamegit push origin tagName: push a tag to the remote repo because tags are not pushed by defaultgit push origin --tags: push all tags to the remote repogit fetch: fetch commits and tags
Merge Conflicts
GitHub docs: link
GitLab docs: link
Wrong Branch
- If working on the wrong branch and did NOT commit the changes yet:
- Do the following and continue working on the correct branch
- If the correct branch doesn't exist yet then replace the second line with
git switch -c correctBranch - If working on the wrong branch and commited the changes 1 time, but did NOT push the changes:
- Do the following and continue working on the correct branch
- reset --soft Head^ will reverse the commit and put the changes back into the staging area
- If working on the wrong branch and commited many changes, but did NOT push the changes:
- Do the following and continue working on the correct branch
- Now the commits are on the new branch, and you can merge it with the correct branch if it exist already
- If working on the wrong branch and you already pushed the changes:
- Switch to the wrong branch, view the
git log,git reversethe commits; then switch to the correct branch andgit cherry-pick the right commits - Now the commits are on the correct branch, and you can continue with your code
git stash
git switch correct-branch
git stash applygit reset --soft HEAD^
git switch correct-branch
git commit -c ORIG_HEADgit stash # skip if all changes are committed
git branch new-branch # create the new branch but does not switch to it
git reset --hard origin/main # reset current (wrong) branch to match the remote main
git switch new-branch # switch to correct branch
git stash pop # skip if all changes were committedgit switch wrong_branch
git revert commitHash1
git switch right_branch
git cherry-pick commitHash1Git Commands Table
Editing files / folders
| Command | Description |
|---|---|
git status | Show changed files, staged changes, and branch info. |
git add <file> | Stage a file's changes for the next commit. |
git add -p | Interactively stage hunks from files. |
git restore <file> | Discard unstaged changes in a file (restore from last commit). |
git restore --staged <file> | Unstage a file (remove from index but keep working changes). |
git checkout -- <file> | Old form to discard changes in a file (use git restore now). |
git mv <old> <new> | Rename or move a file (stages the change). |
git rm <file> | Remove a file and stage its deletion. |
Branches
| Command | Description |
|---|---|
git branch <name> | Create a new branch pointing at the current commit (does not switch). |
git switch <name> | Switch to an existing branch. |
git switch -c <name> | Create a new branch and switch to it (shortcut for create+switch). |
git merge <branch> | Merge another branch into the current branch (creates a merge commit unless fast-forward). |
git rebase <base> | Reapply commits on top of <base> (rewrites history of the current branch). |
git branch -d <name> | Delete a branch (safe: only deletes if merged). |
git branch -D <name> | Force-delete a branch even if unmerged (dangerous). |
git push origin --delete <name> | Delete a remote branch. |
Staging area & commits
| Command | Description |
|---|---|
git add <file> | Stage file changes (put changes into the index for the next commit). |
git restore --staged <file> | Unstage a file (remove it from the index). |
git commit -m "msg" | Create a commit from staged changes with message "msg". |
git commit --amend | Amend the most recent commit (modify message or add new staged changes). |
git reset --soft <commit> | Move HEAD to <commit> but keep staged and working changes. |
git reset --mixed <commit> | Move HEAD to <commit> and reset the index (unstage changes) but keep working files. |
git reset --hard <commit> | Move HEAD to <commit> and reset index + working tree (discard changes). |
git stash | Save uncommitted changes to the stash stack and clean the working directory. |
git stash pop | Apply the latest stash and remove it from the stash list. |
git stash apply | Apply a stash but keep it in the stash list. |
Repository management (remote & history)
| Command | Description |
|---|---|
git init | Create a local repo in the current directory |
git clone <url> | Clone a remote repository to your local machine. |
git remote add origin <url> | Add a new remote repo and give it the alias origin. |
git remote add <name> <url> | Add a new remote reference. <name> is an alias (origin is commonly used), not the name of the repo |
git remote -v | List remotes and their URLs. |
git fetch | Download commits, refs, and objects from remote without merging. |
git pull | git fetch then merge (or rebase) remote changes into current branch. |
git push | Upload local branch commits to the remote. |
git log | Show commit history for the current branch. |
git reflog | Show local history of HEAD movements (useful to recover lost commits). |
git tag <name> | Create a lightweight tag pointing at current commit. |
git push --tags | Push local tags to the remote. |
git gc | Run garbage collection to optimize repository storage (housekeeping). |