What is Git?
Git is a distributed version control system that has become essential for software engineers and developers worldwide. It allows you to track changes in your codebase, collaborate with others, and maintain different versions of your project.
Key benefits of using Git:
- Version Control: Keep track of all changes made to your code over time.
- Collaboration: Easily work with others on the same project without conflicts.
- Branching: Create separate lines of development for new features or experiments.
- Backup: Store your code securely on remote servers.
- Open Source: Contribute to and benefit from the vast ecosystem of open-source projects.
Real-world example: Imagine you're working on a web application. You want to add a new feature, but you're not sure if it will work well. With Git, you can:
- Create a new branch for the feature
- Develop and test the feature without affecting the main codebase
- If it works, merge it back into the main branch
- If it doesn't, discard the branch without any impact on your stable code
This workflow allows for safe experimentation and easy collaboration with team members.
Installing Git
Windows
- Download the installer from the official Git website.
- Run the installer and follow the installation wizard.
Open Command Prompt or Git Bash to verify the installation:
git --version
macOS
Verify the installation:
git --version
Install Git using Homebrew:
brew install git
Install Homebrew if you haven't already:
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
Linux (Ubuntu/Debian)
Verify the installation:
git --version
Install Git:
sudo apt install git
Open Terminal and update your package index:
sudo apt update
After installation, configure your Git identity:
git config --global user.name "Your Name"
git config --global user.email "your.email@example.com"
Basic Git Commands
Git Init
To initialize a new Git repository in your project directory:
cd /path/to/your/project
git init
This creates a new .git
subdirectory in your project folder, which contains all the necessary metadata for the repository.
Example scenario:
mkdir my_new_project
cd my_new_project
git init
echo "# My New Project" > README.md
git add README.md
git commit -m "Initial commit: Add README"
Git Status
To check the status of your repository:
git status
This command shows you which files have been modified, which are staged for commit, and which are untracked.
Example output:
On branch main
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: src/main.py
Untracked files:
(use "git add <file>..." to include in what will be committed)
docs/
Git Add
To stage changes for commit:
# Stage a specific file
git add filename.txt
# Stage all changed files
git add .
# Stage all files with a specific extension
git add *.js
# Interactively stage parts of files
git add -p
The -p
option allows you to interactively choose which changes to stage, which is useful for creating clean, logical commits.
Git Commit
To commit your staged changes:
git commit -m "Your descriptive commit message"
For more detailed commit messages, omit the -m
flag to open your default text editor:
git commit
Best practices for commit messages:
- Keep the subject line concise (ideally under 50 characters)
- Use the imperative mood (e.g., "Fix bug" instead of "Fixed bug")
- Describe what was changed and why
- Separate subject from body with a blank line
- Wrap the body at 72 characters
Example of a good commit message:
Implement user authentication
- Add login and registration forms
- Set up JWT token-based authentication
- Create protected routes for authenticated users
- Update tests to cover new authentication flow
Closes #123
Working with Remote Repositories
Git Remote
To connect your local repository to a remote GitHub repository:
git remote add origin https://github.com/username/repository.git
To view your remote repositories:
git remote -v
To change the URL of an existing remote:
git remote set-url origin https://github.com/new-username/new-repository.git
Git Push
To upload your local commits to GitHub:
git push -u origin main
The -u
flag sets up tracking, so you can simply use git push
in the future.
For force pushing (use with caution):
git push --force origin feature-branch
Git Pull
To fetch and merge changes from the remote repository:
git pull origin main
This is equivalent to running git fetch
followed by git merge
.
To pull changes with rebasing instead of merging:
git pull --rebase origin main
Git Clone
To download a remote repository to your local machine:
git clone https://github.com/username/repository.git
To clone a specific branch:
git clone -b feature-branch https://github.com/username/repository.git
To clone with a different name for the local directory:
git clone https://github.com/username/repository.git custom-directory-name
Branching and Merging
Git Branch
To create a new branch:
git branch feature-branch
To list all branches:
git branch
To list all remote branches:
git branch -r
To delete a branch:
git branch -d feature-branch
Git Checkout
To switch to a different branch:
git checkout feature-branch
To create and switch to a new branch in one command:
git checkout -b new-feature-branch
To discard changes in a file and restore it to the last committed state:
git checkout -- filename.txt
Git Merge
To merge changes from one branch into another:
git checkout main
git merge feature-branch
For a non-fast-forward merge with a commit message:
git merge --no-ff -m "Merge feature-branch into main" feature-branch
Resolving Merge Conflicts
When Git can't automatically merge changes, you'll need to resolve conflicts manually:
- Open the conflicting file(s) in your text editor.
- Look for conflict markers (
<<<<<<<
,=======
,>>>>>>>
). - Edit the file to resolve the conflict.
- Remove the conflict markers.
Complete the merge:
git commit -m "Resolve merge conflict between feature-branch and main"
Stage the resolved file:
git add resolved-file.txt
An example of a conflict in app.py
:
<<<<<<< HEAD
def greeting():
return "Hello, World!"
=======
def greeting(name):
return f"Hello, {name}!"
>>>>>>> feature-branch
To resolve this, you might choose to keep the feature branch version:
def greeting(name):
return f"Hello, {name}!"
Then stage and commit the resolved file.
GitHub Features
Forking
Forking creates a personal copy of someone else's project on GitHub. To fork a repository:
- Navigate to the repository on GitHub.
- Click the "Fork" button in the top-right corner.
Use cases for forking:
- Contributing to open-source projects
- Using someone's project as a starting point for your own
- Proposing changes to someone else's project
Pull Requests
To submit a pull request (PR) on GitHub:
- Create a new branch with your changes.
- Push the branch to your forked repository.
- Navigate to the original repository on GitHub.
- Click "Pull requests" > "New pull request".
- Select your fork and the branch containing your changes.
- Fill out the PR description and create the pull request.
Best practices for PRs:
- Keep them small and focused on a single issue or feature
- Provide a clear description of the changes and their purpose
- Reference any related issues
- Include tests for your changes
- Be responsive to feedback and make requested changes promptly
GitHub Codespaces
GitHub Codespaces provides a cloud-powered development environment:
- Navigate to your repository on GitHub.
- Click the "Code" button.
- Select "Open with Codespaces".
- Click "New codespace" to create a new environment.
Benefits of Codespaces:
- Consistent development environment across team members
- Quick setup for new contributors
- Access your development environment from any device with a web browser
- Seamless integration with GitHub features
Undoing Changes
Git Reset
To undo staged changes:
git reset HEAD filename.txt
To undo commits:
# Soft reset (keep changes, unstage commits)
git reset --soft HEAD~1
# Mixed reset (keep changes, unstage commits and modified files)
git reset --mixed HEAD~2
# Hard reset (discard changes and commits)
git reset --hard HEAD~3
Example scenario: You've made three commits but realize the last two were a mistake.
# View the commit history
git log --oneline
# Reset to the desired commit, keeping the changes in your working directory
git reset --mixed HEAD~2
# Make changes and create a new commit
git add .
git commit -m "Combine previous work into a single, correct commit"
Git Revert
To create a new commit that undoes a previous commit:
git revert commit-hash
Example:
# View commit history
git log --oneline
# Revert a specific commit
git revert abc1234
# Push the revert commit
git push origin main
Git Commit --amend
To update the last commit message:
git commit --amend -m "New commit message"
To add files to the last commit:
git add forgotten-file.txt
git commit --amend --no-edit
Note: Avoid amending commits that have already been pushed to a shared repository, as it can cause conflicts for other contributors.