玩命加载中 . . .

Git 填坑之 error 整理

一、Git 环境配置

下载安装流程就不一一赘述了,安装好之后在命令行输入 git 回车或鼠标右键界面空白处查看是否出现 Git GUI Here Git Bash Here 检查是否安装成功。

Git 安装好后再去 GitHub 上注册一个账号,注册好后,点击 Git Bash,用账号进行环境配置:

配置用户名

git config --global user.name "xxx"

配置邮箱

git config --global user.email "xxx@xxx.com"

生成ssh
ssh-keygen -t rsa

然后连敲三次回车键,结束后去系统盘目录下(一般在 C:\Users\你的用户名.ssh)(mac: /Users/用户/.ssh)查看是否有 ssh 文件夹生成,此文件夹中两个文件:id_rsa id_rsa.pub

将ssh文件夹中的公钥( id_rsa.pub)添加到 GitHub 管理平台中(貌似这样后面每次推送代码就不用重输账号密码了),在 GitHub 个人账户的设置中找到如下界面:

Title 随便起一个,将公钥( id_rsa.pub)文件中内容复制粘贴到 key 中,然后点击 Ass SSH key 添加成功。

Git Bash 中输入 ssh -T git@github.com 回车,若出现以下提示就说明配置好啦:

二、Git 与 SVN

2.1 集中式(SVN)

SVN 因为每次存入的都是差异,需要的硬盘空间会相对的小一点,可是回滚的速度会很慢。
优点: 
代码存放在单一的服务器上,便于项目的管理。
缺点: 
服务器宕机:代码得不到保障。
服务器炸了:整个项目的历史记录都会丢失。

2.2 分布式(Git)

Git 每次存入的是项目的完整快照 需要的硬盘空间会相对大一点。
Git 团队对代码做了极致压缩,最终需要的实际空间比 SVN 多不了太多,可是 Git 的回滚速度极快。

三、Git 命令

3.1 底层命令(可跳过不实用)

git对象
git hash-object -w fileUrl: 生成一个key(hash值):val(压缩后的文件内容)键值对存到 .git/objects
tree对象
git update-index --add --cacheinfo 100644 hash test.txt: 
往暂存区添加一条记录(让git对象对应上文件名)存到 .git/index
git write-tree: 生成树对象存到 .git/objects
commit对象
echo 'first commit' | git commit-tree treehash: 生成一个提交对象存到 .git/objects
对以上对象的查询
git cat-file -p hash: 拿对应对象的内容
git cat-file -t hash: 拿对应对象的类型

3.2 查看暂存区

git ls-files -s

3.3 高层命令

查看 Git 版本

git --version

初始化配置

git config --global user.name "xxx"
git config --global user.email xxx@xxx.com    
git config --list

初始化仓库

git init

C (新增)

在工作目录中新增文件
git status 查看文件的状态
git add . 将修改添加到暂存区
git commit -m "msg" 将暂存区提交到版本库

U(修改)

在工作目录中修改文件
git status 查看文件的状态
git add . 将修改添加到暂存区
git commit -m "msg" 将暂存区提交到版本库

D(删除 & 重命名)

git rm 要删除的文件
git mv 原文件名 新文件名:将工作目录中的文件进行重命名,再将修改添加到暂存区。
git rm 文件名:删除工作目录中对应的文件,再将修改添加到暂存区

R(查询)

git status: 查看工作目录中文件的状态(已跟踪(已提交 已暂存 已修改) 未跟踪)
git diff: 查看未暂存的修改
git diff --cache: 查看未提交的暂存
git log --oneline: 查看提交记录

四、分支

分支的本质其实就是一个提交对象!所有的分支都会有机会被HEAD所引用(HEAD一个时刻只会指向一个分支),当我们有新的提交时HEAD会携带当前持有的分支往前移动。
HEAD:
是一个指针,默认指向master分支,切换分支时其实就是让HEAD指向不同分支。
每次有新提交时,HEAD都会带着当前指向的分支一起往前移。

分支命令:

git log --oneline --decorate --graph --all: 查看整个项目的分支图  
git branch: 查看分支列表
git branch -v: 查看分支指向的最新的提交
git branch name: 基于当前分支创建新的分支
git branch --orphan name: 不基于当前分支创建新的分支(分支间不相互关联)
git branch name commithash: 在指定的提交对象上创建新的分支
git checkout name: 切换分支
git branch -d name: 删除空的分支 删除已经被合并的分支
git branch -D name: 强制删除分支 
创建分支: git branch branchname
切换分支: git checkout  branchname
创建&切换分支: git checkout -b branchname
版本穿梭(时光机): git branch branchname commitHash  
普通删除分支: git branch -d branchname
强制删除分支: git branch -D branchname
合并分支: git merge branchname
快进合并 --> 不会产生冲突
典型合并 --> 有机会产生冲突
解决冲突 --> 打开冲突的文件进行修改 add commit 
查看分支列表: git branch
查看合并到当前分支的分支列表: git branch --merged
一旦出现在这个列表中就应该删除
查看没有合并到当前分支的分支列表: git branch --no-merged
一旦出现在这个列表中就应该观察一下是否需要合并

分支的注意点:

在切换的时候一定要保证当前分支是干净的!动三个地方:HEAD、暂存区、工作目录
    允许切换分支: 
        分支上所有的内容 处于已提交状态    
        (避免)分支上的内容是初始化创建 处于未跟踪状态
        (避免)分支上的内容是初始化创建 第一次处于已暂存状态
    不允许切分支:
         分支上所有的内容处于 已修改状态或第二次以后的已暂存状态  
         
在分支上的工作做到一半时 如果有切换分支的需求, 我们应该将现有的工作存储起来
    git stash: 会将当前分支上的工作推到一个栈中
    分支切换 进行其他工作 完成其他工作后 切回原分支
    git stash apply: 将栈顶的工作内容还原 但不让任何内容出栈 
    git stash drop: 取出栈顶的工作内容后 就应该将其删除(出栈)
    git stash pop: git stash apply +  git stash drop 
    git stash list: 查看存储

撤销操作:

工作区
    撤销工作目录的修改: git checkout -- filename
暂存区
    撤销暂存区的修改: git reset HEAD  filename
版本库
    撤销提交: git commit --amend

reset:

git log、git reflog: HEAD有变化,git reflog就会记录下来。
git reset --soft commithash 用commithash的内容重置HEAD内容。
git reset [--mixed] commithash 用commithash的内容重置HEAD内容,重置暂存区。
git reset --hard commithash 用commithash的内容重置HEAD内容,重置暂存区,重置工作目录。

路径 reset:

所有的路径reset都要省略第一步!
第一步是重置HEAD内容,HEAD本质指向一个分支,分支的本质是一个提交对象,
提交对象指向一个树对象,树对象又很有可能指向多个git对象,
一个git对象代表一个文件,HEAD可以代表一系列文件的状态。
git reset HEAD filename 动了暂存区
git reset [--mixed] commithash filename 用commithash中filename的内容重置暂存区

checkout 深入理解:

git checkout brancname 跟 git reset --hard commithash特别像
    共同点
        都需要重置 HEAD 暂存区 工作目录
    区别
        checkout 对工作目录是安全的 reset --hard是强制覆盖
        checkout 动HEAD时不会带着分支走而是切换分支
        reset --hard 是带着分支走        
checkout + 路径
      git checkout commithash filename 重置暂存区、工作目录
      git checkout -- filename 重置工作目录     

五、Eslint 结合 Git

5.1 Eslint

js代码的检查工具
下载: npm i eslint -D
使用:
    生成配置文件: npx eslint --init
    检查js文件: npx eslint 目录名
    命中的规则:
        字符串必须使用单引号
        语句结尾不能有分号
        文件的最后必须要有换行

六、协作

6.1 推送、拉取

正常的数据推送和拉取步骤:
    1. 确保本地分支已经跟踪了远程跟踪分支
    2. 拉取数据: git pull + 指定分支
    3. 推送数据: git push + 指定分支
    
一个本地分支怎么去跟踪一个远程跟踪分支:
    1. 当克隆的时候会自动生成一个master本地分支(已经跟踪了对应的远程跟踪分支)
    2. 在新建其他分支时可以指定想要跟踪的远程跟踪分支,本地没有分支:
            git checkout -b 本地分支名 远程跟踪分支名
            git checkout --track 远程跟踪分支名(remote/分支名)
    3. 将一个已经存在的本地分支改成一个跟踪分支,本地已经创建了分支:   
            git branch -u 远程跟踪分支名(remote/分支名) 

6.2 团队协作

1. 仓库负责人初始化远程仓库:
   一定要初始化一个空的仓库,在github或gitlab等平台上操作
