Typical Git Workflow
- Clone a remote repository
- Create a branch with a name to commit any changes that you plan to make in your local workspace
- Commit your changes to the branch. It is also possible to have multiple commits or squash several commits into one commit.
- Tag your commit, if needed.
- Rebase your branch with master branch to resolve any possible merge conflicts. Merge conflicts may appear in your branch when other people may have introduced additional changes to the files which you had modified as part of your work.
- Push your branch to the remote repository
- Create a pull request so that others can review your changes. If you receive any comments from the reviewers, you might need to make additional commits to incorporate reviewers feedback and push your changes to your branch.
- When the pull request is approved, you are allowed to merge your branch into the master branch so that your changes are made available to other people.
General Configuration
User details
git config --global user.name "<user name>"
git config --global user.email "<user@email.com>"Aliasing Git commands
Aliases are used to create shorter commands that map to longer commands. Aliases enable more efficient workflows by requiring fewer keystrokes to execute a command.
git config --global alias.co checkout
git config --global alias.br branch
git config --global alias.ci commit
git config --global alias.st statusDefault configuration for future merge conflicts
git config --global merge.conflictstyle diff3Cloning
Clone a remote repository
git clone <repository-URL>Clone a remote repository and checkout to a specific branch.
git clone -o <user-defined-remote-name> -b <branch-to-checkout> \
<http[s|]ssh|git|ftp[s]>://<repository-url> <directory>
git clone --origin enzyme --branch gh-pages --progress \
git@github.com:airbnb/enzyme.git enzymeClone a bare Git repository.
git clone --bare git@github.com:lodash/lodash.gitDon’t clone any tags
git clone git@github.com:lodash/lodash.git --no-tagsNOTE: Cloning into an existing directory is only allowed if the
Staging and Unstaging
Add file(s) to staging area
git add <file-name-1> ... <file-name-n>Remove file(s) from working tree and from staging area This will not remove file(s) from working directory
git rm <file-name(s)>Snapshotting
Commit file change(s) added to staging area
git commit -m <commit-message>Change the most recent commit The command lets you combine staged changes with the previous commit instead of creating an entirely new commit.
git commit --amendUndo most recent commit
git reset --soft HEAD~1Remove most recent commit
git reset --hard HEAD~1Revert a recently made upstream commit
git revert HEAD~Revert a recently made merge commit
git revert -mRecover a removed commit
git reflog
git checkout -b <branch-name> <commit-ID-which-was-removed>Pulling
fetch, which downloads the changes from your remote repo but does not apply them to your code.merge, which applies changes taken fromfetchto a branch on your local repo.pull, which is a combined command that does afetchand then amerge.
# pull = fetch + merge
git checkout <branch>
git fetch
git merge
# pull changes to a specific branch
git pull <remote> <branch>
# pull rebase
git pull --rebaseSharing
force push to master branch (if remote allows it)
git push [-f/--force] origin masterForce push to only one branch
git push origin +<branch-name>Inspecting
git status -sbwhat you had in your branch before the merge
git diff --ours -bwhat was on their side
git diff --theirs -bhow a file has changed from both sides
git diff --base -bsee tag data along with commit information
git show <tag-name>git ls-filesyour repository will be back to the last committed state
git reset --hard HEADLogging
full list of all of the unique commits that were included in either branch involved in a merge
git log --oneline --left-right HEAD...MERGE_HEADgit log --graph --oneline --decorate --allwhen you need information on the history of a file
git log --merge --decorate --source -p path/to/file/you/care/aboutre-checkout file and replace merge conflict markers with ours, base and theirs
git checkout --conflict=diff3 <filename>Stashing
Store away your workspace
git stash save "<stash-name>"Re-apply stored workspace
git stash apply "<stash-name>"Delete stored workspace
git stash drop "<stash-name>"Cleaning
clear out extra files created due to merge but no longer need
git clean -fdBranching
Create a new local branch and push it upstream
git checkout -b <branch-name>
git push --set-upstream origin <branch-name>
git push -u origin <branch-name>Check if commit exists in your local branch
git branch -a --contains <commit-id>Rename your local branch
git branch -m <old-branch-name> <new-branch-name>Rename remote branch
git push <remote-name> :<old-branch-name> <new-branch-name>
git push origin -u <new-branch-name>Tagging
Create a new tag
git tag -a <tag-annotation> -m <tag-name>Tag a commit
git tag -a <tag-annotation> <commit-ID>Push a tag to upstream repository
git push origin <tag-name>Push all tags to upstream repository
git push origin --tagsCheckout to tag (Detached HEAD mode)
git checkout <tag-name>Create a branch from a tagged commit and checkout to the branch
git checkout -b <brach-name> <tag-name>Merging
Merge one branch into another
git checkout <target-branch>
git merge <source-branch>Dealing with Merge Conflicts
There are three kinds of conflicts:
- File deleted and changed Use modified or deleted file?
- File deleted and created Use created or deleted file?
- File changed both locally and remotely Start merge tool.
Four versions of the same file: | Base | The latest version of the file that exist in both repositories | | Local | The latest local version of the file | | Remote | The latest remote version of the file | | Merged | The result of the merge |
Rebasing
Use rebase to update your branch with the latest changes from the main branch.
Squashing
With rebase, you can condense the changes made in a set of commits down to one single commit. Squashing is useful to clean up the commit history before they are pushed to a remote branch.
git rebase -i HEAD~2
---
pick eb45fef Updated app.js
squash 01843df Updated README.mdCherry-Picking
Use cherry-pick to copy commits from one branch to another. Cherry-pick only brings the changes from the commits you select, instead of all the changes in a branch. With cherry-pick, you can pick a set of commits from the main branch (e.g. master) without rebasing your branch with the main branch.
git checkout <branch>
git cherry-pick <commit-id> # pick a commit from another branchPatching
git format-patch master --stdout > patch--001.patch
git checkout <branch>
git am patch-001.patchDebugging
Use git blame to determine which commit and committer was responsible for lines in a file.
git blame -L 23,15 README.mdEveryday Git
git clonefrom an upstream repository to your local workspace repository.git checkoutto discard changes in local workspace.git checkoutand git-branch to switch branches.git addto manage the file in staging area/index.git diffand git-status to see what you are in the middle of doing.git committo advance the current branch.git resetand git-checkout (with pathname parameters) to undo changes.git cherry-pickto choose a commit from one branch and apply it onto another.git mergeto merge between local branches.git rebaseto maintain topic branches.git revertto undo botched commits.git tagto mark a known point.git pullandgit fetchfrom "origin" to keep up-to-date with the upstream.git request-pullto create a summary of changes for your upstream to pull.git pushto publish your changes to shared repository.git format-patchto prepare and send suggested alternatives to contributors via e-mail submissiongit send-emailto send your e-mail submission without corruption by your MUA.git amto apply patches e-mailed in from your contributors.
Glossary
- Repository - a virtual storage of your project
- Downstream - when you copy (clone, pull, etc.) from a repository
- Upstream - when you send your changes to a repository
- Tree - represents a particular directory state of a working directory
- Commit Tree - repesents a commit object with zero or more number of parent commits. With no commit as parent, a commit will be a root commit. With a single parent, a commit will be an ordinary commit. With more than one parent, a commit will be a merge commit.
- Commit - a snapshot or changeset, represents the state of a working directorry in "time", and explains how to get there
- HEAD - a reference (ref) to the currently checked out commit
- Staging Area - a file which stores information about what will go into your next commit
- Working Directory or Tree - workspace
- History rewriting commands - checkout, reset, revert