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