baby sword‘s blog baby sword‘s blog
首页
  • java基础
  • java进阶
大数据
  • mysql

    • mysql索引
    • mysql日志
  • redis

    • 单机下的redis
    • 集群下的redis
  • Spring
  • springboot
  • RPC
  • netty
  • mybatis
  • maven
  • 消息队列
  • kafka
  • zookeeper
  • rocketmq
  • 七大设计原则
  • 创建型模式
  • 结构型模式
  • 行为型模式
  • SpringCloud

    • eureka
  • SpringCloud Alibaba

    • nacos
  • 计算机网络
  • 操作系统
  • 算法
  • 个人项目
  • 个人面试面经
  • 八股记忆
  • 工作积累
  • 逻辑题
  • 面试

    • 百度后端实习二面
GitHub (opens new window)

zhengjian

不敢承担失去的风险,是不可能抓住梦想的
首页
  • java基础
  • java进阶
大数据
  • mysql

    • mysql索引
    • mysql日志
  • redis

    • 单机下的redis
    • 集群下的redis
  • Spring
  • springboot
  • RPC
  • netty
  • mybatis
  • maven
  • 消息队列
  • kafka
  • zookeeper
  • rocketmq
  • 七大设计原则
  • 创建型模式
  • 结构型模式
  • 行为型模式
  • SpringCloud

    • eureka
  • SpringCloud Alibaba

    • nacos
  • 计算机网络
  • 操作系统
  • 算法
  • 个人项目
  • 个人面试面经
  • 八股记忆
  • 工作积累
  • 逻辑题
  • 面试

    • 百度后端实习二面
GitHub (opens new window)
  • 华仔聊技术

  • 业务设计

  • 场景设计

  • 运维

  • 安全

  • 面试

  • mac相关工具推荐

  • 开发工具

    • git安装后怎么做
      • 一. 安装git
        • 1. 检查是否安装成功
        • 2. 将ssh添加到对应的github或者gitlab
        • 3. 配置git姓名和邮箱
        • 4. 提交代码测试
      • 二. git 基础
        • 1. git中的三种状态
        • 2. git常用操作
        • 2.1 获取 Git 仓库
        • 2.2 记录每次更新到仓库
        • 2.3 一般流程
        • 2.4 commit日志
        • 2.5 回滚
        • 2.6 操作日志
        • 2.7 暂存区相关操作
        • 2.8文件删除
        • 2.9 文件忽略
        • 3. 工作区与暂存区
        • 3.1 工作区(Working Directory)
        • 3.2 版本库(Repository)
        • 3.3 暂存区的撤销与修改
        • 4. 远程git
        • 4.1 使用SSH进行双方的连接
        • 4.2 添加远程库
        • 4.3 SSH警告
        • 4.4 删除远程库
        • 4.5 克隆仓库
      • 三. 标签管理
        • 1.标签的本质
        • 2. 标签的分类
        • 3. 标签何时使用
        • 4. 标签相关命令
        • 4.1 创建一个标签
        • 4.2 显示标签
        • 4.3 显示标签内容
        • 4.4 查找标签
        • 4.5 标签推送到远程
        • 4.6 删除远程标签
        • 4.7 删除本地标签
        • 4.8 标签的切换
        • 4.9 拉取标签
      • 七.分支管理
        • 1. 分支原理
        • 2. 推送新分支到远程
        • 3. 拉取远程对应的分支到本地
        • 4. 合并冲突
        • 5. merge与rebase区别
        • 5.1 merge
        • 5.2 rebase
        • rebase冲突
        • 6. bug分支
        • 6.1 stash
        • 6.2 cherry-pick
        • 7. feature分支
        • 8. 团队协作
        • 9. 推送分支
      • 八.git 底层原理
      • 九.其他特殊操作
        • 1. 本地已经提交的commit修改邮箱等信息
    • git介绍
    • git常用命令
    • git三剑客
    • git标签详解
    • merge的方式
    • 记一次git rebase操作
    • 持续集成、持续交付、持续部署
    • 开机自启脚本方法
    • shell语法
    • 解决mac安装软件后显示已经被损坏
    • 不同序列化工具性能测试
    • JMH测试工具介绍
  • 人工智能

  • 推荐

  • 阅读

  • 工具

  • 计划

  • 产品

  • 云原生

  • go

  • QVM

  • 软件设计师

  • 极客时间

  • 单元测试

  • 其他
  • 开发工具
xugaoyi
2023-08-14
目录

git安装后怎么做

# 一. 安装git

# 1. 检查是否安装成功

git --version
1

查看git基本命令是否可用

# 2. 将ssh添加到对应的github或者gitlab

ssh-keygen -t rsa -C "your_email@example.com"
1

复制对应的key:

cat ~/.ssh/id_rsa.pub
1

生成新key并添加到github

登录到Github页面 -> 右上角Setttings -> SSH keys ->Add key

# 3. 配置git姓名和邮箱

git config --global user.name   "你的名字或昵称"
git config --global user.email  "你的邮箱"
1
2

# 4. 提交代码测试

git clone https://gitlab.testgu.com/ycyzharry/HelloGit.git #将远程仓库克隆到本地
git add . #将当前目录所有文件添加到git暂存区
git commit -m "my first commit" #提交并备注提交信息
git push origin master  #将本地提交推送到远程仓库
1
2
3
4

参考:使用Homebrew安装Git(Mac) (opens new window)

# 二. git 基础

# 1. git中的三种状态

Git 有三种状态,你的文件可能处于其中之一:

  1. 已提交(committed):数据已经安全的保存在本地数据库中。
  2. 已修改(modified):已修改表示修改了文件,但还没保存到数据库中。
  3. 已暂存(staged):表示对一个已修改文件的当前版本做了标记,使之包含在下次提交的快照中。

由此引入 Git 项目的三个工作区域的概念:Git 仓库(.git directory)、工作目录(Working Directory) 以及 暂存区域(Staging Area) 。

image-20230131162154630

基本的 Git 工作流程如下:

  1. 在工作目录中修改文件。
  2. 暂存文件,将文件的快照放入暂存区域。
  3. 提交更新,找到暂存区域的文件,将快照永久性存储到 Git 仓库目录。

另外需要注意,git追踪的是修改,不是文件,所以只要文件有修改,就会产生暂存区与工作区的不一致。

