Git 常见问题及解决办法

工具利器 Dec 3, 2019

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项目存在父项目中,子项目可以有自己的独立的commitpushpull。而父项目以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  

Tags

Great! You've successfully subscribed.
Great! Next, complete checkout for full access.
Welcome back! You've successfully signed in.
Success! Your account is fully activated, you now have access to all content.