目录
git从放弃到入门
- 本质:一套内容寻址的文件系统
git 命令操作的图形化
http://onlywei.github.io/explain-git-with-d3/
.git目录及内容
git对象模型
对象名
- 对文件用哈希算法进行计算,然后生成40个字符的字符串用来表示对象名
- 字符串由对象内容做SHA-1哈希计算得来
- 通过比较SHA-1值来比较两个文件的内容
blob
存储文件数据,通常是一个文件,当文件修改后会生成,可以看做是文件的快照
blob对象内容全是二进制格式数据
tree
类似一个目录,用于管理tree和blob
包括:mode、对象类型、SHA1值、名字
- 一串指向blob或其它tree对象的指针
-
表示目录树的内容、内容之间的层次目录关系
commit
每次使用
commit
进行一次提交就会生成一个commit对象
commit对象指向一个tree对象,标记项目某个特定时间点的状态
tag
用来标记某一个提交(commit)
git引用
分支branch
HEAD:表示当前指向的分支
标签tag
指向某个分支的commit对象
git tag [tag name] //添加轻量级tag
git tag -a -m "tag messge" [tag name] //添加重量级tag
- 轻量级tag为commit对象
-
重量级tag为tag对象,包含提交人和提交信息,会在对象库中生成对象保存起来.
对象库位于.git/objects
git的三种状态
已提交(committed)
- 已修改表示修改了文件,但还没保存到数据库中
已修改(modified)
- 已暂存表示对一个已修改文件的当前版本做了标记,使之包含在下次提交的快照中
已暂存(staged)
- 已提交表示数据已经安全地保存在本地数据库中
三大工作区状态转换
git的三个阶段
工作目录(Working Directory)
工作区是对项目的某个版本独立提取出来的内容。 这些从 Git 仓库的压缩数据库中提取出来的文件,放在磁盘上供你使用或修改。
-
git版本库
位于工作目录中,要想
git版本库
添加文件需要文件位于工作目录下
暂存区域(Sraging Area)
暂存区是一个文件,保存了下次将要提交的文件列表信息,一般在 Git 仓库目录中。 按照 Git 的术语叫做“索引”,不过一般说法还是叫“暂存区”。
存放在.git目录中名为index的一个文件.
git仓库(版本库)
Git 仓库目录是 Git 用来保存项目的元数据和对象数据库的地方。 这是 Git 中最重要的部分,从其它计算机克隆仓库时,复制的就是这里的数据。
git基本流程
一般工作流程如下:
- 克隆 Git 资源作为工作目录。
- 在克隆的资源上添加或修改文件。
- 如果其他人修改了,你可以更新资源。
- 在提交前查看修改。
- 提交修改。
-
在修改完成后,如果发现错误,可以撤回提交并再次修改并提交。
下图展示了 Git 的工作流程:
基本的 Git 工作流程如下:
- 在工作区中修改文件。
- 将你想要下次提交的更改选择性地暂存,这样只会将更改的部分添加到暂存区。
- 提交更新,找到暂存区的文件,将快照永久性存储到 Git 目录。
如果 Git 目录中保存着特定版本的文件,就属于
已提交
状态。 如果文件已修改并放入暂存区,就属于
已暂存
状态。 如果自上次检出后,作了修改但还没有放到暂存区域,就是
已修改
状态。 在 Git 基础 一章,你会进一步了解这些状态的细节, 并学会如何根据文件状态实施后续操作,以及怎样跳过暂存直接提交。
专业术语中英文对照
Linux下安装git
sudo apt-get install git
可能会出现以下情况
E: Could not open lock file /var/lib/dpkg/lock-frontend – open (13: Permission denied)
E: Unable to acquire the dpkg frontend lock (/var/lib/dpkg/lock-frontend), are you root?
解决方法可参考:
解决方法
.
查看当前git版本
git --version
新建仓库 git init
git配置 git config
–global
- 添加–global选项表示全局修改
- 若无–global选项表示仅仅修改当前用户/仓库的配置
配置姓名,邮箱,颜色,别名
- 配置自己本地姓名,用于提交时分辨哪个用户提交.
git congif --global user.name "SnowyNight"
- 配置自己本地邮箱,用于提交时分辨哪个用户提交.
git congif --global user.email"Email@163.com"
- 配置自己本地文件名字颜色,用于区分不同类型的文件.
git congif --global color.ui true
- 配置自己本地git命令的别名,将init设置别名为it.
git congif --global alias.it init
- 查看用户配置
git config --list
命令自动补全
如果命令无法自动补全需要从官网下载配置文件脚本.
参数选项说明
-
–global:修改全局配置文件,会去修改~/.gitconfig文件
- –system:修改所有用户的配置文件:/etc/gitconfig文件
-
无参数:修改本仓库配置文件:.git/config
工作区修改,保存修改,提交修改
查看状态 git status
git add
- 将工作区的内容添加到暂存区
- 已经追踪的文件:将修改从工作区保存到暂存区
- 未追踪的文件:加入git追踪范围
git add readme
git add ./
git commot
- 将暂存区的内容提交到版本库
- 单步提交:git commit –m “commit info”
- 一次性提交:git commit –a
- 修改最后一次提交:git commit –amend //更新(改)最后一次提交
git commit -m "add message"
-
如果不添加
-m
选项来添加信息将会进入一个文本编辑界面进行文本编辑,输入添加信息后保存退出即可提交成功.
查看提交历史 git log
git log
git log -c //查看修改内容
git log -p //查看修改内容
git reflog //查看隐藏的历史提交
git log -2 //显示最近的两次提交
单行显示 git log –oneline
git log --pretty=oneline //单行显示
git log --oneline //更简短的单行显示
git log --oneline //更简短的单行显示最近3行
拓扑图显示 git log –graph
git log --graph
图形化工具gitk
命令行运行gitk(需安装gitk)
使用
sudo apt-get install gitk
进行安装
统计提交历史git shortlog
查看某个提交具体修改git show [哈希值]
修改后的提交
查看提交差异 git diff
一次性从工作区到版本库提交(不建议使用)
不建议使用改方法,因为工作可能存在大量不相关文件,如备份文件等
git commit -a -m "commit messge"
git commit -am "commit messge"
查看具体文件修改历史git blame
- 可以知道具体文件每行具体添加或修改的时间和内容
git blame file
- 查看第1到3行代码是谁的提交:
git blame file.c –L 1,+3
更多参数
克隆一个远程仓库 git clone
文件删除 git rm / git reset
- git rm [file] //从暂存区和工作区删除
- git rm -f [file] //强制从工作区和暂存区删除
- git rm –cached [file] //从暂存区删除
- git reset –soft HEAD^ // 撤销提交到暂存区
- git reset –mixed HEAD^ //撤销提交工作区
- git reset –hard HEAD^ //将工作区,暂存区,版本库恢复到指定版本
文件重命名
- git mv [old_file] [new_file]
分支和标签
- git仓库创建时会默认有一个master分支(主分支)
创建分支git branch [branch name]
git branch newbranch
切换分支git checkout [branch name]
查看分支git branch
创建标签git tag [tag name]
git tag tagnanme
查看标签git tag
删除标签
git tag -d v1.0
查看标签对应修改 git show [tag name]
git show v1.0
忽略文件
- 命名.gitignore
- 忽略以#开头的行,即注释
- 忽略某种格式结尾文件:*.[abc] 此处忽略以.a .b .c结尾的文件
- 忽略临时文件 *~
- 忽略某个目录或文件 /catalogfile
- 忽略某个目录下的指定文件或所有文件 /catalog/ 或 /catalog/*.a
撤销修改
撤销工作区的修改 git checkout [file]
- 撤销工作区文件的修改(修改或删除等操作)
- 若文件没有添加到暂存区则撤销至版本库一样的内容
- 若文件已经添加到暂存区且做了修改则撤销到暂存区状态
git checkout filename
撤销暂存区的内容
- 将暂存区的修改撤销掉,重新放回工作区
git reset HEAD file
撤销版本库的提交
git reset --hard HEAD^
差异比较
- 比较三个工作之间的差异
比较工作区和暂存区的差异
git diff
比较暂存区和版本库的差异
git diff --cached [HEAD]
git diff --staged HEAD^
比较工作区和版本库的差异
git diff HEAD(SHA1)
比较两个版本之间的差异
git diff SHA1 SHA2
压缩仓库
压缩版本库
- 通过git gc命令压缩增量存储单元,节省磁盘空间
快照的存储
- 对于修改的内容:做快照处理并保存
- 对于未修改的文件:做引用处理
版本回退
- git reset 从版本库回退到工作区
- git reset –soft 从版本库回到暂存区
- git reset –hard从版本库和工作目录中删除提交
git reset HEAD^ //回退到上一个版本
git reset SHA //回退到某个版本,可以回到之后或之前的版本,但需要有该版本的哈希值
提交查找 git grep
git grep t //查找当前目录下关键字 t
git grep -n 1 //查找当前目录下关键字 1 同时显示行号
git grep --name-only t //查找当前目录下包含关键字 t 的文件
git grep -c t //查找当前目录下包含关键字 t 的文件有多少个匹配
git grep t v1.2//查找v1.2版本下包含关键字 t 的文件有多少个匹配
git grep -e t --and -e 1 // 查找当前目录下同时包含关键字 t 和 1的文件
git grep -e t --or -e 1 // 查找当前目录下包含关键字 t 或 1的文件
提交修改
- 修改最后一次提交:修改提交信息或者内容
git commit --amend
git revert SHA //反转(恢复)某次提交,需要解决冲突
解决冲突
可以用 vi 编辑器手动解决冲突
可以用 git mergetool 图形化工具来解决冲突
提交排序/合并提交 git rebase
git rebase -i HEAD~3 [SHA] //编辑提交信息,可能会产生冲突
解决冲突:
1.修改文件 vim file
2.提交 git add file
3.git rebase –continue
- 合并提交会生成一个新的commit对象
修改成如下
提交分解
修改为
- 修改文件
- git add file
- git commit –amend //一定要用这个进行提交
- 修改文件
- git add file
- git commit -m “messge”
- 修改文件
- git add file
- git commit -m “messge”
- …
- git rebase continue
分支
- master 主分支,指向主分支的最新提交
- HEAD 指向当前分支的最新提交
- tag 标签,指向某个分支的某个提交
创建新分支
- git branch new //创建一个名为new的新分支
- git branch new SHA //在SHA节点创建一个名为new的新分支
- git checkout -b new //创建一个名为new的新分支并跳转到新分支
查看/切换 分支
切换分支会更新工作区和暂存区的内容,所以切换前务必检查
- git branch
- git branch -v
-
git checkout file
- git branch –merged //查看已经合并的分支
- git branch –no-merged //查看未合并的分支
分支重命名 git branch -m
git branch -m oldbranchname newbranchname
git branch -M oldbranchname newbranchname //强制重命名,即使有重名的分支存在也修改
删除分支 git branch -d
git branch -d branchname
git branch -D branchname //强制删除分支,即使分支未合并
合并分支 git merge branchfile
git merge dev //将dev分支合并到当前分支(快速提交)
冲突解决
- 当两个分支对同一个文件做了修改,在合并的时候会产生冲突.
存在冲突会出现以下情况
图中 ======== 分割不同commit版本的代码
解决冲突即保留需要的信息,并删除>>>>和====和<<<<信息.
然后重新添加并提交.
合并后会产生一个新的commit
图像化工具解决冲突 git mergetool
- git config –global diff.tool vimdiff //配置工具
- git mergetool //运行
压合提交 git merge –squash branchname
将某个分支的多个提交合成一个提交
挑选合并 git cherry-pick
-
挑选一个提交,添加到当前分支末梢
git cherry -pick SHA
压栈 git stash
- 当需要切换到其他分支工作,但当前分支内容未达到需要提交的情况时使用.
git stash //压栈
git stash list //查看栈中内容
git stash apply //将工作内容恢复,但栈中内容不删除
git stash pop //将工作内容恢复,并将栈中内容删除
git stash clear //清除栈中全部内容
git stash apply stash@{n} //恢复栈中某个内容
恢复已删除的分支的某个提交
- 删除分支仅仅只是删除指针,但commit对象依然存在于版本库
git fasck --lost-found //列出未加入链表的对象
git show SHA //查看提交信息
git rebase SHA //衍合提交
git merge SHA // 合并提交
使用git branch 查看分支时出现git no branch
-
造成no branch的原因
与远程存在冲突,push/pull后可能会切换到此状态
其实是指在某个未知的commit上,可以看作是一个匿名的branch
解决方法
-
如果改动较小
看一下提交ID:git log
切换到要合并的分支上master: git checkout master
直接将该提交ID合并到当前分支:git merge SHA -
如果改动较大
先建一个新分支:git checkout –b temp SHA1
再对该分支进行提交或合并处理: git merge temp -
如果你已经不在 no branch上,切换不到no branch上了
找回丢失的commit_ish:git reflog | git fsck –lost-found
检出提交并备份到新分支上:git checkout SHA; git checkout –b tmp ;
或者直接合并到master分支:git checkout master; git merge SHA
此时的SHA可以看作一个匿名的branch
远程仓库
协议
-
SSH
同时支持读和写的网络协议,Git默认使用的网络协议
优点:安全性高,数据传输都是加密和授权的
缺点:不能匿名访问,读也要授权,不利于开源的项目 -
git
git自带的网络协议:适用于不需要对读进行授权的大型项目
优点:传输速度最快
缺点:授权机制不灵活,要么不能推送,要么都能推送 -
HTTP/HTTPS
优点:容易架设,适用于提供只读的仓库、防火墙穿透强
缺点:传输速度慢、开销大
SSH Key
SSH公钥生成
-
查看 ~/.ssh
id_rsa 密钥
id_esa.pub 公钥 ,用于服务器 -
生成密钥
ssh-keygen -t rsa –C “user@163.com” -
验证key是否添加成功
ssh –T git@github.com
添加远程仓库
- git remote add origin_name git@gitee.com:snowy-night/git_learn.git
查看远程仓库 git remote -v
git remote
git remote -v
推送 git push
-
git push origin_name branch_name
克隆 git clone
git clone addr
从远程仓库拉取数据
git fetch //仅仅拉取,不合并到本地
git pull //自动拉去某个分支更新
删除远程仓库
git remote rm origin_name
远程仓库重命名
git remote rename old_name new_name
远程分支
查看所有分支 git branch -a
git branch -a
红色为远程分支
跟踪远程分支
git checkout –b local_branch origin/mybranch2
git push local_branch 建立关联后,就可以直接进行pull和push
指定分支提交
git push origin mybranch:otherbranch
删除远程分支
git push origin [空格]:remote_branch
远程仓库合并
1.先git fetch将分支拉取到本地
2.用git rebase合并,并解决冲突
3.git push推送
远程仓库的标签
检出 git checkout v1.0
git checkout v1.0
删除远程标签
git tag –d v1.0 //先删除本地
git push origin :refs/tags/v1.0 //再删除远程标签