Git
git config --global user.name tianchenghang && \git config --global user.email 'hangtiancheng@qq.com' && \git config --global core.autocrlf false && \git config --global credential.helper store && \git config --global init.defaultBranch main && \git config --global core.filemode false
ssh-keygen -t rsa -C 'hangtiancheng@qq.com'
ssh-keygen -t rsa -C 'yukinohangtiancheng@gmail.com' -f ~/.ssh/id_rsa_githubssh-keygen -t rsa -C 'yukinohangtiancheng@gmail.com' -f ~/.ssh/id_rsa_github-2
# vim ~/.ssh/configHost github.com HostName github.com User git IdentityFile ~/.ssh/id_rsa_github IdentitiesOnly yes
Host github.com-2 HostName github.com User git IdentityFile ~/.ssh/id_rsa_github-2 IdentitiesOnly yes工作区 add 暂存区 commit 本地仓库 push 远程仓库
git init # 初始化空 git 仓库git status # 查看 git 状态git add <filename> # 将工作区的文件添加到暂存区git rm -r --cached <filename> # 删除暂存区的文件git commit -m <message> # 将暂存区的文件提交到本地仓库git commit --amend # 修改最后一次提交的 messagegit log # 查看 git 日志git diff # 查看工作区与暂存区的差异git diff --staged # 查看暂存区与最近提交的差异git restore <file> # 放弃工作区修改git restore --staged <file> # 取消暂存.gitignore
Section titled “.gitignore”vim ./.git/info/exclude.gitignore 统一忽略规则, ./.git/info/exclude 仅对本地仓库有效
branch
Section titled “branch”# 查看本地分支git branchgit branch --list "*feat*"# 在 HEAD 指向的 commitHash 处创建本地分支git branch bugfix# 在指定的 commitHash 处创建本地分支git branch bugfix <commitHash># 删除本地分支git branch -d bugfix # -D 强制删除# 切换到本地分支git switch bugfix # git checkout bugfix
# 查看远程分支git branch -r# 创建并切换到本地分支git switch -c bugfixgit checkout -b bugfix# 将本地分支推送到远程仓库, 以创建远程分支git push origin bugfix# 删除远程分支git push origin --delete bugfix
# 查看本地分支和远程分支git branch -agit merge <mergedBranch>
#! git checkout main && git merge bugfix# bugfix main*# | |# *------ main*
#! git checkout bugfix && git merge main# bugfix* main# | |# bugfix* ---*rebase
Section titled “rebase”git rebase <baseBranch> # 将当前分支的提交 rebase 到 baseBranch 后git rebase <baseBranch> <curBranch> # 将 curBranch 的提交 rebase 到 baseBranch 后git rebase -i <baseBranch> # 交互式 rebasegit rebase --continue # 解决冲突后继续git rebase --abort # 放弃 rebase#! git checkout bugfix && git rebase main# bugfix* main# |# bugfix*
#! git rebase bugfix main# bugfix, main*交互式 rebase
Section titled “交互式 rebase”交互式 rebase: --interactive, 简写为 -i
常用指令: pick, reword, edit, squash, fixup, drop
git rebase HEAD~5 --interactive# 合并前 5 个提交为 1 个提交后, 推送本地 main 分支到远程 main 分支git push origin main --force-with-lease| 指令 | 含义 |
|---|---|
| pick (p) | 保留该提交, 默认 |
| reword (r) | 保留该提交, 修改提交信息 |
| squash (s) | 与上一个提交合并, 保留两者 message |
| fixup (f) | 与上一个提交合并, 丢弃当前 message |
| drop (d) | 丢弃该提交 |
| exec (x), edit (e), break (b) |
- branch: branch 是指向提交 (commitHash) 的引用
- 未 detach 的 HEAD (HEAD 等于某个 branch): HEAD 是指向的 branch 的别名 (指向 commitHash 的二级指针)
- detach 的 HEAD (HEAD 不等于任何一个 branch): HEAD 是指向的 commitHash 的别名 (指向 commitHash 的一级指针)
cat .git/HEAD # ref: refs/heads/maingit symbolic-ref HEAD # refs/heads/main分离 HEAD
git checkout main^ # git checkout main~1git checkout main^^ # git checkout main~2git checkout HEAD^ # git checkout HEAD~1git checkout HEAD^^ # git checkout HEAD~2# 强制移动 main 分支git branch -f main [main^ | main~1 | HEAD^ | HEAD~1 | <commitHash>]reset & revert
Section titled “reset & revert”工作区 add 暂存区 commit 本地仓库 push 远程仓库
git reset --soft <ref> # 撤销旧提交, 保留暂存区和工作区 (保留 diff)git reset --soft HEAD~2 # 撤销 2 个旧提交, 保留暂存区和工作区 (保留 diff)git reset --mixed <ref> # 撤销旧提交, 保留工作区
git reset --hard <ref> # 撤销旧提交, 丢弃暂存区和工作区 (不保留 diff)git reset --hard HEAD~2 # 撤销 2 个旧提交, 丢弃暂存区和工作区 (不保留 diff)
git revert HEAD # 创建 1 个新提交, 以撤销 1 个旧提交git revert HEAD HEAD~1 # 创建 2 个新提交, 以撤销 2 个旧提交git revert HEAD~2..HEAD # 创建 多个新提交, 以撤销多个旧提交tag 也是别名
# 创建一个指向 HEAD 的标签, 表示 v1.0.0 版本git tag v1.0.0# 创建一个指向 commitHash 的标签, 表示 v1.0.0 版本git tag v1.0.0 <commitHash>
git describe <ref># <ref> 可以是 HEAD, branchName, commitHash, tagName 等# 输出 <tag>_<numCommits>_g<hash># tag: 距离 ref 最近的标签名# numCommits: ref 比 tag 多 numCommits 个提交# hash: ref 所在的 commitHash 的前缀- 从远程仓库中下载本地仓库中缺少的提交
- 更新远程分支 origin/main
- 不会更新本地 main 分支, 即不会修改本地文件
当前分支 track origin/main 时, git fetch && git merge origin/main 等价于 git pull
fetch + rebase + push
Section titled “fetch + rebase + push”git fetch && git rebase origin/main && git push 等价于 git pull --rebase && git push
fetch + merge + push
Section titled “fetch + merge + push”git fetch && git merge origin/main && git push 等价于 git pull && git push
本地分支跟踪 (track) 远程分支
Section titled “本地分支跟踪 (track) 远程分支”默认本地 main 分支跟踪远程 main 分支
# 创建并切换到跟踪远程 main 分支的新分支 anotherMaingit checkout -b anotherMain origin/main# branch 'anotherMain' set up to track 'origin/main'
#! 等价于# 创建新分支 anotherMaingit branch anotherMain# 切换到新分支 anotherMaingit switch anotherMain# 新分支 anotherMain 跟踪远程 main 分支git branch -u origin/main# branch 'anotherMain' set up to track 'origin/main'
#! 等价于# 创建新分支 anotherMaingit branch anotherMain# 新分支 anotherMain 跟踪远程 main 分支git branch -u origin/main anotherMain# branch 'anotherMain' set up to track 'origin/main'push 参数
Section titled “push 参数”git push <remote> <branchName>, 例如 git push origin main
git push -u <remote> <branchName> 设置上游分支
git push --force-with-lease 仅在远程分支没有被其他人更新时, 强制推送
推送本地 main 分支到远程 main 分支 (默认是 HEAD 指向的分支)
git push <remote> <localRef>:<remoteBranchName>
localRef 可以是 HEAD, branchName, commitHash, tagName 等, 例如 git push origin foo^:main
fetch 参数
Section titled “fetch 参数”git fetch <remote> <branchName>, 例如 git fetch origin main
从远程仓库中下载本地仓库中缺少的提交, 并更新远程分支 origin/main
git fetch <remote> <remoteRef>:<localBranchName>
remoteRef 可以是 HEAD, branchName, commitHash, tagName 等, 例如 git fetch origin HEAD^:main
如果只是 git fetch, 则更新该远程的所有远程分支与标签
pull 的参数
Section titled “pull 的参数”git pull <remote> <remoteRef>:<localBranchName>
等价于 git fetch <remote> <remoteRef>:<localBranchName> && git merge <localBranchName>
submodule
Section titled “submodule”git clone <url> --recurse-submodules # 克隆仓库, 初始化/更新子模块git submodule add <submodule_url> path/to/submodule # 添加子模块, 写入 .gitmodulesgit submodule update --init --recursive # 初始化/更新子模块git submodule update --remote # 更新子模块stash 用于缓存工作区 + 暂存区修改
git stash push -m "wip" # 缓存工作区 + 暂存区修改, 默认不包含未跟踪文件 (untracked)git stash push -u -m "wip" # 包含未跟踪文件 (untracked)git stash list # 查看 stash 列表git stash pop # 应用最新 stash 并出栈git stash apply stash@{1} # 应用指定 stash, 不出栈git stash drop stash@{0} # 删除指定 stashgit stash branch fix stash@{0} # 基于 stash 创建分支cherry-pick
Section titled “cherry-pick”将一些提交复制到当前分支
git cherry-pick <old-hash> <new-hash>git cherry-pick <old-hash>...<new-hash> # (old-hash, new-hash]git cherry-pick <old-hash>^..<new-hash> # [old-hash, new-hash]git cherry-pick --continue # 解决冲突后继续git cherry-pick --abort # 放弃 cherry-pickgit tag
Section titled “git tag”# 删除本地分支git branch --delete gh-pages# 删除远程分支git push origin --delete gh-pages
# 创建 taggit tag v0.0.1# 推送 taggit push origin v0.0.1
# 删除本地 taggit tag --delete v0.0.1# 删除远程 taggit push origin :refs/tags/v0.0.1git diff
Section titled “git diff”git diff [--stat] origin/feat..feat/tiancheng/layout-v2