小白Git 学习总结

Git/版本控制
32
0
0
2024-05-08

小白快速掌握Git 心得:

Learn Git Branching 去这个网址玩通关,结合此篇文档,再在项目里用一用,应该就明白了。

这个闯关游戏每关的答案可以搜到,建议每关用最优的代码,多思考。

命令概览

git命令使用流程

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的要求就是 多用分支。

本地分支设置跟踪的远程分支

1、方法一

2、方法二