Git
配置 ssh
- 设置 user name 和 email
# 如果需要配置当前项目,则不用加--global
git config --global user.name 'wing'
git config --global user.email 'wing@qq.com'# 如果需要配置当前项目,则不用加--global
git config --global user.name 'wing'
git config --global user.email 'wing@qq.com'- 生成 SSH 密钥过程
(1)查看是否已经有了 ssh 密钥:cd ~/.ssh
路径:c:/用户/Administrator/.ssh 删除.ssh 下面的所有文件
(2)生成密钥
ssh-keygen -t rsa -C 'wing@qq.com' // 回车之后记得根据提示按下yesssh-keygen -t rsa -C 'wing@qq.com' // 回车之后记得根据提示按下yes注意:如果提示 ssh-keygen 不是内部命令或者其他的报错,则需要以下配置
找到 git/usr/bin 目录下的 ssh-keygen.exe,之后配置到 Path 环境变量;

- 生成密钥之后就可以去官网绑定了
配置多个 ssh
创建 ssh key,名字随便写,后面地址记得修改为自己的.ssh 地址,mac 为~/.ssh,window 为 c 盘下面的用户下面的.ssh
bashssh-keygen -t rsa -C "hny@q.com" -f ~/.ssh/id_rsa_gitlabssh-keygen -t rsa -C "hny@q.com" -f ~/.ssh/id_rsa_gitlab创建一个 config 文件,没有后缀,编辑以下内容:
bash# gitee Host gitee.com HostName gitee.com PreferredAuthentications publickey IdentityFile ~/.ssh/id_rsa.gitee # github Host github.com HostName github.com PreferredAuthentications publickey IdentityFile ~/.ssh/id_rsa.github # gitlab Host gitlab.com HostName gitlab.com PreferredAuthentications publickey IdentityFile ~/.ssh/id_rsa.gitlab# gitee Host gitee.com HostName gitee.com PreferredAuthentications publickey IdentityFile ~/.ssh/id_rsa.gitee # github Host github.com HostName github.com PreferredAuthentications publickey IdentityFile ~/.ssh/id_rsa.github # gitlab Host gitlab.com HostName gitlab.com PreferredAuthentications publickey IdentityFile ~/.ssh/id_rsa.gitlab最后进行测试连通性
bashssh -T git@gitlab.comssh -T git@gitlab.com
注意
配置 ssh 后,拉项目仍然提示无权限,查看是否有
known_hosts文件存在.ssh里面,如果没有的话在拉项目会提示生成,输入 yes 即可生成,如果回车则不会生成仍无权限,尝试在.ssh 文件夹下新增 config 文件,并加入如下
bashPubkeyAcceptedKeyTypes +ssh-rsaPubkeyAcceptedKeyTypes +ssh-rsa仍无权限,使用新的签名算法
bashssh-keygen -t ed25519 -C "xxx@email.com"ssh-keygen -t ed25519 -C "xxx@email.com"
分支操作
分支常用命令
git branch查看本地分支git branch -a查看所有分支git branch -r列出所有远程分支git branch -vv查看本地分支写远程分支的对比git branch -m master main重命名分支git branch -d [分支名]删除分支git checkout <branch>切换到一个分支,本地没有的分支远程有的话也可以直接切换git checkout -b dev创建一个新分支git checkout -b dev origin/dev切换到一个新的分支,并追踪到远程分支上;git checkout --orphan [分支名]新建一个空白分支git push --set-upstream origin dev将本地新分支推到远程git fetch拉取最新远程信息git merge master合并 master 内容git rebase dev2.0融合 dev2.0 分支最新的内容git branch --track [分支名] [远程分支名]新建一个分支,与指定的远程分支建立追踪关系git push origin --delete [分支名]git branch -dr [remote/分支名]删除远程分支
分支命名规范
master:master 分支为主分支,也是用于部署生产环境的分支,master 分支一般由其他分支进行合并,任何时间都不能直接修改 master 分支;develop:develop-4.0.0;分支为开发分支,一般开发新功能时,feature 分支都是基于 develop 分支创建的;feature:feature-user;开发新功能时,以 develop 为基础创建 feature 分支release:release-4.0.0;release 为预上线分支,发布提测hotfix:hotfix-***;线上出现紧急问题时,需要及时修复,以 master 分支为基线,创建 hotfix 分支,修复完成后,需要合并到 master 分支和 develop 分支

