Pro Git
2022-05-24 23:17:16 20 举报
AI智能生成
git
作者其他创作
大纲/内容
本地版本控制系统
集中化
分布式
版本控制系统分类
直接记录快照,而非差异比较
Git 在本地磁盘上就保存着所有当前项目的历史更新
近乎所有操作都是本地执行
时刻保持数据完整性
多数操作仅添加数据
已修改
已暂存
已提交
状态
子主题
图示
文件的三种状态
git基础
1.起步
在工作目录中初始化新仓库
git clone [url]
从现有仓库克隆
获取git仓库
git diff --cached
已经暂存起来的文件和上次提交时的快照之间的差异
git commit
提交更新
git commit -a
跳过使用暂存区域
git rm <file>
移除文件
git mv file_from file_to
等价$ mv README.txt README $ git rm README.txt $ git add README
移动文件并改名
git status
检查当前文件状态
git add <file/url>
跟踪新文件/存放到暂存区
.gitignore
忽略某些文件
git diff
比较的是工作目录中当前文件和暂存区域快照之间的差异,也就是修改之后还没有暂存起来的变化内容。
查看尚未暂存的文件更新了哪些部分
记录每次更新到仓库
git log
查看提交历史
git commit --amend
修改最后一次提交
git reset HEAD <file>...
取消已经add暂存的文件
git checkout -- <file>...
取消对文件的修改
撤消操作
git remote -v
查看当前的远程库
git remote add [shortname] [url]
添加远程仓库
git fetch [remote-name]
会到远程仓库中拉取所有你本地仓库中还没有的数据。运行完成后,你就可以在本地访问该远程仓库中的所有分支
fetch 命令只是将远端的数据拉到本地仓库,并不自动合并到当前工作分支
抓取目标远程仓库最新信息
git push [remote-name] [branch-name]
推送数据到远程仓库
git remote show [remote-name]
查看远程仓库信息
git remote rename [oldName] [newName]
对远程仓库的重命名,也会使对应的分支名称发生变化
远程仓库的删除
git remote rm [remoteName]
远程仓库重命名
远程仓库的使用
同大多数 VCS 一样,Git 也可以对某一时间点上的版本打上标签。人们在发布某个软件版本(比如 v1.0 等等)的时候,经常这么做
git tag
列显已有的标签
打标签
2.基础
在 Git 中提交时,会保存一个提交(commit)对象,该对象包含一个指向暂存内容快照的指针,包含本次提交的作者等相关附属信息
当使用 git commit 新建一个提交对象前,Git 会先计算每一个子目录(本例中就是项目根目录)的校验和,然后在 Git 仓库中将这些目录保存为树(tree)对象。之后 Git 创建的提交对象,除了包含相关提交信息以外,还包含着指向这个树对象(项目根目录)的指针,如此它就可以在将来需要的时候,重现此次快照的内容了。
现在,Git 仓库中有五个对象:三个表示文件快照内容的 blob 对象;一个记录着目录树内容及其中各个文件对应 blob 对象索引的 tree 对象;以及一个包含指向 tree 对象(根目录)的索引和其他提交信息元数据的 commit 对象
单提交对象数据结构
作些修改后再次提交,那么这次的提交对象会包含一个指向上次提交对象的指针(译注:即下图中的 parent 对象)。两次提交后,仓库历史会变成图 3-2 的样子:
多个提交对象之间的链接关系
提交对象
何谓分支
本质上仅仅是个指向 commit 对象的可变指针。Git 会使用 master 作为分支的默认名字。在若干次提交后,你其实已经有了一个指向最后一次提交对象的 master 分支,它在每次提交的时候都会自动向前移动。
概述
git branch
-v : 连带最后一个提交对象的信息
查看当前分支的直接上游分支
--merge
尚未合并的分支
--no-merge
参数
查看
git branch <branch-name>
新增
git checkout <branch-name>
分支不存在则创建
-b
切换
git merge <branch-target>
讲目标分支合并入当前分支
快进: fast forward
多祖先合并
冲突合并
特别情况
合并
git branch -d <branch-name>
d大写化: 强制删除
删除
操作
Git 是如何知道你当前在哪个分支上工作的呢?其实答案也很简单,它保存着一个名为 HEAD 的特别指针
它是一个指向你正在工作中的本地分支的指针(译注:将 HEAD 想象为当前分支的别名。)
运行 git branch 命令,仅仅是建立了一个新的分支,但不会自动切换到这个分支中去
HEAD 指向当前所在的分支
HEAD
由于 Git 中的分支实际上仅是一个包含所指对象校验和(40 个字符长度 SHA-1 字串)的文件,所以创建和销毁一个分支就变得非常廉价。说白了,新建一个分支就是向一个文件写入 41 个字节(外加一个换行符)那么简单,当然也就很快了。
这和大多数版本控制系统形成了鲜明对比,它们管理分支大多采取备份所有项目文件到特定目录的方式,所以根据项目文件数量和大小不同,可能花费的时间也会有相当大的差别,快则几秒,慢则数分钟。而 Git 的实现与项目复杂度无关,它永远可以在几毫秒的时间内完成分支的创建和切换。同时,因为每次提交时都记录了祖先信息(译注:即 parent 对象),将来要合并分支时,寻找恰当的合并基础(译注:即共同祖先)的工作其实已经自然而然地摆在那里了,所以实现起来非常容易。Git 鼓励开发者频繁使用分支,正是因为有着这些特性作保障。
为什么非常快
长期分支
特性分支是指一个短期的,用来实现单一特性或与其相关工作的分支
特性分支
分支使用
远程分支(remote branch)是对远程仓库中的分支的索引。它们是一些无法移动的本地分支;只有在 Git 进行网络交互时才会更新。远程分支就像是书签,提醒着你上次连接远程仓库时上面各分支的位置
我们用 (远程仓库名)/(分支名) 这样的形式表示远程分支。比如我们想看看上次同 origin 仓库通讯时 master 分支的样子,就应该查看 origin/master 分支。如果你和同伴一起修复某个问题,但他们先推送了一个 iss53 分支到远程仓库,虽然你可能也有一个本地的 iss53 分支,但指向服务器上最新更新的却应该是 origin/iss53 分支。
与本地分支的区别
git fetch <remote-name>
从远程服务器获取你尚未拥有的数据,更新你本地的数据库,然后把 origin/master 的指针移到它最新的位置上
在 fetch 操作下载好新的远程分支之后(假设为serverfix),你仍然无法在本地编辑该远程仓库中的分支。换句话说,在本例中,你不会有一个新的 serverfix 分支,有的只是一个你无法移动的 origin/serverfix 指针。
更新远程分支信息
git push <remote-name>:<remote-branch>
你创建的本地分支不会因为你的写入操作而被自动同步到你引入的远程服务器上,你需要明确地执行推送分支的操作
推送本地分支
从远程分支 checkout 出来的本地分支,称为 跟踪分支 (tracking branch)。跟踪分支是一种和某个远程分支有直接联系的本地分支。在跟踪分支里输入 git push,Git 会自行推断应该向哪个服务器的哪个分支推送数据。同样,在这些分支里运行 git pull 会获取所有远程索引,并把它们的数据都合并到本地分支中来。
在克隆仓库时,Git 通常会自动创建一个名为 master 的分支来跟踪 origin/master。这正是 git push 和 git pull 一开始就能正常工作的原因
$ git checkout --track origin/serverfix Branch serverfix set up to track remote branch refs/remotes/origin/serverfix. Switched to a new branch \"serverfix\"
git checkout -b [分支名] [远程名]/[分支名]
简化版本 $ git checkout -b sf origin/serverfix Branch sf set up to track remote branch refs/remotes/origin/serverfix. Switched to a new branch \"sf\"
--track简化版: git checkout --track [远程名]/[分支名]
创建跟踪远程分支
git push [remote] --delete [branch-name]
git push [远程名] :[分支名]
推送空分支到远程
删除远程分支
跟踪远程分支
远程分支
合并结果中最后一次提交所指向的快照,无论是通过衍合,还是三方合并,都会得到相同的快照内容,只不过提交历史不同罢了。衍合是按照每行的修改次序重演一遍修改,而合并是把最终结果合在一起。
基本的变基
git rebase [主分支] [特性分支]
会先取出特性分支 server,然后在主分支 master 上重演
当前操作的即是即是特性分支
git rebase [主分支]
特别地:
命令
一旦分支中的提交对象发布到公共仓库,就千万不要对该分支进行衍合操作。
准则
如果把衍合当成一种在推送之前清理提交历史的手段,而且仅仅衍合那些尚未公开的提交对象,就没问题
建议
风险
分支的变基(衍合): rebase
3.分支
$ git clone file:///opt/git/project.git
本地协议
$ git clone ssh://user@server/project.git
优点
不支持匿名访问
缺点
SSH协议
现存最快的传输协议
git协议
架设简便
HTTP/S 协议
协议
4.服务器上的git
集中式工作流
集成管理员工作流
司令官与副官工作流
分布式工作流程
合作开发中的分支
项目的管理
5.分布式git
修订版本(Revision)选择
交互式暂存
经常有这样的事情发生,当你正在进行项目中某一部分的工作,里面的东西处于一个比较杂乱的状态,而你想转到其他分支上进行一些工作。问题是,你不想提交进行了一半的工作,否则以后你无法回到这个工作点。解决这个问题的办法就是git stash命令。“‘储藏”“可以获取你工作目录的中间状态——也就是你修改过的被追踪的文件和暂存的变更——并将它保存到一个未完结变更的堆栈中,随时可以重新应用
$ git stash Saved working directory and index state \\ \"WIP on master: 049d078 added the index file\" HEAD is now at 049d078 added the index file (To restore them type \"git stash apply\")
储藏
$ git stash list stash@{0}: WIP on master: 049d078 added the index file stash@{1}: WIP on master: c264051... Revert \"added file_size\" stash@{2}: WIP on master: 21d80a5... added number to log
查看储藏列表
git stash apply [stashName]
不指定储藏名默认最近的储藏
应用储藏
取消储藏
从储藏中创建分支
$ git commit --amend
这会把你带入文本编辑器,里面包含了你最近一次提交说明,供你修改。当你保存并退出编辑器,这个编辑器会写入一个新的提交,里面包含了那个说明,并且让它成为你的新的最近一次提交。
改变提交说明
进行目标增补操作如git add .
git commit -amend
步骤
使用这项技术的时候你必须小心,因为修正会改变提交的SHA-1值。这个很像是一次非常小的rebase——不要在你最近一次提交被推送后还去修正它。
注意
改变你刚刚通过增加,改变,删除而记录的快照。
改变最近一次提交
rebase工具
修改多个提交说明
交互式rebase工具
重排提交
压制(Squashing)提交
拆分提交
过滤批处理
filter-branch
重写历史
使用 Git 调试
子模块
子树合并
6.git工具
7.自定义git
8.git与其它系统
底层命令和高层命令
git对象
树对象
你可以执行像 git log 1a410e 这样的命令来查看完整的历史,但是这样你就要记得 1a410e 是你最后一次提交,这样才能在提交历史中找到这些对象。你需要一个文件来用一个简单的名字来记录这些 SHA-1 值,这样你就可以用这些指针而不是原来的 SHA-1 值去检索了。在 Git 中,我们称之为“引用”(references 或者 refs,译者注
$ git update-ref refs/heads/master 1a410efbd13591db07496601ebc7a059dd55cfe9
每当你执行 git branch (分支名称) 这样的命令,Git 基本上就是执行 update-ref 命令,把你现在所在分支中最后一次提交的 SHA-1 值,添加到你要创建的分支的引用。
新增引用指向提交对象
基本引用
HEAD一个指向你当前所在分支的引用标识符
HEAD 标记
Tag 对象指向一个 commit 而不是一个 tree。它就像是一个分支引用,但是不会变化——永远指向同一个 commit,仅仅是提供一个更加友好的名字。
tag对象
remote reference
Git References
Packfiles
The Refspec
高级传输协议
维护及数据恢复
9.git内部原理
https://git.oschina.net/progit/index.html
Git Pro
https://learngitbranching.js.org/?demo
在线git分支游戏
其它资源
Pro Git
0 条评论
回复 删除
下一页