Skip to content

Git ​

配置 ssh ​

  1. 设置 user name 和 email
bash
# 如果需要配置当前项目,则不用加--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'
  1. 生成 SSH 密钥过程

(1)查看是否已经有了 ssh 密钥:cd ~/.ssh

路径:c:/用户/Administrator/.ssh 删除.ssh 下面的所有文件

(2)生成密钥

bash
ssh-keygen -t rsa -C 'wing@qq.com'   // 回车之后记得根据提示按下yes
ssh-keygen -t rsa -C 'wing@qq.com'   // 回车之后记得根据提示按下yes

注意:如果提示 ssh-keygen 不是内部命令或者其他的报错,则需要以下配置

找到 git/usr/bin 目录下的 ssh-keygen.exe,之后配置到 Path 环境变量;

image-20240712163821432

  1. 生成密钥之后就可以去官网绑定了

配置多个 ssh ​

  1. 创建 ssh key,名字随便写,后面地址记得修改为自己的.ssh 地址,mac 为~/.ssh,window 为 c 盘下面的用户下面的.ssh

    bash
    ssh-keygen -t rsa -C "hny@q.com" -f ~/.ssh/id_rsa_gitlab
    ssh-keygen -t rsa -C "hny@q.com" -f ~/.ssh/id_rsa_gitlab
  2. 创建一个 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
  3. 最后进行测试连通性

    bash
    ssh -T git@gitlab.com
    ssh -T git@gitlab.com

注意

  1. 配置 ssh 后,拉项目仍然提示无权限,查看是否有known_hosts文件存在.ssh里面,如果没有的话在拉项目会提示生成,输入 yes 即可生成,如果回车则不会生成

  2. 仍无权限,尝试在.ssh 文件夹下新增 config 文件,并加入如下

    bash
    PubkeyAcceptedKeyTypes +ssh-rsa
    PubkeyAcceptedKeyTypes +ssh-rsa
  3. 仍无权限,使用新的签名算法

    bash
    ssh-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

bash
git tag -a v0.1 -m '部署包版本名'
git tag -a v0.1 -m '部署包版本名'

清理本地分支 ​

bash
git remote show origin
git remote prune origin
git remote show origin
git remote prune origin

删除分支 ​

删除不能删除远程的分支

(1)删除单个分支

bash
git branch -D dev
git branch -D dev

(2)批量删除:删除除去 master 分支:

bash
git checkout master
git branch | grep -v 'master' | xargs git branch -D
git checkout master
git branch | grep -v 'master' | xargs git branch -D

gitlab 分支介绍 ​

所有分支针对master做比较,下图中,左边为落后master分支数量,右边为超前master分支数量;

image-20240712163835666

删除中间的版本 ​

bash
git rebase -i commit-id
git rebase -i commit-id

执行命令之后会弹出来一个 vim 编辑器,将要删除的版本的pick改为drop,之后保存,之后执行git push -f -u强制推送远程

常见分支问题 ​

  1. 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 文件放置在项目根目录下

该文件内可将某个文件或目录忽略,不再提示要求提交该文件了。

sh
temp.js
.gitignore
/node_modules/
*.html
temp.js
.gitignore
/node_modules/
*.html
sh
# 提交暂存区到仓库区
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;

不同分支之间的合并

bash
# 当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 使用

不关心内容,自己合并冲突,递归解决

bash
git rebase -s recursive -X theirs <branch>
git rebase -s recursive -X theirs <branch>

之后 rebase 冲突,只需要执行以下命令继续解决:

bash
git add .
git rebase --continue
git add .
git rebase --continue

产生分叉的条件

  1. 当 push 时,提示需要拉代码,这时 pull 之后再 push,就会产生分叉,解决办法就是 pull 之后执行git rebase之后再提交即可
  2. 基于 master 拉的 dev 分支,master 提交了新的代码之后再合并 dev 分支,这时 master 有个单独的 commit,就会产生分叉了,解决办法就是当 merge 分支代码时,如果出现分叉,尽量使用 rebase,而不是使用 merge

分叉时 rebase 的使用

当出现分叉时,哪个分支代码落后,就在哪个分支 rebase 最新的分支

如果代码发生冲突,则会在 rebase 时,让你解决,

  • 冲突解决没有更改:git rebase --skip
  • 冲突解决有更改:使用git add . and git rebase --continue