主分支 master 建议每次上线打上 tag
git tag -a v0.1 -m '部署包版本名'git tag -a v0.1 -m '部署包版本名'清理本地分支
git remote show origin
git remote prune origingit remote show origin
git remote prune origin删除分支
删除不能删除远程的分支
(1)删除单个分支
git branch -D devgit branch -D dev(2)批量删除:删除除去 master 分支:
git checkout master
git branch | grep -v 'master' | xargs git branch -Dgit checkout master
git branch | grep -v 'master' | xargs git branch -Dgitlab 分支介绍
所有分支针对master做比较,下图中,左边为落后master分支数量,右边为超前master分支数量;

删除中间的版本
git rebase -i commit-idgit rebase -i commit-id执行命令之后会弹出来一个 vim 编辑器,将要删除的版本的pick改为drop,之后保存,之后执行git push -f -u强制推送远程
常见分支问题
ignoring broken ref refs 问题
- 找到.git 目录下 refs/remotes/origin 目录(子模块的这个目录是在主模块的.git 目录下,因为子模块没有.git 目录)
- 删除里面的 HEAD 文件或者所有文件
- 然后运行 git fetch –all
commit
commit 提交消息类型
- build:主要目的是修改项目构建系统(例如 glup,webpack,rollup 的配置等)的提交
- ci:主要目的是修改项目继续集成流程(例如 Travis,Jenkins,GitLab CI,Circle 等)的提交
- docs:文档更新
- feat:新增功能
- fix:bug 修复
- perf:性能优化
- refactor:重构代码(既没有新增功能,也没有修复 bug)
- style:不影响程序逻辑的代码修改(修改空白字符,补全缺失的分号等)
- test:新增测试用例或是更新现有测试
- revert:回滚某个更早之前的提交
- chore:不属于以上类型的其他类型
重复上次提交信息
git commit --amend --no-edit; 一般用于上次 commit 忘记修改的文件了;
文件忽略
创建一个 .gitignore 文件放置在项目根目录下
该文件内可将某个文件或目录忽略,不再提示要求提交该文件了。
temp.js
.gitignore
/node_modules/
*.htmltemp.js
.gitignore
/node_modules/
*.html# 提交暂存区到仓库区
git commit -m [提交信息]
# 替换上一次 commit(如无代码改动,就重写上一次 commit 的提交信息)
git commit --amend -m [提交信息]# 提交暂存区到仓库区
git commit -m [提交信息]
# 替换上一次 commit(如无代码改动,就重写上一次 commit 的提交信息)
git commit --amend -m [提交信息]常用指令
- 获取最后一个 commitId:
git log -1 --pretty=%H - 获取当前远程比本地多几个 commit:
git rev-list --count --left-only @{u}...HEAD - 获取当前分支:
git rev-parse --abbrev-ref HEAD
git rebase
git rebase 会将当前分支的提交复制到指定的分支之上;
git rebase master 将 master 分支的 commit 合并到当前分支上
rebase 可以保留一个漂亮的、线性的 git 历史记录;
同一分支的合并
当拉代码遇到冲突时,需要 pull,这时,git log --oneline --graph 会发现多出了一个分叉,这时输入git rebase即可合并当前的分叉,之后执行 push 提交代码;
也可以直接:git pull --rebase;不需要 pull 之后再 rebase;
不同分支之间的合并
# 当dev1分支修改后, 切换到dev2分支, 并rebase dev1分支
git checkout dev2
git rebase dev1
git checkout dev1# 当dev1分支修改后, 切换到dev2分支, 并rebase dev1分支
git checkout dev2
git rebase dev1
git checkout dev1如果在 rebase 时,出现冲突,比如:代码修改
rebase 冲突之后:git rebase --continue;因为之前的 rebase 其实只完成了一半;
参考文献:Git rebase 使用
不关心内容,自己合并冲突,递归解决
git rebase -s recursive -X theirs <branch>git rebase -s recursive -X theirs <branch>之后 rebase 冲突,只需要执行以下命令继续解决:
git add .
git rebase --continuegit add .
git rebase --continue产生分叉的条件
- 当 push 时,提示需要拉代码,这时 pull 之后再 push,就会产生分叉,解决办法就是 pull 之后执行
git rebase之后再提交即可 - 基于 master 拉的 dev 分支,master 提交了新的代码之后再合并 dev 分支,这时 master 有个单独的 commit,就会产生分叉了,解决办法就是当 merge 分支代码时,如果出现分叉,尽量使用 rebase,而不是使用 merge
分叉时 rebase 的使用
当出现分叉时,哪个分支代码落后,就在哪个分支 rebase 最新的分支
如果代码发生冲突,则会在 rebase 时,让你解决,
- 冲突解决没有更改:
git rebase --skip - 冲突解决有更改:使用
git add .andgit rebase --continue
冲突解决完成之后,由于本地的分支与远程不一致,会让 pull,这时使用 git push -f强制推送,强制推送之前尽量检查下之前的 commit 代码是否存在;
如果没有出现分叉,使用 merge 或者 rebase 都是一样的
rebase 时冲突过多
检查是否有同一个 message 重复多次,将重复的 message 使用git rebase -i,之后 drop 掉重复 message 的 commitId,这样就不会出现冲突了
git stash
为什么需要暂时:
- (1)当我们写代码时,发现写错分支了,此时需要将代码保存到暂存区,切换到正确的分支再拉下来
- (2)当我们修改了一些文件时,想查看修改的文件是否造成了其他问题,可以先保存在暂存区,测试完再拉下来
基础使用
git stash # 提交到暂存区
git stash pop # 拉下来git stash # 提交到暂存区
git stash pop # 拉下来- 常用的 git stash 命令
git stash save 'message':执行存储时,添加备注,方便查找,git stash 不方便查找git stash list:查看 stash 了哪些存储git stash show:显示做了哪些改动,默认 show 第一个存储,git stash show stash@{1}: 显示第一个修改文件git stash apply: 应用某个存储,但不会把存储从存储列表中删除,默认使用第一个git stash apply stash@{1}:应用第一个git stash pop: 命令恢复之前的缓存工作目录,将缓存堆栈中的对应 stash 删除git stash pop stash@{1}:应用指定的 stashgit stash drop stash@{1}:丢弃第几个存储,从列表中删除这个存储git stash clear: 删除所有缓存的 stash;
注意:新增的文件,直接执行stash是不会被存储的,如果有新增文件的时候,需要首先执行 git add 添加新文件到 git 库中,不需要提交和commit,然后再执行git stash即可;
git cherry-pick
如果需要合并所有的内容,直接使用 merge 即可,如果只需要部分内容,则使用git cherry-pick,需要切换到想要 cherry-pick 的分支
- 合并单个:
git cherry-pick commitId如果跟的是分支名,表示合并分支最新提交 - 合并多个:
git cherry-pick commitIdA commitIdB - 合并连续不包含 A:
git cherry-pick commitIdA..commitIdB - 合并连续包含 A:
git cherry-pick commitIdA^..commitIdB
其他操作
- 如果合并过程中发生冲突,待解决冲突之后,执行
git add .,之后执行git cherry-pick --continue - 冲突之后放弃合并:
git cherry-pick --abort - 冲突之后直接退出:
git cherry-pick --quit
标签
# 列出所有 tag
git tag
# 根据当前 commit 创建一个 tag
git tag [tag]
# 根据指定 commit 创建一个 tag
git tag [tag] [commit id]
# 删除本地 tag
git tag -d [tag]
# 删除远程 tag
git push origin :refs/tags/[tagName]
# 查看 tag 信息
git show [tag]
# 提交指定 tag
git push [remote] [tag]
# 提交所有 tag
git push [remote] --tags
# 新建一个分支,指向某个tag
git checkout -b [分支名] [tag]# 列出所有 tag
git tag
# 根据当前 commit 创建一个 tag
git tag [tag]
# 根据指定 commit 创建一个 tag
git tag [tag] [commit id]
# 删除本地 tag
git tag -d [tag]
# 删除远程 tag
git push origin :refs/tags/[tagName]
# 查看 tag 信息
git show [tag]
# 提交指定 tag
git push [remote] [tag]
# 提交所有 tag
git push [remote] --tags
# 新建一个分支,指向某个tag
git checkout -b [分支名] [tag]用户管理
git config --list 查看 git 配置
版本管理
状态查看
git status 查看文件 add 的状态,以及远程是否有更新
日志查看
git log# 获取版本 idgit reflog# 查看所有的版本 id,可以查看到回退之后的之前的版本
reflog 可以查看到所有的操作信息,比如 push、reset、commit 等等;
比如:1-10 的版本回退到 1-8 的版本,git log 只能看到最新的 8,reflog 还可以看到 10;
回退版本
- 软重置:
git reset --soft HEAD~2或 id;
执行软重置不会移除提交之后加入的修改,但是会修改 git 的历史记录,当使用了 reset 可以使用 status 查看修改内容,意味着可以重新修改重新提交;
- 硬重置:
git reset --hard id不保留提交引入的修改,看不到之前的修改内容;
常用的回退版本命令:
git reset --hard id # 回退本地代码库
git push -f -u origin master # 推送到远程服务器
git pull # 重新拉取代码git reset --hard id # 回退本地代码库
git push -f -u origin master # 推送到远程服务器
git pull # 重新拉取代码回退上一个版本:git reset --hard head^
添加多个仓库地址
配置远程仓库:git remote add origin url
如果不行重命名也可以:git remote add originOther url
一次推送到所有仓库:git push --all
**set-url **
设置新的 url 地址:git remote set-url origin url
添加一个新的 url 地址:git remote set-url --add origin url
删除一个 url 地址:git remote set-url --delete origin url
使用 set-url 添加的新的地址,在 push 时会同时 push 两个
切换远程仓库地址
git remote -v # 查看本地仓库远程地址
git remote rm origin # 删除本地远程地址
git remote add origin url # 添加远程仓库地址
git branch --set-upstream-to=origin/master master # 将本地分支追踪到远程mastergit remote -v # 查看本地仓库远程地址
git remote rm origin # 删除本地远程地址
git remote add origin url # 添加远程仓库地址
git branch --set-upstream-to=origin/master master # 将本地分支追踪到远程mastergit 项目迁移
git clone --bare git地址 # 拉下来之后是.git的文件夹
git push --mirror git地址 # 直接push到新的项目仓库git clone --bare git地址 # 拉下来之后是.git的文件夹
git push --mirror git地址 # 直接push到新的项目仓库git 常见问题
描述出错怎么修改描述
第一种方法:git commit --amend,之后直接修改描述保存即可
第二种方法:
- 通过 git log 找到上一个提交的 commit_id

