小白快速掌握Git 心得:
Learn Git Branching 去这个网址玩通关,结合此篇文档,再在项目里用一用,应该就明白了。
这个闯关游戏每关的答案可以搜到,建议每关用最优的代码,多思考。
命令概览
Workspace:工作区,集成开发环境的界面区 显示的 代码、文件 就是工作区,如vs2019。
Index/Stage:暂存区,用于临时存放你的改动。
Local Repository:本地仓库,托管在 本地机器。其中HEAD指向最新放入本地仓库的提交。
Remote Repository:远程仓库,托管在 远程服务器,可以简单的认为是你项目组中的一台电脑24h不关机的 用于远程数据交换 的机器。
commit提交:将暂存区 保存的修改,提交 到 本地仓库。(需要附加 提交信息,提交信息 可以查阅 此次修改了什么内容)
push推送:将 本地仓库的记录 提交到 远程仓库。
提交消息的书写规范
冲突
何时发生:
1、使用pull命令
2、合并分支
如何解决:
对冲突部分的代码进行预览,择取要留下来的代码。
Learn Git游戏
Branch
分支就是git的精髓,要 早建分支、多用分支
原因:
因为即使创建再多的分支,
不会造成 储存或内存上 的开销
按逻辑分解工作到不同的分支,要比维护那些特别臃肿的分支简单多了。
命令:
git branch 新分支名
强制移动分支
git branch -f main # 更新main分支到最新,空白默认为当前HEAD
git branch -f main bugFix #将main分支更新到bugFix分支
合并分支
Merge
优点:使得历史记录按序
缺点:生成的树不美观
效果:在当前分支,调用 Git merge 另一分支名,就相当于把另一分支与本分支合并,
会在本分支 新生成一个提交。合并两个分支。
Rebase
中意:重建基底
Rebase
优点:就是可以创造更线性的提交历史
缺点:修改了提交的历史记录
Git rebase xx
效果:在 作为基底的分支xx 后,新增当前HEAD所在的分支的提交记录。合并两个分支。
Git rebase main == git rebase main bugFix
代表:以main为基底,bugFix分支 合并到 main分支后
随后,bugFix这个分支指向的提交 会消失
总结
HEAD
Head指向 当前分支/某个提交记录
如果head指向分支,在此分支上进行提交后,head会自动移动到最近的提交
相对引用^ ~ -f
撤销变更
Reset
被撤销的记录 不会加到暂存库
更改不存在 + 提交记录不存在
Revert
清除所作的更改 + 保留了提交记录
择取记录复制到当前分支 cherry-pick
命令名:cherry-pick
使用:git cherry-pick <提交号>
适用场景:想要把这个提交放到这里,那个提交放到刚才那个提交的后面
将side分支上的C2、C4提交,复制到main分支后面。
交互式的Rebase:Rebase-i
以C1 为基底,调整C1以后的记录的顺序
只取一个提交记录
适用场景:
就是说 调试的代码 是提交C2,打印的代码是另一次提交C3,修改bug的代码是C4,
每次提交和每次提交 修改的代码不同,最后我只想取C4的提交 和 主分支 合并
说明了:某次提交,只记录 当次修改的代码
技巧1 reabse倒序
技巧2 cherry-pick优化rebase
使用rebase颠倒顺序的问题:但这样做就唯一的问题就是要进行两次排序,而这有可能造成由 rebase 而导致的冲突。
Tag
效果:Git 的 tag 可以 永久地将某个特定的提交命名为里程碑,然后就可以像分支一样引用了。
特点:
它们并不会随着 新的提交而移动。
你也不能切换到某个标签上面进行修改提交,它就像是提交树上的一个锚点,标识了某个特定的位置。——在tag上进行新git commit --amend会创建新分支。
语法:
git tag v1 C1:我们将这个标签命名为 v1,并且明确地让它指向提交记录 C1。
git tag v1 如果你不指定提交记录,Git 会用 HEAD 所指向的位置。
Describe
效果:用来描述离你最近的锚点(也就是标签)
语法:git describe <ref>
<ref> 可以是任何能被 Git 识别成提交记录的引用,如果你没有指定的话,Git 会以你目前所检出的位置(HEAD)
结果的解析:
·输出结果为 <tag>_<numCommits>_<hash>
tag表示的是离 ref 最近的标签,
numCommits 是表示这个 ref 与 tag 相差有多少个提交记录,
hash 表示的是你所给定的 ref 所表示的提交记录哈希值的前几位。
特点:当 ref 提交记录上有某个标签时,则只输出标签名称
切换到指定的parent记录
适用场景:某个提交有2个parent节点,如何用checkout自如的切换到 两个的任一个
此处,是在C1处进行merge,把C2 merge进来,所以 main^ 会是左侧的,main^2会是右侧的
如果在C2处进行merge,把C1 merge进来,所以 main^ 会是右侧的,main^2会是左侧的
总之,main^ 是指向离main最近的提交。上图中就是C1
远程仓库
origin 代表的是远程仓库 , origin是远程仓库在本地的别名
在我们的本地仓库多了一个名为 o/main 的分支, 这种类型的分支就叫远程分支,反映的是远程分支的状态。
目的:方便理解 本地存储的远程分支状态 和 真实的远程分支状态的差异
特别之处:git checkout 到 远程分支时,会自动进入 HEAD分离(HEAD与远程分支分离)的状态,Git 这么做是出于不能直接在这些分支上进行操作的原因, 你必须在别的地方完成你的工作, (更新了远程分支之后)再用远程分享你的工作成果。
举例:
master和origin/master 代表的是
本地的master指针 和 远程仓库的master指针
当我们git push的时候
git push <远程主机名> <本地分支名>:<远程分支名>
如果本地分支名与远程分支名相同
git push <远程主机名> <本地分支名>
git push origin master 本地分支master提交到远端master
当test分支到远端test分支
git push origin test:test
Ftech
作用:将远程仓库分支的状态 更新到 本地的远程分支
1、本地分支名 = 远程分支名
2、远程分支 到 本地指定位置
如果本地仓库不存在bar分支,会自动创建bar分支 在当前HEAD处
3、直接git fetch
直接使用 git fetch 会下载远程仓库中所有的提交记录 到 本地的对应 远程分支
4、Fetch 远程的空 到 本地分支
Pull
pull 操作时, 提交记录会被先下载到 o/main 上,之后再合并到本地的 HEAD 分支。隐含的合并目标由这个关联确定的。
Git pull = git fetch + git merge
Git pull --rebase 记住:当前的HEAD会被合并到从远程载入到本地的分支 后。
Push
push 操作时, 我们把工作从 main(当前分支) 推到远程仓库中的 main 分支(同时会更新远程分支 o/main) 。
这个推送的目的地也是由这种关联确定的!
1、本地分支名 = 远程分支名
Push的前提是:远程分支的状态 = 远程仓库内分支 的状态(如图就是o/main 和 远程仓库的main 状态一致)
~
git push <remote> <place>
Source是本地仓库的分支
Destination 是远程仓库的分支
2、指定source和Destination
举例1:
3、推送到的远程分支不存在
举例2:
4、Push空 到远程仓库
远程的分支更新太多与本地不匹配
解决:将远程分支更新,与远程分支 合并(Git这么做是为了确保两边无冲突),再提交
Git pull /Git pull --rebase(会创建更线性的提交历史)
Git push
启示:要push到远程仓库时,先进行 拉取,确保本地仓库 和 远程分支 无冲突
远程仓库Main分支被锁定
如果你直接提交(commit)到本地main, 然后试图推送(push)修改, 你将会收到这样类似的信息: ! 远程服务器拒绝 main -> main (TF402455: 不允许推送(push)这个分支; 你必须使用pull request来更新这个分支.)
原因:在一个大的合作团队中工作, 很可能是main被锁定了。不允许直接push到 远程main分支。并且,git的要求就是 多用分支。