- Configuring git
- Introduction
- Working with git
- Git branching
- Git Diff
- Stashing
- Undoing changes
- GitHub
- Fetch and pull
- Git collaboration workflows
- Rebasing
- Git tags
- Git behind the scenes
- Reflog
- Git aliases
- Need to set the name and email of the user
git config --global user.name "<name>"
git config --global user.email "<email-id>"
# Creating a git repository, At the top level folder containing the project
git init
# Checking the status for git repository
git status
# See the logs
git log
# or
git log --oneline
git add file1 file2
# or
git add . # stage all changes at once
git commit -m "<inline-message>"
- Amending commits: Redoing the previous commit
git commit -m "commit-msg"
git add file1
git commit --amend # modifies the prev commit to include file1
- Writing commit messages: Follow present tense imperative style eg. Add feature 1
- Atomic commits
- Ignoring files: .gitignore
- Stucture of git commits
- Branches: Useful for segregating multiple contexts
- Head
- Viewing all branches
git branch
git branch -v # to view more info
git branch <branch-name>
git switch <branch-name> # newer
# or
git checkout <branch-name> #older
# switch to new branch while also creating it
git switch -c <branch-name>
Note: Untracked files follow the head to wherever it goes while if we have some changes in tracked files and we try to switch branches then git gives us an error
- Deleting branch
- Switch to some other branch as cannot delete the branch at which we are currently checked out
git branch -d <branch-name>
# or
git branch -D <branch-name> #delete a branch which is not fully merged; Shortcut for -df (--delete --force)
- Renaming branch
- Switch to branch you want to rename
git branch -m <new-branch-name>
- Merging branches
git diff #shows changes between the staging area and working directory
git diff HEAD #lists all changes in the working directory since the last commit; staged + unstaged changes
git diff --staged #shows diff between the staging area and the last commit; "Show me what will be included in my commit if I run git commit right now"
# OR
git diff --cached
# diff-ing particular files
git diff HEAD <filename>
# OR
git diff --staged <filename>
# diff-ing branches
git diff branch1..branch2
# diff-ing commits
git diff commit1..commit2
- Switching from one branch to another:
git stash list # View the list of stashes
git stash
# OR
git stash save # Saves all the uncommited changes to the stash; Doesn't includes the untracked files
git stash -u # Saves all the uncommited files including the untracked files to stash
git stash pop # Removes the most recently stashed changes in your stash and re-apply them to your working copy.
git stash apply # applies whatever is in the stash to the current branch without deleting it from the stash
# OR
git stash apply <stash-name> # Applies a particular stash
git stash clear # Deletes all the stashes
# OR
git stash drop <stash-name> # Deletes a particular stash
- Detached HEAD
- In detached head state we can do following things: - Stay in detached HEAD to examine the contents of the old commit. Poke around, view the files, etc - Leave and go back to wherever you were before - reattach the HEAD - Create a new branch and switch to it. You can now make and save changes, since HEAD is no longer detached.
# git checkout: Used to create branches, switch to new branches, restore files, and undo history
git checkout <commit-hash> # Detached head statte
git switch <branch-name> # Reattach the head
git checkout HEAD~1 # Previous commit
git checkout HEAD~2 # (Head - 2)th commit
git switch - # Switch to the last branch we were on
git checkout HEAD <filename> # Discard any changes in the file and make the match the content of the file at HEAD
# OR
git checkout -- <filename> # Discard any changes in the file
git restore <filename> # Discard any changes in the file and make the match the content of the file at HEAD
git restore --source <commit-hash> <file-name> # Discard any changes in the file and make the match the content of the file at the commit
git restore --staged <filename> # Remove a file from the staging area
git reset <commit-hash> # Soft reset; Removes the commits but keeps the changes
git reset --hard <commit-hash> # Hard reset; Removes the commits as well as changes
- Git revert
- Both git reset and git revert help us reverse changes, but there is a significant difference when it comes to collaboration. If you want to reverse some commits that other people already have on their machines, you should use revert. If you want to reverse commits that you haven't shared with others, use reset and no one will ever know!
- Github is a hosting platform for git repositories. You can put your own Git repos on Github and access them from anywhere and share them with people around the world. Beyond hosting repos, Github also provides additional collaboration features that are not native to Git (but are super useful). Basically, Github helps people share and collaborate on repos.
- Cloning
- Git will retrieve all the files associated with the repository and will copy them to your local machine.
git clone <repo-url>
# View remotes
git remote -v
# OR
git remote
# Adding a new remote
git remote add <name> <url> # name is just a label or alias for a particular remote
# removing a remote
git remote remove <name>
# renaming a remote
git remote rename <old-name> <new-name>
# pushing the code to remote
git push <remote> <branch>
# pushing a local branch to a different remote branch
git push <remote> <local-branch>:<remote-branch>
# setting upstream of a branch
git push -u <remote> <branch>
# View remote references
git remote -r
git remote -r # list all remote branches
# track a remote branch via a local branch
git switch <remote-branch-name> # makes a local branch AND sets it up to track the concerned remote branch
# OR
git checkout --track <remote>/<branch-name>
# Fetching
git fetch <remote>
git fetch <remote> <branch>
git fetch # updates the list of remote branches
# Run it from the branch where you want to merge the pulled changes
git pull <remote> <branch>
- Centralized workflows
- The simplest collaborative workflow is to have everyone work on the master branch (or main, or any other SINGLE branch).
- Issues
- Lots of time spent resolving conflicts and merging code, especially as team size scales up.
- No one can work on anything without disturbing the main codebase. How do you try adding something radically different in? How do you experiment?
- The only way to collaborate on a feature together with another teammate is to push incomplete code to master. Other teammates now have broken code...
- Feature branches
- The workflow
- Fork and clone: Another workflow
# Cleaning history
git switch feature # switch to branch which is to be rebased
git rebase master # the branch on whom to rebase
# Interactive rebase
git rebase -i <commit-hash> # inplace rebasing
# eg. git rebase -i HEAD~9
git tag # List all tags
git tag -l "<pattern>" # List all tags satisfying the pattern
git checkout <tag-name> # To checkout at a particular tag
git tag <tag-name> # Create a lightweight tag, By default, Git will create the tag referring to the commit that HEAD is referencing
git tag -a <tag-name> # Create annotated tags
# OR
git tag -a <tag-name> -m <message>
# OR
git tag <tag-name> <commit-hash> # Tagging previous commits
git tag -f <tag-name> # Forcing the reuse of a used tag
git tag -d <tag-name> # Deleting a tag
# By default, the git push command doesn’t transfer tags to remote servers.
git push --tags # Transfer all of your tags to the remote server that are not already there.
echo hello | git hash-object --stdin # Just spits out the hashed value without writing anything to .git directory
echo hello | git hash-object --stdin -w # write the content of the input in .git/objects folder
git cat-file -p <object-hash> # Takes the stored file in the .git/objects directory and converts it back to the original file; -p is for pretty print
# Viewing trees
git cat-file -p master^{tree} # master^{tree} syntax specifies the tree object that is pointed to by the tip of our master branch
git cat-file -t <commit-hash> # type of git object