- 通过:git reset --soft commit_id,执行一遍,之后就可以重新 git commit 了;
项目名字被修改,地址被更换
# 第一种
git remote set-url origin url # 重新设置远程地址
# 第二种
git remote rm origin # 删除跟踪远程
git remote add origin url # 重新配置远程地址# 第一种
git remote set-url origin url # 重新设置远程地址
# 第二种
git remote rm origin # 删除跟踪远程
git remote add origin url # 重新配置远程地址放弃本地修改
没有git add .的情况
- 放弃单个文件修改:
git checkout -- readme.md - 放弃所有修改:
git checkout .
有git add .的情况
- 放弃单个文件:
git reset HEAD readme.md - 放弃所有:
git reset HEAD .
修改错分支
没有提交的情况
无论有没有添加到暂存区都行(暂存区就是有 commit 代码)
bashgit checkout -b new_branch # 建立临时分支, 这样改动会被带到新分支 git stash # 保存在栈区 git checkout 目标分支 git pull # 将代码拉下来, 避免解决冲突 git stash pop # 将栈区内容取出放到当前分支git checkout -b new_branch # 建立临时分支, 这样改动会被带到新分支 git stash # 保存在栈区 git checkout 目标分支 git pull # 将代码拉下来, 避免解决冲突 git stash pop # 将栈区内容取出放到当前分支
已提交
当前分支也需要内容
bashgit checkout targetBranch git cherry-pick commitIdgit checkout targetBranch git cherry-pick commitId当前分支不需要内容
bashgit reset HEAD^ # 撤销最近一次提交git reset HEAD^ # 撤销最近一次提交
已提交
bash# 撤回这次提交,但保留改动的内容 git reset HEAD~ --soft git stash # 现在切到正确的那个分支去 git checkout name-of-the-correct-branch git stash pop git add . # 或者你可以添加指定的文件 git commit -m "your message here"; # 现在你的改动就在正确的分支上啦# 撤回这次提交,但保留改动的内容 git reset HEAD~ --soft git stash # 现在切到正确的那个分支去 git checkout name-of-the-correct-branch git stash pop git add . # 或者你可以添加指定的文件 git commit -m "your message here"; # 现在你的改动就在正确的分支上啦第二种方法
bashgit checkout name-of-the-correct-branch # 抓取 master 分支上最新的那个 commit git cherry-pick master # 然后删掉 master 上的那个 commit git checkout master git reset HEAD~ --hardgit checkout name-of-the-correct-branch # 抓取 master 分支上最新的那个 commit git cherry-pick master # 然后删掉 master 上的那个 commit git checkout master git reset HEAD~ --hard
git 统计代码量
修改 since 开始日期,和 until 到什么日期,如果不修改则是至今
如果单独查询某个用户,修改$name 为用户邮箱
git log --format='%aN' | sort -u | while read name; do echo -en "$name\t"; git log --author="$name" --pretty=tformat: --since =2020-03-30 --until=2020-04-02 --numstat | awk '{ add += $1; subs += $2; loc += $1 - $2 } END { printf "added lines: %s, removed lines: %s, total lines: %s\n", add, subs, loc }' -; donegit log --format='%aN' | sort -u | while read name; do echo -en "$name\t"; git log --author="$name" --pretty=tformat: --since =2020-03-30 --until=2020-04-02 --numstat | awk '{ add += $1; subs += $2; loc += $1 - $2 } END { printf "added lines: %s, removed lines: %s, total lines: %s\n", add, subs, loc }' -; done--since 限制显示输出的范围
--since,--after仅显示指定时间之后的提交--until,--before仅显示指定时间之前的提交--author仅显示指定作者相关的提交
例子:
git log --until=1.minute.ago// 一分钟之前的所有 loggit log --since=1.day.ago// 一天之内的 loggit log --since=1.month.age --until=2.weeks.age// 一个月之前到半月之前的 log
指定时间
git log --format='%aN' | sort -u | while read name; do echo -en "$name\t"; git log --author="$name" --pretty=tformat: --since ='2020-04-02 00:00:00' --until='2020-04-02 23:59:59' --numstat | awk '{ add += $1; subs += $2; loc += $1 - $2 } END { printf "added lines: %s, removed lines: %s, total lines: %s\n", add, subs, loc }' -; donegit log --format='%aN' | sort -u | while read name; do echo -en "$name\t"; git log --author="$name" --pretty=tformat: --since ='2020-04-02 00:00:00' --until='2020-04-02 23:59:59' --numstat | awk '{ add += $1; subs += $2; loc += $1 - $2 } END { printf "added lines: %s, removed lines: %s, total lines: %s\n", add, subs, loc }' -; donegit 其他操作
在一行查看提交日志:git log --oneline --decorate --graph
git rm
git rm:同时从工作区和索引中删除文件git rm -r --cached:从索引中删除文件,但是本地文件还在常用的删除远程文件命令:
bashgit rm -r --cached target # 删除target文件 git commit -m 'delete target' git pushgit rm -r --cached target # 删除target文件 git commit -m 'delete target' git push
Cao Note