Git basics and commands
Official documentation (Chinese): https://git-scm.com/book/zh/v2
This document is written based on official documents, and the official documents shall prevail.
Git basics
Git is divided into work area, staging area, and history area (version library).The workspace is added to the staging area through git add, and the staging area is added to the history area through git commit.
Initialize warehouse
# 本地目录初始化仓库
git initIf you clone the project from a remote repository, the project is an already initialized git repository.
Clone remote repository
#初始化一个版本仓库
git init
#Clone远程版本库
git clone git@xbc.me:wordpress.git
#添加远程版本库origin,语法为 git remote add [shortname] [url]
git remote add origin git@xbc.me:wordpress.git
#查看远程仓库
git remote -vWhen you clone a repository for the first time, all files in the working directory are tracked files and are in an unmodified state because Git has just checked them out and you have not edited them yet.
Global configuration
#配置使用git仓库的人员姓名
git config --global user.name "Your Name Comes Here"
#配置使用git仓库的人员email
git config --global user.email you@yourdomain.example.com
#配置到缓存 默认15分钟
git config --global credential.helper cache
#修改缓存时间
git config --global credential.helper 'cache --timeout=3600'
git config --global color.ui true
git config --global alias.co checkout
git config --global alias.ci commit
git config --global alias.st status
git config --global alias.br branch
git config --global core.editor "mate -w" # 设置Editor使用textmate
git config -1 #列举所有配置
#用户的git配置文件~/.gitconfig
git config --list 查看所有的git配置项的列表
git logCheck configuration information
git config --listFile operations
View, add, submit, delete, retrieve, reset modified files
git help <command> # 显示command的help
git show # 显示某次提交的内容
git show $id
git checkout -- <file> # 抛弃工作区修改
git checkout . # 抛弃工作区修改 注:会先从缓存区中拿内容,如没有则从历史区(版本库)中获取内容
git add <file> # 将工作文件修改提交到本地暂存区
git add . # 将所有修改过的工作文件提交暂存区
git rm <file> # 从版本库中删除文件
git rm <file> --cached # 从版本库中删除文件,但不删除文件
git reset <file> # 从暂存区恢复到工作文件
git reset -- . # 从暂存区恢复到工作文件 (可用于解决your branch is ahead of 'origin/dev' by 1 commit)
git reset --soft HEAD^ # 撤销你刚刚的commit操作,所有文件都还在
git resotre . # 撤销你刚刚的add的操作,所有文件都还在
git reset --hard # 恢复最近一次提交过的状态,即放弃上次提交后的所有本次修改
git reset --hard 版本号 # 回滚到任意一次
git commit <file>
git commit .
git commit -a # 将git add, git rm和git ci等操作都合并在一起做
git commit -am "some comments"
git commit --amend # 修改最后一次提交记录
git revert <$id> # 恢复某次提交的状态,恢复动作本身也创建了一次提交对象
git revert HEAD # 恢复最后一次提交的状态
# 仅仅只是撤销已提交的版本库,不会修改暂存区和工作区
git reset --soft 版本库ID 仅仅只是撤销已提交的版本库和暂存区,不会修改工作区
git reset --mixed 版本库IDView file diff
git diff <file> # 比较当前文件和暂存区文件差异
git diff
git diff <$id1> <$id2> # 比较两次提交之间的差异
git diff <branch> # 工作区和某分支对比
git diff <branch1>..<branch2> # 在两个分支之间比较
git diff --staged # 比较暂存区和历史区
git diff --cached # 比较暂存区和历史区
git diff --stat # 仅仅比较统计信息View submission history
git log
git log <file> # 查看该文件每次提交记录
git log -p <file> # 查看每次详细修改内容的diff
git log -p -2 # 查看最近两次详细修改内容的diff
git log --stat # 查看提交统计信息
git log --oneline --graph # 显示图
# tig可以让命令行可视化,在Mac上可以使用tig代替diff和log,brew install tiggit reflog can view all operation records of all branches.
Note
There is a bug in gitlib. If you submit the code directly after losing the code in git pull, the code will be lost.The code cannot be retrieved, even with git reflog.So when pulling code, you can use git pull --rebase instead of git pull.
Check file status
# 查看详细状态说明
git status
# 查看简明状态说明
git status -s # -s 或 --short
M README # 已修改,但未暂存 (M的位置靠右,红色)
MM Rakefile # 已修改,暂存后又作了修改(有暂存和未暂存)
A lib/git.rb # 新添加到暂存区,未提交
M lib/simplegit.rb # 已修改,已暂存 (M的位置靠左,绿色)
?? LICENSE.txt # 新添加,未跟踪The status of files in the git directory includes: whether it is tracked, whether it is modified, and whether it has been stored in the staging area.
parametric One horizontal bar represents an abbreviation, and two horizontal bars represent the full name.
Submit your changes
#添加当前修改的文件到暂存区
git add .
#如果你自动追踪文件,包括你已经手动删除的,状态为Deleted的文件
git add -u
#提交你的修改
git commit –m "你的注释"
#推送你的更新到远程服务器,语法为 git push [远程名] [本地分支]:[远程分支]
git push origin master
#查看文件状态
git status
#跟踪新文件
git add readme.txt
#从当前跟踪列表移除文件,并完全删除
git rm readme.txt
#仅在暂存区删除,保留文件在当前目录,不再跟踪
git rm –cached readme.txt
#重命名文件
git mv reademe.txt readme
#查看提交的历史记录
git log
#修改最后一次提交注释的,利用–amend参数
git commit --amend
#忘记提交某些修改,下面的三条命令只会得到一个提交。
git commit –m "add readme.txt"
git add readme_forgotten
git commit –amend
#假设你已经使用git add .,将修改过的文件a、b加到暂存区
#现在你只想提交a文件,不想提交b文件,应该这样
git reset HEAD b
#取消对文件的修改
git checkout –- readme.txt
# 将在工作空间但是不在暂存区的文件撤销更改
git restore <file>
# 将暂存区的文件从暂存区撤出,但不会更改文件
git restore --staged <file>ignore file
Add a file called .gitignore listing the patterns of files to ignore
*.[oa] # 忽略以 .o 或 .a 结尾的文件(一般这类文件是编译过程出现)
*~ # 忽略以 ~ 结尾的文件(一般是文本编辑软件保存的副本)The format specification of the file .gitignore is as follows:
All empty lines or lines starting with
#will be ignored by Git (comment symbol).Standard glob pattern matching can be used, which is applied recursively throughout the workspace.
A glob pattern refers to a simplified regular expression used by the shell
Matching patterns can start with (
/) to prevent recursion.The matching pattern can specify directories ending with (
/).To ignore files or directories outside the specified pattern, add an exclamation mark (
!) before the pattern to negate it.
- The asterisk (
*) matches zero or more arbitrary characters [abc]matches any character listed in square brackets (this example matches either an a, a b, or a c)- Question mark (
?) matches only one arbitrary character [0-9]means match all numbers from 0 to 9.Use a dash in square brackets to separate two characters, indicating that all characters within the range of these two characters can be matched.- Use two asterisks (
**) to match any intermediate directory. For example,a/**/zcan matcha/z,a/b/zora/b/c/z, etc.
# 忽略所有的 .a 文件
*.a
# 但跟踪所有的 lib.a,即便你在前面忽略了 .a 文件
!lib.a
# 只忽略当前目录下的 TODO 文件,而不忽略 subdir/TODO
/TODO
# 忽略任何目录下名为 build 的文件夹
build/
# 忽略 doc/notes.txt,但不忽略 doc/server/arch.txt
doc/*.txt
# 忽略 doc/ 目录及其所有子目录下的 .pdf 文件
doc/**/*.pdfGitHub has a very detailed database for dozens of projects and languages .gitignore file list, you can https://github.com/github/gitignore Find it.
View the specific content of the modification
git diff # 比较修改之后还没有暂存起来的变化内容。
git diff --staged # 查看已暂存的将要添加到下次提交里的内容git status can only view the status of file changes, but cannot view the specific content that has been modified.Use git diff to see the specific changes.
Submit update
git commit # 未带参数的会打开默认文本编辑器让你输入提交说明
git commit -m '提交说明' # 带-m参数直接输入提交说明Use git commit to submit updates. Before doing this, be sure to confirm that all changes have been added to the staging area by git add.
Skip using staging area
git commit -a -m '提交说明'Adding the -a option can skip the git add step and submit already tracked files together.
Note: this operation Unable to submit untracked file.
Git Basics - View commit history
git logBy default without passing in any parameters, git log will list all commits in chronological order, with the most recent updates at the top.
One of the data printed by this command is a long sequence of SHA-1 check codes.
bring in -p or --patch See the specific differences submitted:
git log -p -2 # -p显示差异 -2显示最近的提交次数--stat displays the difference statistics of each submission
git log --stat--pretty This option can display the commit history in a different format than the default
This option has some built-in sub-options for you to use.For example, oneline will display each commit on one line, which is very useful when browsing a large number of commits.There are also short, full and fuller options, which display information in basically the same format, but with different levels of detail:
$ git log --pretty=oneline
ca82a6dff817ec66f44342007202690a93763949 changed the version number
085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7 removed unnecessary test
a11bef06a3f659402fe7563abf99ad00de2209e6 first commitThe most interesting thing is format, which can customize the display format of records.Such output is especially useful for post-extraction analysis - because you know the output format will not change with Git updates:
$ git log --pretty=format:"%h - %an, %ar : %s"
ca82a6d - Scott Chacon, 6 years ago : changed the version number
085bb3b - Scott Chacon, 6 years ago : removed unnecessary test
a11bef0 - Scott Chacon, 6 years ago : first commitgit log --pretty=format Common options lists the common format placeholders accepted by format and their meanings.
When oneline or format with another log Options --graph Especially useful when used in combination.This option adds some ASCII strings to visualize your branch and merge history:
$ git log --pretty=format:"%h %s" --graph
* 2d3acf9 ignore errors from SIGCHLD on trap
* 5e3ee11 Merge branch 'master' of git://github.com/dustin/grit
|\
| * 420eac9 Added a method for getting the current branch.
* | 30e367c timeout code and tests
* | 5a09431 add timeout protection to grit
* | e1193f8 support for heads with slashes in them
|/
* d6016bc require time for xmlschema
* 11d191e Merge branch 'defunkt' into localGit basics - undo operations
After submitting, you find that you have forgotten to temporarily save some required changes. You can do this as follows:
$ git commit -m 'initial commit'
$ git add forgotten_file
$ git commit --amend # 重新提交,且只有一次提交记录Eventually you will only have one commit - the second commit will replace the results of the first commit.
For more undo operations, please learn about the reset command.
Git basics - use of remote warehouses
View remote warehouse
git remote # 仅显示远程仓库的名称
git remote -v # 显示远程仓库的名称 + 地址Add remote warehouse
git remote add <远程仓库名> <url>Crawl and pull from remote repositories
As you just saw, to get data from a remote warehouse, you can execute:
git fetch <remote>This command will access the remote repository and pull any data you don't have yet.Once the execution is complete, you will have references to all branches in that remote repository, which can be merged or viewed at any time.
Note: git fetch The command will only download the data to your local repository - It does not automatically merge or modify your current work .You must manually incorporate it into your job when ready.
git pullUse the git pull command to automatically fetch and merge the remote branch into the current branch.This may be a simpler and more comfortable workflow.By default, the git clone command automatically sets the local master branch to track the master branch (or the default branch by another name) of the cloned remote repository.Running git pull will usually grab the data from the originally cloned server and automatically try to merge into the current branch.
Push to remote warehouse
git push <remote> <branch> # git push origin masterView a remote warehouse
git remote show <remote> # git remote show originView the details of the remote repository.This command lists the remote branches that will be automatically pushed to when you perform git push on a specific branch.
Rename and remove remote repository
git remote rename <原名> <新名> # 重命名
git remote remove paul <remote># 移除远程仓库Git basics - tagging
list tags
git tag # 完整标签列表
git tag -l "v2.0*" # 只显示包含 v2.0 的标签。 注意加星号(*)Either -l or --list will work.
Create tags
Git supports two types of tags: lightweight tags (lightweight) and annotated tags (annotated).
A lightweight tag is much like a branch that never changes - it Just a reference to a specific commit 。
The annotation tag is a complete object stored in the Git database, and they can be verified. Contains the tagger's name, email address, date and time, and a tag information , and can be signed and verified using GNU Privacy Guard (GPG).It is often recommended to create note tags so that you have all of the above information.But if you just want to use a temporary label, or don't want to save the information for some reason, you can also use a lightweight label.
Notes label
git tag -a v1.4 -m "my version 1.4" # -a表示add, -m 表示附件信息You can see tag information and corresponding commit information by using the git show command:
git show v1.4lightweight tags
Lightweight tags essentially store commit checksums into a file - no other information is saved.To create a lightweight tag, you do not need to use the -a, -s or -m options, you only need to provide the tag name:
git tag v1.4-lw # 不需要添加选项At this point, if you run git show on the tag, you will see no additional tag information.The command will only display commit information:
$ git show v1.4-lw
commit ca82a6dff817ec66f44342007202690a93763949
Author: Scott Chacon <schacon@gee-mail.com>
Date: Mon Mar 17 21:52:11 2008 -0700Tag later
You can also tag past commits.Assume the commit history looks like this:
$ git log --pretty=oneline
166ae0c4d3f420721acbb115cc33848dfcc2121a started write support
9fceb02d0ae598e95dc970b74767f19372d61af8 updated rakefile
8a5cbc430f1a9c3d00faaeffd07798508422908a updated readmeNow, let's say that in v1.2 you forgot to tag the project, i.e. commit in the "updated rakefile".You can add labels later.To tag that commit, you need to specify the commit's checksum (or partial checksum) at the end of the command:
$ git tag -a v1.2 9fceb02 # 打的标签属于附注标签share tags
The git push command does not transfer tags to the remote repository server.After creating the tag you must explicitly push the tag to the shared server.The process is just like sharing a remote branch - you can run git push origin <tagname>.
git push origin v1.5 # 显式地推送标签到远程仓库
git push origin --tags # 一次性推送所有不在远程仓库上的标签Now, when others clone or pull from the repository, they can also get those tags of yours.
Delete tag
To delete a tag on your local repository, use the command git tag -d <tagname>.For example, you can delete a lightweight tag using the following command:
$ git tag -d v1.4-lw
Deleted tag 'v1.4-lw' (was e7d5add)Note that the above command does not remove the tag from any remote repository, you must use git push <remote> :refs/tags/<tagname> to update your remote repository:
The first variant is git push <remote> :refs/tags/<tagname> :
$ git push origin :refs/tags/v1.4-lw
To /git@github.com:schacon/simplegit.git
- [deleted] v1.4-lwThe meaning of the above operation is to push the null value before the colon to the remote tag name, thus effectively deleting it.
The second, more intuitive way to delete remote tags is:
$ git push origin --delete <tagname>Checkout tag
If you want to see the file version pointed to by a certain tag, you can use the git checkout command, although this will put your repository in a "detached HEAD" state - this state has some bad side effects:
$ git checkout 2.0.0
Note: checking out '2.0.0'.
You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.
If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:
git checkout -b <new-branch>
HEAD is now at 99ada87... Merge pull request #89 from schacon/appendix-final
$ git checkout 2.0-beta-0.1
Previous HEAD position was 99ada87... Merge pull request #89 from schacon/appendix-final
HEAD is now at df3f601... add atlas.json and cover imageIn the "detached head pointer" state, if you make certain changes and then commit them, the tags will not change, but your new commits will not belong to any branch, and will not be accessible except by the exact commit hash.So if you need to make changes, say you want to fix a bug in an older version, you usually need to create a new branch:
$ git checkout -b version2 v2.0.0
Switched to a new branch 'version2'If another commit is made after this, the version2 branch will be moved forward due to this change, and it will be slightly different from the v2.0.0 label, so be careful.
Git command aliases
Git doesn't automatically infer the command you want when you type part of it.If you don't want to type the full Git command every time, you can easily set an alias for each command through the git config file.Here are some examples you can try:
$ git config --global alias.co checkout
$ git config --global alias.br branch
$ git config --global alias.ci commit
$ git config --global alias.st statusThis means that when you want to type git commit, you only need to type git ci.
This technique can be useful when creating commands that you think should exist.For example, to solve the ease-of-use issue of unstaged files, you can add your own unstaged alias to Git:
$ git config --global alias.unstage 'reset HEAD --'This makes the following two commands equivalent:
$ git unstage fileA
$ git reset HEAD -- fileAThis looks a little clearer.Usually a last command is also added, like this:
$ git config --global alias.last 'log -1 HEAD'This way, the last commit can be easily seen:
$ git last
commit 66938dae3329c7aebe598c2246a8e6af90d04646
Author: Josh Goebel <dreamer3@example.com>
Date: Tue Aug 26 19:48:51 2008 +0800
test for current head
Signed-off-by: Scott Chacon <schacon@example.com>As you can see, Git simply replaces the alias with the corresponding command.However, you may want to execute an external command rather than a Git subcommand.In that case, you can add the ! symbol in front of the command.That's useful if you want to write some tools of your own that work with Git repositories.We now demonstrate defining git visual as an alias of gitk:
$ git config --global alias.visual '!gitk'