冲突解决完成之后,由于本地的分支与远程不一致,会让 pull,这时使用 git push -f强制推送,强制推送之前尽量检查下之前的 commit 代码是否存在;

如果没有出现分叉,使用 merge 或者 rebase 都是一样的

rebase 时冲突过多

检查是否有同一个 message 重复多次,将重复的 message 使用git rebase -i,之后 drop 掉重复 message 的 commitId,这样就不会出现冲突了

git stash ​

  1. 为什么需要暂时:

    • (1)当我们写代码时,发现写错分支了,此时需要将代码保存到暂存区,切换到正确的分支再拉下来
    • (2)当我们修改了一些文件时,想查看修改的文件是否造成了其他问题,可以先保存在暂存区,测试完再拉下来
  2. 基础使用

bash
git stash # 提交到暂存区
git stash pop # 拉下来
git stash # 提交到暂存区
git stash pop # 拉下来
  1. 常用的 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} :应用指定的 stash
  • git 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

标签 ​

sh
# 列出所有 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 # 获取版本 id

  • git 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 不保留提交引入的修改,看不到之前的修改内容;

常用的回退版本命令:

bash
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 两个

切换远程仓库地址 ​

bash
git remote -v # 查看本地仓库远程地址
git remote rm origin # 删除本地远程地址
git remote add origin url # 添加远程仓库地址
git branch --set-upstream-to=origin/master master # 将本地分支追踪到远程master
git remote -v # 查看本地仓库远程地址
git remote rm origin # 删除本地远程地址
git remote add origin url # 添加远程仓库地址
git branch --set-upstream-to=origin/master master # 将本地分支追踪到远程master

git 项目迁移 ​

bash
git clone --bare git地址 # 拉下来之后是.git的文件夹
git push --mirror git地址  # 直接push到新的项目仓库
git clone --bare git地址 # 拉下来之后是.git的文件夹
git push --mirror git地址  # 直接push到新的项目仓库

git 常见问题 ​

描述出错怎么修改描述 ​

第一种方法:git commit --amend,之后直接修改描述保存即可

第二种方法:

  1. 通过 git log 找到上一个提交的 commit_id

image-20240712163846030

  1. 通过:git reset --soft commit_id,执行一遍,之后就可以重新 git commit 了;

项目名字被修改,地址被更换 ​

bash
# 第一种
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 .

修改错分支 ​

  1. 没有提交的情况

    • 无论有没有添加到暂存区都行(暂存区就是有 commit 代码)

      bash
      git 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 # 将栈区内容取出放到当前分支
  2. 已提交

    • 当前分支也需要内容

      bash
      git checkout targetBranch
      git cherry-pick commitId
      git checkout targetBranch
      git cherry-pick commitId
    • 当前分支不需要内容

      bash
      git reset HEAD^ # 撤销最近一次提交
      git reset HEAD^ # 撤销最近一次提交
  3. 已提交

    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";
    # 现在你的改动就在正确的分支上啦

    第二种方法

    bash
    git checkout name-of-the-correct-branch
    # 抓取 master 分支上最新的那个 commit
    git cherry-pick master
    # 然后删掉 master 上的那个 commit
    git checkout master
    git reset HEAD~ --hard
    git 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 为用户邮箱

bash
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 }' -; done
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 }' -; done

--since 限制显示输出的范围

  • --since, --after 仅显示指定时间之后的提交
  • --until, --before 仅显示指定时间之前的提交
  • --author 仅显示指定作者相关的提交

例子:

  • git log --until=1.minute.ago // 一分钟之前的所有 log
  • git log --since=1.day.ago // 一天之内的 log
  • git log --since=1.month.age --until=2.weeks.age // 一个月之前到半月之前的 log

指定时间

bash
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 }' -; done
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 }' -; done

git 其他操作 ​

在一行查看提交日志:git log --oneline --decorate --graph

git rm ​

  • git rm:同时从工作区和索引中删除文件

  • git rm -r --cached:从索引中删除文件,但是本地文件还在

  • 常用的删除远程文件命令:

    bash
    git rm -r --cached target # 删除target文件
    git commit -m 'delete target'
    git push
    git rm -r --cached target # 删除target文件
    git commit -m 'delete target'
    git push

打造自己的 git bash ​

https://blog.csdn.net/Dancer__Sky/article/details/81632640