# 2. git常用操作

# 2.1 获取 Git 仓库

有两种取得 Git 项目仓库的方法。

  1. 在现有目录中初始化仓库: 进入项目目录运行 git init 命令,该命令将创建一个名为 .git 的子目录。
  2. 从一个服务器克隆一个现有的 Git 仓库: git clone [url] 自定义本地仓库的名字: git clone [url] directoryname

# 2.2 记录每次更新到仓库

  1. 检测当前文件状态 : git status
  2. 提出更改(把它们添加到暂存区):git add filename (针对特定文件)、git add *(所有文件)、git add *.txt(支持通配符,所有 .txt 文件)
  3. 忽略文件:.gitignore 文件
  4. 提交更新: git commit -m "代码提交信息" (每次准备提交前,先用 git status 看下,是不是都已暂存起来了, 然后再运行提交命令 git commit)
  5. 跳过使用暂存区域更新的方式 : git commit -a -m "代码提交信息"。 git commit 加上 -a 选项,Git 就会自动把所有已经跟踪过的文件暂存起来一并提交,从而跳过 git add 步骤。
  6. 移除文件 :git rm filename (从暂存区域移除,然后提交。)
  7. 对文件重命名 :git mv README.md README(这个命令相当于mv README.md README、git rm README.md、git add README 这三条命令的集合)

# 2.3 一般流程

git add .

git commit -m "提交信息"

git push
1
2
3
4
5

理解commit

就像存档一样,当我们写了一定的代码量过后,应该主动进行一次commit,以便于我们在可以进行回滚操作

# 2.4 commit日志

我们怎么知道我们提价的信息是什么,应该进行怎么回滚,这就需要我们查询相关的日志

git log

git log pretty=oneline
1
2
3
$ git log --pretty=oneline
1094adb7b9b3807259d8cb349e7df1d4d6477073 (HEAD -> master) append GPL
e475afc93c209a690c39c13a46716e8fa000c366 add distributed
eaadf4e385e865d25c48e7ca9c8395c3f7dfaef0 wrote a readme file
1
2
3
4

其中每次提交都会对应应该id,使用的是SHA1算法

# 2.5 回滚

git reset --hard HEAD^  //回滚到上一个commit
git reset --hard commitId //回滚到指定的commit
1
2

Git的版本回退速度非常快,因为Git在内部有个指向当前版本的HEAD指针,当你回退版本的时候,Git仅仅是把HEAD从指向append GPL:

┌────┐
│HEAD│
└────┘
   │
   └──▶ ○ append GPL
        │
        ○ add distributed
        │
        ○ wrote a readme file
1
2
3
4
5
6
7
8
9

改为指向add distributed:

┌────┐
│HEAD│
└────┘
   │
   │    ○ append GPL
   │    │
   └──▶ ○ add distributed
        │
        ○ wrote a readme file
1
2
3
4
5
6
7
8
9

然后顺便把工作区的文件更新了。所以你让HEAD指向哪个版本号,你就把当前版本定位在哪。

注意git reset --hard commitid会把暂存区中的信息清空

# 2.6 操作日志

git reflog

e475afc HEAD@{1}: reset: moving to HEAD^
1094adb (HEAD -> master) HEAD@{2}: commit: append GPL
e475afc HEAD@{3}: commit: add distributed
eaadf4e HEAD@{4}: commit (initial): wrote a readme file
1
2
3
4
5
6

根据操作日志,我们可以找到我们对应的commitid,然后重返未来的commit

# 2.7 暂存区相关操作

git add把文件从工作区>>>>暂存区,git commit把文件从暂存区>>>>仓库,

git diff查看工作区和暂存区差异,

git diff --cached查看暂存区和仓库差异,

git diff HEAD 查看工作区和仓库的差异,

git add的反向命令git checkout,撤销工作区修改,即把暂存区最新版本转移到工作区,

git commit的反向命令git reset HEAD,就是把仓库最新版本转移到暂存区。
1
2
3
4
5
6
7
8
9
10
11

另外需要注意,git追踪的是修改,不是文件,所以只要文件有修改,就会产生暂存区与工作区的不一致。

# 2.8文件删除

当我们的文件已经提交,此时如果我们在工作区删除一个文件、此时文件的删除会被git跟踪。

这个时候,Git知道你删除了文件,因此,工作区和版本库就不一致了,git status命令会立刻告诉你哪些文件被删除了:

现在你有两个选择,一是确实要从版本库中删除该文件,那就用命令git rm删掉,并且git commit:

小提示:先手动删除文件,然后使用git rm file和git addfile效果是一样的。

另一种情况是删错了,因为版本库里还有呢,所以可以很轻松地把误删的文件恢复到最新版本:

$ git checkout -- test.txt
1

git checkout其实是用版本库里的版本替换工作区的版本,无论工作区是修改还是删除,都可以“一键还原”。

# 2.9 文件忽略

有时候我们想要忽略git对一些文件目录的追踪,有什么办法呢?

.gitignore 文件是一个文本文件,它告诉Git 要忽略项目中的哪些文件或文件夹。 本地 .gitignore 文件通常被放置在项目的根目录中。 你还可以创建一个全局 .gitignore 文件,该文件中的所有条目都会在你所有的Git 仓库中被忽略。

HELP.md
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**
!**/src/test/**
logs/

### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache

### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr

### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/

### VS Code ###
.vscode/

/logs
**/.DS_Store
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

# 3. 工作区与暂存区

Git和其他版本控制系统如SVN的一个不同之处就是有暂存区的概念。

先来看名词解释。

# 3.1 工作区(Working Directory)

就是你在电脑里能看到的目录,比如我的learngit文件夹就是一个工作区:

image-20230131162213763

# 3.2 版本库(Repository)

工作区有一个隐藏目录.git,这个不算工作区,而是Git的版本库。

Git的版本库里存了很多东西,其中最重要的就是称为stage(或者叫index)的暂存区,还有Git为我们自动创建的第一个分支master,以及指向master的一个指针叫HEAD。

image-20230131162222297

分支和HEAD的概念我们以后再讲。

前面讲了我们把文件往Git版本库里添加的时候,是分两步执行的:

第一步是用git add把文件添加进去,实际上就是把文件修改添加到暂存区;

第二步是用git commit提交更改,实际上就是把暂存区的所有内容提交到当前分支。

