Git 进阶
修改很久之前的提交
# 1. rebase -i
git rebase -i master~5
# 2. 修改 pick 为 edit ,并 :wq 保存退出
# 3. 修改
# 4. 放到stash
git add .
# 5. 这一步如果只是修改, commit message不用输入
git commit --amend
# 最后一步
git rebase --continue
本地操作
# 创建分支,并切换分支
git branch newImage
git checkout newImage
# 创建分支,并切换分支
git checkout -b newImage
merge
# 把bugFix分支merge到main
git checkout main
git merge bugFix
rebase
# 把bugFix分支里的工作移动到main分支上
git checkout bugFix
git rebase main
# 此时bugFix在main前面
git checkout main
git rebase bugFix
# 此时mian和bugFix在同一位置
# 把bugFix分支里的工作移动到main分支上
git rebase main bugFix
HEAD
# HEAD总是执行最近一次提交的分支名
git checkout logId # HEAD直接指向提交记录(分离HEAD)
# 相对引用
^ HEAD向上移动一个提交记录
~<num> HEAD向上移动num个提交记录
# 移动分支名
git branch -f 分支名 HEAD~3 | 提交记录
reset
# 向前移动一个提交
git reset HEAD~1
# 创建一个提交,来取消当前commit的需改
git revert HEAD # 用于和其他人共享
cherry-pick
git cherry-pick 提交号
# 将side分支的C2和C4提交,放到main分支上
git checkout main
git cherry-pick C2 C4
rebase -i
# 交互式删除、修改提交顺序
git rebase -i HEAD~4
本地栈式提交
# 一些调试信息的提交,不想要
# 可以用cherry-pick 或者 rebase -i
提交技巧1
# 之前在 newImage 分支上进行了一次提交,然后又基于它创建了 caption 分支,然后又提交了一次。
# 此时你想对某个以前的提交记录进行一些小小的调整
# 比如设计师想修改一下 newImage 中图片的分辨率,尽管那个提交记录并不是最新的了。
1. 使用rebase -i,将提交的分支移到最前面,然后git commit --amend,然后再rebase -i,恢复原先的顺序
2. 也可以使用cherry-pick
tag
# 分支名容易被移动,但是tag不容易被移动
git tag tag名 提交记录
# 如果不指定提交记录,会默认打在HEAD所在位置上
git tag tag名
git describe
# Git Describe 能帮你在提交历史中移动了多次以后找到方向
git describe 提交记录
<tag>_<numCommits>_g<hash>
选择父提交记录
# 有两个父提交
git reset HEAD^ # 回到默认的父提交
git reset HEAD^2 # 回到另一个父提交
git checkout HEAD~^2~2
远程操作
# 远程分支命名规范
<remote name>/<branch name>
o/main 的分支,那么这个分支就叫 main,远程仓库的名称就是 o
# 远程分支有一个特别的属性,在你检出时自动进入分离 HEAD 状态
fetch
# 从远程仓库下载本地仓库中缺失的提交记录,更新(本地的)远程分支指针(如 o/main)
# git fetch 实际上将本地仓库中的远程分支更新成了远程仓库相应分支最新的状态。
# git fetch 不会更新main分支
# 更新main分支
git cherry-pick o/main
git rebase o/main
git merge o/main
pull
git pull = git fetch && git merge o/main
push
# 如果远程分支已经有提交
git fetch
git rebase o/main | git merge o/main
git push
# 或者合并
git pull --rebase
git push
# 或者
git pull
git push
远程服务器拒绝!(Remote Rejected)
# 远程服务器拒绝直接推送(push)提交到main, 因为策略配置要求 pull requests 来提交更新.
# 解决方法
新建一个分支feature, 推送到远程服务器. 然后reset你的main分支和远程服务器保持一致
远程跟踪
# 本地main远程关联o/main
# 其实可以改变这个属性
# 方法一:通过远程分支检出一个新的分支
git checkout -b totallyNotMain o/main
# 方法二:设置远程追踪分支的方法就是使用:git branch -u 命令
git branch -u o/main totallyNotMain
# 如果当前就在 totallyNotMain 分支上, 还可以省略 totallyNotMain:
git branch -u o/main
Git push 参数
git push <remote> <place>
git push origin main
把这个命令翻译过来就是:
切到本地仓库中的“main”分支,获取所有的提交,
再到远程仓库“origin”中找到“main”分支,将远程仓库中没有的提交记录都添加上去,搞定之后告诉我。
# 当为 git push 指定 place 参数为 main 时,我们同时指定了提交记录的来源和去向。
git push origin <source>:<destination>
git push origin foo^:main
# 如果你要推送到的目的分支不存在, git 会在远程仓库中根据你提供的名称帮你创建这个分支
git push origin main:notExist
fetch 与 push相似,只不过方向相反
git fetch origin foo
# Git 会到远程仓库的 foo 分支上,然后获取所有本地不存在的提交,放到本地的 o/foo 上。
git fetch origin foo:bar
# 将远程的foo更新到本地的bar
# 如果本地不存在这个分支,则新建一个分支
git fetch origin main:notExist
不指定source
# 删除main分支
git push origin :main
# 在本地新建一个bar分支
git fetch origin :bar
git pull
git pull origin foo
# 等同于
git fetch origin foo; git merge o/foo
git pull origin bar~1:bugFix
# 等同于
git fetch origin bar~1:bugFix; git merge bugFix
添加远程库
git remote add origin git@github.com:michaelliao/learngit.git
git push -u origin master
带上-u 参数其实就相当于记录了push到远端分支的默认值,这样当下次我们还想要继续push的这个远端分支的时候推送命令就可以简写成git push即可。
修改分支名
-
修改本地分支名
# git branch -m oldName newName
-
修改远程分支名(假设本地分支名与远程分支名相同)
重命名远程分支对应的本地分支
# git branch -m oldName newName
删除远程分支
git push --delete origin oldName
重新上传新命名本地分支
git push origin newName
把修改后的本地分支与远程分支关联
git branch --set-upstream-to origin/nameName