Interstellar
Interstellar
发布于 2024-08-06 / 5 阅读
0
0

Git

Git

就是只有一份文件,通过分出不同的分支,不同分支上提交的文件只在对应分支可见,完成功能后的分支可以合并到主分支上,完成功能的分支可以选择被删除

软件配置管理 Software Configuration Management 软件配置管理(SCM)是指通过执行版本控制、变更控制的规程,以及使用合适的配置管理软件,来保证所有配置项的完整性和可跟踪性。配置管 理是对工作成果的一种有效保护。


提交一个文件创建了三个版本号
第一个版本号指向了状态信息版本号?
状态信息版本号指向文件版本号?
文件版本号指向文件内容


parent 指向上一次的提交信息



删除文件

紫色代表删除的状态


文件在 git 中并没有真正被删除,只是不指向


head 中指向了 main记录了最新的文件


分支只是产生了新的不同提交,不同分支引用了不同文件,并没有备份

分支会提取对应分支版本的文件

GitSource

检出: 切换到所在位置提交时文件的状态
重置当前分支到此次提交 : 将本地文件恢复到这次提交,之后改动的文件全部放到暂存区域

软合并-保持所有本地改动,文件会出现在已暂存文件
混合合并-保持工作副本但重置索引,文件会出现在未暂存文件
强行合并-丢弃所有工作副本改动
  1. 快进(Fast-forward):在Git中,当你合并分支时,如果被合并的分支的所有新提交都是建立在目标分支最新提交之上的,Git会执行一种叫做"快进"的合并方式。这意味着Git只需简单地将目标分支指针直接指向被合并分支的最新提交,从而合并完成。在这种情况下,没有实际的合并操作发生,因为目标分支并没有发生变化,只是指向了被合并分支的最新提交。这种合并方式保持了提交历史的线性整洁性。


title:简介


Git

git check

git checkout -b feature c2 在指定位置创建分支并检出

git branch x

x 为位置,没有为当前检出位置添加分支

git branch -f x y

强行制定 x 到 y 处

git merge

另一个分支--> 融入 -->当前分支

git merge 让另外一个分支或指定 HEAD 融入到自己的分支

git checkout main
git merge other 让其他线程融入自己

git rebase 变基

git rebase x
当前分支 y--> 依靠 -->另一个分支 x

git rebase x y
y 依靠到 x 上,相当于 y 获得所有 x 的更改

git rebase : 相比 merge 会创造更线性的提交历史, Rebase 实际上就是取出自己的一系列的提交记录,“复制”它们,然后在另外一个地方逐个的放下去。使得代码演变过程更容易理解和跟踪。特别是在长时间开发的分支中,rebase 可以帮助保持提交历史的清晰度。

在公共仓库中,尤其是已经共享的分支上,应尽量避免使用 rebase,因为它会重写提交历史,可能导致其他开发者的工作产生冲突。

当前分支 rebase 另一个分支

Head: HEAD 是一个对当前所在分支的符号引用,也就是指向你正在其基础上进行工作的提交记录。HEAD 总是指向当前分支上最近一次提交记录。大多数修改提交树的 Git 命令都是从改变 HEAD 的指向开始的。

HEAD 通常情况下是指向分支名的(如 bugFix)。在你提交时,改变了 bugFix 的状态,这一变化通过 HEAD 变得可见

git checkout head 后可以进行 git commit,但不属于任何一个分支

相对引用:查看

  • 使用 ^<num> 指向当前提交的父提交,数字代表选择哪个父提交
  • 使用 ~<num> 向上移动多个提交记录,如 HEAD~3,向上移动 3 个
  • 链式操作 ~<num>或^<num> 之间随意组合,如

parent(父提交)指的是一个提交的直接 前一个提交,想要在提交树中自由移动则使用上面的 HEAD^<num>,HEAD~<num>

main 有两个 parent 提交,为c1c2

^数字 当前提交的某个 parent 提交

git checkout 具体head 可以一直使用 HEAD^ 向上移动

git checkout HEAD^
git checkout HEAD^
git checkout HEAD~

相对引用:移动

git branch -f 分支 HEAD~2 对于该分支提交过的前两个

git branch -f 分支 另一个head(可以为分离式 head)强制到具体分支,即使不是该分支提交

后面的提交会被舍弃变成 分离式head

撤销变更/重置提交 reset

不能在分离式 head 中使用

git reset HEAD

HEAD 可以是 HEAD,HEAD^,HEAD~x,或特定head

对远程分支无效
本地分支使用 reset



因为 reset 会造成历史记录不同

回滚提交 revert

git revert HEAD
远程分支使用 revert

  1. git revert HEAD: 使用 git revert HEAD 命令会撤销当前分支上最新的提交(即 HEAD 指向的提交)。这意味着将会撤销最近一次的提交,并创建一个新的提交来保存撤销的更改。

  2. git revert HEAD^: 使用 git revert HEAD^ 命令会撤销当前分支上倒数第二个提交(即 HEAD 指向的提交的父提交)。这样会撤销倒数第二次的提交,并创建一个新的提交来保存撤销的更改。

git rebase c2
git reset c5

磷选 git cherry-pick

是复制了一份,比之前多了一份

复制到当前的 head 位置下

git cherry-pick 1 2 3 4
当前分支复制其他分支内容

  • 通常用于提取固定的记录

其他分支遇到 bug 后,需要调试可能包括很多步骤,同步到主分支会包含很多不必要的信息,只需要最后解决问题的步骤同步到著代码即可

交互式变基 rebase

git rebase -i HEAD~4

