Git小记
关于版本控制
本地版本控制系统
集中式版本控制系统(CVCS)
分布式版本控制系统(DVCS)
git特点
直接记录快照,而非差异比较
Git 和其他版本控制系统的主要差别在于,Git 只关心文件数据的整体是否发生变化,而大多数其他系统则只关心文件内容的具体差异。
近乎所以的操作是本地执行
时刻保持数据的完整性
在保存到 Git之前,所有数据都要进行内容的校验和(checksum)计算,并将此结果作为数据的唯一标识和索引。
Git 使用 SHA-1 算法计算数据的校验和,通过对文件的内容或目录的结构计算出一个 SHA-1 哈希值,作为指纹字符串。多数操作仅添加数据
文件对三种状态
- 已提交(committed):表示文件已被安全地保存在本地数据库中了。
- 已修改(modified):表示修改了某个文件,但还没有提交保存。
- 已暂存(staged):表示把已修改的文件放到下次提交时要保存的清单了。
文件流转三个工作区:git的工作目录区,暂存区,本地仓库
每个项目都有一个 Git 目录(译注:如果 git clone 出来的话,就是其中 .git 的目录;如果 git clone –bare 的话,新建的目录本身就是 Git 目录。),它是 Git 用来保存元数据和对象数据库的地方。该目录非常重要,每次克隆镜像仓库的时候,实际拷贝的就是这个目录里面的数据。
从项目中取出某个版本的所有文件和目录,用以开始后续工作的叫做工作目录。这些文件实际上都是从 Git 目录中的压缩对象数据库中提取出来的,接下来就可以在工作目录中对这些文件进行编辑。
所谓的暂存区域只不过是个简单的文件,一般都放在 Git 目录中。有时候人们会把这个文件叫做索引文件,不过标准说法还是叫暂存区域。
基本的 Git 工作流程如下:
- 在工作目录中修改某些文件。
- 对修改后的文件进行快照,然后保存到暂存区域。
- 提交更新,将保存在暂存区域的文件快照永久转储到 Git 目录中。
文件状态变化周期
其中灰色箭头表示文件未跟踪状态,红色箭头表示文件已跟踪状态。
git安装
1 | apt-get install # hehe |
git初始化配置
命令工具:git config
or git-config
–>用来配置和读取相应的工作环境变量。
/etc/gitconifg
文件:系统中对所有用户都普遍适用的配置。使用命令git config --system
就是读取该文件。~/.gitconfig
文件:用户目录下的配置文件只适用于该用户。使用命令git config --global
就是读取该文件。.git/config
文件:对当前项目有效。该配置文件会覆盖掉/etc/gitconfig
中的同名变量。
配置用户信息
首先需要配置个人用户名和邮件地址。命令:1
2git config --global user.name "monkee"
git config --global user.email monkee_lei@sina.com
文本编辑器配置
默认是vi or vim1
git conifg --global core.editor emacs
差异分析工具
1 | git config --global merge.tool vimdiff |
git可以理解的合并工具有:kdiff3,tkdiff,meld,xxdiff,emerge,vimdiff,gvimdiff,ecmerge,和 opendiff 等
查看配置信息
1 | git config --list |
帮助信息
1 | #三种方式 |
git创建仓库或克隆仓库
在工作目录中初始化新仓库1
git init #执行后目录下会创建一个名为.git的目录
将当前目录下的文件纳入版本控制1
2
3
4git add filename #告诉git开始跟踪这些文件
git commit -m 'initial project version' # 提交
#合并以上两步
git commit -a -m
克隆现有的仓库1
2
3
4
5git clone [url]
# example
git clone git://github.com/schacon/grit.git
#当前目录下会创建一个名为grit的目录,目录下会有包含一个.git子目录,同样也可以修改目录名
git clone git://github.com/schacon/grit.git mygrit
检测文件状态
1 | git status |
移除文件
1 | git rm <file> # 对于修改过且放进暂存区的文件,必须加参数-f |
移动文件
1 | git mv file_from file_to |
git mv
相当于三条命令:1
2
3mv file_from file_to
git rm file_from
git add file_to
查看提交历史
1 | git log |
参数说明
选项 | 说明 |
---|---|
-p |
展开显示每次提交内容差异 |
-n |
显示最近的n次更新 |
--stat |
增改行统计 |
--word-diff |
按word diff格式显示差异 |
--abbrev-commit |
仅显示SHA-1的前几个字符 |
--pretty |
使用其他格式显示历史提交信息。可用的选项包括 oneline,short,full,fuller和format(后跟指定格式) |
--since,--after |
仅显示指定时间之后的提交 |
--until,--before |
仅显示指定时间之前的提交 |
-author |
仅显示指定作者相关提交 |
--committer |
仅显示指定提交者相关的提交 |
撤销操作
撤销操作不可逆
修改最后一次提交
1
git commit --amend #重新提交
取消已经暂存的文件
1
git reset HEAD <file>
取消对文件的修改
1
git checkoout --<file>
远程仓库使用
查看当前的远程库
1
2
3
4git remote #至少可以看到一个origin的远程库,git默认使用这个名字来标识所克隆的原始仓库
#加参数-v,显示对应的克隆地址
git remote -v添加远程仓库
1
git remote add [shortname] [url]
从远程仓库仓库抓取数据
1
2
3
4git fetch [remote-name]
#例如
git fetch origin
如果设置了某个分支用于跟踪某个远端仓库的分支(参见下节及第三章的内容),可以使用git pull
命令自动抓取数据下来,然后将远端分支自动合并到本地仓库中当前分支。在日常工作中我们经常这么用,既快且好。实际上,默认情况下 git clone
命令本质上就是自动创建了本地的 master
分支用于跟踪远程仓库中的 master
分支(假设远程仓库确实有 master
分支)。所以一般我们运行 git pull
,目的都是要从原始克隆的远端仓库中抓取数据后,合并到工作目录中的当前分支。
推送数据到远程仓库
1
2
3
4git push [remote-name] [branch-name]
#例如将bending的master分支推送到origin服务器上
git push origin master查看远程仓库信息
1
git remote show [remote-name]
分支
分支一个很重要的作用是:分支开发工作流
查看分支
1
2
3git log --decorate
git log --decorate --graph --all分支的创建 & 删除
1
2git branch branch-name #创建
git branch -d branch-name #删除分支切换
1
2
3
4
5
6
7
8#分支切换会改变你工作目录中的文件
git checkout branch-name
#创建并切换分支
git checkout -b branch-name
#创建并切换分支
git checkout -b branch-name分支的合并
1
2git checkout master #切换到master分支
git merge testing #合并分支master和分支testing
合并时需注意分支的创建对先后关系以及是否属于同一分支等问题。
- 显示分支
1
2git branch # 加选项-v可以显示更详细的信息
#--merged与--no-merged这两个有用的选项可以过滤这个列表中已经合并或尚未合并到当前分支的分支
git支持的协议
git可以使用四种主要的协议来传输资料:本地协议(local)、HTTP协议、SSH(Secure Shell)协议和git协议。
play with github
github是一个git版本库托管商,很多开源项目都是使用github实现托管的。
- SSH公钥的生成
github使用SSH公钥进行认证。默认情况下,用户的SSH密钥存放在~/.ssh
目录下,我们需要查看是否有以id_dsa
或id_rsa
命名的文件,其中一个带有.pub
扩展名,即为公钥,另一个为私钥。如果没有该文件或者没有.ssh
目录,可以使用ssh-keygen
生成。
1 | ssh-keygen -t rsa -C "monkee_lei@sina.com" |
登陆github添加公共密钥。
验证是否配置成功1
2
3ssh -T git@github.com
-->
Hi username! You've successfully authenticated, but GitHub does not provide shell access.