There are several ways to revert a Git repo to a previous commit. Here are the most common approaches:
## Method 1: Using `git revert` (Recommended for shared branches)
This creates new commits that undo the changes, preserving history:
```bash
# Revert a single commit
git revert <commit-hash>
# Revert multiple commits (creates separate revert commits)
git revert <oldest-commit>..<newest-commit>
# Revert multiple commits as one commit
git revert --no-commit <oldest-commit>..<newest-commit>
git commit -m "Revert multiple commits"
# Push to remote
git push origin <branch-name>
```
## Method 2: Using `git reset` (Use with caution on shared branches)
This actually moves the branch pointer back:
```bash
# Soft reset (keeps changes staged)
git reset --soft <commit-hash>
# Mixed reset (keeps changes unstaged) - default
git reset --mixed <commit-hash>
# Hard reset (discards all changes)
git reset --hard <commit-hash>
# Force push to remote (DANGEROUS if others are using the branch)
git push --force-with-lease origin <branch-name>
```
## Method 3: Create a new commit that matches a previous state
```bash
# Reset to previous commit but don't move HEAD
git reset --soft <commit-hash>
git reset --mixed HEAD
# Or use checkout to get files from a specific commit
git checkout <commit-hash> -- .
git add .
git commit -m "Revert to state at <commit-hash>"
# Push normally
git push origin <branch-name>
```
## Which method to choose?
- **Use `git revert`** if:
- The branch is shared with others
- You want to preserve history
- You're working on main/master branch
- **Use `git reset`** if:
- You're working on a private branch
- You want to rewrite history
- You're okay with force-pushing
- **Use the checkout method** if:
- You want the safest approach
- You want to create a clear "revert" commit
## Example workflow:
```bash
# 1. Find the commit hash you want to revert to
git log --oneline
# 2. Revert (using git revert - safest method)
git revert abc1234
# 3. Push to remote
git push origin main
```
**Important**: Always use `--force-with-lease` instead of `--force` when force-pushing, as it's safer and won't overwrite others' work.