Git Mastery

A collection of notes and references

Published: 6/20/2025
# List tracked files
git ls-tree -r main --name-only
# List files modified since most recent commit
git status -s
# List files modified in most recent commit:
git diff --name-only HEAD~0 HEAD~1
#List branches [all | local | remote]:
git branch -a
git branch -l
git branch -r
# Delete a local branch
git branch -D branchName
# Delete a remote branch
git push origin -d branchName
git remote add origin git@github.com:<path/to/repo>.git
git branch -M main
git push -u origin main

git pull --force

# Downloads the latest from the remote
git fetch origin

# Makes local branch exactly match the remote branch
git reset --hard origin/main
git rm -r --cached . && git add .
git log --oneline --graph --all
* 66e3e7d (HEAD -> main) 3rd commit
* 6733ccf Second commit
* 10555c8 Init

Let’s rename Second commit to 2nd commit.

git rebase -i HEAD~2
  1. Navigate to the commit (using arrows)
  2. Press i to enter interactive mode
  3. Edit pick to reword
  4. Press CTRL+C to exit interactive mode, followed by :wq to save and exit (or :q! to exit without saving)
  5. (Next screen) Edit the message
  6. CTRL+C, then :wq

Need to abort the rebase? git rebase --abort

git log --oneline --graph --all
* fbb8fc8 (HEAD -> main) 3rd commit
* 2c92099 2nd commit
* 10555c8 Init

What if we try to push it to remote?

git push
To some-remote-repo.git
 ! [rejected]        main -> main (non-fast-forward)
error: failed to push some refs to 'some-remote-repo.git'

How to push rebased history to remote

Squash a commit (into the previous one).

git log --oneline --graph --all
* a6b64be (HEAD -> main) 4th commit
* d6470d7 3rd commit
* fad02a1 2nd commit
* 10555c8 Init

Let’s delete 3rd commit.

git rebase -i HEAD~3
  1. Navigate to the commit (using arrows)
  2. Press i to enter interactive mode
  3. Edit pick to squash
  4. Press CTRL+C to exit interactive mode, followed by :wq to save and exit (or :q! to exit without saving)
  5. (Next screen) Edit the message
  6. CTRL+C, then :wq
# This is a combination of 2 commits.
# This is the 1st commit message:

2nd and 3rd commit

# Please enter the commit message for your changes. Lines starting
# ...

Need to abort the rebase? git rebase --abort

git log --oneline --graph --all
* d0b28da (HEAD -> main) 4th commit
* 6b7002e 2nd and 3rd commit
* 10555c8 Init

What if we try to push it to remote?

git push
To some-remote-repo.git
 ! [rejected]        main -> main (non-fast-forward)
error: failed to push some refs to 'some-remote-repo.git'

How to push rebased history to remote

After rebasing, the commit history has changed. To update the remote main branch, you have two options.

If you’re working alone on the branch, you can safely overwrite the remote:

git push --force-with-lease

--force-with-lease is safer than --force, as it aborts if the remote has unexpected changes.

If you’re working with others, avoid rewriting main directly.

Instead, do your rebasing on a feature branch, then merge.

This way, main remains stable, and collaborators aren’t affected by rebased history.

# Start a new branch for your work
git checkout -b fix-commit-history

Perform the rebase.

# Push it to remote
git push origin fix-commit-history

Then open a Pull Request (or):

# Merge your clean history back into main
git checkout main

# --ff-only works for linear commit histories, allowing merge without requiring a commit
git merge --ff-only fix-commit-history
git push

A fast-forward only works if main is strictly behind fix-commit-history, no extra commits, no divergence.

Without adding a commit.

# Push feature branch
git push origin <branch-name>
git checkout main
# Merge with fast-forward only (no merge commit)
git merge --ff-only <branch-name>
git push origin main
git push origin --delete <branch-name>
# List files staged/unstaged
git status

# Unstage a file
git restore --staged <path/to/file>
# Reset file to last committed version (discard unstaged changes)
git restore <path/to/file>
# Reset file to a specific commit
git checkout HEAD~1 -- <path/to/file>