Git
用于记录 git 使用过程中的一些经验和基础操作
分支变基 rebase
这种变基操作非常不建议在多人协作中使用,这样会直接影响到他人的历史,如果是自己的仓库可以这样随便操作。
修改 commit 记录并重新推送,保持提交记录始终为一条路径并且没有分出去 选择最近的两个 commit 进行更改
1
git rebase -i HEAD~2
git 会先后自动打开两份文件,第一份需要将需要被合并的 commit 前的 pick 修改为 squash,即压缩。
保存并退出文档后会打开第二份,选择需要保留的 commit 信息,剩下的删去即可,保存并推出。
最后要记得:
1
2
# 直接强制推送!
git push --force-with-lease
不要先 git pull 否则会将两个不同的提交记录分为两个路,最后汇到当前历史。
分支历史回滚 reset
在一个分支上,如果你想回滚/还原到之前的操作,你需要判断:
现在到还原点之间的这些历史是否还需要记录?
如不需要则可以使用 git reset 命令,如仍旧希望保留则使用 git revert 。
不保留做法:
1
2
3
4
5
6
7
8
9
10
# 查看历史提交,会在终端进入一个类似 Vim 的交互界面,按q即可退出
git log --oneline
# 找到你希望的还原点 commit ID 然后执行重置
# --soft 参数会将当前的代码保存在暂存区
# --hard 会销毁一切内容
git reset --hard [commit_ID]
# 因为没有保留历史,相当于修改了历史,需要强制推送
git push -f origin <branch_name>
reset --hard 还有一个使用场景,见提出PR的回退过程。
保留做法:在公共分支上这是更加合理的做法。
1
git revert [commit ID]
Git 会弹出一个编辑器让你写提交信息,保存退出即可。原理是在原来的历史上增加一个新的相反的 commit 来抵消之前的改动。
rebase 和 reset 的区别在于:
rebase会将多个提交融合并新建一个提交,更换这段历史的起点commit ID也会改变。一般用于清理整合杂乱的提交。reset则是抹除一些提交内容,历史线性回退。用于清理自己没写好的代码。
.gitignore文件
.gitignore 不会忽略已经处于跟踪状态中的文件,所以需要先断开跟踪。
1
2
3
4
5
# 断开跟config.json文件的跟踪
git rm --cached config.json
# 断开当前仓库下对全部文件的追踪(需要在根目录下)
git rm -r --cached .
然后添加需要忽略的文件即可。
变换分支
查看本地分支:
1
2
3
4
5
# 查看本地分支
git branch
# 查看当前本地追踪的分支
git branch -v
在多人协作时,通常会采用不同的分支来记录不同的功能,首先我们需要创建并移动到一个用于不同功能的分支 feature
1
git checkout -b feature
在这个不同的分支下,拉取合并等操作建议都添加上完整的路径(仓库+分支)而不是使用 -u 参数重新设置默认上游分支,比如需要从 main 分支中拉取当前状态到现在的分支
1
git pull origin main
在当前分支完成工作后同样进行 add,commit 操作后,
1
git push origin feature
合并使用 merge 命令,合并到 main 分支:
1
2
3
4
5
# 首先切换到需要合并到的分支
git checkout main
# 将被合并的分支合并进来
git merge feature
上述操作都会将远程仓库的文件拉取到本地,并且在本地进行合并操作。 但是很多时候管理员可以不必将每个分支全部拉取到本地,而是只需要获得(抓取 fetch)分支在远程仓库的镜像快照后在目标分支进行 merge 即可。
分支合并
管理者可以通过 fetch 来抓取远程仓库的快照,相当于去看了远程仓库每个分支的当前信息(快照)而不用实际拉取到本地。
1
2
# 抓取远程仓库的全部分支快照
git fetch origin
假设当前处于测试分支 test ,也是管理者负责管理的分支
1
2
3
4
5
6
# 确认处于需要统一合并的管理分支
git checkout test
# 将之前抓取的feature快照对应的分支内容与当前分支合并
# 也就是直接从远程仓库获取分支内容而不再需要本地分支
git merge origin/feature
两种路径:
1
2
1、远程仓库feature (pull)--> 本地feature (merge)--> 合并到本地test
2、远程仓库feature快照 (fetch)-->(merge) 合并到本地test
删除分支
删除本地分支:
1
2
3
4
git branch -d <branch_name>
# 如果此分支还未合并,会出现提示,如果确认此分支不再需要,进行强制删除
git branch -D <branch_name>
删除远程分支:
1
git push origin --delete <branch_name>
清理本地对远程仓库 origin 上已删除分支的本地引用:
1
git remote prune origin
提出PR
向一个仓库提出PR通常是将自己fork的仓库的一个分支(假如是main)和owner的main分支进行合并。需要注意的是,如果你的PR还没有被合并,一旦向main分支进行了push,你的PR也会动态发生更改。所以如果还要进行开发特别建议在另一个分支下进行,并且确保功能和代码无误后再合并。
如果你不小心将还没确认的更改push到了自己的 main 分支(PR也同步发生了更改),那么需要自己另开一个分支先存下当前分支的内容,然后回退 main 分支。
回退过程:
1
2
3
4
5
6
7
8
9
10
11
# 添加原作者远程仓库为 upstream
git remote add upstream <Owner_URL>
# 获取原作者的所有更新
git fetch upstream
# 切换到 main
git checkout main
# 强制重置到原作者的 main 分支
git reset --hard upstream/main
现在main分支已经变干净了。
可以选择从头开始调整,修改完之后正常提交就行。如果想从之前的某个提交开始修改:
1
2
3
4
5
# 通过log在保留的另一个dev分支找到正确修改的commitID
git log dev
# 选择从这个commit开始修改
git cherry-pick <commitID>
最后强推到个人的远程仓库。
Tips: 这里需要确认处于自己的对应仓库,否则后面就会向原作者的仓库push,倒反天罡会出现403 Forbidden。
1
git push -f origin main
这样PR中显示的修改也会和当前 main 分支中正确的修改动态同步了。