Skip to main content

1.git基础知识

1.git 工作区域

根据 git 文件存储区域划分,可以划分为 4 个:

  • 工作区:你在本地编辑器里改动的代码,所见即所得,里面的内容都是最新的
  • 暂存区:通过 git add 指令,会将你工作区改动的代码提交到暂存区里
  • 本地仓库:通过 git commit 指令,会将暂存区变动的代码提交到本地仓库中,本地仓库位于你的电脑上
  • 远程仓库:远端用来托管代码的仓库,通过 git push 指令,会将本地仓库的代码推送到远程仓库中

2.初始配置

配置用户信息

首次使用 git 时,设置提交代码时的信息:

# 配置用户名 
git config --global user.name "yourname"
# 配置用户邮箱
git config --global user.email "[email protected]"
# 查看当前的配置信息
git config --global --list
# 通过 alias 配置简写 ## 例如使用 git co 代替 git checkout
git config --global alias.co checkout

ssh key

向远端仓库提交代码时,需要在远端仓库添加本地生成的 ssh key。

#1.生成本地 ssh key,若已有直接到第 2 步:
ssh-keygen -t rsa -C "[email protected]"

#2.查看本地 ssh key:
cat ~/.ssh/id_rsa.pub

#3.将 ssh key 粘贴到远端仓库

3.高频命令

git clone: 克隆仓库

工作区提交到暂存区,用到的指令为 git add

# 克隆远端仓库到本地 
git clone <git url>
# 克隆远端仓库到本地,并同时切换到指定分支
branch1 git clone -b branch1 <git url>
# 克隆远端仓库到本地并指定本地仓库的文件夹名称为 my-project
git clone my-project <git url>

git add: 提交到暂存区

# 将所有修改的文件都提交到暂存区 
git add .
# 将修改的文件中的指定的文件 a.js 和 b.js 提交到暂存区
git add ./a.js ./b.js
# 将 js 文件夹下修改的内容提交到暂存区
git add ./js

git commit: 提交到本地仓库

将工作区内容提交到本地仓库所用到的指令为 git commit

# 将工作区内容提交到本地仓库,并添加提交信息 your commit message 
git commit -m "your commit message"

# 将工作区内容提交到本地仓库,并对上一次 commit 记录进行覆盖
## 例如先执行 git commit -m "commit1" 提交了文件a,commit_sha为hash1;再执行 git commit -m "commit2" --amend 提交文件b,commit_sha为hash2。最终显示的是a,b文件的 commit 信息都是 "commit2",commit_sha都是hash2
git commit -m "new message" --amend

# 将工作区内容提交到本地仓库,并跳过 commit 信息填写
## 例如先执行 git commit -m "commit1" 提交了文件a,commit_sha为hash1;再执行 git commit --amend --no-edit 提交文件b,commit_sha为hash2。最终显示的是a,b文件的 commit 信息都是 "commit1",commit_sha都是hash1
git commit --amend --no-edit

# 跳过校验直接提交,很多项目配置 git hooks 验证代码是否符合 eslint、husky 等规则,校验不通过无法提交
## 通过 --no-verify 可以跳过校验(为了保证代码质量不建议此操作QwQ)
git commit --no-verify -m "commit message"

# 一次性从工作区提交到本地仓库,相当于 git add . + git commit -m
git commit -am

git push: 提交到远程仓库

git push 会将本地仓库的内容推送到远程仓库

# 将当前本地分支 branch1 内容推送到远程分支 origin/branch1 
git push <remote> <branch>
# 若当前本地分支 branch1,没有对应的远程分支 origin/branch1,需要为推送当前分支并建立与远程上游的跟踪
git push --set-upstream origin branch1
# 强制提交
## 例如用在代码回滚后内容
git push -f

#遠程新建分支
#新建遠程分支main,並將本地main分支推送到遠程main
git push origin main:main # origin 本地:远程
#推送后查看是否成功
git branch -a

#刪除分支main
git push origin --delete main
#或者也可以推送一個空分支main(沒有代碼),效果等同刪除分支
git push origin :main

git pull: 拉取远程仓库并合并

git pull 会拉取远程仓库并合并到本地仓库,相当于执行 git fetch + git merge

# 若拉取并合并的远程分支和当前本地分支名称一致 
## 例如当前本地分支为 branch1,要拉取并合并 origin/branch1,则直接执行:
git pull

# 若拉取并合并的远程分支和当前本地分支名称不一致 git pull <远程主机名> <分支名>
## 例如当前本地分支为 branch2,要拉取并合并 origin/branch1,则执行:
git pull [email protected]:zh-lx/git-practice.git branch1

# 使用 rebase 模式进行合并
git pull --rebase

git checkout: 切换分支

git checkout 用于切换分支及撤销工作区内容的修改

# 切换到已有的本地分支 branch1 
git checkout branch1

