Git 常用命令及常见问题

常用命令

基础知识

# 查看本地公钥
cat ~/.ssh/id_rsa.pub

# 查看服务器的签名算法
ssh git@gerrit.edu.ubtrobot.com -vvv 2>&1 | grep ssh-rsa

# 删除本地分支
git branch -D feature/fans

# 删除远程分支
git push origin -d feature/fans

cz

npm install -g commitizen
npm install -g conventional-changelog conventional-changelog-cli
echo '{ "path": "cz-conventional-changelog" }' > ~/.czrc

commitHash

commit 或者 cz 的时候控制台会输出,比如:

[develop 97176e965] fix: 扩展中心的筛选逻辑

97176e965 就是 commitHash 或者 git log 里面的 SHA-1: 97176e965b4d0d92af18a3c8c36346ef3b9b1fe8

git stash

提交之前先本地 stash,拉取远程后,stash apply,处理冲突,然后 commit

git add .
git stash
git pull
git stash apply(默认最近一个,如果要指定stash使用 git stash apply n 或者 git stash apply stash@{0}# 处理冲突(如果有)
git add .
git cz

stash 的编号n从 0 开始,可以从 stash list 获取,需要哪个用哪个。

Cherry pick

使用 commitHash 将指定 commit 合并到当前分支。

git checkout develop
git cherry-pick #commitHash#
git push origin HEAD:refs/for/develop

或者使用分支名,表示将该分支最新的提交都转移到当前分支

git checkout develop
git cherry-pick feature/3.6
git push origin HEAD:refs/for/develop

解决冲突

git checkout develop
git cherry-pick #commitHash#
# 解决冲突,:wq退出 message 编辑
# 重新提交
git add .
git push origin HEAD:refs/for/develop

pick 多个提交

冲突概率高,推荐一个一个来

git checkout develop
git cherry-pick #commitHash1# #commitHash2# #commitHash3#
git push origin HEAD:refs/for/develop

commit --amend

修改尚未合并到远程分支的 commit,不生成新的 commit,而是在旧的 commit 上修改。

常见场景:push 了代码到 gerrit,发现代码需要调整。

# 本地修改
git add .
git commit --amend --no-edit
# 手动删除gerrit的提交,然后重新push
git push origin HEAD:refs/for/develop

更多操作可参考: http://www.ruanyifeng.com/blog/2020/04/git-cherry-pick.html

pull --rebase

git push 产生冲突,说明有人先你一步同步了他的本地代码到远程。

这时候,你需要先拉取代码,可以使用命令

git pull , 该命令会将远程的提交和你本地的提交 merge,如果有冲突需要手动解决并提交,会产生 merge 的记录

git pull -- rebase 该命令会把你的提交“放置”在远程拉取的提交之后,即改变基础(变基),会使 commit 树保持为一根直线

如果你修改了别人删除的文件,那你就手动删掉这个文件。

rm the_file
git add the_file
# 如果有冲突,解决所有冲突的文件,git add <冲突文件>
git rebase --continue
# 保存退出
:wq

完美解决问题。

更新远程 feature 分支

需要从 develop 更新远程 feature 分支。

通过 cherry-pick

如果需要更新的 commit 不多,推荐使用 pick 会更方便。

git checkout feature
git cherry-pick HASH

通过中间分支 merge

如果两个分支差异已经很大,使用 cherry-pick 需要重复多次操作,还可能需要多次处理冲突。

这种情况,建议使用 merge 来一次性合并。

  • 重新基于 develop 创建 feature-merge 分支
  • 将 feature 分支 merge 到 feature-merge 分支(则 feature 分支弃用,后面可删除)
# 重新基于 develop 创建 feature-merge 分支
git checkout -b feature-merge

# 将 feature 分支 merge 到 feature-merge 分支
git merge feature

# 解决冲突,如果有

# 删除旧feature分支
git branch -D feature

# feature-merge 重命名为 feature
git branch -M feature

# push到远程feature分支
git branch --set-upstream-to origin/feature
git push origin feature

重命名远程分支

不能直接操作。只能先删除远程分支,然后推送新分支。(慎重操作!)

  • 删除远端的 feature 分支
  • 将本地的 feature-merge 分支重命名为 feat,推到远端
git push origin --delete feature
git branch -m feature-merge feature
git branch --set-upstream-to origin/feature
git push origin feature

本地文件入库

远程创建一个空仓库,拿到 remote_URL

git init
git add .
git cz
git remote add origin <remote_URL>
git push -u origin --all

-u--set-upstream 的简写方式。

或者通过指定分支名称来达到 localBranch 不和 remoteBranch 相同的效果。

git push -u origin localBranch:remoteBranch

忽略指定文件

一般情况下,在.gitignore添加即可。 如果是已经入库的文件,则必须额外处理。

git rm --cached apps/website/public/designApi.json

如果是文件夹,需要额外参数 -r

git rm --cached .\packages\ui\dist -r

大小写敏感

全局设置大小写敏感:

git config --global core.ignorecase false

如果文件已经入库,可能会出现大小写两份文件。需要使用git rm单独处理。

git rm --cached .\packages\ui\dist -r

找回丢失的 commit

在使用 Git 的过程中,有时候会因为一些误操作,比如 reset、rebase、merge 等。特别是在 Commit 之后又执行了 git reset --hard HEAD 强制回滚本地记录以及文件到服务器版本,导致本地做的修改全部恢复到 Git 当前分支的服务器版本,同时自己的 Commit 记录也消失了。

git reflog --all

d0c1b98 HEAD@{8}: commit: docs: 文档更新
0ecfa96 HEAD@{9}: commit: fix: 修复构建在二级目录下静态资源路径错误的问题

我们要找回我们第二个 commit,只需要做如下操作:

git reset --hard 0ecfa96

常见问题

CRLF 换行符的问题

查看全部配置

git config --list

查看当前使用的配置

git config --global --edit

重新配置

# 全局设置为lf
git config --global core.eol lf
# input: 当文件进入时,将其转换为lf
git config --global core.autocrlf input

重新规划文件

git rm -rf --cached .
git reset --hard HEAD

Delete eslint

yarn run lint --fix

没有生成 Change-Id

可以使用临时方案手动填写一个,或者新建文件夹重新拉代码。

git commit --amend
# 按键盘的insert键进入插入模式
# 在message下面空一行,输入一个假的
Change-Id: I55862204ef71f69bc88c79fe2259f7cb8365699a
# 按ESC键退出插入模式,输入:wq保存退出

你还是要解决为何你的开发环境没有正确生产 Change-Id。(一般是 hooks 没有正确运行,可参考下面的链接)

https://stackoverflow.com/questions/8845658/gerrit-error-when-change-id-in-commit-messages-are-missing

© 2022  Arvin Xiang
Built with ❤️ by myself