Git补充问题
Git¶
github push¶
git push
¶
- 正常推送:仅在远程分支没有新的提交且你的本地分支包含所有远程分支的最新提交时,推送才会成功。(提交消息不能落后,代码状态不能落后)
- 推送失败情况:如果远程分支有新的提交,推送会被拒绝,提示你先获取(pull)最新的远程提交。
git push --force-with-lease
¶
- 强制推送:允许你覆盖远程分支的历史,但在进行强制推送之前会检查远程分支的状态。(提交消息可以落后,代码状态不能落后)
- 更安全的强制推送:只有在远程分支的状态与你本地分支在准备推送时看到的状态一致时,才会执行强制推送。如果远程分支在你准备推送的过程中被其他人更新,推送操作将会被拒绝。
--force-with-lease¶
- 如果amend last commit,修改了历史提交消息。此时本地分支的提交历史落后于远程分支的提交历史,就需要使用--force-with-lease来安全地强制推送,它会在推送之前检查远程分支的最新提交是否与本地分支在准备推送时的预期状态一致。(只是修改了提交消息,提交消息落后,但是代码状态没有落后,能成功)
- 如果远程分支在你准备推送的过程中被更新,推送会被拒绝,以避免覆盖其他人的工作。(代码状态落后,会失败)
(github不允许对受保护分支使用强制推送,需要修改分支保护规则)
pull¶
git强制覆盖本地代码(与git远程仓库保持一致)¶
fetch¶
仓库管理¶
因为我是仓库管理员,所以即使我没有勾选“Do not allow bypassing the above settings”选项,我也能绕过”equire a pull request before merging“的branch规则,而其他人绕不过。
我勾选了“Do not allow bypassing the above settings”选项,管理员和其他人都无法绕过”equire a pull request before merging“的branch规则。
Collaborators¶
分配权限:
- 默认情况下,添加的协作者会被赋予
Write
权限。你可以通过点击他们名字旁边的权限级别选项来更改权限(例如Read
,Write
, 或Admin
)。 Admin
权限允许协作者管理仓库设置和添加其他协作者。
权限级别
- Read:只能查看仓库内容,不能进行修改。- Write:可以查看和修改仓库内容,包括推送代码、创建和合并 Pull Request,但不能绕过分支保护规则,即使“Do not allow bypassing the above settings”未勾选。
- Admin:拥有仓库的所有权限,包括管理设置、保护分支、删除仓库等。如果“Do not allow bypassing the above settings”未勾选,他们可以绕过保护规则;如果勾选了,他们也无法绕过。
公有仓库与私有仓库¶
公共仓库
- 任何人:任何拥有 GitHub 账户的用户都可以对公共仓库进行 Fork 操作,并基于 Fork 创建 Pull Request。
- 步骤:
- 用户 Fork 你的公共仓库。
- 在他们自己的 Fork 中进行更改。
- 提交更改并创建 Pull Request,目标仓库为你的公共仓库。
私有仓库
- 被邀请的 Collaborators:只有被添加为 Collaborators 的用户才能访问和创建 Pull Request。
- 外部贡献者:无法直接访问私有仓库,因此不能创建 Pull Request。
公有仓库的Collaborators和非Collaborators¶
Collaborators 的 Pull Request
- 权限:
- Collaborators 对仓库有直接的写权限,可以直接推送更改到仓库的分支。
- 他们可以在仓库的主分支或其他受保护分支上工作,受保护分支的更改可能需要满足特定的审核和检查要求。
- 工作流程:
- Collaborators 可以直接在仓库的分支上进行更改并提交 Pull Request。
- 他们的 Pull Request 通常会自动触发 CI/CD 流程,且可以在仓库的上下文中查看和管理。
非-Collaborators 的 Pull Request
- 权限:
- 非-Collaborators 没有直接的写权限,无法直接推送更改到仓库的分支。
- 他们需要通过 Fork 仓库的方式来进行更改。
- 工作流程:
- 非-Collaborators 首先 Fork 公共仓库,创建其副本。
- 在 Fork 仓库中进行更改并提交到他们自己的分支。
- 从 Fork 仓库创建 Pull Request,目标仓库为原始公共仓库。
- 他们的 Pull Request 也会触发 CI/CD 流程,但需要仓库维护者进行进一步的审核和合并。
补充¶
已删除远程分支,本地远程分支跟踪信息没更新¶
更新本地的远程跟踪分支信息
使用 git fetch
命令来更新本地的远程跟踪分支信息:
其中,-p
或 --prune
选项会删除本地已经不存在的远程分支的引用。
查看本地的远程跟踪分支
你可以使用以下命令查看本地的远程跟踪分支:
强制更新本地¶
比如在虚拟机上,拉取分支,并强制更新本地
git fetch origin #命令会更新所有远程追踪分支的信息。
git reset --hard origin/分支名 #命令会将当前分支的 HEAD、索引和工作目录都重置为指定的远程分支的状态,丢弃所有未提交的更改。
git fetch origin && git reset --hard origin/分支名
windows下设置git对大小写敏感¶
git clone远程仓库的指定分支¶
git clone网络太差总是失败¶
git clone 网络太差总是失败:error: RPC 失败。curl 92 HTTP/2 stream 5 was not closed cleanly: CANCEL (err 8)
❯ git clone https://github.com/Almamu/linux-wallpaperengine.git .
正克隆到 '.'...
remote: Enumerating objects: 6271, done.
remote: Counting objects: 100% (1447/1447), done.
remote: Compressing objects: 100% (628/628), done.
error: RPC 失败。curl 92 HTTP/2 stream 5 was not closed cleanly: CANCEL (err 8)
error: 预期仍然需要 6355 个字节的正文
fetch-pack: unexpected disconnect while reading sideband packet
fatal: 过早的文件结束符(EOF)
fatal: fetch-pack:无效的 index-pack 输出
解决方法
分支落后¶
看你本地的分支是否有些东西落后于你要push的分支
- 直接push算一次提交
- pull request算一次提交
所以:
我本地仓库更改了,然后本地分支push到了dev_asus分支,接着dev_asus分支pull request到dev分支;之后再想本地分支直接push force到dev分支,会失败
因为dev分支有这个pull request提交,而本地分支没有这个提交记录,导致远程dev分支领先于本地分支,因此失败。
git pull -rebase什么作用,TortoiseGit 的“Launch Rebase after Fetch”¶
就是有人将远程仓库更新了,我就得这么做,如果有人出现冲突,直接在tortoiseGit里解决冲突,然后marked as resolve
git pull --rebase
是 Git 中的一个命令,用于从远程仓库拉取最新的更改并将这些更改应用到你的本地分支上,同时使用 rebase 而不是默认的 merge 方式来整合这些更改。它的主要作用和好处如下:
作用¶
- 拉取远程更改:
-
从远程仓库获取最新的提交和更改。
-
重写本地提交历史:
- 将远程分支的更改应用到你的本地分支上,同时将你的本地提交“重新应用”到这些更改之上。具体来说,它会先将你的本地提交临时保存(即“摘下”),然后将远程提交应用到本地分支,最后再将你的本地提交一个一个地重新应用到更新后的分支上。
使用场景¶
- 保持提交历史的整洁:
-
使用
git pull --rebase
可以避免产生不必要的合并提交(merge commit),从而保持提交历史的线性和整洁。 -
同步团队工作:
- 当多个开发者在同一个分支上工作时,使用
git pull --rebase
可以减少合并冲突,并确保每个开发者的提交都“顺序”应用到主分支上。
示例¶
假设你正在 feature
分支上工作,并且你的本地分支已经有一些提交。与此同时,远程的 feature
分支也有一些新的提交。执行 git pull --rebase
的过程如下:
- 当前状态:
- 本地分支有提交
A
、B
和C
。 -
远程分支有提交
D
和E
。 -
执行
git pull --rebase
: -
操作顺序:
- Git 会首先将你的本地提交
A
、B
和C
摘下(暂存)。 - 然后,它会将远程的提交
D
和E
应用到你的本地分支。 -
最后,Git 会将你的本地提交
A
、B
和C
重新应用到D
和E
之后。 -
结果:
-
你的本地分支将会有提交
D
、E
、A
、B
和C
,而没有产生额外的合并提交。
注意事项¶
- 冲突处理:
-
当
rebase
过程中遇到冲突时,Git 会暂停并提示你解决冲突。你需要手动解决冲突,然后使用git rebase --continue
继续 rebase 过程。 -
避免在公共分支上使用:
- 对于已经推送到远程仓库的公共分支(如
main
或master
),避免使用rebase
,因为它会重写提交历史,可能会导致其他开发者的工作混乱。对于公共分支,通常推荐使用merge
。
总结¶
git pull --rebase
是一个强大的命令,能够帮助你保持提交历史的线性和整洁,同时减少合并冲突。在团队协作中,它可以让每个开发者的提交顺序应用到主分支上,从而简化代码集成过程。然而,在使用时需要注意冲突处理和避免在公共分支上使用。
区别和联系¶
-
自动化程度:
git pull --rebase
是一个单一的命令,自动完成fetch
和rebase
两个步骤。- TortoiseGit 的“Launch Rebase after Fetch”是一个选项,当你执行
fetch
操作时,它会提示你是否要进行rebase
,让用户有更多的控制权。 -
用户交互:
-
git pull --rebase
是一个命令行操作,适合熟悉 Git 命令的用户。 - TortoiseGit 提供了图形用户界面,适合喜欢 GUI 操作的用户,并且在
fetch
之后会有提示,用户可以选择是否进行rebase
。 -
使用场景:
-
git pull --rebase
适合那些希望在每次拉取远程更改时自动进行rebase
的用户,通常在脚本或命令行环境中使用。 - TortoiseGit 的选项适合那些希望在执行
fetch
后有更多控制权的用户,尤其是在图形界面中操作时。
.gitignore¶
通配符¶
在通配符模式中,*
和 **
是两个不同的通配符,它们在匹配文件和目录时具有不同的含义。
-
*
(星号):匹配零个或多个字符(不包括目录分隔符)。例如,*.txt
可以匹配所有以.txt
结尾的文件名。 -
**
(双星号):匹配零个或多个目录和子目录。它可以用于递归匹配任意深度的目录结构。例如,src/**/file.txt
可以匹配src
目录下的任意深度的子目录中的file.txt
文件。
在上面提到的例子中,thirdparty/*/out/
使用了 *
通配符来匹配一个目录级别,它只匹配 thirdparty
目录下的一级子目录中的 out
文件夹。而 thirdparty/**/out/
使用了 **
通配符来匹配任意深度的子目录,它匹配 thirdparty
目录下的所有子目录中的 out
文件夹,无论子目录的深度如何。
因此,*
用于匹配单个目录级别或文件名,而 **
用于匹配任意深度的目录结构。