# 切换到远程分支 branch1
git checkout origin/branch1

# 基于当前本地分支创建一个新分支 branch2,并切换至 branch2
git checkout -b branch2

# 基于远程分支 branch1 创建一个新分支 branch2,并切换至 branch2
git checkout origin/branch1 -b branch2
## 当前创建的 branch2 关联的上游分支是 origin/branch1,所以 push 时需要如下命令关联到远程 branch2
git push --set-upstream origin branch2

# 撤销工作区 file 内容的修改。危险操作,谨慎使用
git checkout -- <file>
# 撤销工作区所有内容的修改。危险操作,谨慎使用
git checkout .

git restore: 取消缓存

git restore 用于将改动从暂存区退回工作区

# 将 a.js 文件取消缓存(取消 add 操作,不改变文件内容) 
git reset --staged a.js
# 将所有文件取消缓存 git reset --staged .

git reset: 回滚代码

git reset 用于撤销各种 commit 操作,回滚代码

# 将某个版本的 commit 从本地仓库退回到工作区(取消 commit 和 add 操作,不改变文件内容) 
## 默认不加 --mixed参数
git reset --mixed <commit_sha>

# 将某个版本的 commit 从本地仓库退回到缓存区(取消 commit 操作,不取消 add,不改变文件内容)
git reset --soft <commit_sha>

# 取消某次 commit 的记录(取消 commit 和 add,且改变文件内容)

git reset --hard <commit_sha>
eg:
git reset --hard HEAD^ 回退到上個版本
git push origin HEAD --force #回退后再推送HEAD的話,需要--force

## 以上三种操作退回了 commit,都是退回本地仓库的 commit,没有改变远程仓库的 commit。通常再次修改后配合如下命令覆盖远程仓库的 commit:
git push -f

4.常用命令

实际的 git 操作场景很多,下面的命令也经常在场景中使用。

git revert: 取消某次 commit 内容

git revert 相比于 git reset,会取消某次 commit 更改的内容,但是不会取消掉 commit 记录,而是进行一次新的 commit 去覆盖要取消的那次 commit:

# 取消某次 commit 内容,但是保留 commit 记录 
git revert <commit-sha>

git rebase: 简洁 commit 记录

git rebase 命令主要是针对 commit 的,目的是令 commit 记录变得更加简洁清晰。

多次 commit 合并为一次

可以通过 git rebase -i 合并多次 commit 为一次。注意:此操作会修改 commit-sha,因此只能在自己的分支上操作,不能在公共分支操作,不然会引起他人的合并冲突

# 进行 git rebase 可交互命令变基,end-commit-sha 可选,不填则默认为 HEAD 
## start 和 end commit-sha 左开右闭原则
git rebase -i <start commit-sha> <end commit-sha>

# 若是中间毫无冲突,变基则一步到位,否则需要逐步调整
# 上次变基为完成,继续上一次的变基操作
git rebase --continue

# 变基有冲突时丢弃有冲突的 commit git rebase --skip

# 若是变基中途操作错误但是未彻底完成,可以回滚到变基之前的状态
git rebase --abort
  • pick: 是保留该 commit(采用)
  • edit: 一般你提交的东西多了,可以用这个把东东拿回工作区拆分更细的 commit
  • reword: 这个可以重新修改你的 commit msg
  • squash: 内容保留,把提交信息往上一个 commit 合并进去
  • fixup: 保留变动内容,但是抛弃 commit msg

使用 rebase 代替 merge

前面说到过 git pull = git fetch + git merge,通过加 --rebase 参数可以启用 rebase 模式, 实际上 git pull --rebase = git fetch + git rebase

git rebase 代替 git merge 是现在许多公司和团队要求使用的一种合并方式。相比于 git mergegit rebase 可以让分支合并后只显示 master 一条线,并且按照 commit 和时间去排序,使得 git 记录简洁和清晰了许多。

# 将本地某分支合并至当前分支 
git rebase <分支名>
# 将远程某分支合并至当前分支
git rebase <远程主机名> <分支名>

git cherry-pick: 合并指定 commit

git cherry-pick 可以选择某次 commit 的内容合并到当前分支

# 将 commit-sha1 的变动合并至当前分支 
git cherry-pick commit-sha1

# 将多次 commit 变动合并至当前分支
git cherry-pick commit-sha1 commit-sha2

# 将 commit-sha1 到 commit-sha5 中间所有变动合并至当前分支,中间使用..
git cherry-pick commit-sha1..commit-sha5

# pick 时解决冲突后继续 pick
git cherry-pick --continue:

# 多次 pick 时跳过本次 commit 的 pick 进入下一个 commit 的 pick
git cherry-pick --skip

# 完全放弃 pick,恢复 pick 之前的状态
git cherry-pick --abort

