Git
的介绍和使用
Git
的介绍
版本控制系统: 版本控制是一种记录一个或若干文件内容变化, 以便将来查阅特定版本修订情况的系统.
Git
的特点
直接记录快照, 而非差异比较
在Git
中, 每当你提交更新或保存项目状态时, 它基本上就会对当时的全部文件创建一个快照并保存这个快照的索引. 为了效率, 如果文件没有修改, Git
不再重新存储该文件, 而是只保留一个连接指向之前存储的文件. Git
对待数据更像是一个快照流.
近乎所有操作都是本地执行
在Git
中的绝大多数操作都只需要访问本地文件和资源, 一般不需要来自网络上其他计算机得信息. 因为你在本地磁盘上就有项目的完整历史. 例如, 要浏览项目的历史, Git
不需要外连到服务器去获取历史, 然后在显示出来, 它只需要直接从本地数据库中读取.
Git
保证完整性
Git
中所有的数据都在存储前计算校验和, 然后以校验和来引用. 这意味着不可能在Git
不知情时更改任何文件内容或目录内容.
Git
一般只添加数据
你执行的Git
操作, 几乎只往Git
数据库中添加数据. 同别的VCS
一样, 未提交更新时有可能丢失或弄乱修改的内容. 但是一旦你提交快照到Git
中, 就难以再丢失数据.
Git
的配置
Git
的配置可以保存在三个地方.
/etc/gitconfig
文件: 包含系统上每一个用户以及他们仓库的通用配置. 如果在执行git config
时带上--system
选项, 那么它就会读写该文件中的配置变量.
~/.gitconfig
或~/.config/git/config
文件: 只针对当前用户. 你可以传递--global
选项让Git
读写此文件, 这会对你系统上该用户的所有仓库有效.
- 当前使用仓库的
Git
目录中的config
文件(.git/config
): 针对该仓库. 你可以传递--local
选项让Git
强制读写该文件, 虽然默认情况下用的就是它. (这个只有你进入某个Git
仓库中才能让该选项生效).
每一个级别会覆盖上一级别的配置, 所以.git/config
的配置会覆盖/etc/gitconfig
中的配置变量.
1 2 3 4 5 6 7 8
| # 查看所在目录的所有配置以及它们所在的文件 git config --list --show-origin
# 设置git配置 git config [--system|--global|--local] <key> <value>
# 查询git配置 git config [--show-origin] <key>
|
获得Git
文档
1 2 3 4 5 6 7
| # 获得详细的文档 git help <verb> git <verb> --help man git-<verb>
#获得简略的文档 git <verb> -h
|
Git
的使用
获得Git
仓库
通常有两种获取Git
项目仓库的方式:
- 将尚未进行版本控制的本地目录装换为
Git
仓库
- 从其塔服务器克隆一个已存在的
Git
仓库
在已存在目录中初始化仓库
不写仓库名,将会在当前目录下创建.git
的子目录, 从而管理当前目录. 但我们现在仅仅做了一个初始化操作, 并没有跟踪任何文件.
克隆现有的仓库
如果不写仓库名, 会以远程仓库命名. 这个命令, 会创建一个目录, 并在其中生成.git
子目录. 当执行git clone
命令的时候, 默认配置下远程仓库中的每一个文件的每一个版本都将被拉取下来. Git
支持https://
协议, git://
协议和SSH
传输协议, 例如user@server:path/to/repo.git
.
记录每次更新到仓库
工作目录中的每一个文件都不外乎这两种状态: 已跟踪或未跟踪. 已跟踪的文件是指那些被纳入了版本控制的文件.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
| # 检查当前文件状态 git status
# 跟踪新文件或暂存已修改的文件 git add 文件或目录
# 恢复文件 git restore [--staged] [-s tree] 文件或目录
# 如果指定--staged从head或tree恢复index # 如果指定-s, 将从tree恢复工作区 # 如果不指定--staged和-s, 将从index恢复工作区
# 状态简介 git status -s
# 查看已暂存和未暂存的修改 git diff [--staged]
# 不加--staged, 比较的是工作区和暂存区的区别 # 加--staged, 比较的时候暂存区和最后一次提交的区别
# 提交更新 git commit [--amend] [-m 提交信息] [-a]
# -a: Git会自动把所有已跟踪过的文件暂存起来一并提交 --amend: 取代上一次提交
# 移除文件 git rm [-f]
# 这个和自己手动用rm移除的区别是, 这个命令会自己将移除的文件提交到暂存区, 如果自己用rm, 需要自己手动添加到暂存区 -f: 如果文件在工作区或暂存区被修改过, 必须要使用-f, 这是为了防止未提交的修改被删除 --cached: 仅从index移除, 而不从工作区移除, 可以用来取消跟踪文件
# 移动文件(重命名文件) git mv file_from file_to
# 这条命令相当于, 所以使用mv命令时, 记得补上后面两条 mv file_from file_to git rm file_from git add file_to
# 查看提交历史 git log [--oneline --graph] [--since|--until="yyyy-MM-dd"] [--author] [--grep=""[--grep=""]...] [--all-match] [-S function_name] [--no-merges] [--] [dir]
--: 是用来隔开参数和目录的, 没有别的作用
|
忽略文件
使用.gitignore
来忽略某些文件. 这个文件是放在仓库的根目录下的, 还可以给子目录添加.gitignore
, 子目录下的.gitignore
只会对子目录有效. 要养成一个开始就为新仓库设置好.gitignore
文件的习惯, 以免将来误提交无用的文件.
远程仓库的使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| # 列出远程仓库 git remote [-v]
-v: 列出url
# 添加远程仓库 git remote add <short> <url>
# 从远程仓库抓取与拉取, 这个命令会访问远程仓库, 从中拉取所有你还没有的数据. 执行完成之后, 你将会拥有那个远程仓库中所有分支的引用, 可以随时查看, 还会更新远程跟踪分支的位置 git fetch <remote>
# 推送到远程仓库 git push <remote> <branch> git push <remote> <localbranch>:<remotebranch>
# 查看远程仓库信息, 可以查看远程仓库当前处于那个分支, 下一次抓取将会存储的分支, 远程已经删除的分支, 这个是实时的, 不需要fetch git remote show <remote>
# 删除存储在本地, 但远端已经删除的分支 git remote prune <remote>
# 远程仓库从命名 git remote rename <oldname> <newname>
# 移除远程仓库 git remote remove <remote>
|
打标签
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| # 列出标签 git tag [-l "blob表达式"] [-n]
# 创建轻量标签 git tag <tagname> [hash]
# 创建附注标签 git tag -a <tagname> -m "注释" [hash]
# 查看标签详情 git show <tagname>
# 删除标签 git tag -d <tagname>
# 推送标签到远端 git push origin <tagname>
# 删除远端标签 git push origin --delete <tagname> git push <remote> :[refs/tags/]<tagname>
|
Git
分支
Git
的分支, 其实本质上仅仅是指向提交对象的可变指针.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| # 创建分支 git branch <branchname>
# 切换分支, 在切换分支前, 需要保证工作目录和暂存区的干净, 如果tree不存在, 有且只有一个同名的本地远程分支, 将会自动创建分支, 并跟踪本地远程跟踪分支 git checkout <tree>
# 创建并切换分支, 如果有本地远程分支, 会自动跟踪 git checkout -b <newbranchname> [本地远程分支]
# 合并分支 git merge <需要被合并的分支> # 查看分支 git branch [-l <pattern>] [-v] [--merged|--no-merged [commit]
-v: 查看提交信息, 以及与本地远程分支的关系(领先或落后) --merged: 过滤出已经合并到当前分支的分支 --no-merged: 过滤出尚未合并到当前分支的分支
# 切换跟踪分支 git branch -u <本地远程分支>
# 查看跟踪分支, 这里的数据来自与从每个服务器最后一次抓取的数据. 这个命令并没有连接服务器, 它只会根据本地缓存的数据. 如果需要统计最新的领先与落后数字, 需要在运行此命令之前抓取所有的远程仓库. git fetch --all; git branch -vv git branch -vv
|
git
变基
变基是将一系列提交按照原有次序依次应用到另一分支上, 而合并是把最终结果合并在一起.
1 2 3 4
| # 不写tree, 默认是当前head执行的分支 git rebase 基底 [tree] # 这个会选中在tree2的, 但没在tree1中的提交 git rebase --onto 基底 tree1 tree2
|
变基的风险
如果提交存在于你的仓库之外, 而别人可能基于这些提交进行开发, 那么不要执行变基.