可以对之前的某次提交删除,更改顺序


用此前的 squash,将两次修改合并,但是这两次修改不能有同一个文件,否则报错

git commit --amend

修改上一次提交,当需要修改某一次提交时

Tag

git Tag Tag_name Head名 不指定 head 则为当前的

分支很容易被改变,大部分分支还只是临时的,并且还一直在变。

有没有什么可以_永远_指向某个提交记录的标识呢,比如软件发布新的大版本,或者是修正一些重要的 Bug 或是增加了某些新特性,有没有比分支更好的可以永远指向这些提交的方法

就是 Tag

git describe

git describe : 输出 tag_距离_分支


其他

title:简介

git rebase c13 将自己独有的一个一个复制到指定的位置后
git branch -f main c13 是强制到指定的位置,自己独有的都抛弃了




title:多个分支合并到main分支

每次合并肯定合并到最新的代码上,分支合并完后,最后再将主分支合并到最新的地方



直接merge的形式,但没有rebase更容易理解和跟踪,但此时分支没有变化,只变化了主线程

远程

  • <remote name>/<branch name>

origin/main
在远程分支提交会变成分离式 head

fetch

  • git fetch 下载远端所有分支到 本地远程分支

  • git fetch origin foo 指定获取远程的 foo 分支,到本地的远程分支

  • git fetch origin <source>:<destination>
    source 远端
    destination 本地

  • git fetch origin :bar fetch 空,会在本地创建个新分支bar


pull

只能在本地远程分支上用,而 fetch 可以直接用

如果该分支没有和远端对应的跟踪,则不能进行 pull

pull --rebase == fetch-->rebase
pull == fetch-->merge

git pull <source>:<destination>
source 远端
destination 本地, 没有会创建

拉取指定分支

本地分支和本地远程分支一致时,使用两者没有区别

title:区别

pull

pull --rebase

本地分支和本地远程分支一致时,使用两者没有区别

git pullgit fetchgit merge 的合并

先把远程的更新下载下来,再和自己本地的合并

  • git cherry-pick o/main
  • git rebase o/main
  • git merge o/main

title:流程

该教程左边本地


git fetch

git merge o/main 或直接git pull

冲突

远程仓库的文件在两个远程被修改,
此时一个推送,另一个推送会拒绝

先 merge 或 rebase 后再 push

title:简介
git -c diff.mnemonicprefix=false -c core.quotepath=false --no-optional-locks push -v origin main:main
Pushing to https://github.com/XCJYO/Subconvert
To https://github.com/XCJYO/Subconvert
! [rejected] main -> main (fetch first)
error: failed to push some refs to 'https://github.com/XCJYO/Subconvert'

hint: Updates were rejected because the remote contains work that you do not hint: have locally. This is usually caused by another repository pushing to hint: the same ref. If you want to integrate the remote changes, use hint: 'git pull' before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
这是因为远程仓库包含了本地仓库中没有的更新

hint翻译为引用

完成时带有错误,见上文。

此时一个推送,另一个获取会

用变基解决

自己当时拉取的代码现在变旧了

直接在新代码的基础上添加你的代码,亦或由于你的提交已经过时而直接忽略你的提交?
因为这情况(历史偏离)有许多的不确定性,Git 是不会允许你 push 变更的。

也就是远程仓库被别人修改了,你的工作就变成了基于项目旧版的代码,与远程仓库最新的代码不匹配了,提交可能被拒绝

pull --rebase==fetch-->rebase
pull==fetch-->merge

title:简介


此时git push会失败

可以通过rebase调整工作



requeset



你应该按照流程, 新建一个分支, 推送 (push)这个分支并申请 pull request, 但是你忘记并直接提交给了 main. 现在你卡住并且无法推送你的更新.

新建一个分支feature, 推送到远程服务器. 然后reset你的main分支和远程服务器保持一致, 否则下次你pull并且他人的提交和你冲突的时候就会有问题.

title:多分支合并提交

先拉去远端分支
然后分支变基本地远程分支
然后其他分支依次变基
最后本地main变基


远程跟踪

git checkout -b x o/main 跟踪远程分支, 自动创建分支

git branch -u o/main foo 跟踪远程分支


就是 maino/main 进行了关联,这种关联就是远程跟踪,mian 被设置为跟踪,克隆的时候,就已经设置好了

进行 pull 时,更新到 o/main 然后自动更新 main
进行 push 时,更新到远程 main, 同时更新 o/main

如果该分支没有和远端对应的跟踪,则不能进行 pull

可以让任意分支跟踪 o/main, 然后该分支会像 main 分支一样得到隐含的 push 目的地以及 merge 的目标。这意味着你可以在支 totallyNotMain 上执行 git push,将工作推送到远程仓库的 main 分支上。

push

  • git push <remote> <place> 将指定分支推送到远端,并建立了跟踪

  • git push origin(固定) <place>

  • git push origin <source>:<destination>
    <source> 本地,可以为 head
    destination 远程,不存在的话远端则会自动创建
    可以将本地指定分支或 head 推送到远端指定的分支

  • git push origin :foo 推送空的, 删除了远端 foo 分支

切到本地仓库中的“place”分支,获取所有的提交,再到远程仓库“remote”中找到“place”分支,将远程仓库中没有的提交记录都添加上去,搞定之后告诉我。

如果直接 git push

git push origin <source>:<destination>
destination 不存在的话远端则会自动创建



总结

操作远程分支喜欢用 rebase 而不是 merge
merge 能保留修改树的历史

喜欢更干净的提交树就用 rebase


评论