因为我们创建Git版本库时,Git自动为我们创建了唯一一个master分支,所以,现在,git commit就是往master分支上提交更改。

你可以简单理解为,需要提交的文件修改通通放到暂存区,然后,一次性提交暂存区的所有修改。

俗话说,实践出真知。现在,我们再练习一遍,先对readme.txt做个修改,比如加上一行内容:

Git is a distributed version control system.
Git is free software distributed under the GPL.
Git has a mutable index called stage.
1
2
3

然后,在工作区新增一个LICENSE文本文件(内容随便写)。

先用git status查看一下状态:

$ git status
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

	modified:   readme.txt

Untracked files:
  (use "git add <file>..." to include in what will be committed)

	LICENSE

no changes added to commit (use "git add" and/or "git commit -a")
1
2
3
4
5
6
7
8
9
10
11
12
13
14

Git非常清楚地告诉我们,readme.txt被修改了,而LICENSE还从来没有被添加过,所以它的状态是Untracked。

现在,使用两次命令git add,把readme.txt和LICENSE都添加后,用git status再查看一下:

$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

	new file:   LICENSE
	modified:   readme.txt
1
2
3
4
5
6
7

现在,暂存区的状态就变成这样了:

image-20230131162328968

所以,git add命令实际上就是把要提交的所有修改放到暂存区(Stage),然后,执行git commit就可以一次性把暂存区的所有修改提交到分支。

$ git commit -m "understand how stage works"
[master e43a48b] understand how stage works
 2 files changed, 2 insertions(+)
 create mode 100644 LICENSE
1
2
3
4

一旦提交后,如果你又没有对工作区做任何修改,那么工作区就是“干净”的:

$ git status
On branch master
nothing to commit, working tree clean
1
2
3

现在版本库变成了这样,暂存区就没有任何内容了:

image-20230131162338322

# 3.3 暂存区的撤销与修改

git checkout -- file 放弃指定文在工作区的修改

命令git checkout -- readme.txt意思就是,把readme.txt文件在工作区的修改全部撤销,这里有两种情况:

一种是readme.txt自修改后还没有被放到暂存区,现在,撤销修改就回到和版本库一模一样的状态;

一种是readme.txt已经添加到暂存区后,又作了修改,现在,撤销修改就回到添加到暂存区后的状态。

总之,就是让这个文件回到最近一次git commit或git add时的状态。

git checkout -- file命令中的--很重要,没有--,就变成了“切换到另一个分支”的命令,我们在后面的分支管理中会再次遇到git checkout命令。

git reset HEAD <file>可以把暂存区的修改撤销掉(unstage),重新放回工作区:

git reset命令既可以回退版本,也可以把暂存区的修改回退到工作区。当我们用HEAD时,表示最新的版本。

# 4. 远程git

# 4.1 使用SSH进行双方的连接

第1步:创建SSH Key。在用户主目录下,看看有没有.ssh目录,如果有,再看看这个目录下有没有id_rsa和id_rsa.pub这两个文件,如果已经有了,可直接跳到下一步。如果没有,打开Shell(Windows下打开Git Bash),创建SSH Key:

$ ssh-keygen -t rsa -C "youremail@example.com"
1

你需要把邮件地址换成你自己的邮件地址,然后一路回车,使用默认值即可,由于这个Key也不是用于军事目的,所以也无需设置密码。

如果一切顺利的话,可以在用户主目录里找到.ssh目录,里面有id_rsa和id_rsa.pub两个文件,这两个就是SSH Key的秘钥对,id_rsa是私钥,不能泄露出去,id_rsa.pub是公钥,可以放心地告诉任何人。

第2步:登陆GitHub,打开“Account settings”,“SSH Keys”页面:

然后,点“Add SSH Key”,填上任意Title,在Key文本框里粘贴id_rsa.pub文件的内容:

image-20230131162349267

点“Add Key”,你就应该看到已经添加的Key:

image-20230131162356777

为什么GitHub需要SSH Key呢?因为GitHub需要识别出你推送的提交确实是你推送的,而不是别人冒充的,而Git支持SSH协议,所以,GitHub只要知道了你的公钥,就可以确认只有你自己才能推送。

当然,GitHub允许你添加多个Key。假定你有若干电脑,你一会儿在公司提交,一会儿在家里提交,只要把每台电脑的Key都添加到GitHub,就可以在每台电脑上往GitHub推送了。

最后友情提示,在GitHub上免费托管的Git仓库,任何人都可以看到喔(但只有你自己才能改)。所以,不要把敏感信息放进去。

如果你不想让别人看到Git库,有两个办法,一个是交点保护费,让GitHub把公开的仓库变成私有的,这样别人就看不见了(不可读更不可写)。另一个办法是自己动手,搭一个Git服务器,因为是你自己的Git服务器,所以别人也是看不见的。这个方法我们后面会讲到的,相当简单,公司内部开发必备。

# 4.2 添加远程库

现在的情景是,你已经在本地创建了一个Git仓库后,又想在GitHub创建一个Git仓库,并且让这两个仓库进行远程同步,这样,GitHub上的仓库既可以作为备份,又可以让其他人通过该仓库来协作,真是一举多得。

首先,登陆GitHub,然后,在右上角找到“Create a new repo”按钮,创建一个新的仓库:

image-20230131162405759

在Repository name填入learngit,其他保持默认设置,点击“Create repository”按钮,就成功地创建了一个新的Git仓库:

image-20230131162414733

目前,在GitHub上的这个learngit仓库还是空的,GitHub告诉我们,可以从这个仓库克隆出新的仓库,也可以把一个已有的本地仓库与之关联,然后,把本地仓库的内容推送到GitHub仓库。

现在,我们根据GitHub的提示,在本地的learngit仓库下运行命令:

$ git remote add origin git@github.com:michaelliao/learngit.git
1

请千万注意,把上面的michaelliao替换成你自己的GitHub账户名,否则,你在本地关联的就是我的远程库,关联没有问题,但是你以后推送是推不上去的,因为你的SSH Key公钥不在我的账户列表中。

添加后,远程库的名字就是origin,这是Git默认的叫法,也可以改成别的,但是origin这个名字一看就知道是远程库。

下一步,就可以把本地库的所有内容推送到远程库上:

$ git push -u origin master
Counting objects: 20, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (15/15), done.
Writing objects: 100% (20/20), 1.64 KiB | 560.00 KiB/s, done.
Total 20 (delta 5), reused 0 (delta 0)
remote: Resolving deltas: 100% (5/5), done.
To github.com:michaelliao/learngit.git
 * [new branch]      master -> master
Branch 'master' set up to track remote branch 'master' from 'origin'.
1
2
3
4
5
6
7
8
9
10

把本地库的内容推送到远程,用git push命令,实际上是把当前分支master推送到远程。

由于远程库是空的,我们第一次推送master分支时,加上了-u参数,Git不但会把本地的master分支内容推送的远程新的master分支,还会把本地的master分支和远程的master分支关联起来,在以后的推送或者拉取时就可以简化命令。

推送成功后,可以立刻在GitHub页面中看到远程库的内容已经和本地一模一样:

image-20230131162424639

从现在起,只要本地作了提交,就可以通过命令:

$ git push origin master
1

把本地master分支的最新修改推送至GitHub,现在,你就拥有了真正的分布式版本库!

# 4.3 SSH警告

当你第一次使用Git的clone或者push命令连接GitHub时,会得到一个警告:

The authenticity of host 'github.com (xx.xx.xx.xx)' can't be established.
RSA key fingerprint is xx.xx.xx.xx.xx.
Are you sure you want to continue connecting (yes/no)?
1
2
3

这是因为Git使用SSH连接,而SSH连接在第一次验证GitHub服务器的Key时,需要你确认GitHub的Key的指纹信息是否真的来自GitHub的服务器,输入yes回车即可。

Git会输出一个警告,告诉你已经把GitHub的Key添加到本机的一个信任列表里了:

Warning: Permanently added 'github.com' (RSA) to the list of known hosts.
1

这个警告只会出现一次,后面的操作就不会有任何警告了。

如果你实在担心有人冒充GitHub服务器,输入yes前可以对照GitHub的RSA Key的指纹信息 (opens new window)是否与SSH连接给出的一致。

# 4.4 删除远程库

如果添加的时候地址写错了,或者就是想删除远程库,可以用git remote rm <name>命令。使用前,建议先用git remote -v查看远程库信息:

$ git remote -v
origin  git@github.com:michaelliao/learn-git.git (fetch)
origin  git@github.com:michaelliao/learn-git.git (push)
1
2
3

然后,根据名字删除,比如删除origin:

$ git remote rm origin
1

此处的“删除”其实是解除了本地和远程的绑定关系,并不是物理上删除了远程库。远程库本身并没有任何改动。要真正删除远程库,需要登录到GitHub,在后台页面找到删除按钮再删除。

# 4.5 克隆仓库

git clone 地址
1

# 三. 标签管理

# 1.标签的本质

标签的本质是一次commit,其指向了一个commit对象。它们的值都为各自指向提交的SHA1值;但是,不同于会随着提交的变化而变化的分支,一旦给某次提交添加了标签,该标签就永远不会发生变化。

标签是一次提交,本次提交可以指向任何分支上的一次提交,且标签定下后,不会再进行改变。

# 2. 标签的分类

  • 轻量级标签(lightweight):不可添加注释;
  • 带有附注的标签(annotated):可以添加注释;

Annotated tags are meant for release while lightweight tags are meant for private or temporary object labels.

以上是git官方文档对两种标签的说明,大意是:带注释的标签用于发布,而轻量级标签则用于私人或临时对象。

# 3. 标签何时使用

  • 版本发布:一般master分支都会作为项目的发布分支,当项目开发到了一个成熟的阶段,准备在master分支进行发布时。一般都会在master分支的当前提交上打上一个类似"v1.2"的标签;
  • 版本管理:可以通过标签的形式记录项目某一阶段的状态。

image-20230412201509398

# 4. 标签相关命令

# 4.1 创建一个标签

  • 轻量级标签

git tag 标签名

我们看看一个轻量级的标签的内容:

image-20230412204829331

这里很容易看出来,轻量级的tag内容就是commit。这说明什么

说明:轻量级标签就是代指了一个commit的指针!!它本身就是一个commit

  • 带附注的标签

git tag -a 标签名 -m "注释"

创建好的标签文件存放在.git/refs/tags中

其实在git中tag也是一个对象,和commit、tree、blob一样

image-20230412204232458

我们看看这个tag的具体信息:

image-20230412204331744

**可以看到标签中有一个内容指向了具体的commit。**且带附注的tag的SAH1和其指向的SAH1不一致

说明带附注的标签更加重量级,他是一个tag对象,不是commit,只是其内部有指向commit的指针

# 4.2 显示标签

git tag 或者git tag --list

切换分支后,使用git tag依然可以展示标签,表示标签与tag是没有关系的

# 4.3 显示标签内容

git show 标签名

# 4.4 查找标签

支持正则表达式

git tag -l <tag_name>

# 4.5 标签推送到远程

默认情况git push 是不会推送tag的。

推送特定的tag

git push origin <tag_name>

推送多个tag

git push origin v2.0 v3.0

推送完整指令

git push origin refs/tags/v4.0:refs/tags/v4.0

推送本地全部的tag

git push origin --tag

# 4.6 删除远程标签

当然,我们可以直接在远程仓库上删除远程标签。但是,最好的方式还是采用命令行进行删除。删除远程标签的方法与删除远程分支的方法非常类似,同样有两种方法:

git push origin :<tag_name>

这种方法相当于推送一个空的标签到远程仓库,由此达到删除的效果。比如删除远程仓库中的标签v3.0:

git push origin :v3.0

1
2

image-20200418154504982

这样远程仓库中的标签V3.0就被删除了:

image-20200418154554319

但是本地仓库中对应的标签V3.0并没有被删除:

image-20200418154631370

上述指令为简写,完整写法如下:

git push origin :refs/tags/v3.0

1
2

image-20200418154906969

git push origin --delete <tag_name>

该方法采用了更加语义化的参数--delete,实现远程标签的删除:

git push origin --delete v2.0

1
2

image-20200418155134748

同样成功地删除了远程仓库中的标签v2.0:

image-20200418155216230

但是,本地的标签v2.0也没有被删除:

image-20200418155311429

采用下列的完整写法,效果是一样的:

git push origin --delete tag v2.0

1
2

