版本控制
版本控制是一种记录一个或若干文件内容变化,以便将来查阅特定版本修订情况的系统
版本控制历史
- 本地版本控制系统
- 集中化的版本控制系统
- 分布式版本控制系统
git起步
git与传统版本控制系统的区别
三种状态
-
commited
- 已安全的保存到数据库中,已经在仓库里了
-
modified
- 文件刚修改时的状态,还没有add
-
staged
- add之后进入暂存区
工作流程
- 修改文件
- 放入暂存区
- 提交更新,将快照永久性存储到Git仓库目录
安装
初次运行时的配置
-
用户信息
- 用户名:git config --global user.name "John Doe"
- 邮箱: git config --global user.email johndoe@example.com
-
默认编辑器是Vim,可以使用如git config --global core.editor emacs更换
-
使用git config --list检查配置信息,使用git config
检查某一项配置 -
获取帮助
- git help
- git
--help - man git-
- 例:git help config
- git help
git基础
获取git仓库
- 本地初始化 git init
- 克隆现有仓库 git clone [url]
记录每次更新到仓库
-
git status 查看哪些文件处于什么状态
-
Untracked files下表示未被追踪的文件,也就是之前的快照中没有,即新建之后还没有add的文件,可使用git add 开始跟踪一个文件
-
Changes to be commited说明在暂存状态,待commit
-
Changes not staged for commit下表示已跟踪文件的内容发生了变化,但还没有放到暂存区,可以使用git add将其放入暂存区
-
将git add理解为“添加内容到下一次提交中”而不是“将一个文件添加到项目中”要更加合适
-
git status -s 或者 --short输出简洁的结果
-
新添加的未追踪文件前面有 ?? 标记
-
新添加到暂存区的文件前面有 A 标记
-
修改过的文件前面有 M 标记
- 靠左边表示修改了并放入了暂存区
- 靠右边表示修改了还未放入暂存区
-
-
-
忽略文件 .gitignore文件
-
所有空行或者以#开头的行都会被Git忽略
-
可以使用标准的glob模式匹配(shell所使用的简化版正则表达式)
-
- 匹配0个或多个任意字符
- [abc]匹配任何一个列在方括号中的字符
- ?只匹配一个任意字符
- 在方括号中使用短划线分隔两个字符,表示所有在这两个字符范围内的都可以匹配
- 使用两个星号(*) 表示匹配任意中间目录,比如
a/**/z
可以匹配 a/z, a/b/z 或a/b/c/z
等
-
-
匹配模式可以以(/)开头防止递归
-
匹配模式可以以(/)结尾指定目录
-
要忽略指定模式以外的文件或目录,可以在模式前加上(!)取反
-
-
git diff 查看已暂存和未暂存的修改
- 直接使用git diff 查看尚未暂存的文件更新了哪些部分
- 使用git diff --cached/staged 查看已暂存的将要添加到下次提交里的内容(已暂存未提交的修改)
- 使用 git difftool 命令来用 Araxis ,emerge 或 vimdiff 等软件输出 diff 分析结果。 使用 git difftool --tool-help 命令来看你的系统支持哪些 Git Diff 插件。
-
提交更新 git commit
- 直接使用会进入文本编辑器供记录提交说明,文本编辑器内会提供status的结果,-v参数可以将status结果变为diff结果
- -m参数可以把提交说明直接附在后面
- 提交结束后git会报告在哪个分支提交的以及本次提交的哈希值(基于SHA-1)
-
跳过使用暂存区域
- 给 git commit 加上 -a 选项,Git 就会自动把所有已经跟踪过的文件暂存起来一并提交,从而跳过 git add 步骤
-
移除文件:从暂存区移除
-
使用git rm移除,并连带从工作目录中删除文件, -f强制删除
-
只从暂存区删除,而不删除源文件,使用git rm --cached
-
git rm后的文件名也可以使用glob模式,如
- git rm log/*.log删除log/目录下拓展名为.log的所有文件
- git rm *~ 删除以~为结尾的所有文件
-
-
移动文件(重命名)
-
git mv file_from file_to相当于这三条命令
- mv file_from file_to
- git rm file_from
- git add file_to
-
查看提交历史git log
-
-p显示每次提交的内容差异
- -2显示最近的两次提交
-
--stat 看到每次提交的简略的统计信息
-
--pretty 指定使用不同于默认格式的方式展示提交历史
- =oneline 会把每个提交放在一行显示
- =short 输出中没有日期信息
- =full 貌似是区分了作者和提交者
- =fuller 貌似是在full的基础上加上了时间
- =format 可以定制要显示的记录格式
- 作者 和 提交者 之间究竟有何差别, 其实作者指的是实际作出修改的人,提交者指的是最后将此工作成果提交到仓库的人。 所以,当你为某个项目发布补丁,然后某个核心成员将你的补丁并入项目时,你就是作者,而那个核心成员就是提交者
-
--since/--until
- 如git log --since=2.weeks
-
--author显示指定作者的提交,--committer
-
--grep选项搜索提交说明中的关键字
-
要得到同时满足两个搜索条件的提交要使用--all-match,斗则所有满足二者之一的都会被搜索出来
-
-S 显示添加或移除了某个关键字的提交
撤销操作
-
提交完了才发现漏掉了几个文件没有添加,或者提交信息写错了,可以使用git commit --amend
- git commit -m "initial commit"
- git add forgotten_file
- git commit --amend
- 这样最终只会有一个提交,第二次提交将替代第一次提交的结果
-
取消暂存的文件
-
git reset HEAD
- 使用--hard选项需谨慎
-
-
撤销对文件的修改
-
git checkout -- [file]
- 是拷贝了另一个文件来覆盖它,所以要慎重使用
-
远程仓库的使用
-
查看远程仓库 git remote
- 至少能看到Git给我们所克隆的仓库服务器的默认名字origin
- -v 选项显示简写+url
-
添加远程仓库 git remote add
-
从远程仓库中抓取和拉取 git fetch [remote-name]
- 该命令会把数据拉取到本地,但不会自动合并,注意与pull的区别
-
推送到远程仓库 git push [remote-name] [branch-name]
- 如 git push origin master
-
查看远程仓库 git remote show [remote-name]
-
git remote rename
-
git remote rm
打标签
-
列出标签
- git tag 以字母顺序列出标签
- -l 'v1.8.5*'以某一模式查找标签
-
创建标签
-
附注标签
- git tag -a [version] -m " "
-
轻量标签
- git tag [verison]
-
git show [version]
-
-
后期打标签
- git tag -a [version] 那次提交的校验和(或部分校验和)
-
共享标签
-
git push 不会提交tag,需要显式的提交
- git push origin [tagname]
- git push origin --tags
-
-
检出标签
- git checkout -b [branchname] [tagname]
Git别名
- git config --global alias.[new] '[old_command]'
- 若是git外的命令需要在命令前加!
Git分支 必杀技特性
分支简介
- git branch [branchname] 创建分支
- git branch -d [branchname]删除分支
- git checkout [branchname] 切换分支
- git log --decorate 查看当前分支信息
分支创建与合并
-
git checkout -b [branchname]创建分支并切换过去,相当于两条命令
-
git merge [branchname]合并分支
- 当分支有冲突时要处理冲突文件然后git commit 完成合并提交
- git mergertool 使用图形化工具
分支管理
-
git branch 查看分支列表
- 前面带*表示当前检出的分支,即HEAD指向的
- -v 参数可以查看分支列表及它们的最后一次提交
-
git branch --merged查看已被当前检出的分支合并的分支,未带*表示已被合并,可以直接-d删除掉
-
git branch --no-merged查看未被合并的分支,若其中包含未合并的工作,则不能直接删除,若要删除可使用-D强制删除
分支开发工作流
-
长期分支
- master
- develop
- topic
-
特性分支
远程分支
-
远程引用是对远程仓库的引用(指针),包括分支、标签
- git ls-remote (remote)查看列表
- git remote show (remote)详细信息
-
推送
-
git push (remote) (branch)将本地分支推送到远程仓库
- git push (remote) (localbranch):(remote branch)可用于推送到与本地名字不同的分支
-
其他人可使用git fetch origin获取这个分支并将其合并到自己分支
-
需要注意的是,不会有一个新的 serverfix 分支 , 只有一个不可以修改的 origin/serverfix 指针,这里的其他人不能直接在上面工作
- 可以通过git checkout -b (branch) (remote)/(branch)在远程分支上建立一个用于工作的本地分支
-
-
-
跟踪分支
-
使用git checkout --track (remote)/(branch)便捷实现上一条命令,只是不能重命名
-
设置已有的本地分支跟踪一个远程分支
- git branch -u (remote)/(branch)
-
跟踪的分支是直接可以pull 的
-
-
拉取
-
pull相当于两个操作,更推荐两个操作分开进行
- git fetch
- git merge
-
-
删除远程分支
- git push [remote] --delete [branch]
变基
-
变基的定义:replay
- git checkout test
- git rebase master
- git checkout master
- git merge test
-
更有趣的变基例子
-
git rebase --onto master server client
- 取出 client 分支,找出处于 client 分支和 server 分支的共同祖先之后的修改,然后把它们在 master 分支上重放一遍
-
git rebase [basebranch] [topicbranch]
- git checkout [topicbranch]
- git rebase [basebranch]
-
-
变基的风险
- 原则:不要对在你的仓库外有副本的分支变基
-
用变基解决变基的风险
- git pull --rebae
-
变基 vs 合并
分布式Git
分布式工作流程
-
集中式工作流
- 类似于SVN等传统工作方式
-
集成管理者工作流
- 最常见,如Github、Gitlab
-
司令官与副官工作流
- 如Linux
向一个项目贡献
-
提交准则
-
提交前使用运行git diff --check检查空白错误
-
不要一次性提交大量变更,将它们拆分开
- git add --patch可以暂存一个文件中的部分
-
优质的提交信息
-
-
私有小型团队
-
私有管理团队
-
派生的公开项目(Github那种)
- 先clone下来做修改
- fork
- git remote add myfork(url)
- git push -u myfork featureA
- git request-pull或者点击PullRequest
- 几个进阶操作
-
通过邮件公开项目
维护项目
-
在特性分支中工作
-
应用来自邮件的补丁
- git apply
- git am
-
检出远程分支
-
确定引入了哪些东西
-
将贡献的工作整合进来
-
为发布打标签
- 注意公钥问题
-
生成一个构建号
- git describe
-
准备一次发布,为不使用git的人创建一个最新的快照归档
- git archive master --prefix='project/' | gzip >
git describe master
.tar.gz - 使用--format=zip可以得到zip包
- git archive master --prefix='project/' | gzip >
-
制作提交简报
- 使用 git shortlog 命令可以快速生成一份包含从上次发布之后项目新增内容的修改日志(changelog)类文档
XMind: ZEN - Trial Version