HEAD and detached HEAD
HEAD
- when you checkout to a branch, git is pointing to the latest commit in that branch, which is the HEAD of that branch
Detached HEAD
- you can also checkout to a specific commit in any branch, when you do that, that commit becomes a detached HEAD, it doesn’t belong to any branch anymore.
- if you made some changes in the detached HEAD and commit it, it is better to create a new branch (which contains all the changes you made), before switching back to other branches, then you could merge the new branch into the master branch. Otherwise if you don’t create a new branch, the changes you made in detached mode will be lost.
Undo changes
git restore
- you could use
git restore <file-name>
orgit restore .
to revert all unstaged changes
git clean
- you could use
git clean -d
to delete new files (unstaged)
Undo staged changes
git restore --staged <file-name>
- this will copy the latest commited file to the staging area, which basically means it will revert all changes that currently are in the staging area now
Deleting commits
soft
git reset --soft HEAD~1
- commit will be deleted, changes will still be in the staging area
mixed (default)
git reset HEAD~1
- commit will be deleted, changes will be removed from the staging area, but the changes will still be in the working directory
hard
git reset --hard HEAD~1
- commit will be deleted, all changes will be removed from the staging area, the all changes will be removed from the working directory too
Stash
add current changes to Stash with a comment
git stash push -m "message"
see the list of stashed changes
git stash list
add changes back to unstaged state and remove from Stash
git stash pop <index>
add changes back to unstaged state but also keep it at Stash
git stash apply <index>
remove a particular stash from the list
git stash drop <index>
clear the entire stash list
git stash clear
Reflog
- allows us to bring back lost information, it could be commits or branches
- use
git reflog
you will see a list of commits for the last 30 days, even the commits you deleted, which can’t be found ingit log
. Then you could usegit reset --hard <commit hash code>
to retrieve lost commits
Merge
fast forward
- can only be used when no additional commit in master (after feature branch was created)
- MERGE moves HEAD forward to the latest commit but does not create new commit
fast forward with squash
git merge --squash <branch name>
- all commits you made in the feature branch will be combined into one new commit when you MERGE it to the master branch
- more specifically, when you use
--squash
, all the changes you made across all commits will be move to the staging area in the master branch.
recursive
- additional commits in both master and feature branch after feature branch was created
- additional commit is created in master branch when MERGE
- NOTE: when you use recursive MERGE, all commits either originated from the feature branch or the master branch, will be showing in the log history. But to revert the commit, you only need to revert for 1 step:
git reset --hard HEAD~1
- if you don’t want to see the commits from the feature branch to be display in your master git log history, you could use
--squash
with recursive MERGE
rebase
- when you have new commits for both master branch and feature branch (after you created the feature branch), you could use
rebase
to let the latest commit in master branch becomes the new base commit for commits created in feature branch - after
rebase
in the feature branch, all commits you made in the feature branch will have new commit code, even though the changes for these commits are the same. These might raise issues when working with others outside the repo because you will have different commit history
when to use rebase?
- you could use
rebase
when there is new commits in the master branch
why use rebase?
- feature branch relies on additional commits in the master branch, then you could rebase the master into feature branch
- feature branch is finished, you want to merge it into master without creating new merge commit
- you could first rebase master into feature branch
- then you could use fast-forward merge because now your master branch don’t have any new commits to your feature branch (because you rebased)
cherry-pick
- add a specific commit from feature branch to your master branch
- a new commit ID will be created, even though the commit content is the same
- useful when you want just a commit to be in your master branch, but you don’t want to merge the entire feature branch
Github
deleteing commits in github
- we could use
git reset --hard HEAD~1
to delete local commits - but when we use
git push
to push to remote git repo, it will fail because our local branch is behind the remote branch - we could use
git push --force origin master
to force push changes to remote repo, in this case the remote commits will be deleted.