image-20200418155513090

不难发现,删除远程分支和远程标签的方法是一样的。

# 4.7 删除本地标签

git tag -d <tag_name>

如通过以下命令删除标签v3.0:

git tag -d v3.0
1

image-20200418155616562

# 4.8 标签的切换

类似于commit的切换,会产生分离头指针

git checkout tag_name

如图所示,在master分支上进行了三次提交,并且添加了相应的标签:

image-20200418161353146

当我们通过checkout命令切换到标签v2.0时:

image-20200418161526176

可见,会出现游离的提交。此时查看各分支状态:

image-20200418161655468

如上图所示,当前处于标签v2.0指向的提交,并且切换标签的过程中改变了HEAD指针的指向。但是,并没有改变分支master的指向。过程如下图所示:

image-20200418162458123

也就是说,切换标签与使用reset进行版本回退十分相似。只不过切换标签只改变了HEAD指针的指向,会造成游离的提交。若有需要可以创建一个新分支进行保存。

# 4.9 拉取标签

在下图所示的情况中,本地仓库mygit与远程仓库有公共的提交历史(同源),并且不发生合并冲突的情况下

image-20200418160517111

可以直接通过git pull将远程仓库的标签拉取下来,并创建本地仓库中没有的标签:

image-20200418160737829

# 七.分支管理

# 1. 分支原理

在版本回退里,你已经知道,每次提交,Git都把它们串成一条时间线,这条时间线就是一个分支。截止到目前,只有一条时间线,在Git里,这个分支叫主分支,即master分支。HEAD严格来说不是指向提交,而是指向master,master才是指向提交的,所以,HEAD指向的就是当前分支。

一开始的时候,master分支是一条线,Git用master指向最新的提交,再用HEAD指向master,就能确定当前分支,以及当前分支的提交点:

                  HEAD
                    │
                    │
                    ▼
                 master
                    │
                    │
                    ▼
┌───┐    ┌───┐    ┌───┐
│   │───▶│   │───▶│   │
└───┘    └───┘    └───┘
1
2
3
4
5
6
7
8
9
10
11

每次提交,master分支都会向前移动一步,这样,随着你不断提交,master分支的线也越来越长。

当我们创建新的分支,例如dev时,Git新建了一个指针叫dev,指向master相同的提交,再把HEAD指向dev,就表示当前分支在dev上:

                 master
                    │
                    │
                    ▼
┌───┐    ┌───┐    ┌───┐
│   │───▶│   │───▶│   │
└───┘    └───┘    └───┘
                    ▲
                    │
                    │
                   dev
                    ▲
                    │
                    │
                  HEAD
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

你看,Git创建一个分支很快,因为除了增加一个dev指针,改改HEAD的指向,工作区的文件都没有任何变化!

不过,从现在开始,对工作区的修改和提交就是针对dev分支了,比如新提交一次后,dev指针往前移动一步,而master指针不变:

                 master
                    │
                    │
                    ▼
┌───┐    ┌───┐    ┌───┐    ┌───┐
│   │───▶│   │───▶│   │───▶│   │
└───┘    └───┘    └───┘    └───┘
                             ▲
                             │
                             │
                            dev
                             ▲
                             │
                             │
                           HEAD
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

假如我们在dev上的工作完成了,就可以把dev合并到master上。Git怎么合并呢?最简单的方法,就是直接把master指向dev的当前提交,就完成了合并:

                           HEAD
                             │
                             │
                             ▼
                          master
                             │
                             │
                             ▼
┌───┐    ┌───┐    ┌───┐    ┌───┐
│   │───▶│   │───▶│   │───▶│   │
└───┘    └───┘    └───┘    └───┘
                             ▲
                             │
                             │
                            dev
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

所以Git合并分支也很快!就改改指针,工作区内容也不变!

合并完分支后,甚至可以删除dev分支。删除dev分支就是把dev指针给删掉,删掉后,我们就剩下了一条master分支:

                           HEAD
                             │
                             │
                             ▼
                          master
                             │
                             │
                             ▼
┌───┐    ┌───┐    ┌───┐    ┌───┐
│   │───▶│   │───▶│   │───▶│   │
└───┘    └───┘    └───┘    └───┘
1
2
3
4
5
6
7
8
9
10
11

真是太神奇了,你看得出来有些提交是通过分支完成的吗?

下面开始实战。

首先,我们创建dev分支,然后切换到dev分支:

$ git checkout -b dev
Switched to a new branch 'dev'
1
2

git checkout命令加上-b参数表示创建并切换,相当于以下两条命令:

$ git branch dev
$ git checkout dev
Switched to branch 'dev'
1
2
3

然后,用git branch命令查看当前分支:

$ git branch
* dev
  master
1
2
3

git branch命令会列出所有分支,当前分支前面会标一个*号。

然后,我们就可以在dev分支上正常提交,比如对readme.txt做个修改,加上一行:

Creating a new branch is quick.
1

然后提交:

$ git add readme.txt 
$ git commit -m "branch test"
[dev b17d20e] branch test
 1 file changed, 1 insertion(+)
1
2
3
4

现在,dev分支的工作完成,我们就可以切换回master分支:

$ git checkout master
Switched to branch 'master'
1
2

切换回master分支后,再查看一个readme.txt文件,刚才添加的内容不见了!因为那个提交是在dev分支上,而master分支此刻的提交点并没有变:

image-20230131162437546

现在,我们把dev分支的工作成果合并到master分支上:

$ git merge dev
Updating d46f35e..b17d20e
Fast-forward
 readme.txt | 1 +
 1 file changed, 1 insertion(+)
1
2
3
4
5

git merge命令用于合并指定分支到当前分支。合并后,再查看readme.txt的内容,就可以看到,和dev分支的最新提交是完全一样的。

注意到上面的Fast-forward信息,Git告诉我们,这次合并是“快进模式”,也就是直接把master指向dev的当前提交,所以合并速度非常快。

当然,也不是每次合并都能Fast-forward,我们后面会讲其他方式的合并。

合并完成后,就可以放心地删除dev分支了:

$ git branch -d dev
Deleted branch dev (was b17d20e).
1
2

删除后,查看branch,就只剩下master分支了:

$ git branch
* master
1
2