2. 仓库负责人创建本地仓库:
    git remote 别名 仓库地址(https)
    git init 将源码复制进来,修改用户名,修改邮箱
    git add
    git commit 
3. 仓库负责人推送本地仓库到远程仓库:
    清理Windows凭据
    git push 别名 分支(输入用户名,密码,推完之后会附带生成远程跟踪分支)
4. 仓库负责人邀请成员&成员接受邀请,在github上操作
5. 成员克隆远程仓库:
   git clone 仓库地址(在本地生成.git文件 默认为远程仓库配了别名 orgin)
   只有在克隆的时候,本地分支master和远程跟踪分支别名/master是有同步关系的
6. 成员将本地分支和远程分支进行关联:
   git remote add upstreamMaster git@xxx... // 配别名,关联master分支
   git checkout branchName // 切换到要开发的分支
   git fetch upstreamMaster xxxbranchName // 关联xxxbranchName分支
   git merge upstreamMaster/xxxbranchName // 关联xxxbranchName分支
   写代码
   git pull 某分支 + git add . + git commit -m "[xxx]:msg" + git push 某分支
7. 在gitlab或其他平台合并代码,在Jenkins或k8s等其他容器云平台构建即可
8. 某个版本稳定后需要打标签封版,版本号的命名规范还请自行百度
   查询版本:
   git tag // 列出已有标签,了解当前的版本状态
   git show <tag_name> // 查看特定标签信息:git show v1.0
   git checkout -b <branch_name> <tag_name> // 检出特定标签
   新增版本:
   git tag <tag_name> <commit_sha> // 创建轻量标签:git tag v1.0 23a5df4
   git tag -a <tag_name> -m "标签说明" <commit_sha> // 创建标签说明:git tag -a v1.0 -m "发布版本 1.0" 23a5df4
   git push origin <tag_name> // 推送标签到远程仓库
   git push origin --tags // 一次性推送所有标签
   删除版本:
   git tag -d <tag_name> // 删除某个标签
   git push origin :refs/tags/<tag_name> // 推送删除后的标签到远程仓库

七、Error Resolve

7.1 conflict 代码冲突

多人协作开发、多分支开发时最容易出现的就是提交代码前拉取新代码冒出 conflict 冲突提示,其实只要事先约定好开发规范就能避免,其关键就是把一个稳定的分支版本作为基线,如经过测试后没问题的分支,其他的功能开发分支基于这个分支来进行拉取提交。

万一发生了冲突就用这三条指令:

git stash // 把工作区的修改提交到栈区,把工作区有冲突的修改先隐藏保存
git pull // 拉取指定的远程分支上的代码并合并到本地分支
git stash pop // 把第一步保存在栈区的冲突部分合并到最新的工作空间中

这时本地工作区会显示具体的冲突文件,如果是自己的冲突就自己处理后 add + commit 提交上去,如果是同事的冲突就呼叫他们处理即可。

7.2 non-fast-forward

问题描述:git push origin login 报错。

原因:远程库与本地库不一致导致。比如别人上传到远程仓库后,你没有及时的同步(拉取)到本地,但是你同时又添加了一些内容(提交),以致于你在提交时,它会检测到你之前从远程仓库拉取的时候的仓库状态和现在的不一样。于是,它为了安全起见拒绝了你的提交(然后就报了这个错误)。

解决方案一:先合并之前的历史,再进行提交——提倡使用。

(1)先把 Git 的东西 fetch 到你本地然后 merge 后再 push

$ git fetch origin login
$ git merge origin FETCH_HEAD

这2句命令等价于:$ git pull origin login,但是使用 git fetch + git merge 更加安全

(2)重定基,可以使历史更加统一,提交历史趋向于一条直线。

git pull --rebase origin login 
意为先取消commit记录,临时保存为补丁之后同步远程库到本地,最后合并补丁到本地库之中

补充:它们间的关系:

git pull = git fetch + git merge FETCH_HEAD 

git pull --rebase =  git fetch + git rebase FETCH_HEAD

接着输入 git status 可能会报错:

提示 amend 或 continue,amend会继续报错,而continue则会提交本地修改完成修复:

git rebase --continue
git push origin login(查看GitHub上login分支没问题了)

解决方案二:放弃之前的历史,强推(用强覆盖方式用你本地的代码替代 Git 仓库内的内容)——谨慎使用。

$ git push -f  或 $ git push --force

