Add Configuration
$ git config [--local | --global | --system] user.name 'your_name'
$ git config [--local | --global | --system] user.email 'your_email@domain.com'
Check configuration
$ git config --list [--local | --global | --system]
Clear configuration
$ git config --unset [--local | --global | --system] user.name
Domain:
`--local`: local repo
`--global`: all user's repo
`--system`: all system's users
Clear configuration
$ git config --unset [--local | --global | --system] user.name
Initiate a project
$ git init
# if there is a project $ git init project_name
# if no project Add files
$ git add [.|-A|--all]
# add modified or deleted or new files $ git add -u
# add modified or deleted files Commit
$ git commit -m 'initial commit'
$ git branch -M main
# specify a branch Push to the remote repo
$ git remote -v
# check remote origin $ git remote add origin git@your_git_server:your_group/your_project.git
$ git push -u origin main
$ git push origin main
# add to remote main branch $ git push
# add to same remote branch Rename
$ git mv readme readme.md
Check files and history
$ ls -al
$ git status
$ git help log
$ git help --web log
$ git log
# log of current branch$ git log --oneline
# simplified$ git log -n4 --oneline
# latest four records$ git log -n2 --oneline
# latest two records$ git branch -v
# number of branches $ git log --all
# log of all branches $ git log --all --graph
# log of all branches in a graph$ git log --oneline --all
$ git log --oneline --all -n4
$ git log --oneline --all -n4 --graph
$ gitk
# check log on GUICheck or modify .git
$ cat .git/HEAD
# HEAD: the directory of current branch$ cat .git/config
# core and user config info$ cat .git/refs
# there are heads and tags files$ cat .git/refs/heads
# there are files for all branchesThree objects of git: commit, tree, blob
Detached HEAD
Any commit that is not on any branch will easily be discarded when switching to other branch. If any change is important, make sure that it is on a branch by running :
$ git checkout newbranch ace1ed38
On the other hand, detached HEAD can be used to test new ideas. Failed changes could be discarded
by reset
. Successful changes could be retained by running the same code.
HEAD
Compare difference between two commits
$ git diff 38a92bss ace1ed38
HEAD^1
or HEAD~1
: the parent of HEAD
HEAD^1^1
or HEAD~2
: the grandparent of HEAD
$ git diff HEAD HEAD^1
$ git diff HEAD HEAD~1
$ git diff HEAD HEAD^1^1
$ git diff HEAD HEAD~2
Delete Branches
$ gitk --all
# check in advance $ git branch -v
# check in advance $ git branch -av
# check in advance $ git branch -d ace1ed38
# if failed use -D to force deletion $ git branch -D ace1ed38
$ git branch -d fix_readme
$ git branch -D fix_readme
Change Commit Messages
Change the latest commit message.
$ git commit --amend
# change message using vi Change old latest commit messages (git rebase
uses detached HEAD).
$ git rebase -i 42924305b
$ git log --graph
# check the change Change first commit message (no parent commit).
$ git rebase -i --root
As a result, the commit hash and children commit hash will be changed.
Combine Commits
If the commits are continuous.
$ git rebase -i ace1ed38
$ git log --graph
# check the change
If the commits are intermittent. Put those commits together.
Reset the merge.
$ git reset --hard HEAD^
Compare Difference
HEAD <===> Stage
$ git add index.html
# add file to the stage $ git diff --cached
# check the difference of a file in HEAD and stage $ git diff --cached -- readme.md
$ git commit -m'Changes'
# commit the file
Workplace <===> Stage
$ git add index.html
# add file to the stage $ git diff
# check all the difference $ git diff -- readme.md
# check a specific file $ git diff -- readme.md styles/style.css
# check specific files
Workplace <===> HEAD
$ git diff HEAD -- readme.md
Compare difference in all files between two branches
$ git branch -av
# check and find commit ID $ git diff temp master
Compare difference in a specific file between two branches:
$ git branch -av
# check and find commit ID $ git diff temp master -- index.html
Recover:
Recover all files from stage to HEAD. After `add` to stage, you want to unstage the file to HEAD, while keep the changes in the workplace intact:
$ git reset HEAD
# recover all files from stage to HEAD [unstage] $ git diff --cached
# check there should be no change --soft
: Does not touch the index file or the working tree at all but resets the head
to `commit`. --mixed
: the changed files are preserved but not marked for commit. This is the default
action. --hard
: Resets the index and working tree. Any changes to tracked files in the working
tree since `commit` are discarded. $ git reset [--soft | --hard | --mixed] [commit]
Recover specific files from stage to HEAD.
$ git reset HEAD -- style/style.css readme.md
Recover from workplace to stage: Discard the changes in the workplace and recover to the stage version.
$ git checkout -- index.html
$ git diff index.html
# check difference between workplace and stage $ vi index.html
# check the content
Cancel Commits
The following command cancels some recent commits (and their changes) and go back to the
specified previous commit '5bf3fd100'. Note that --hard
is dangerous since it
cancels new changes in the file.
$ git reset --hard 5bf3fd100
Delete file
$ git rm index.html
Stash
If you want to save incomplete work to stage and do something else, after that you want to get back previous incomplete work and continue the work.
$ git stash
# workplace => stage $ git stash apply
# stage => workplace, delete it in stage $ git stash pop
# stage => workplace, preserve it in stage
Backup to local place
$ git clone --bare /Users/dizhen/git/.git ya.git
$ git clone --bare file:///Users/dizhen/git/.git zhineng.git
$ git remote -v
# check whether there is a remote repo $ git remote add zhineng file:///Users/dizhen/git/.git zhineng.git
$ git push --set-upstream zhineng di
Config SSH key
Find detail instruction of adding new SSH key on GitHub.
$ ls -al ~/.ssh
# check whether there is SSH key $ ssh-keygen -t rsa -b 4096 -C "your_email@email.com"
$ cat ~/.ssh/id_rsa.pub
# find token, copy and paste it to GitHub account
Create a repo
$ git remote -v
# check $ git remote add github git@github.com:git/git_learning.git
$ git push github --all
# error, need to fetch first $ git fetch github master
# fetch remote files to local $ git branch -va
# check local and remote branch $ git merge github/master
# merge branches, error due to unrelated history $ git merge --allow-unrelated-history github/master
# merge branches so that
they have the same parent $ git push github master
# no error
Make change on remote branches
Note that we cannot use `git clone` and modify branches. We can only create local branch based on
remote branch and create commits, using git checkout -b ...
$ git branch -av
# check branches $ git checkout -b feature/add_git_commands origin/feature/add_git_commands
#
create a new branch "feature/add_git_commands" based on old branch "origin/feature/add_git_commands"
$ git add readme.md
$ git commit -m 'add description'
$ git push
# now the new branch can be pushed to the repo and related to the old
branch "origin/feature/add_git_commands" When pushing into a branch on a repo, if there is a problem of "updates were rejected because the remote contains work that you do not have locally." we solve by
$ git push github
# error of not fast forward $ git fetch github
$ git branch -av
# note that there can be "07c85df [ahead 1, behind 1]" $ git merge github/featrue/add_git_commands
$ git push github
# no error Make changes to different files
Note that we cannot use git clone
and modify branches. We can only create local
branch based on remote branch and create commits, using git checkout -b ...
.
$ git branch -av
# check branches $ git checkout -b feature/add_git_commands origin/feature/add_git_commands
#
create a new branch "feature/add_git_commands" based on old branch "origin/feature/add_git_commands"
$ git add readme.md
$ git commit -m 'add description'
$ git push
# now the new branch can be pushed to the repo and related to the old
branch "origin/feature/add_git_commands" When pushing into a branch on a repo, if there is a problem of "updates were rejected because the remote contains work that you do not have locally." we solve by
$ git push github
# error of not fast forward $ git fetch github
$ git branch -av
# note that there can be "07c85df [ahead 1, behind 1]" $ git merge github/featrue/add_git_commands
$ git push github
# no error
Make different changes in a file
$ git pull
# synchronize remote to local (update local to be same as remote)
$ git branch -av
# check branches $ git push
# could be an error if local and remote are not the same or someone
has just changed sth before you push $ git fetch
# [ahead 1, behind 1] $ git merge origin/feature/add_git_commands
# "fetch + merge" can be replaced by
"pull", but "fetch" first can see the different before sync $ git branch -av
# check now should be [ahead 2] $ git push
Make a change in a file at the same position
$ git merge github/feature/add_git_commands
# Already up to date... $ git pull
# since there is difference between local and remote. but error
appears since both local and remote are changed $ git commit
$ git push github
Others change file name and content
$ git pull
# deal with this issue automatically