因为创建、合并和删除分支非常快,所以Git鼓励你使用分支完成某个任务,合并后再删掉分支,这和直接在master分支上工作效果是一样的,但过程更安全。

  • switch

我们注意到切换分支使用git checkout <branch>,而前面讲过的撤销修改则是git checkout -- <file>,同一个命令,有两种作用,确实有点令人迷惑。

实际上,切换分支这个动作,用switch更科学。因此,最新版本的Git提供了新的git switch命令来切换分支:

创建并切换到新的dev分支,可以使用:

$ git switch -c dev
1

直接切换到已有的master分支,可以使用:

$ git switch master
1

使用新的git switch命令,比git checkout要更容易理解。

# 2. 推送新分支到远程

首先在本地创建新分支

git checkout -b dev

然后将新分支推到远程(远程没有该分支)

git push --set-upstream origin dev

# 3. 拉取远程对应的分支到本地

git checkout -b 本地分支名x origin/远程分支名x

# 4. 合并冲突

人生不如意之事十之八九,合并分支往往也不是一帆风顺的。

准备新的feature1分支,继续我们的新分支开发:

$ git switch -c feature1
Switched to a new branch 'feature1'
1
2

修改readme.txt最后一行,改为:

Creating a new branch is quick AND simple.
1

在feature1分支上提交:

$ git add readme.txt

$ git commit -m "AND simple"
[feature1 14096d0] AND simple
 1 file changed, 1 insertion(+), 1 deletion(-)
1
2
3
4
5

切换到master分支:

$ git switch master
Switched to branch 'master'
Your branch is ahead of 'origin/master' by 1 commit.
  (use "git push" to publish your local commits)
1
2
3
4

Git还会自动提示我们当前master分支比远程的master分支要超前1个提交。

在master分支上把readme.txt文件的最后一行改为:

Creating a new branch is quick & simple.
1

提交:

$ git add readme.txt 
$ git commit -m "& simple"
[master 5dc6824] & simple
 1 file changed, 1 insertion(+), 1 deletion(-)
1
2
3
4

现在,master分支和feature1分支各自都分别有新的提交,变成了这样:

                            HEAD
                              │
                              │
                              ▼
                           master
                              │
                              │
                              ▼
                            ┌───┐
                         ┌─▶│   │
┌───┐    ┌───┐    ┌───┐  │  └───┘
│   │───▶│   │───▶│   │──┤
└───┘    └───┘    └───┘  │  ┌───┐
                         └─▶│   │
                            └───┘
                              ▲
                              │
                              │
                          feature1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

这种情况下,Git无法执行“快速合并”,只能试图把各自的修改合并起来,但这种合并就可能会有冲突,我们试试看:

$ git merge feature1
Auto-merging readme.txt
CONFLICT (content): Merge conflict in readme.txt
Automatic merge failed; fix conflicts and then commit the result.
1
2
3
4

果然冲突了!Git告诉我们,readme.txt文件存在冲突,必须手动解决冲突后再提交。git status也可以告诉我们冲突的文件:

$ git status
On branch master
Your branch is ahead of 'origin/master' by 2 commits.
  (use "git push" to publish your local commits)

You have unmerged paths.
  (fix conflicts and run "git commit")
  (use "git merge --abort" to abort the merge)

Unmerged paths:
  (use "git add <file>..." to mark resolution)

	both modified:   readme.txt

no changes added to commit (use "git add" and/or "git commit -a")
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

我们可以直接查看readme.txt的内容:

Git is a distributed version control system.
Git is free software distributed under the GPL.
Git has a mutable index called stage.
Git tracks changes of files.
<<<<<<< HEAD
Creating a new branch is quick & simple.
=======
Creating a new branch is quick AND simple.
>>>>>>> feature1
1
2
3
4
5
6
7
8
9

Git用<<<<<<<,=======,>>>>>>>标记出不同分支的内容,我们修改如下后保存:

Creating a new branch is quick and simple.
1

再提交:

$ git add readme.txt 
$ git commit -m "conflict fixed"
[master cf810e4] conflict fixed
1
2
3

现在,master分支和feature1分支变成了下图所示:

                                     HEAD
                                       │
                                       │
                                       ▼
                                    master
                                       │
                                       │
                                       ▼
                            ┌───┐    ┌───┐
                         ┌─▶│   │───▶│   │
┌───┐    ┌───┐    ┌───┐  │  └───┘    └───┘
│   │───▶│   │───▶│   │──┤             ▲
└───┘    └───┘    └───┘  │  ┌───┐      │
                         └─▶│   │──────┘
                            └───┘
                              ▲
                              │
                              │
                          feature1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

用带参数的git log也可以看到分支的合并情况:

$ git log --graph --pretty=oneline --abbrev-commit
*   cf810e4 (HEAD -> master) conflict fixed
|\  
| * 14096d0 (feature1) AND simple
* | 5dc6824 & simple
|/  
* b17d20e branch test
* d46f35e (origin/master) remove test.txt
* b84166e add test.txt
* 519219b git tracks changes
* e43a48b understand how stage works
* 1094adb append GPL
* e475afc add distributed
* eaadf4e wrote a readme file
1
2
3
4
5
6
7
8
9
10
11
12
13
14

最后,删除feature1分支:

$ git branch -d feature1
Deleted branch feature1 (was 14096d0).
1
2

工作完成。

哪些命令可能会产生冲突?

push、pull、stash、rebase、merge

产生冲突的本质就是不同的分支在 同一个文件中修改了同一行内容

# 5. merge与rebase区别

首先需要明确,两种方案都是将两个分支合并为一个分支。既然是合并,那么就有可能会产生冲突,过程中需要我们手动解决冲突。

# 5.1 merge

image-20230201232521410

如图所示,有两个分支,一个为master分支,一个为dev分支。在commit 1节点,开启了新的分支,后续master继续开发,dev继续向前开发。当开发到如图所示的情况时,master分支想要合并dev分支,此时master可以使用以下命令:

git merge dev
1

注意作用对象,是让目标分支融合到当前分支

即站在master的视角下,让dev分支合并到master分支。结果如下:

image-20230201232606184

此时master会产生一个新的提交,dev也会产生一个新的提交。经过冲突解决后,形成如图所示的分支结构。这样,master分支就能成功感知到dev分支的存在了。dev分支也可以感知到master的存在,至此,两个分支代码相同了

