本文章参考了Pro Git
1 Git简介
Linux内核开源项目有着众多参与者,为了提高开发效率,项目组于2002年开始启用分布式版本控制系统BitKeeper来管理和维护代码。在BitKeeper同Linux内核开源社区合作关系于2005年合作关系结束后,Linux开源社区,特别是Linux缔造者,Linus Torvalds不得不吸取教训,决心开发出属于自己的版本控制系统。他们对新的系统制定了若干目标:
- 速度
- 简单的设计
- 对非线性开发模式的强力支持(允许上千个并行开发的分支)
- 完全分布式
- 有能力高效管理类似Linux内核一样的超大规模项目(速度和数据量)
由此Git诞生,它在高度易用的同时,速度飞快,极其适合管理大项目,还有着令人难以置信的非线性分支管理系统,可以应付各种复杂项目的开发需求。
Git与其他版本控制系统的主要差别在于,Git只关心文件数据的整体是否发生变化,而大多数其他系统则关系文件内容的具体差异。这类系统,如CVS、Subversion、Perforce、Bazaar等等,每次都记录有哪些文件做了更新,以及更新了哪些行的什么内容。而Git并不保存这些前后变化的差异数据,它将变化的文件做快照后,记录在一个微型的文件系统中。每次提交更新时,它会纵览一遍所有文件的指纹信息并对文件作一快照,然后保存一个指向这次快照的索引。为提高性能,若文件没有变化,Git不会再次保存,而只对上次保存的快照作一链接。
在保存到Git之前,所有数据都要进行内容的校验和(checksum)计算,并将此结果作为数据的唯一标识和索引。Git使用SHA-1算法计算数据的校验和,通过对文件的内容或目录的结构计算出一个SHA-1哈希值,作为指纹字符串。该字串由40个十六进制字符(0-9 及 a-f)组成。
对于任何一个文件,在Git内都只有三种状态:已提交(committed),已修改(modified)和已暂存(staged)。已提交表示该文件已经被安全地保存在本地数据库中了;已修改表示修改了某个文件,但还没有提交保存;已暂存表示把已修改的文件放在下次提交时要保存的清单中。
2 安装Git
在Windows上安装比较简单,到GitHub的页面上:http://msysgit.github.com/下载exe安装文件。
Linux、Mac上的安装方式可以查看https://git-scm.com/book/zh/v2/起步-安装-Git
3 初次运行Git前的配置
在新的系统上,需要先配置Git工作环境。git config命令专门配置或读取相应的工作环境变量。git config命令的参数不同时,环境变量将存放在不同位置:
- /etc/gitconfig 文件:系统中对所有用户都普遍适用的配置。若使用 git config 时用 --system 选项,读写的就是这个文件。
- ~/.gitconfig 文件:用户目录下的配置文件只适用于该用户。若使用 git config 时用 --global 选项,读写的就是这个文件。
- 当前项目的git目录中的配置文件(也就是工作目录中的 .git/config 文件):这里的配置仅仅针对当前项目有效。每一个级别的配置都会覆盖上层的相同配置,所以 .git/config 里的配置会覆盖 /etc/gitconfig 中的同名变量。
3.1 配置用户信息
个人的用户名和电子邮件地址,在每一次Git提交时都会引用,会随更新内容被永久纳入历史记录。
$ git config --global user.name "new way"
$ git config --global user.email xxxx@qq.com
用了 --global 选项,那么更改的配置文件就是位于用户主目录下的那个,以后所有的项目都会默认使用这里配置的用户信息。如果要在某个特定的项目中使用其他名字或者电邮,只要去掉 --global 选项重新配置即可,新的设定保存在当前项目的 .git/config 文件里。
3.2配置文本编辑器
Git需要输入一些额外消息的时候,会自动调用一个外部文本编辑器。
$ git config --global core.editor vscode
3.3配置差异化工具
还有一个比较常用的是,在解决合并冲突时使用哪种差异分析工具。比如要改用 vimdiff 的话:
$ git config --global merge.tool vimdiff
Git 可以理解 kdiff3,tkdiff,meld,xxdiff,emerge,vimdiff,gvimdiff,ecmerge,和 opendiff 等合并工具的输出信息。
3.4查看配置信息
git config --list 命令查看所有配置信息:
$ git config --list
diff.astextplain.textconv=astextplain
filter.lfs.clean=git-lfs clean -- %f
filter.lfs.smudge=git-lfs smudge -- %f
filter.lfs.process=git-lfs filter-process
filter.lfs.required=true
http.sslbackend=openssl
http.sslcainfo=C:/Program Files/Git/mingw64/ssl/certs/ca-bundle.crt
core.autocrlf=true
core.fscache=true
core.symlinks=false
credential.helper=manager
filter.lfs.clean=git-lfs clean -- %f
filter.lfs.smudge=git-lfs smudge -- %f
filter.lfs.process=git-lfs filter-process
filter.lfs.required=true
user.name=new way
user.email=xxxx@qq.com
core.editor=vscode
gui.recentrepo=D:/gitregion/pro1/articles
有时候会看到重复的变量名,那就说明它们来自不同的配置文件(比如 /etc/gitconfig 和 ~/.gitconfig),不过最终 Git 实际采用的是最后一个。
也可以直接查阅某个环境变量的设定,只要把特定的名字跟在后面即可,像这样:
$ git config user.name
new way
4 取得第一个Git仓库
有两种取得 Git 项目仓库的方法。第一种是在现存的目录下,通过导入所有文件来创建新的 Git 仓库。第二种是从已有的 Git 仓库克隆出一个新的镜像仓库来。
4.1 在工作目录中初始化仓库
要对现有的某个项目开始用 Git 管理,只需到此项目所在的目录,执行:
$ git init
如果当前目录下有几个文件想要纳入版本控制,需要先用 git add 命令告诉 Git 开始对这些文件进行跟踪,然后提交:
$ git add .
4.2 从现有仓库克隆
克隆仓库的命令格式为 git clone [url]比如,要克隆 Ruby 语言的 Git 代码仓库 Grit,可以用下面的命令:
$ git clone git://github.com/schacon/grit.git
如果希望在克隆的时候,自己定义要新建的项目目录名称,可以在上面的命令末尾指定新的名字:
$ git clone git://github.com/schacon/grit.git mygrit
5 记录每次更新到仓库
5.1 检查文件状态
$ git status
5.2 跟踪新文件
以README文件为例:
$ git add README
5.3 暂存已修改文件
假设README文件被修改过,同样使用 git add 将其提交至暂存区:
$ git add README
5.4 忽略某些文件
一般我们总会有些文件无需纳入 Git 的管理,也不希望它们总出现在未跟踪文件列表。通常都是些自动生成的文件,比如日志文件,或者编译过程中创建的临时文件等。我们可以创建一个名为 .gitignore 的文件,列出要忽略的文件模式。
文件 .gitignore 的格式规范如下:
- 所有空行或者以注释符号 # 开头的行都会被 Git 忽略。
- 可以使用标准的 glob 模式匹配。
- 匹配模式最后跟反斜杠(/)说明要忽略的是目录。
- 要忽略指定模式以外的文件或目录,可以在模式前加上惊叹号(!)取反。
例如:
# 忽略所有 .a 结尾的文件
*.a
# 但 lib.a 除外
!lib.a
# 仅仅忽略项目根目录下的 TODO 文件,不包括 subdir/TODO
/TODO
# 忽略 build/ 目录下的所有文件
build/
# 会忽略 doc/notes.txt 但不包括 doc/server/arch.txt
doc/*.txt
5.5 查看已暂存和未暂存的更新
实际上 git status 的显示比较简单,仅仅是列出了修改过的文件,如果要查看具体修改了什么地方,可以用 git diff 命令。
$ git diff #查看尚未暂存的文件更新了哪些部分
$ git diff --cached #查看已经暂存的文件和上次提交的快照之间的差异
$ git diff --staged #查看已经暂存的文件和上次提交的快照之间的差异,Git1.6.1及以上版本支持
5.6 提交更新
$ git commit -m "说明信息"
若不加-m参数,则会调用默认文本编辑器输入本次提交的说明
5.7 跳过使用暂存区域
$ git commit -a
5.8 移除文件
$ git rm README
参数--cached表示从仓库中删除,但保留在工作目录中
5.9 移动文件
$ git mv file_from file_to
6 查看提交历史
$ git log
-
-p 展开显示每次提交内容的差异
-
-2 仅显示最近两次更新
-
--stat 仅显示简要的增改行数统计
-
--prett 指定不同于默认格式的方式展示提交历史,参数包括:oneline、short、full、fuller和format等,比如:
$ git log --pretty=format:"%h - %an, %ar : %s"
其中占位符有:
%H 提交对象(commit)的完整哈希字串
%h 提交对象的简短哈希字串
%T 树对象(tree)的完整哈希字串
%t 树对象的简短哈希字串
%P 父对象(parent)的完整哈希字串
%p 父对象的简短哈希字串
%an 作者(author)的名字
%ae 作者的电子邮件地址
%ad 作者修订日期(可以用 -date= 选项定制格式)
%ar 作者修订日期,按多久以前的方式显示
%cn 提交者(committer)的名字
%ce 提交者的电子邮件地址
%cd 提交日期
%cr 提交日期,按多久以前的方式显示
%s 提交说明
7 远程仓库的使用
7.1 查看当前的远程库
$ git remote
$ git remote -v #显示对应的克隆地址
7.2 添加远程库
$ git remote add [shortname] [url]
7.3从远程仓库抓取数据
$ git fetch [remote-name]
7.4 推送数据到远程仓库
$ git push [remote-name] [branch-name]
$ git push origin master
7.5 查看远程仓库信息
$ git remote show [remote-name]
7.6 远程仓库的删除和重命名
假设有个 origin 库
重命名:
$ git remote rename pb origin
删除:
$ git remote rm origin
8 打标签
8.1 列出已有标签
$ git tag
8.2 新建标签
$ git tag -a [版本号] -m [附注信息] #含附注标签
$ git tag -s [版本号] -m [附注信息] #签署标签
$ git tag [版本号] #轻量级标签
$ git tag -a [版本号] [校验和或前几位字符] #补充标签
8.3 分享标签
$ git push origin [tagname]
9 新建分支
$ git branch [分支名] #新建分支
$ git checkout [分支名] #切换分支
$ git checkout -b [分支名] #新建并切换分支
10 合并分支
$ git merge [分支名] #将分支并入主分支,有快进和合并两种模式
$ git rebase [分支名] #衍合
11 管理分支
$ git branch #列出当前所有分支清单
$ git branch -v #分支清单与各分支最后一个提交对象的信息
$ git branch --merged #已经并入当前分支的分支
$ git branch --no-merged #尚未并入当前分支的分支
12 远程分支
$ git fetch origin #同步远程服务器上的数据到本地
$ git push [远程仓库名] [分支名] #上传本地分支至远程仓库
$ git pull [远程仓库名] [分支名] #将远程索引合并到本地分支
$ git push [远程名] :[分支名] #删除远程分支
13 小结
本文是笔者学习入门Git的简易手册,记录了Git常见命令,Git的版本控制能力,强悍!