以下所有内容摘自廖雪峰老师的Git 教程。
一. 简介
- Git是开源的分布式版本控制系统
- 版本控制系统介绍:
- 开源的集中式版本控制系统: CVS(会造成提交文件不完整,版本库莫名其妙损坏的情况), SVN(修正了CVS的稳定性问题,是目前用的最多的集中式版本控制系统)
收费的集中式版本控制系统:IBM的ClearCase:占内存,运行慢; 微软的VSS
- 分布式版本控制系统:Git, BitKeeper, Mercurial, Bazaar
- 集中式 VS 分布式
- 集中式版本控制系统:版本库是几种存放在中央服务器的
二. 创建版本库:
- 创建版本库:mkdir -> git init
把文件添加到版本库:git add -> git commit -m + file name
Tips: 所有的版本控制系统,其实只能跟踪文本文件的改动,比如TXT文件,网页,所有的程序代码;没法跟踪二进制文件如图片视频的具体改动内容
三. 时光机穿梭
- 一些命令:
Git status: 查看仓库当前状态
Git diff + file name: 查看文件具体的修改内容
git diff: 是工作区(work dict)和暂存区(stage)的比较
git diff --cached: 是暂存区(stage)和分支(master)的比较
Git log: 查看修改的历史记录;显示从最近到最远的提交日志
Git log --prettty=online: 显示从最近到最远的提交日志,只显示commit id,和修改的内容
Git reflog:记录每一次命令(包含commit id,操作的命令,文件名)
- 版本回退:
HEAD表示当前版本,即最新提交的版本。
HEAD^表示上一个版本
HEAD^^表示上上一个版本
HEAD~100表示往上100个版本
回退到上一个版本:Git reset --hard HEAD^
回退到任意版本:Git reset --hard + Commit id
HEAD is now at ea34578 add distributed:HEAD指向的版本就是当前的版本
- HEAD指向的版本就是当前版本,因此,Git允许我们在版本的历史之间穿梭,使用命令git reset --hard commit_id。
- 穿梭前,用git log可以查看提交历史,以便确定要回退到哪个版本。
- 要重返未来,用git reflog查看命令历史,以便确定要回到未来的哪个版本。
- 工作区和暂存区
工作区(Working Directory):就是你在电脑里面能看到的目录
版本库(Repository):工作区有一个隐藏目录.git,这个不算工作区,而是GIt的版本库。Git的版本库存了很多东西,其中最重要的就是暂存区stage(也叫index),还有Git为我们自动创建的第一个分支master,以及指向master的一个指针HEAD
git add命令实际上就是把要提交的所有修改放到暂存区(Stage),然后,执行git commit就可以一次性把暂存区的所有修改提交到分支。
- 管理修改
Git跟踪并管理的是修改,而非文件。每次修改,如果不add到暂存区,就不会加入到commit中。暂存区的文件可以一起提交。所以修改一定要先add,可以一起commit.
- 撤销修改
把文件在工作区的修改全部撤销掉: Git checkout -- [File name] (让文件回到最近一次git commit或 git add时的状态)
把文件在暂存区的修改撤销掉,需要两步:1. git reset HEAD file; 2. Git checkout -- [File name]
把文件在commit之后但是没有推送到远程库的修改撤销掉:1. Git reset --hard + Commit id;;2. git reset HEAD file;3. Git checkout -- [File name]
- 删除文件
删除文件:git rm + [File name]
删除也是一个修改操作,如果误删的话可以通过第四部分的管理修改章节进行恢复。
- 总结
注:git的commit id是一个SHA1计算出来的数字,用十六进制表示。目的是为了避免多个用户在同一个版本库里面工作时起冲突。
四. 远程操作
Git是分布式版本控制系统,同一个Git仓库,可以分布到不同的机器上面。每台机器有一个原始版本库,其他的机器可以克隆这个原始的版本库,而且每台机器的版本库其实都是一样的,没有主次之分。
- 远程仓库:
获得Git远程仓库:自己搭建一台运行Git的服务器/注册一个GitHub账号并创建SSH key
GitHub:提供Git仓库托管服务。注册一个GitHub的账号,就可以免费获得Git远程仓库。
- 添加远程库
- 要关联一个远程库,使用命令git remote add origin git@server-name:path/repo-name.git;
- 关联后,使用命令git push -u origin master第一次推送master分支的所有内容;
- 此后,每次本地提交后,只要有必要,就可以使用命令git push origin master推送最新修改;
- 分布式版本系统的最大好处之一是在本地工作完全不需要考虑远程库的存在,也就是有没有联网都可以正常工作,而SVN在没有联网的时候是拒绝干活的!当有网络的时候,再把本地提交推送一下就完成了同步,真是太方便了
- 从远程库克隆
- 要克隆一个仓库,首先必须知道仓库的地址,然后使用git clone命令克隆。
- Git支持多种协议,包括https,但通过ssh支持的原生git协议速度最快。
五. 分支管理
(一)创建与合并分支
- Master是主banch
- 一开始的时候,master分支是一条线,git用master指向最新的提交,再用HEAD指向master;每次提交,master分支都会向前移动一步。
- 一些命令:
查看分支:git branch
创建分支:git branch + [branch name]
切换分支:git checkout + [branch name]
创建+切换分支:git checkout -b + [branch name]
合并某分支到当前分支:git merge + [branch name]
删除分支:git branch -d + [branch name]
(二). 解决冲突:
- 当Git无法自动合并分支时,就必须首先解决冲突,解决冲突后,再提交,合并完成
- 用git log --graph命令可以看到分支合并图
- 解决冲突并提交之后,两个branch都会到最新版本
- 合并分支时,加上--no-ff 参数就可以用普通模式合并,合并后的历史有分支,能看出来曾经做过合并,而fast forward合并就看不出来曾经做过合并。
git merge --no-ff -m "merge with no-ff" dev
(三). Bug 分支
- 修复bug时,我们会通过创建新的bug分支进行修复,然后合并,最后删除;
- 当手头工作没有完成时,先把工作现场git stash一下,然后去修复bug,修复后,再git stash pop,回到工作现场。
add并commit的是正常的普通的dev分支,切换分支会隐藏
add并没有commit的是stash的使用条件,切换分支也会隐藏
没有add没有commit是普通文件,切换分支也不会隐藏起来
- 可通过git stash list查看stash的内容
(四). 删除没有合并过的分支:git branch -D <name>
(五). 多人协作:
- 查看远程库信息,使用git remote -v;
- 本地新建的分支如果不推送到远程,对其他人就是不可见的;
- 从本地推送分支,使用git push origin branch-name,如果推送失败,先用git pull抓取远程的新提交;
- 在本地创建和远程分支对应的分支,使用git checkout -b branch-name origin/branch-name,本地和远程分支的名称最好一致;
- 建立本地分支和远程分支的关联,使用git branch --set-upstream branch-name origin/branch-name;
- 从远程抓取分支,使用git pull,如果有冲突,要先处理冲突。
(六). 标签管理
- 标签是版本库的一个快照(tag),相当于指向某个commit的指针,是一个容易记住的名字
- 创建标签:切换到需要打标签的分支上,然后git tag <tagname>。此时标签默认打到最新的commit上面
- 指定标签信息:git tag -a <tagname> -m "xxxx"
- 查看所有标签:git tag
- 查看标签信息: git show <tagname>
- 给之前提交的commit打标签:git tag <tag name> <commit id>
- 删除本地标签: git tag -d <tagname>
- 推送标签到远程:git push origin <tagname>
- 删除远程标签:1. git tag -d < tagname> 2. git push origin :refs/tags/<tagname>
(七). 自定义git
- 显示颜色:git config --global color.ui true
- 配置别名:
Git config --global alias.st status (设置git st = git status)
每个仓库的配置文件存放在.git/config中
当前用户的git配置文件放在用户主目录下的一个隐藏文件.gitconfig中
配置别名也可通过直接更改配置文件
友情附赠国外网友制作的Git Cheat Sheet,建议打印出来备用:Git Cheat Sheet