优点:

  • 使用 merge 是很好的方式,因为它是一种非破坏性的操作,对现有分支不会以任何方式被更改。
  • 另一方面,这也意味着 feature 分支每次需要合并上游更改时,它都将产生一个额外的合并提交。

缺点:

  • 如果master 提交非常活跃,这可能会严重污染你的 feature 分支历史记录。不过这个问题可以使用高级选项 git log 来缓解

# 5.2 rebase

还是如图所示的图:

image-20230201232521410

如果我们在dev的视角下,rebase master,会出现以下的结果

image-20230201232712987

从图中我们可以看出来,rebase过后,变成了一条平滑的曲线,没有分支操作。另外,rebase不会进行新的提交,而是做“桥接”工作。

其找到dev和master的公共祖先commit,然后将5、6拼接到公共祖先,原先的4,3,2则嫁接到dev分支的末尾。

优点:

  • rebase 的主要好处是可以获得更清晰的项目历史。首先,它消除了 git merge 所需的不必要的合并提交;其次,正如你在上图中所看到的,rebase 会产生完美线性的项目历史记录,你可以在 feature分支上没有任何分叉的情况下一直追寻到项目的初始提交。

缺点:

  • 破坏了原来的分支提交结构,无法从原本上去查看提交情况。
# rebase冲突

其实在rebase时也是会产生冲突的,当产生冲突时,会产生以下提示

image-20230210192841216

当出现以下提示时,我们可以用idea自带的工具来解决冲突。

当解决冲突后,就会有以下选项进行

git rebase --continue 修改了冲突,继续rebase

git rebase --skip 跳过这个冲突(不建议使用,因为本地代码可能会丢失)

git rebase --abort 放弃本次rebase,回到rebase之前。

一般不会使用skip。如果有能力修改冲突,修改冲突后continue,如果没有能力修改冲突,就abort放弃本次rebase。

参考:

【Git】:git rebase和git merge有什么区别? (opens new window)

git rebase 用法详解与工作原理 (opens new window)

# 6. bug分支

软件开发中,bug就像家常便饭一样。有了bug就需要修复,在Git中,由于分支是如此的强大,所以,每个bug都可以通过一个新的临时分支来修复,修复后,合并分支,然后将临时分支删除。

当你接到一个修复一个代号101的bug的任务时,很自然地,你想创建一个分支issue-101来修复它,但是,等等,当前正在dev上进行的工作还没有提交:

$ git status
On branch dev
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

	new file:   hello.py

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

	modified:   readme.txt
1
2
3
4
5
6
7
8
9
10
11
12

并不是你不想提交,而是工作只进行到一半,还没法提交,预计完成还需1天时间。但是,必须在两个小时内修复该bug,怎么办?

# 6.1 stash

image-20230203000029444

幸好,Git还提供了一个stash功能,可以把当前工作现场“储藏”起来,等以后恢复现场后继续工作:

$ git stash
Saved working directory and index state WIP on dev: f52c633 add merge
1
2

现在,用git status查看工作区,就是干净的(除非有没有被Git管理的文件),因此可以放心地创建分支来修复bug。

首先确定要在哪个分支上修复bug,假定需要在master分支上修复,就从master创建临时分支:

$ git checkout master
Switched to branch 'master'
Your branch is ahead of 'origin/master' by 6 commits.
  (use "git push" to publish your local commits)

$ git checkout -b issue-101
Switched to a new branch 'issue-101'
1
2
3
4
5
6
7

现在修复bug,需要把“Git is free software ...”改为“Git is a free software ...”,然后提交:

$ git add readme.txt 
$ git commit -m "fix bug 101"
[issue-101 4c805e2] fix bug 101
 1 file changed, 1 insertion(+), 1 deletion(-)
1
2
3
4

修复完成后,切换到master分支,并完成合并,最后删除issue-101分支:

$ git switch master
Switched to branch 'master'
Your branch is ahead of 'origin/master' by 6 commits.
  (use "git push" to publish your local commits)

$ git merge --no-ff -m "merged bug fix 101" issue-101
Merge made by the 'recursive' strategy.
 readme.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
1
2
3
4
5
6
7
8
9

太棒了,原计划两个小时的bug修复只花了5分钟!现在,是时候接着回到dev分支干活了!

$ git switch dev
Switched to branch 'dev'

$ git status
On branch dev
nothing to commit, working tree clean
1
2
3
4
5
6

工作区是干净的,刚才的工作现场存到哪去了?用git stash list命令看看:

$ git stash list
stash@{0}: WIP on dev: f52c633 add merge
1
2

工作现场还在,Git把stash内容存在某个地方了,但是需要恢复一下,有两个办法:

一是用git stash apply恢复,但是恢复后,stash内容并不删除,你需要用git stash drop来删除;

另一种方式是用git stash pop,恢复的同时把stash内容也删了:

$ git stash pop
On branch dev
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

	new file:   hello.py

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

	modified:   readme.txt

Dropped refs/stash@{0} (5d677e2ee266f39ea296182fb2354265b91b3b2a)
1
2
3
4
5
6
7
8
9
10
11
12
13
14

再用git stash list查看,就看不到任何stash内容了:

$ git stash list
1

你可以多次stash,恢复的时候,先用git stash list查看,然后恢复指定的stash,用命令:

$ git stash apply stash@{0}
1

在master分支上修复了bug后,我们要想一想,dev分支是早期从master分支分出来的,所以,这个bug其实在当前dev分支上也存在。

那怎么在dev分支上修复同样的bug?重复操作一次,提交不就行了?(思考:可以在dev上rebase master吗)

有木有更简单的方法?

# 6.2 cherry-pick

有!

同样的bug,要在dev上修复,我们只需要把4c805e2 fix bug 101这个提交所做的修改“复制”到dev分支。注意:我们只想复制4c805e2 fix bug 101这个提交所做的修改,并不是把整个master分支merge过来。

为了方便操作,Git专门提供了一个cherry-pick命令,让我们能复制一个特定的提交到当前分支:

$ git branch
* dev
  master
$ git cherry-pick 4c805e2
[master 1d4b803] fix bug 101
 1 file changed, 1 insertion(+), 1 deletion(-)
1
2
3
4
5
6

