• Home
  • About
  • Notes
  • Projects
<- Back to notes
notestools9/23/2025

Git Commands Reference

Personal reference notes for git commands I frequently use

1. status

  • untracked -> staged -> committed : (add .) -> (commit -m <MESSAGE>) -> (push)

2. log

  • shows all commits and their hashes
  • --no-pager, -n <NUM>
  • --decorate=full|short|no
  • --oneline
  • --graph
  • -p -> shows changes made in commit

3. cat-file -p <HASH>

  • shows contents of the commit
  • file -> blob, dir -> tree
  • so if I want to see actual contents of a file, i need to provide blob hash

4. config

  • --add <SECTION>.<KEY> <VALUE>
    • stored in .git/config
    • or I can use --global flag to be stored in $HOME/.gitconfig file
    • --get <SECTION>.<KEY>
[SECTION]
KEY = VALUE
  • '--list' flag shows all stored section.key-value pairs

5. branch <NEW BRANCH NAME>

  • branch is a pointer to a latest commit
  • 'switch -c <NEW BRAMCH NAME>' will create new branch and checkout to it
  • new branch starts from HEAD commit - if no commit, it will not diverge from its parent

6. merge <BRANCH NAME>

  • merge <BRANCH NAME> to the branch you are currently on
  • if branch tip diverged, new commit will be created then be merged (merge commit)
  • if branch tip did not diverge, child branch will just merge into its parent (fast-forward merge)
  • conflicts
    • whenever same file was changed from more than 2 different branches at the same time and tries to merge them, conflict occurs.
    • git shows the files that conflicts occured, marking <<< HEAD ===== >>> branch something like this
    • just deal with the conflicts then commit it again -> after committing it, branches will be merged automatically

7. rebase

  • 'replays' previous commits on feature(or child) branch -> enables fast-forward merge
  • think of this like moving feature branch tip to attach it after main branch tip
  • I can use 'checkout [--ours | --theirs] <FILENAME>' to resolve conflict like I do in merge but keep in mind that [--ours | --theirs] might work differently than in merge
    • or I can manually fix the file myself
    • when resolving a conflict, I will be on new temporary branch
    • after resolving the conflict, 'git add .' then 'git rebase --continue'

8. undo changes

  • going back to previous commits
  • git reset --soft <COMMIT HASH>
    • soft reset -> go back to commit but keep the changes
    • --soft HEAD~1 -> go back 1 commit from HEAD
  • git reset --hard <COMMIT HASH>
    • hard reset -> go back to commit and undo all changes
  • commit --amend -> allow to change last commit

9. remote

  • remote add <ORIGIN NAME> <URI>
  • fetch -> copies .git/objects (metadata files)
  • pull -> copying all files into local filesystem
  • I can still manage remote branches
    • git log <REMOTE NAME>/<BRANCH NAME>
    • git merge <REMOTE NAME>/<BRANCH NAME>

10. fork (only for github)

- forking a repo is copying other people's repo into my account
- this is how contributing to other's projects
- fork -> new branch -> make changes -> make pull request to original repo

11. reflog

- HEAD = pointer to the last commit in current branch
- "reference log" -> tracks all the changes i made on 'HEAD' (? not clear : i see this command shows all the commits i made and history of manipulating branches)
- in case i accidentally deleted files +) get commit hash from the reflog -> use cat-file -p to recover deleted contents
- same case +) or i can use 'merge <commitish>' where commitish means hash for branches, reflog entries, commits, tags, ... (in this case i could use HEAD@{1}, if HEAD@{1} was deleted)

12. checkout

- i thoghut this command was to move around between branches
- that too, but it also resolves conflicts
- checkout <--ours | --theirs>
  - --ours being keeping current branche's change, --theirs opposite

13. rerere (reuse recorded resolution)

- git config rerere.enabled [true | false]
- when enabled, git will record my resolution and will use it to automatically fix the same conflicts

14. squash commits into 1 commit

- git rebase -i HEAD~n (n being # of commits I want to squash, -i for interactive mode)
- above command will open up an editor -> choose squashing commits -> might need to revise the commit for squashing

15. stash

- temporarily save changes in "stack"
- stash list - shows list of the stash
- stash pop - pops last stash out of the stash entry (removed from entry)
- stash apply stash@{[index]} - apply stash without removing it from the entry
- stash drop stash@{[index]} - drops stash
- stash -m <MESSAGE> - stash with a message

16. revert <COMMIT HASH>

- reverts changes of the commit -> like reset but this one creates new commit to do this

17. diff

- shows difference between commits, working trees, and etc
- diff <COMMIT HASH1> <COMMIT HASH2>
- diff HEAD~1

18. cherry-pick

- only bring in a certain commit into current branch
- cherry-pick <COMMIT HASH>

19. bisect

- to find the commit that introduced a bug
- git bisect start
- git bisect bad <COMMITSH> & git bisect good <COMMITSH>
- keep marking result commit hashes until bisecting is done
- git bisect reset - ends bisecting
- after finding buggy commit, you can revert it back to that commit or something
- or "git bisect run <SCRIPT PATH>" to run automated bisecting - return 0 for good 1 for bad

20. worktree

- way to make a heavy footprint instead of stash
- it creates individual directory of a worktree in my filesystem
- any changes made in linked worktree will be visible in main worktree
- worktree add [PATH] [BRANCH NAME] - branch name is optional
- worktree remove [worktree name]
- worktree prune - removes all the pointers to a linked worktree
- worktree list

21. tags

- tags are named pointer to a commit and it cannot be modified
- git tag -> list all tags
- git tag -a [TAG NAME] -m "[any messages]" -> add tag to the latest commit