Git 常见问题及解决办法
Git 是一个分布式版本控制软件,最初由林纳斯·托瓦兹创作,于 2005 年以 GPL 发布。最初目的是为更好地管理 Linux 内核开发而设计。经过多年发展,如今已成为绝大多数软件开发版本控制的首选工具,掌握它能使得我们更加高效工作;这里收录了一些 Git 常见问题及解决办法,以供各路朋友遇到时候可以参考。
如何检查当前分支中没有什么要提交的?
手动更新代码(包括子模块),不利于有些项目自动化执行;而利用脚本执行,需要执行检查是否存在有需要提交的内容,否则会产生错误,导致脚本执行中断;如何检查当前分支中没有什么要提交的?下面这段代码可以参考:
#!/usr/bin/env sh
# 确保脚本抛出遇到的错误
set -e
# 更新项目下所用到的所有子模块 & 提交
git submodule foreach git pull
if [ -n "$(git status --porcelain)" ]; then
git add tools
git commit -m '📌 uodate tools submodule'
git push
else
echo "there no changes about submodule 🖥";
fi
Git 如何创建干净的空分支?
git checkout --orphan empty-branch
git rm -rf .
git commit --allow-empty -m "root commit"
git push origin empty-branch
更详细的内容,可以参见 Github create empty branch。
如何解决 .gitignore 不起作用问题
.gitignore
仅适用于未跟踪的文件。如果您正在跟踪,那么 .gitignore
将不适用;如果想暴力的解决,可以使用如下方法,予以修复:
git rm --cached -r .
git add .
更详细的答案,可参见: ignore-files-that-have-already-been-committed-to-a-git-repository。
如何删除远程分支
git push origin --delete branch-name
// eg:
git push origin --delete develop
Git 同时 push 到多个仓库(同步)
为防止一个 Git 仓库由于各种原因造成无法访问,可以将代码 push 到多个仓库。编辑本地仓库目录下面的 .git 目录下的 config 文件(命令:vim ./git/config
)。添加类如以下命令:
[remote "all"]
url = git@github.com:licess/licess.git
url = git@gitcafe.com:licess/licess.git
再 push 时,运行如下命令即可:
git push all master
如何切换多个 GitHub 账号
Git 共有三个级别的 config 文 件,分别是 system、global 和 local。可以使用 git config --list | grep user
(windows 需用 sls 替换 grep)来查看配置;当 git commit
时,Author 信息依次读取 local、global 和 system 的配置,如果找到则不再继续读取。其他配置的读取顺序也是如此。更改配置可运行:git config --local user.name your-name
,更多详情可查看 这里。
从 Git 存储库中删除敏感数据
git filter-branch --commit-filter '
if [ "$GIT_AUTHOR_EMAIL" = "your-secret-email" ];
then
GIT_AUTHOR_NAME="your-can-be-known-name";
GIT_AUTHOR_EMAIL="your-can-be-known-email";
GIT_COMMITTER_NAME="your-can-be-known-name";
GIT_COMMITTER_EMAIL="your-can-be-known-email";
git commit-tree "$@";
else
git commit-tree "$@";
fi' HEAD
具体可参见:Removing sensitive data from a repository。
如何修改提交的 Message
git commit --amend
可以对上一次提交做修改(如果还没 push 的话);git commit --amend --no-edit
修改提交,却不更改 commit message;push -f
如果上一次的提交已经 push 了,那么需要加 f 参数覆盖(需慎重)。
解决升级 Mac 系统后 git: error: unable to locate xcodebuild
git: error: unable to locate xcodebuild, please make sure the path to the Xcode folder is set correctly!
git: error: You can set the path to the Xcode folder using /usr/bin/xcode-select -switch
解决办法如下:
xcode-select --install
sudo xcode-select --switch /Library/Developer/CommandLineTools/
Git stash 用于保存和恢复工作进度
- Git stash
保存当前的工作进度。会分别对暂存区和工作区的状态进行保存 - Git stash save "message..."
这条命令实际上是第一条git stash
命令的完整版 - Git stash list
显示进度列表。此命令显然暗示了 Git stash 可以多次保存工作进度,并用在恢复时候进行选择 - Git stash pop [--index] []
如果不使用任何参数,会恢复最新保存的工作进度,并将恢复的工作进度从存储的工作进度列表中清除。
如果提供参数(来自git stash list
显示的列表),则从该中恢复。恢复完毕也将从进度列表中删除
。
选项--index 除了恢复工作区的文件外,还尝试恢复暂存区。 - Git stash apply [--index] []
除了不删除恢复的进度之外,其余和git stash pop
命令一样 - Git stash clear
删除所有存储的进度
使用 Git Submodule 管理子模块
git Submodule
是一个很好的多项目使用共同类库的工具,他允许类库项目做为repository
,子项目做为一个单独的git项目
存在父项目中,子项目可以有自己的独立的commit
,push
,pull
。而父项目以Submodule
的形式包含子项目,父项目可以指定子项目header
,父项目中会的提交信息包含Submodule
的信息,再clone父项目
的时候可以把Submodule
初始化。
在项目中使用 Submodule
git submodule add https://github.com/nicejade/awesome-vue-cli3-example.git custom-module-name
更新 Submodule
# 方法一:在父项目的目录下直接运行
git submodule foreach git pull
# 方法二:在Submodule的目录下面更新
cd custom-module-name && git pull
Submodule
的目录中,使用git
和单独的一个项目是一样的,注意更新Submodule
的时候如果有新的commit id
产生,需要在父项目产生一个新的提交,子模块文件中的 Subproject commit
会变为最新的commit id
。
克隆含有子模块的项目
# 初始化本地配置文件
git submodule init
# 抓取所有数据并检出父项目中列出的合适的提交(`--recursive`递归)
git submodule update --recursive
如何有效删除 Submodule
git submodule deinit -f custom-module-name
rm -rf .git/modules/custom-module-name
git rm -f custom-module-name
git rm --cached custom-module-name
Git 如何合并多笔 Commit
- 查看提交历史,Git log
- 选择出想要合并的那几条
# 从HEAD版本开始往过去数 2个版本
git rebase -i HEAD~2
# 指名要合并的版本「之前」的版本号
git rebase -i 1a3146b
注意
1a3146b
这个版本是不参与合并的,可以把它当做一个坐标。
- 选取要合并的提交
执行如上命令之后,会弹出如下内容窗口,将要合并的那(几)条 pick
改为squash
或者 s
,之后保存并关闭文本编辑窗口即可。
0 pick 301747e test merge commit 01
1 pick 5f83c1c test merge commit 02
然后保存退出,Git 会压缩提交历史,如果有冲突,需要修改,修改的时候要注意,保留最新的历史,不然我们的修改就丢弃了。修改以后要记得敲下面的命令:
git add .
git rebase --continue
备注:如果你想放弃这次合并的话,可执行以下命令:
git rebase --abort