1、git 的基本概念
1.1、git 的3层结构
working directory 工作区
staging index 暂存区
git directory(Repository) 版本库
1.2、git 中文件的4中状态
untracked : 表示文件只在工作区存在,并未被 git 追踪
modified : 表示工作区修改了某个文件但还没有添加到暂存区
staged : 表示把工作区的修改的文件添加到了暂存区但还没有提交到版本库
committed : 表示数据已经存贮在本地版本库中
2、git 配置
告诉 git 你是谁:
git config --global user.name "your name"
git config --global user.email "your_email@youremail.com"
查看 git 所有配置
git config --list
所有配置均在 ~/.gitconfig 文件中,也可以手动修改次文件添加配置
3、git 基本命令
【命令】git init
【说明】初始化 git 版本仓库
【命令】git add filename
【说明】添加工作去中的文件到暂存区
【命令】git commit
【说明】提交修改,使用编辑器编辑提交说明
【选项】
-m 在 git commit 命令时直接附带提交说明,eg: git commit -m "message"
-a 将所有已追踪的文件的修改或删除操作都提交到版本仓库,即使它们没有经过 git add 添加到暂存区,如果是新添加的
文件,将不能被提交到版本仓库
【命令】git status
【说明】查看工作区和暂存区的文件状态
【命令】git diff
【说明】比较工作区与暂存区文件的差异
【命令】git diff --staged
【说明】比较版本库与暂存区的文件差异
【命令】git diff commit-id commit-id
【说明】比较分支内两个提交之间的文件差异
【命令】git diff branch-name branch-name
【说明】比较两个分支的最新提交版本的文件差异
【命令】git log
【说明】查看提交记录
example:
$ mkdir git_eg # 创建 git 工作区目录,或直接切换入已存在的目录
$ cd git_eg
$ touch test.c # 创建测试文件,或者使用目录中已存在的文件
$ git init # 初始化 git 版本参考,执行成功会在 git_eg 目录下生成一个 .git 目录
$ git add test.c # 将 test.c 添加到暂存区,
# 也可使用 git add ./ 一次将当前目录中所有文件添加至暂存区
$ git status # 查看工作区和暂存区的状态,可以看到 test.c 文件已经在暂存区
$ git commit -m "first commit, add test.c" # 提交修改至版本库
$ git log # 查看提交记录,可以看到一条 "first commit, add test.c" 的信息
4、git 撤销操作
【命令】git commit --amend
【说明】撤销上一次的提交并将暂存区的文件重新提交
【使用场景1】
当执行 git commit 完成后发现有个文件修改不完善,可以修改后执行 git add 将文件添加到缓存区,然后再执行 git commit --amend 撤销上一次的提交并将暂存区的文件重新提交,这样在版本库中就只会存在一条提交记录了
【命令】git checkout -- filename
【说明】拉取暂存区的文件并将其替换工作区的文件
【使用场景1】
当修改了工作区的文件后发现所做的修改又不需要了,想回退到修改之前,就可以使用此命令
也可以使用 git checkout ./ 回退当前目录下的所有文件修改
【命令】git reset HEAD -- filename
【说明】拉取最近一次提交的版本库中的指定文件到暂存区,该操作不影响工作区
HEAD: git 头指针,一直指向当前分支的最近一次提交
也可以使用版本号(每次提交生成的 HASH )替换 HEAD ,拉取版本库中指定版本的文件到暂存区
【使用场景1】
当将一个文件的修改添加到缓存区中后,发现并不希望这个文件的修改在下次提交中存在,只希望修改暂时存在于工作区,即将一个文件误添加到了暂存区,可以使用该命令撤销暂存;如果不想保留工作区的修改,可以继续执行 git checkout -- filename 命令撤销工作区的修改
【命令】git reset commit-id -- filename
【说明】拉取版本库中指定版本的指定文件到暂存区,该操作不影响工作区,如果不加 filename ,则拉取版本库中指定版本的所有文件到暂存区
commit-id: 版本号,每次提交生成的 HASH
【使用场景1】
将版本库和工作区中的文件回退至指定版本
step1 git reset commit-id -- filename
将暂存区的文件回退至指定版本
step2 git commit
将暂存区的文件提交至版本库,即完成版本库的文件回退
step3 git checkout -- filename
拉取暂存区的文件并将其替换工作区的文件,即完成将工作区文件回退至指定版本
【使用场景2】
查看指定文件在指定版本时的内容后恢复文件与版本库同步
step1 git reset commit-id -- filename
将暂存区的文件回退至指定版本
step2 git checkout -- filename
拉取暂存区的文件并将其替换工作区的文件,即完成将工作区文件回退至指定版本,然后查看指定文件内容
step3 git reset HEAD -- filename
将暂存区的文件恢复至与版本库同步
step4 git checkout -- filename
拉取暂存区的文件并将其替换工作区的文件,即完成将工作区文件恢复至与版本库同步
【命令】git reset --hard commit-id
【说明】彻底回退版本,将版本库、暂存区、工作区的文件回退至指定版本
【命令】git reset --mixed commit-id
【说明】将版本库、暂存区回退到指定版本,工作区的文件不受影响
【命令】git reset --soft commit-id
【说明】将版本库回退到指定版本,暂存区、工作区的文件不受影响
【命令】git revert commit-id
【说明】撤销指定的提交,同时创建一个新的提交,相较于 git reset,不会改变现有的提交历史
5、git 文件删除
【命令】git rm filename
【说明】删除工作区和暂存区中的指定文件
相当于 rm filename; git add ./
【使用场景1】
当需要删除版本库中的指定文件,且工作区也不需要保留该文件
step1 git rm filename
删除暂存区和工作区的指定文件,如果工作区的文件有修改,使用选项 -f,即 git rm -f filename
step2 git commit
提交删除操作至版本库
【使用场景2】
当执行 git add 命令误将不需要 git 版本库追踪的文件添加到了暂存区,需要删除暂存区的指定文件,但保留工作区的文件,使用 --cahed 选项,即 git rm --cahed filename
【命令】git mv oldname newname
【说明】重命名暂存区的指定文件
相当于 mv oldname newname; git rm oldname; git add newname
【命令】git clean
【说明】删除没有被追踪的文件和目录
【选项】
-n 提示那些文件会被删除,但不会真正的删除文件
-f 删除没有被追踪的文件,但不会删除 .gitignore 文件里面指定的文件夹和文件,,不管这些文件有没有被追踪
-d 删除没有被追踪的目录
-xf 删除所有没有被追踪的文件。 不管是否是 .gitignore 文件里面指定的文件夹和文件
【使用场景1】
当工作区已经对文件做了修改,包括添加了新的文件,甚至已经添加了部分修改到暂存区,现在需要回退所有修改,恢复一个干净的工作区到最近一次提交
step1 git reset --hard
彻底回退修改,将版本库、暂存区、工作区的文件回退至最近一次提交
step2 git clean -df
删除工作区没有追踪的目录和文件
6、git 分支
6.1、分支查看
【命令】git branch
【说明】查看本地已经存在分支,并在当前分支的前面用 " * "标记
【命令】git branch -r
【说明】查看远程版本库分支列表
【命令】git branch -a
【说明】查看所有分支列表,包括本地和远程
【命令】git branch -vv
【说明】查看本地分支对应的远程分支
6.2、分支创建与切换
【命令】git branch dev
【说明】创建名为 dev 的分支,创建时需要工作区是最新的且干净的,创建分支后依然停留在当前分支
【命令】git checkout master
【说明】切换分支 master 为当前分支,切换之前的分支的工作区和暂存区应该是干净的
【命令】git checkout -b dev
【说明】创建分支 dev,并切换 dev 为当前分支
【命令】git branch -m oldname newname
【说明】重命名分支
6.3、分支删除
【命令】git branch -d dev
【说明】删除分支 dev,分支 dev 不能为当前分支,且不能有一些未 merge 的提交,否则删除失败
【命令】git branch -D dev
【说明】强制删除分支 dev
6.4、分支合并
【命令】git merge branch_name
【说明】合并 branch_name 分支到当前分支,如果合并有冲突会告警,并中断
【冲突处理】
如果合并时出现合并冲突,git 会提示有冲突的文件,打开文件会看到以下标记
<<<<<<< HEAD
……(当前分支的内容)
=======
……( branch_name 分支的内容)
>>>>>>> branch_name
手动处理冲突后删除标记再使用 git commit 提交
6.5、储存变更
【命令】git stash
【说明】储存当前分支工作区和暂存区的修改
【使用场景1】
在当前分支对文件做了一些修改,甚至添加了部分修改至暂存区,但这些修改还不能构成提交条件,此时由于工作需要,需要切换工作分支,此时可用此命令将当前分支的修改储存,这样就不会导致切换分支告警了。
【命令】git stash list
【说明】查看已储存的变更的信息,信息以 stash@{num} 开始显示每条储存所在的分支和储存时的 commit-id
【命令】git stash apply stash@{num}
【说明】应用储存的信息,恢复变更,但不删除存储的信息。如果不加 stash@{num} 则应用最近一次的储存信息
【使用场景1】
在 git stash 储存变更,切换分支完成工作后,重新切换至之前开发的分支时,需要恢复之前储存的变更,使用此命令。在使用此命令恢复变更之前,建议使用 git stash list 查看储存列表,确认要恢复的变更
【命令】git stash drop stash@{num}
【说明】删除存储的信息
【命令】git stash pop stash@{num}
【说明】应用并删除储存的信息
相当于执行了 git stash apply stash@{num} 和 git stash drop stash@{num}
7、git 远程仓库
7.1、远程仓库创建
远程仓库可以使用 GitHub 创建,也可以在自己的服务器上创建。
GitHub 创建远程仓库方法参见《GitHub 配置与使用》
服务器创建远程仓库方法:
【step1】登录服务器
【step2】创建仓库目录 temp.git (这里以 temp 为例,一般在仓库目录后面添加 " .git " 后缀 )
【step3】初始化远程仓库,远程仓库一般使用命令 git init --bare 创建一个裸仓库,此时仓库即创建成功
访问远程仓库使用的 URL 分为 HTTP 格式和 SSH 格式两种:
GitHub 远程仓库 URL 格式:
HTTP 格式 https://github.com/your_name/your_repo.git
SSH 格式 git@github.com:your_name/your_repo.git
服务器远程仓库 URL 格式:
SSH 格式 user@server-ip:/path/to/temp.git
7.2、常用命令
【命令】git clone [url]
【说明】克隆远程仓库到本地
【命令】git remote add [shortname] [ual]
【说明】为本地仓库添加一个新的远程仓库,可以指定一个简单的名字(一般使用 origin),以便将来引用。
【命令】git push -u origin master
【说明】将本地提交推送至远程仓库的 master 分支,origin 也可用 URL 替代
【命令】git branch --set-upstream master origin/dev
【说明】指定本地分支 master 追踪远程仓库中的分支 dev
【命令】git remote -v
【说明】列出远程仓库的详细信息,在每一个名字后面列出其远程 url
【命令】git pull origin master
【说明】拉取远程仓库的 master 分支到本地,并与当前分支合并,
如果当前分支与远程仓库分支 master 存在追踪关系,可以省略 master,即使用命令 git pull origin
【命令】git pull origin master:dev
【说明】拉取远程仓库的 master 分支到本地,并与本地分支 dev 合并
【命令】git fetch origin master:dev
【说明】拉取远程仓库的 master 分支到本地,并创建分支 dev,但不与本地分支合并,如要合并手动执行 git merge 命令
7.3、git ssh 免密登录
【step1】本地执行 ssh-keygen -t rsa 生成秘钥
【step2】本地执行 ssh-copy-id user@server 将本地公钥复制到远程服务器的 authorized_keys 文件中。
如果不是自己的服务器,可以将本地公钥发送给服务器管理员,由其添加到 authorized_keys 文件中。
8、git 文件过滤
有些时候工作区会存在一些必须的目录或者文件,但这些文件又不能提交到版本库中,每次执行 git status 时都会显示 Untracked files ...,而且在修改了大量文件要添加到暂存区时还需要手动过滤,比较麻烦。此时可以使用 .gitignore
文件,在相应目录下创建一个 .gitignore
文件,并将需要过滤的文件名添加到该文件中,git 就会自动忽略这些文件,即可解决上述烦恼。
9、git commit 模板
参考:《阮一峰的网络日志:Commit message 和 Change log 编写指南》
一个好的 commit 格式有助于保证代码提交信息的准确,便于后期版本的维护和 Bug 修正,特别是在团队协作时。一个标准的 commit 模板有助于快速编辑风格统一的提交信息。
添加模板的步骤:
【step1】从网上下载后者自己编辑一份模板放到指定路径
【step2】添加 commit 模板
git config --global commit.template <template_path> # 添加模板
git config --global core.editor vim #添加 commit 编辑器,这里使用 vim ,也可以配置为自己常用的文本编辑器
附一份模板:
# Type(<scope>): <subject>
# <body>
# <footer>
# type 字段:
# feat:新功能(feature)
# fix:修补bug
# docs:文档(documentation)
# style: 格式(不影响代码运行的变动)
# refactor:重构(即不是新增功能,也不是修改bug的代码变动)
# test:增加测试
# chore:构建过程或辅助工具的变动
# scope 字段: 用于说明 commit 影响的范围
# subject 字段: commit 目的的简短描述,不超过50个字符
# Body 部分是对本次 commit 的详细描述,可以分成多行
# Footer :
# 用来关闭 Issue 或以 BREAKING CHANGE 开头,后面是对变动的描述、
# 以及变动理由和迁移方法,如果没有,可以省略