Git自动给dev分支做了一次提交,注意这次提交的commit是1d4b803,它并不同于master的4c805e2,因为这两个commit只是改动相同,但确实是两个不同的commit。用git cherry-pick,我们就不需要在dev分支上手动再把修bug的过程重复一遍。

有些聪明的童鞋会想了,既然可以在master分支上修复bug后,在dev分支上可以“重放”这个修复过程,那么直接在dev分支上修复bug,然后在master分支上“重放”行不行?当然可以,不过你仍然需要git stash命令保存现场,才能从dev分支切换到master分支。

修复bug时,我们会通过创建新的bug分支进行修复,然后合并,最后删除;

当手头工作没有完成时,先把工作现场git stash一下,然后去修复bug,修复后,再git stash pop,回到工作现场;

在master分支上修复的bug,想要合并到当前dev分支,可以用git cherry-pick <commit>命令,把bug提交的修改“复制”到当前分支,避免重复劳动。

merge和rebase其实是一个在分支维度上进行的操作,而cherry-pick其实是在 commit节点上维度的进行操作

# cherry-pick 常用命令
git cherry-pick commitId
git cherry-pick commitId1 commitId2 commitId3
git cherry-pick commitId1..commitId3
1
2
3
4

cherry-pick和merge、rebase本质目的都一样,就是要合并代码。所以cherry-pick也会产生冲突,这个时候git会给出以下几种选项供我们选择

解决冲突,之后:git add ,git cherry-pick --continue
回滚:git cherry-pick --abort
中断: git cherry-pick --quit
1
2
3

image-20230203001127670

# 7. feature分支

软件开发中,总有无穷无尽的新的功能要不断添加进来。

添加一个新功能时,你肯定不希望因为一些实验性质的代码,把主分支搞乱了,所以,每添加一个新功能,最好新建一个feature分支,在上面开发,完成后,合并,最后,删除该feature分支。

现在,你终于接到了一个新任务:开发代号为Vulcan的新功能,该功能计划用于下一代星际飞船。

于是准备开发:

$ git switch -c feature-vulcan
Switched to a new branch 'feature-vulcan'
1
2

5分钟后,开发完毕:

$ git add vulcan.py

$ git status
On branch feature-vulcan
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

	new file:   vulcan.py

$ git commit -m "add feature vulcan"
[feature-vulcan 287773e] add feature vulcan
 1 file changed, 2 insertions(+)
 create mode 100644 vulcan.py
1
2
3
4
5
6
7
8
9
10
11
12
13

切回dev,准备合并:

$ git switch dev
1

一切顺利的话,feature分支和bug分支是类似的,合并,然后删除。

但是!

就在此时,接到上级命令,因经费不足,新功能必须取消!

虽然白干了,但是这个包含机密资料的分支还是必须就地销毁:

$ git branch -d feature-vulcan
error: The branch 'feature-vulcan' is not fully merged.
If you are sure you want to delete it, run 'git branch -D feature-vulcan'.
1
2
3

销毁失败。Git友情提醒,feature-vulcan分支还没有被合并,如果删除,将丢失掉修改,如果要强行删除,需要使用大写的-D参数。。

现在我们强行删除:

$ git branch -D feature-vulcan
Deleted branch feature-vulcan (was 287773e).
1
2

终于删除成功!

# 8. 团队协作

当你从远程仓库克隆时,实际上Git自动把本地的master分支和远程的master分支对应起来了,并且,远程仓库的默认名称是origin。

要查看远程库的信息,用git remote:

$ git remote
origin
1
2

或者,用git remote -v显示更详细的信息:

$ git remote -v
origin  git@github.com:michaelliao/learngit.git (fetch)
origin  git@github.com:michaelliao/learngit.git (push)
1
2
3

上面显示了可以抓取和推送的origin的地址。如果没有推送权限,就看不到push的地址。

# 9. 推送分支

推送分支,就是把该分支上的所有本地提交推送到远程库。推送时,要指定本地分支,这样,Git就会把该分支推送到远程库对应的远程分支上:

$ git push origin master
1

如果要推送其他分支,比如dev,就改成:

$ git push origin dev
1

但是,并不是一定要把本地分支往远程推送,那么,哪些分支需要推送,哪些不需要呢?

  • master分支是主分支,因此要时刻与远程同步;
  • dev分支是开发分支,团队所有成员都需要在上面工作,所以也需要与远程同步;
  • bug分支只用于在本地修复bug,就没必要推到远程了,除非老板要看看你每周到底修复了几个bug;
  • feature分支是否推到远程,取决于你是否和你的小伙伴合作在上面开发。

总之,就是在Git中,分支完全可以在本地自己藏着玩,是否推送,视你的心情而定!

# 八.git 底层原理

https://jingsam.github.io/2018/06/03/git-objects.html

# 九.其他特殊操作

# 1. 本地已经提交的commit修改邮箱等信息

因为公司的审核系统,git commit提交的邮箱必须是公司的工作邮箱,不能是自己的邮箱。这就意味着我本地的新提交如果不是公司的邮箱就无法进行提交,该怎么办呢?这个时候就要使用git rebase操作了。

①首先,我们可以通过git log --oneline查出我们需要修改哪些commit的提交信息。选择我们需要提交的信息的上一个commitHash

②使用以下命令进入rebase 的交互页面

git rebase -i commitHash
1

此时你会进入到一个交互界面,这个时候,在对应的commitHash前面讲pick修改为e,然后:wq 退出。

image-20230410210308055

③如果要进行author邮箱等修改操作,使用以下命令更新邮箱

git config --global user.email ”email“

git config --global user.name "name“  
1
2
3

之后可以检测结果

git config user.email
git config user.name
1
2

没有问题后,使用命令

git commit --amend --reset-author
1

④遇到交互界面,什么都不用做,直接退出即可。

之后在通过git log --oneline检查是否有误

问:如果修改的是第一次提交怎么办?

我们使用git rebase -i 第一次hash 是没有办法修改首节点的,这个时候我们可以使用下面的命令修改首commit节点

git rebase -i --root
1
编辑 (opens new window)
上次更新: 2024/02/22, 14:03:19
mac窗口最前置顶
git介绍

← mac窗口最前置顶 git介绍→

最近更新
01
spark基础
02-22
02
mysql读写分离和分库分表
02-22
03
数据库迁移
02-22
更多文章>
Theme by Vdoing | Copyright © 2019-2024 Evan Xu | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式