# 未冲突的 commit 自动变更,冲突的不要,退出这次 pick
git cherry-pick --quit

git stash:缓存代码

git stash 用于将当前的代码缓存起来,而不必提交,便于下次取出。

# 把本地的改动缓存起来 
git stash
# 缓存代码时添加备注,便于查找。强烈推荐

git stash save "message"
# 查看缓存记录
## eg: stash@{0}: On feat-1.1: 活动功能

git stash list
# 取出上一次缓存的代码,并删除这次缓存

git stash pop
# 取出 index 为2缓存代码,并删除这次缓存,index 为对应 git stash list 所列出来的
git stash pop stash@{2}

# 取出上一次缓存的代码,但不删除这次缓存
git stash apply

# 取出 index 为2缓存代码,但不删除缓存
git stash apply stash@{2}

# 清除某次的缓存
git stash drop stash@{n}

# 清除所有缓存
git stash clear

场景

某日开发老哥正愉快地开发着活动功能的代码,突然pm大喊:线上出 bug 了!!于是开发老哥不得不停下手头的工作去修改线上bug,但是开发老哥又不想将现在的活动代码提交,于是开发老哥执行了 stash 命令:git stash message "活动功能暂存",之后转去修复线上 bug 了。

5.其他常用命令

git init: 初始化仓库

git init 会在本地生成一个 .git 文件夹,创建一个新的本地仓库:

git init <dir>

git remote: 关联远程仓库

git remote 用于将本地仓库与远程仓库关联

# 关联本地 git init 到远程仓库 
git remote add origin <git url>

# 新增其他上游仓库
git remote add <git url>

# 移除与远程仓库的管理
git remote remove <git url>

# 修改推送源
git remote set-url origin <git url>

#查看所有遠程倉庫鏈接
git remote -v

git status: 查看工作区状态

git status 用于查看工作区的文件,有哪些已经添加到了暂存区,哪些没有被添加:

# 查看当前工作区暂存区变动 
git status

# 以概要形式查看工作区暂存区变动
git status -s

# 查询工作区中是否有 stash 缓存
git status --show-stash

git log: 查看 commit 日志

git log 用于查看 commit 的日志

# 显示 commit 日志 
git log

# 以简要模式显示 commit 日志
git log --oneline

# 显示最近 n 次的 commit 日志
git log -n

# 显示 commit 及分支的图形化变更
git log --graph --decorate

git reflog: 查看commit和reset日志

已刪除的commit記錄也能看到,而git log 不能查看。

git reflog
e35c0e9 HEAD@{0}: checkout: moving from 07fda10f1c4001701ae9cdaf022351cc792f7888 to remotes/origin/master
07fda10 HEAD@{1}: checkout: moving from dev to remotes/origin/dev
e35c0e9 HEAD@{2}: checkout: moving from justtest to dev
e35c0e9 HEAD@{3}: checkout: moving from master to justtest
e35c0e9 HEAD@{4}: clone: from http://xxxxxxx/halo-theme-dream2.0.git

git branch: 管理分支

git branch 常用于删除、重命名分支等

# 删除分支 
git branch -D <分支名>

# 重命名分支
git branch -M <老分支名> <新分支名>

# 将本地分支与远程分支关联
git branch --set-upstream-to=origin/xxx

# 取消本地分支与远程分支的关联
git branch --unset-upstream-to=origin/xxx

#显示所有分支
git branch -a

git rm:重新建立索引

git rm 用于修改 .gitignore 文件的缓存,重新建立索引

# 删除某个文件索引(不会更改本地文件,只会是 .gitignore 范围重新生效) 
git rm --cache -- <文件名>

# 清除所有文件的索引
## 例如你首次提交了很多文件,后来你建立了一个 .gitignore 文件,有些文件不想推送到远端仓库,但此时有的文件已经被推送了
## 使用此命令可以是 .gitignore 重新作用一遍,从远程仓库中取消这些文件,但不会更改你本地文件
git rm -r --cached .

git diff: 对比差异

git diff 用于对比工作区、缓存区、本地仓库以及分支之间的代码差异:

# 当工作区有变动,暂存区无变动,对比工作区和本地仓库间的代码差异 
# 当工作区有变动和暂存区都有变动,对比工作区和暂存区的代码差异
git diff

# 显示暂存区和本地仓库间的代码差异
git diff --cached # or git diff --staged

# 显示两个分支之间代码差异
git diff <分支名1> <分支名2>

git fetch: 获取更新

git fetch 用于本地仓库获取远程仓库的更新,不会merge到工作区

# 获取远程仓库特定分支的更新 
git fetch <远程主机名> <分支名>
# 获取远程仓库所有分支的更新
git fetch --all

git merge: 合并代码

git merge 前面在 git rebase 内容中也提到过,用于合并代码,用法和 git rebase 类似:

# 将本地某分支合并至当前分支 
git merge <分支名>
# 将远程某分支合并至当前分支
git merge <远程主机名> <分支名>

gitlab相关操作

合并请求的建议和最佳实践

  • 在您的分支本地工作时,添加多个提交并仅在您完成后推送,因此极狐GitLab 一次只为所有提交运行一个流水线。通过这样做,您可以节省 CI/CD 分钟。
  • 在合并时或合并后删除功能分支以保持仓库清洁。
  • 一次只做一件事,并尽可能进行最小的更改。这样审核速度会更快,并且您的更改更不容易出错。
  • 不要在分支名称中使用大写字母或特殊字符。

使用Merge Request时的操作步骤:

  1. 编写代码并将其推送到单独的分支。
  2. 为主要开发分支创建合并请求。 Assignee以及说明字段和评论中被提到的那些人将通过电子邮件通知合并请求。如果需要某一位开发人员关注,你可以在描述字段中@该名开发人员。
  3. 等到MR被接受或拒绝,并提供有关必要修复的评论。
  4. 参与有关修复的讨论。 (GitLab允许回复评论)
  5. 修复。
  6. 将更改推送到你的分支。
  7. 打开一个新合并如果最后一个MR被关闭(如果合并请求未关闭,它将自动更新,直到最后一次提交为止)。
  8. 通过注释合并请求或以其他方式报告已实施的修复。

Issue相关操作

添加一个关联议题

  • 从 12.8版本开始引入。
  • 在 13.0 版本中尝试关闭被其他人阻止的问题时发出警告。当您尝试关闭开发受阻的议题时,您会看到可以一条可以忽略的警告。

要将一个议题链接到另一个议题:

  1. 在议题的 关联项 部分中,选择添加关联议题按钮 ()。

  2. 选择两个议题的关联关系。可以有如下选项:

  3. 输入议题号或者议题的完整URL地址。

    1. 同一项目的议题可以仅通过编号指定。 来自不同项目的会议需要额外的信息,比如组和项目名称。 例如:

      • 同一个项目:#44
      • 同一个组:project#44
      • 不同的组:group/project#44

      正确有效的引用会被添加到一个临时列表中供您查看。

  4. 选择了所有的相关议题后,选择 添加 . 添加完所有关联议题后,会自动进行归类,以便可以更好地理解它们的关系。

    您还可以从提交信息或另一个议题或 MR 的描述中添加关联议题。交叉关联议题

移除关联议题

关联项 部分, 点击要删除的关联议题右边的删除按钮 ()。

由于双向关系的因素,该关系不再出现在任一议题中。

gitlab提交Issues简单操作流程

1.在issues列表新建一个项目的issue,如果有相关的Issue的话,需要关联

2.着手开始修复issue时,在issue界面点击“创建分支”或“创建合并请求及分支”。

3.选择“创建分支”的话,推送已修复的代码后,与主线或其他功能分支合并,分支合并后,issue会被自动关闭。

描述模板

您可以定义模板以用作描述 为您的问题合并请求

您可以在项目、组或实例中定义这些模板。项目 继承在更高级别定义的模板。

您可能希望使用以下模板:

  • 适用于工作流的不同阶段,例如功能建议、功能改进或错误报告。
  • 对于特定项目的每个问题或合并请求,因此布局是一致的。
  • 对于服务台电子邮件模板

要使描述模板正常工作,它们必须:

  • 与扩展程序一起保存。.md
  • 存储在项目存储库的 or 目录中。.gitlab/issue_templates.gitlab/merge_request_templates
  • 存在于默认分支上。

创建合并请求模板

GitHub 的话是在项目下新建一个 .github文件夹,里面加一个 PULL_REQUEST_TEMPLATE.md文件即可。

GitLab 的话是在项目下新建一个 .gitlab文件夹,然后再新建一个 merge_request_templates<span> </span>文件夹,里面放 .md文件即可,可以放多个,在提交合并请求的时候可以选。

创建ISSUES请求模板

GitLab 的话是在项目下新建一个 .gitlab文件夹,然后再新建一个 issue_templates文件夹,里面放 .md文件即可,可以放多个,在提交合并请求的时候可以选。

提交 issue 也是可以预设模板的,去参照开源项目即可。

以下为几个举例:

🛠️ git 指令看这一篇就够 —— 各种工作场景的 git 指令大全 - 掘金 (juejin.cn)

合并请求入门 | 极狐GitLab

描述模板 |吉特实验室 (gitlab.com)

GitLab/GitHub合并请求的模板 · Issue #21 · findxc/blog

https://www.jianshu.com/p/198915ac64ba

Gitlab项目中添加issue或bug模板 | 奇客谷教程 💯 (qikegu.com)

GitLab权限设置、分支保护、Issue/Merge Request模板 - ArnoldLu - 博客园 (cnblogs.com)