Git #
分支 #
# 本地仓库 分支引用
refs/heads/v1.0.0
# 远程跟踪分支引用, 远程仓库 origin 中有一个分支 v1.0.0
refs/remotes/origin/v1.0.0
# 标签引用,包括远程和本地
refs/tags/v1.0.0
tag #
- 远程 tag 被视为本地 tag 的一种,它们都存储在 refs/tags/ 路径下。当你从远程仓库拉取或推送 tag 时,Git 会自动同步这些 tag 到本地仓库中的 refs/tags/ 路径
分支和 tag 重名 #
远程有个 v1.0.0 tag,想基于它拉一个远程 v1.0.0 分支 #
# 本地拉 v1.0.0 tag
git fetch origin tag v1.0.0
# git fetch origin --tags
# 基于 tag 拉 v1.0.0 分支,
# git co -b 分支名 tag名
git co -b v1.0.0 v1.0.0
# 把本地分支推送到远程分支
git push origin refs/heads/v2.11.3:refs/heads/v2.11.3
原理:
git show-ref v2.11.3
git module #
git submodule foreach git reset --hard HEAD
git submodule update
git submodule foreach "git checkout master; git pull"
git submodule foreach git clean -f
更新 submodule #
git submodule update --init
git submodule update --remote
merge vs squash vs rebase #
merge 不能保持 master 分支干净,但是保持了所有的 commit history,大多数情况下都是不好的,个别情况挺好 squash 也可以保持 master 分支干净,但是 master 中 author 都是 maintainer,而不是原 owner rebase 可以尽可能保持 master 分支干净整洁,并且易于识别 author
squash merge #
# 切换到目标分支
$ git checkout master
# 以 squash 的形式 merge
$ git merge --squash devel
# it does not produce a commit right away: you need an additional commit
$ git commit -m "squash branch"
- 你会发现,在 master 分支上居然有未提交的修改,然后你就需要在 master 上主动提交了修改,
- 注意,这里是你 commit 的,也就是改变了 commit 的 author。
- git merge has a –commit option, but it cannot be used with –squash.
- It was never possible to use –commit and –squash together.
参考:
rebase merge #
# 先切换到 devel 分支(不一样咯)
$ git checkout devel
# 变基
$ git rebase -i master
# 切换回目标分支
$ git checkout master
# 合并
$ git merge
- 我们在 devel 里面对照 master 进行了变基
- 所谓的变基其实就是找到两个分支共同的祖先
- 然后在当前分支上合并从共同祖先到现在的所有 commit
- 会选择怎么处理这些 commit
- 然后我们就得到了一个从公共 commit 到现在的单个 commit
- 这个时候别人将我们这个 commit 合并到 master 也只会在 master 上留下一个 commit 记录
合并 git commit #
参考:
git branch 与 git tag 同名 #
需要使用完整路径
git checkout refs/heads/v1.5.2
git checkout refs/tags/v1.5.2
git push -u origin refs/heads/v4.8.0
参考:
git pull force #
git fetch --all
# git reset --hard origin/<branch_name>
git reset --hard origin/master
参考:
hard reset
vs mixed reset
vs soft reset
#
# 回到 reset 版本,之后的文件都属于 git add 的状态
git reset --soft
# git reset 默认就是 --mixed
# 回到 reset 版本,之后的文件都属于 git add 前的状态
git reset --mixed
# 回到 reset 版本,之后文件都丢弃(使用 git reflog 可以找回来)
git reset --hard
git reflog #
reflog
是 Git 操作的一道安全保障,它能够记录几乎所有本地仓库的改变。
包括所有分支 commit 提交,已经删除的 commit
(其实并未被实际删除)都会被记录。
只要 HEAD 发生变化,就可以通过 reflog
查看到。
git 回退 #
# 文件放弃本地修改
git checkout -- <file>
# 回退到某个版本
git checkout commit-id <path>
git reset -- <path>
参考:
config 权限 #
问题: Bad owner or permissions on ~/.ssh/config
解决:
chown $USER ~/.ssh/config
chmod 644 ~/.ssh/config
git submodule #
拉取 submodule #
git submodule init
git submodule update --remote
git submodule add -b
#
参考:
submodule 修改 url #
- edit the
.gitmodules
file to update the URL git submodule sync
参考: How to change the remote repository for a git submodule?
delete submodule #
- Delete the relevant section from the .gitmodules file.
- Stage the .gitmodules changes
git add .gitmodules
- Delete the relevant section from
.git/config
. - Run
git rm --cached path_to_submodule
(no trailing slash). - Run
rm -rf .git/modules/path_to_submodule
(no trailing slash). - Commit
git commit -m "Removed submodule "
- Delete the now untracked submodule files
rm -rf path_to_submodule
参考:
untracked status #
[submodule "example"]
path = example
url = git://github.com/ikingye/example.git
ignore = dirty
教程 #
pcottle/learnGitBranching #
LearnGitBranching is a git repository visualizer, sandbox, and a series of educational tutorials and challenges.
https://learngitbranching.js.org/
常见问题 #
保留 remote 的历史记录,但是不关心未来这个文件的变化 #
比如某个文件频繁变化,希望不再管理后续更新。
git update-index --assume-unchanged xxx-filepath
# 继续跟进变化
git update-index --no-assume-unchanged xxx-filepath
叶王 © 2013-2024 版权所有。如果本文档对你有所帮助,可以请作者喝饮料。