Git是一种功能强大的分布式版本控制工具。
一、Git 基础
git的常用命令:
0、查找命令使用方式 git --help xx命令
1、git 初始化
查看git版本 git --version
在开始使用之前,使用git config 命令设置git的配置变量
(1)配置姓名
git config --global user.name "testuser"
(2)配置邮箱
git config --global user.email "test@126.com"
(3)开启颜色显示
git config --global color.ui true
(4)git命令别名
git config --global alias.ci commit //将 git commit 别名为 git ci
git config --global alias.unstage 'reset HEAD --'
2、创建版本库以及第一次提交
(1)首先创建一个新的工作目录,在该目录下创建版本库
cd xxx
mkdir demo
cd demo
git init //创建版本库
显示 Initialized empty Git repository in xxx/demo/.git ( .gti为隐藏目录,这个 .git目录就是git版本库)
(2)向工作区添加文件
echo "hello" > welcome.txt
将这个文件添加到版本库
git add welcome.txt
然后,提交一次,进入版本库
git commit -m "Initialized" (提交必须有提交说明, -m参数给出提交说明)
3、git 信息显示与编辑
显示版本库 目录
git rev-parse --git-dir
显示工作区根目录
git rev-parse --show-toplevel
打开 .git/config文件进行编辑,
git config -e (git 版本库级别的配置文件)
打开 /home/git/gitconfig 文件进行编辑
git config -e --global
打开 /etc/gitconfig 系统级配置文件进行编辑
git config -e --system
查看当前状态
git status
4、git 工作区、暂存区
git diff
git add 命令作用:
1)将一个新建的文件加入跟踪
2)将修改过的文件放入暂存区
git commit 命令将暂存区中的文件提交到版本库,如果一个文件没被跟踪或者修改后没有 git add,则不对该文件进行提交
git reset HEAD filename 命令将一个新建的文件从跟踪状态变回未跟踪状态
git checkout -- filename 对文件用版本库中的版本更新工作区中的版本(撤销工作区的更改)
在工作主目录下创建 .gitignore 文件,可以设置被git 版本库忽略的文件
如 .gitignore 文件中为:
*.[ao]
则表示忽略所有 .a .o 文件,即git 版本库不对该类文件进行跟踪。
git diff 查看尚未暂存的文件更改了哪些部分
该命令比较的是 工作区中的文件和暂存区中的快照,即修改之后还没有暂存起来的部分。
gid diff --cached 比较暂存区中的内容和上次提交的快照之间的区别,即暂存了但没有commit的部分。
git commit -a filename 命令 跳过暂存区域直接提交工作区中的文件到版本库(即省略git add 步骤)
git rm filename 将文件从 git的暂存区中移除(即从已跟踪文件清单中移除),然后提交,并且同时删除工作区中的该文件。
如果删除文件之前修改过并且存放到暂存区域,则必须使用强制删除选项 -f, 以防误删除文件后丢失修改的内容。
git rm --cached filename 将文件从暂存区域中删除,但保留在当前工作区域中的内容。
git mv file1 file2 在git 中对文件进行改名操作
git mv file1 file2 实际执行了三个命令:
1) mv file1 file2
2) git rm file1
3)git add file2
git log 查看提交记录, git log -p 在查看提交记录的同时,比较前后两次提交的不同。 git log -p -2 只查看和比较两次提交结果
5、撤销操作
注意,有些操作并不总是都可以撤销的,需要小心使用。
(1) 修改最后一次提交(比如上次提交有几个文件没有加,或者提交注释写的不对)
在修改完之后
git commit --amend
(2) 取消已经暂存的文件
git reset HEAD filename
(3)取消对文件的修改
git checkout -- filename //从暂存区中工作区中的更改
6、远程仓库的使用
(1)查看远程仓库
git remote 查看当前工作目录中的远程仓库,并列出远程仓库的简短名字
当克隆某个远程仓库后,可以看到一个名为origin的远程库,git 默认使用这个名字来标识你克隆的远程仓库。
git remote -v 显示当前目录下的远程仓库,以及列出远程仓库对应的克隆地址
(2)添加远程仓库
git remote add [shortname] [url] (此时本地仓库中并没有该远程库中的内容,只具有一个记录)
例如 git remote add pd git://github.com/paulboone/ticgit.git
在之后可以用 shortname 代替 远程仓库url
(3)从远程仓库抓取数据到本地
git fetch [remote-name]
如果是克隆了一个仓库,此命令会自动将远程仓库归于origin 下。所以 git fetch origin 会抓取从你上次克隆以来别人上传到此远程仓库中的所有更新(或者从上次 fetch以来 别人提交的更新)。 fetch只是将远程git库内容拉到本地,并不会合并到当前工作分支!
(4)推送数据到远程仓库
git push [remote-name] [branch-name]
如果将本地的master主枝推送到origin 服务器上,则 使用 git push origin master
(git clone 操作会自动使用默认的 master 和 origin)
只有在所克隆的服务器上有写权限,并且在同一时刻没有别人在向服务器推送,才能push成功。否则,在你推送前有其他人已经推送了若干更新,则会被驳回。需要将他们的更新抓取到本地,并放到本地项目中,然后才能再次推送。
git push 远程仓库名S 本地分支名A:远程分支名B //将本地分支A 推送到远程仓库S的远程分支B上
(5)查看远程仓库信息
git remote show [remote-name]
(6)远程仓库的删除和重命名
git remote rename name1 name2 # 修改某个远程仓库的简短命名
git remote rm 仓库简短名 #移除远端仓库
7、打标签
git可以对某个时间点的版本进行打标签。
(1) 列显已有的标签 git tag
使用 git tag show 查看相应标签的版本信息,并连同显示打标签时的提交对象。
(2)签署标签
轻量级标签实际上就是i一个保存着对应提交对象的校验和信息的文件。要创建这样的标签,一个 -a, -s, -m 都不用,只需要给出标签名字即可。
git tag v1.0
(3)验证标签
可以使用 git tag -v [tag-name] 的方式验证已经签署的标签。
二、Git分支
git会把出现变更的文件直接拷贝,形成新的blob(二进制大对象),而非与上一个版本的diff。所以一旦需要查看某版本直接load即可,而其他差异版本控制需要做merge,所以快。空间换时间。并非每个当前版本都需要做备份,如果没有改变,那么快照其实是链接上一个版本。git会在隐藏目录.git里存在object里,定期会优化,保证快照空间,和读取时间的平衡。
在git提交中,会保存一个提交(commit)对象,它包含一个指向暂存内容快照的指针,作者和相关附属信息,以及一定数量(也可能没有)指向该提交对象直接祖先的指针。第一次提交是没有直接祖先的,普通提交有一个祖先,由两个或多个分支合并的提交有多个祖先。
1、git 提交
(1)git 的暂存操作(git add)会为当前工作目录的更新文件计算校验和,然后把当前版本的文件快照保存到git仓库(git仓库使用blob类型的对象存储这些快照),并将校验和加入暂存区域;
(2)当用commit 新建一个提交对象前,git会先计算每一个子目录的校验和,然后再git仓库中将这些目录保存为树对象。之后git创建的提交对象,除了包含相关提交信息外,还包含指向这个树对象(根目录)的指针。
2、git对象
git中最常见的就是40位16进制的ID号,查看提交记录
git log (-1 最近一次,没有表示所有) --pretty=raw
可以看到一次提交里有三个ID:
commit 本次提交的唯一标识
tree 本地提交所对应的目录树
parent 本次提交的父提交
研究git对象的一个常用的方式是
git cat-file -t [ID] 查看ID 类型 git cat-file -p [ID] 查看ID 内容
通过这个命令可以对历史提交进行追踪
3、git分支
(1) git通过创建一个新的分支指针来创建一个新的分支。
git branch testing
这会在当前commit对象上创建一个分支指针。
git 通过名为 HEAD 的特殊指针来确定当前正在哪个分支上工作。
(2) git checkout 分支名 ( 来切换工作分支, 同时HEAD 指针指向新的工作分支)
git checkout -b 分支名
相当于:
git branch 分支名
git checkout 分支名
此时,在新的分支(如 testing)中进行新的操作(如修改某个文件),则新的对象图为:
(3) 再回到master分支,进行操作,新的提交后的版本仍和testing分支不同,此时的版本图为
4、基本的分支与合并
(1)Fast Forward 合并
下图是将master 分支和 hotfix分支合并(二者在同一条链上)
(2)基本合并
下图将 master分支和iss53分支进行合并(二者不是在同一条链上)
此时,分支都已经合并到C6,所以iss53分支就没有用,可以进行删除。删除使用 git branch -d iss53
(3)冲突的合并
如果修改了两个待合并的分支的同一个文件的同一部分,则git无法干净的将两个分支合并到一起。git做了合并,但没有提交,会等待用户进行冲突解决。
解决的方法是,通过git add 选择一个file进行暂存,并提交。
5、分支管理
git branch
查看当前存在的所有分支
git branch -v
查看所有分支最后一次commit的信息
git branch --merge (--no-merge)
查看分支中哪些分支合并到了当前分支 (未合并到当前分支)
6、分布式工作流程
(1)长期分支
由于git使用简单的三方合并,所以可以拥有多个开放的分支,每个分支用于完成一个特定的任务,随着开发的推进,你可以随时将某个特性的 分支成果合并到另一个分支中。
(2)特性分支
特性分支是短期的、用于实现单一特性或与其相关工作的分支。
(3)远程分支
远程分支是对远程仓库状态的索引,他们是无法移动的本地分支,只有在进行git的网络活动时才会更新。用 远程仓库名/远程分支名 来表示远程分支。
如果想和他人分享本地的一个分支,需要把它推送到一个自己具有写权限的远程仓库。本地分支不会自动同步到引入的远程分支,除非明确执行推送操作。
(4)跟踪分支
从远程分支检出的本地分支,成为跟踪分支。跟踪分支是一种和远程分支有直接联系的本地分支。在跟踪分支里输入 git push, Git会自动判断要向哪个服务器的哪个分支上push;在跟踪分支里 git pull, 会自动将对应的远程服务器上的远程分支下载到本地。
创建跟踪分支: git checkout -b 跟踪分支名 远程名/分支名