# Fix mistakes

## Fix the last commit

You committed too early, with the wrong message.

```bash
git commit --amend -m "Add contributing guide"
```

You also forgot a file. Stage it and fold it into the same commit.

```bash
git add CODEOWNERS
git commit --amend --no-edit
```

`--amend` rewrites the last commit, so only use it before you push. Once a commit is on a shared branch, rewriting it forces everyone else to reconcile their history with yours.

## Unstage a file

You staged a file you are not ready to commit.

```bash
git restore --staged notes.txt
```

The edit stays in your working tree. It is only no longer staged.

## Throw away changes to a file

You want to discard an edit you have not staged.

```bash
git restore notes.txt
```

The edit is gone. Git does not keep a copy of changes you never staged or committed.

## Undo the last commit, keep the work

You committed but want to change what is in the commit.

```bash
git reset --soft HEAD~1
```

`--soft` moves the branch pointer back one commit and leaves the changes staged, ready to commit again.

## Undo a commit that is already pushed

The commit is already on the shared branch, so rewriting it is not an option.

```bash
git revert HEAD
git push
```

`git revert` adds a new commit that undoes the old one. History stays intact, which is why it is safe on a branch other people have already pulled.

## Committed on the wrong branch

You meant to start a branch first, but committed on main instead.

```bash
git switch -c release-checklist
git switch main
git reset --hard origin/main
git switch release-checklist
```

Create the new branch before you reset main: it carries the commit forward, so resetting main afterward only removes the commit from main, not from anywhere.

## Get back a lost commit

You reset too far and a commit seems gone.

```bash
git reflog
```

`git reflog` lists every commit HEAD has pointed to on this machine, including ones no branch points to anymore.

```bash
git reset --hard HEAD@{1}
```

## Resolve a merge conflict

A teammate changed the same line of `notes.txt` you did, on main.

```bash
git merge origin/main
```

Git stops the merge and marks the conflict.

```bash
git status
```

```text
On branch release-checklist
You have unmerged paths.
  (fix conflicts and run "git commit")

Unmerged paths:
  (use "git add <file>..." to mark resolution)
	both modified:   notes.txt
```

`notes.txt` now contains both versions, separated by marker lines:

```text
<<<<<<< HEAD
Daily notes
=======
Weekly sync notes
>>>>>>> origin/main
```

Edit the file to keep what belongs, and delete the marker lines.

```bash
git add notes.txt
git commit
```

Git opens your editor with a prepared merge message; save and close it.

## Push after rewriting your own branch

You already pushed `release-checklist`, then amended the last commit.

```bash
git push -u origin release-checklist
git commit --amend -m "Add release checklist with rollback steps"
git push --force-with-lease
```

`--force-with-lease` refuses to push if the remote branch moved since you last fetched it, so it only overwrites history you know about. Use it only on a branch nobody else has built on, never on main.

Git basics is licensed under [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/): copy it, adapt it, keep the credit.