官方文档提示:This flag disables these checks, and can cause the remote repository to lose commits; use it with care.(即:此标志禁用这些检查,并可能导致远程存储库丢失提交;小心使用。)

7.3 failed to push some refs to ‘https://github.com/

问题描述:在 git bash 中键入 $ git push origin master 提交时出现。

原因:远程库与本地库不一致导致,在 hint 中也有提示把远程库同步到本地库即可。

解决方案:

git pull --rebase origin master

该命令的意思是把远程库中的更新合并到(pull = fetch + merge)本地库中,–-rebase 的作用是取消掉本地库中刚刚的 commit,并把它们对接到更新后的版本库之中。

7.4 … you have unmerged files

问题描述:将本地代码提交到 GitHub 后某些组件插件或其他文件夹丢失。

原因:使用 Git 时,没有提前 git pull,就把自己本地修改的文件 git addgit commit,就会出现 “ … you have unmerged files.” 的 error。

解决方案:

git reflog:复制以前分支的 hash

git reset --hard hash:回溯之前版本

然后重新提交:

git status
git add . 
git commit -m "msg"

git push origin 分支 可能会出现报错:non-fast-forward ,参考上述解决方案。

7.5 删除 node_modules

场景:需要删掉整个项目,或某些操作导致各种包依赖环境相互冲突报错又忘记该具体卸载哪个包时。

问题描述:清空 node_modules 文件夹时由于文件数量大,左上角系统不停计算剩余文件的进度条导致删除缓慢。

解决方案:在node_modules所在当前目录下执行

rm -rf node_modules

7.6 error setting certificate verify locations

问题描述:执行 git push origin master 命令时出错:

fatal: unable to access ‘https://github.com/…/’: error setting certificate verify locations:
CAfile: D:/Git/Git/mingw64/ssl/certs/ca-bundle.crt
CApath: none

解决方案:

(1)git config –system http.sslcainfo “C:\Program Files (x86)\git\bin\curl-ca-bundle.crt”

(2)git config –system http.sslverify false

(3)顺着报错信息在文件树里找,发现:D:/Git/mingw64/libexec 没有 ssl 目录。但在 D:\Git\mingw64 目录下有 ssl/certs/ca-bundle.crt 这个路径。将 ssl 目录 复制到 D:/Git/mingw64/libexec 下即可。

7.7 Git Bash Here 失效

问题描述:在某个文件夹下右键选择 git bash/gui here ,结果显示 “找不到应用程序”,这是 Git 相关的文件路径变更导致的。

解决方案:

(1)win + R 打开命令行窗口,输入 regedit 打开注册表。

(2)根据路径查找 [HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Directory\background\shell\git_shell\command] 和[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Directory\shell\git_shell\command] 。

将其数值数据里面的路径修改为现在的 git bash.exe 的路径:

将其 git_shell 改为 git_gui ,找到两个路径,将其数值数据里面的路径修改为现在的 git gui.exe 的路径
关闭注册表,接着在文件夹右键选择 git bash/gui here ,发现可以打开,完成。

然后你会发现新问题:git clone 不好用,解决:在 Git 安装包下,找到 gitconfig 文件修改里边的路径信息

这里改好就好了,记住安装完 Git 不要随便移动路径,因为注册表中的信息不会改变。

7.8 管理小程序

和管理日常项目流程如出一撤,具体如何用 Git 管理小程序就不一一赘述了,有需要可以看这篇:微信小程序如何使用Git实现版本管理

说下遇到的问题:push 远程仓库提示 error invalid authentication scheme

解决方案:在微信小程序的设置里面配置仓库设置中的网络认证,认证选择用户名和密码,然后填写好你创建远程仓库时候设置的用户名和密码。

7.9 问题征集

到此为止关于 Git 相关的知识就整理完毕了,阿呆暂时只遇到了这些问题,以后出现新问题我会及时整理更新,诸君有其他的疑问也欢迎在评论区留言哦。


 上一篇
VSCode 配置分享 VSCode 配置分享
VSCode 作为前端主流的开发利器之一,本文整理了一些自用的配置和插件方便日常开发。
2021-06-28
下一篇 
HTML 回顾 HTML 回顾
作为一个前端小白打好基础很重要,虽然 HTML 的语法不多正处于完善阶段,但总会有一丢丢忘记的知识点,学而时习之,这样才可以形成一个系统的知识体系,不用在遇到问题的时候搜索文档,最好还是能了然于胸~
2021-03-03
  目录