Git命令教程

你的本地仓库有 Git 维护的三棵“树”组成,这是 Git 的核心框架。这三棵树分别是:工作区域、暂存区域和 Git 仓库

 

 

 

工作区域(Working Directory)就是你平时存放项目代码的地方。

暂存区域(Stage)用于临时存放你的改动,事实上它只是一个文件,保存即将提交的文件列表信息。

Git 仓库(Repository)就是安全存放数据的位置,这里边有你提交的所有版本的数据。其中,HEAD 指向最新放入仓库的版本(这第三棵树,确切的说,应该是 Git 仓库中 HEAD 指向的版本)。

Git 的工作流程一般是:

  1. 在工作目录中添加、修改文件;

  2. 将需要进行版本管理的文件放入暂存区域;

  3. 将暂存区域的文件提交到 Git 仓库。

因此,Git 管理的文件有三种状态:已修改(modified)、已暂存(staged)和已提交(committed),依次对应上边的每一个流程。

一初始化Git

在自己方便的盘中新建一个文件夹,这里以MyProject为例,注意路径中不要含有中文字符。打开cmd命令窗口,操作如下:

C:\Users\lenovo>F:
F:\>
F:\>cd MyProject
F:\MyProject>
#初始化Git项目,成功后创建有一个.git隐藏文件
F:\MyProject>git init
Initialized empty Git repository in F:/MyProject/.git/
#在文件夹MyProject中添加一个文本文件README,md格式指Markdown格式(建议使用Notepad++编辑)
#然后输入以下命令将文件加入暂存区
F:\MyProject>git add README.md
#将文件提交到git仓库(-m表示添加本次提交的说明,强制要求写的)
F:\MyProject>git commit -m "add a readme file"
[master (root-commit) 9e08cf4] add a readme file
 1 file changed, 1 insertion(+)
 create mode 100644 README.md

二.D:\>Clone>git clone 目标  克隆github 上别人的代码

三.使用git status查看当前状态

F:\MyProject>git status
On branch master
nothing to commit, working tree clean //表示没有提交过代码,很干净
F:\MyProject>git status
On branch master
Untracked files:
  (use "git add <file>..." to include in what will be committed)

        LICENSE(红色)

nothing added to commit but untracked files present (use "git add" to track)

Untracked files 说明存在未跟踪的文件(下边红色的那个)

所谓的“未跟踪”文件,是指那些新添加的并且未被加入到暂存区域或提交的文件。它们处于一个逍遥法外的状态,但你一旦将它们加入暂存区域或提交到 Git 仓库,它们就开始受到 Git 的“跟踪”。

这里圆括号中的英文是 git 给我们的建议:使用 git add <file> 命令将待提交的文件添加到暂存区域。

F:\MyProject>git add LICENSE

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

        new file:   LICENSE(绿色)
use "git reset HEAD <file>..." to unstage 的意思是“如果你反悔了,你可以使用 git reset HEAD 命令恢复暂存区域”。如果后面接文件名,表示恢复该文件;如果不接文件名,则表示上一次添加的文件。
F:\MyProject>git reset HEAD

F:\MyProject>git status
On branch master
Untracked files:
  (use "git add <file>..." to include in what will be committed)

        LICENSE(红色)

nothing added to commit but untracked files present (use "git add" to track)

再次添加到暂存区域,然后执行 git commit -m "add a license file" 命令:

F:\MyProject>git add LICENSE

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

        new file:   LICENSE


F:\MyProject>git commit -m "add a license file"
[master 9fdf9f4] add a license file
 1 file changed, 7 insertions(+)
 create mode 100644 LICENSE

F:\MyProject>git status
On branch master
nothing to commit, working tree clean

关于修改

突然发现版权那块忘了写上自己的名字了……
打开 LICENSE 文件,将 Copyright (C) <year> <copyright holders> 改为 Copyright (C) 2016 FishC,保存……

执行 git status 命令:

F:\MyProject>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:   LICENSE(红色)

no changes added to commit (use "git add" and/or "git commit -a")

 

由于你对工作目录的文件进行了修改,导致这个文件和暂存区域的对应文件不匹配了,所以 Git 又给你提出两条建议:

  • 使用 git add 命令将工作目录的新版本覆盖暂存区域的旧版本,然后准备提交
  • 使用 git checkout 命令将暂存区域的旧版本覆盖工作目录的新版本(危险操作:相当于丢弃工作目录的修改)

还有一种情况我们没分析,大家先把新版本的文件覆盖掉暂存区域的旧版本:

F:\MyProject>git add LICENSE

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

        modified:   LICENSE(绿色)

 然后我们打开 LICENSE 文件,将 FishC 改为 FishC.com,保存……

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

        modified:   LICENSE(绿色)

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:   LICENSE(红色)

 这次情况是:被绿的 LICENSE 说明文件存放在暂存区域(待提交),同时红色的 LICENSE 说明文件还在工作目录等待添加到暂存区域。

这种情况你应该意识到这里存在两个不同版本的 LICENSE 文件,这时如果你直接执行 commit 命令,那么提交的是暂存区域的版本(FishC),如果你希望提交工作目录的新版本(FishC.com),那么你需要先执行 add 命令覆盖暂存区域,然后再提交……

一步到位

从工作目录一步添加到仓库:git commit -am “说明”

F:\MyProject>git commit -am "change the license file"

-a的意思是add。

git log 查看历史操作记录

Git使用教程5---回到过去

有关回退的命令有两个:reset 和 checkout

回滚快照

注:快照即提交的版本,每个版本我们称之为一个快照。

现在我们利用 reset 命令回滚快照,并看看 Git 仓库和三棵树分别发生了什么。

执行 git reset HEAD~ 命令:

注:HEAD 表示最新提交的快照,而 HEAD~ 表示 HEAD 的上一个快照,HEAD~~表示上上个快照,如果表示上10个快照,则可以用HEAD ~10

此时我们的快找回滚到了第二棵数(暂存区域)

git reset HEAD~ 命令其实是 git reset --mixed HEAD~ 的缩写, --mixed 选项是默认的。

默认
git reset HEAD~ 命令其实影响了两棵树:首先是移动 HEAD 的指向,将其指向上一个快照(HEAD~);然后再将该位置的快照回滚到暂存区域。
--soft选项
git reset --soft HEAD~ 命令就相当于只移动 HEAD 的指向,但并不会将快照回滚到暂存区域。相当于撤消了上一次的提交(commit)。一不小心提交了,后悔了,那么你就执行 git reset --soft HEAD~ 命令即可(此时执行 git log 命令,也不会再看到已经撤消了的那个提交)。
--hard选项
reset 不仅移动 HEAD 的指向,将快照回滚动到暂存区域,它还将暂存区域的文件还原到工作目录。

 

回滚指定快照
reset 不仅可以回滚指定快照,还可以回滚个别文件。

命令格式为: git reset 快照 文件名/路径

这样,它就会将忽略移动 HEAD 的指向这一步(因为你只是回滚快照的部分内容,并不是整个快照,所以 HEAD 的指向不应该发生改变),直接将指定快照的指定文件回滚到暂存区域。

不仅可以往回滚,还可以往前滚!
这里需要强调的是:reset 不仅是一个“复古”的命令,它不仅可以回到过去,还可以去到“未来”。

唯一的一个前提条件是:你需要知道指定快照的 ID 号。

那如果不小心把命令窗口关了不记得ID号怎么办?
命令:git reflog
Git记录的每一次操作的版本ID号

比较暂存区域与工作目录

直接执行 git diff 命令是比较暂存区域与工作目录的文件内容:

这里可能出现一个问题,直接执行的结果出现中文乱码。在cmd界面的冒号:后面输入q退出,使用Notepad++打开README文件,点击编码→转为UTF-8编码。(旧版本中选择UTF-8(无BOM),新版中的UTF-8默认为无BOM)重新执行git diff发现还是不行!怎么肥四??在本菜查遍各网站论坛之后,终于找到了解决方法
执行以下三条命令(别问我明明是四条为啥说三条...)

git config --global i18n.commitencoding utf-8
git config --global i18n.logoutputencoding utf-8

export LESSCHARSET=utf-8 ## linux bash配置环境变量
set LESSCHARSET=utf-8 #windows配置环境变量

比较两个历史快照

我们执行 git commit -am "添加功能:玩家只有三次机会" 命令,添加并提交工作目录中的所有文件。执行 git log 命令,可以看到现在 Git 仓库中已经有两个快照了:

 

 执行 git diff 6e26975 ed3708c 命令,即可比较 Git 仓库中两个快照的差异:

比较之前版本的快照与当前工作目录内容
输入 git diff ed3708c 命令即可

比较当前版本快照与当前工作目录内容
输入 git diff HEAD 命令即可

Git使用教程7---修改最后一次提交、删除文件和重命名文件

由于使用reset命令过于繁琐,需要提交一个新的版本,这里可以使用带 --amend 选项的 commit 命令,(即git commit --amend)Git 会“更正”最近的一次提交。由于这里没有-m说明,
如果不需要修改,可以连续按下两个大写Z来退出,或者按下(:)再输入q!退出,Git会保留旧的提交说明。如果需要提交说明又不想用这么繁琐的方式,输入git commit --ammend -m “新的提交说明” 即可。

删除文件

问题一:不小心删除文件怎么办?
现在从工作目录中手动删除 README.md 文件,然后执行 git status 命令:

提醒使用 checkout 命令可以将暂存区域的文件恢复到工作目录:

文件就会重新返回。
问题二:那么如何彻底删除一个文件呢?
假如你不小心把小黄图下载到了工作目录,然后又不小心提交到了 Git 仓库:

执行 git rm yellow.jpg 命令:

此时工作目录中的小黄图(yellow.jpg)已经被删除……
但执行 git status 命令,你仍然发现 Git 还不肯松手:

意思是说它在仓库的快照中发现有个叫 yellow 的东西,但似乎在暂存区域和当前目录不见了!

此时可以执行 git reset --soft HEAD~ 命令将快照回滚到上一个位置,然后重新提交,Git 就不会再提小黄图的事儿了:

注意:rm 命令删除的只是工作目录和暂存区域的文件(即取消跟踪,在下次提交时不纳入版本管理)

问题三:我在工作目录中增加一个 test.py 文件,然后执行 git add test.py 命令将其添加到暂存区域,此时我修改 test.py 文件的内容,那么暂存区域和工作目录就是两个不同的 test.py 文件了,此时如果我执行 git rm test.py 命令,Git 会下意识地阻止我,这是怎么办?

因为两个不同内容的同名文件,谁知道你是不是搞清楚了都要删掉?还是提醒一下好,别等一下出错了又要赖机器……
根据提示,执行 git rm -f test.py 命令就可以把两个都删除。

问题四:我只想删除暂存区域的文件,保留工作目录的,应该怎么操作?
执行 git rm --cached 文件名 命令。

重命名文件

直接在工作目录重命名文件,执行git status出现错误:

正确的姿势应该是:

git mv 旧文件名 新文件名

注:Windows 使用 ren 命令修改文件名,Linux 是使用 mv 命令

教程6彩蛋

如何让Git 识别某些格式的文件,然后自主不跟踪它们?
比如工作目录中有三个文件1.temp、2.temp 和 3.temp,我们不希望后缀名为 temp 的文件被追踪,可是每次执行git status都会出现:

解决办法:在工作目录创建一个名为 .gitignore 的文件。

然后你发现 Windows 压根儿不允许你在文件管理器中创建以点(.)开头的文件。windows需要在命令行窗口创建(.)开头的文件。执行 echo *.temp > .gitignore 命令,创建一个 .gitignore 文件,并让 Git 忽略所有 .temp 后缀的文件:

好了,Git 已经忽略了所有的 *.temp 文件(你还可以把 .gitignore 文件也一并忽略)。

Git使用教程7---创建和切换分支

分支是什么?

假设你的大项目已经上线了(有上百万人在使用),过了一段时间你突然觉得应该添加一些新的功能,但是为了保险起见,你肯定不能在当前项目上直接进行开发,这时候你就有创建分支的需要了。

对于其它版本控制系统而言,创建分支常常需要完全创建一个源代码目录的副本,项目越大,耗费的时间就越多;而 Git 由于每一个结点都已经是一个完整的项目,所以只需要创建多一个“指针”(像 master)指向分支开始的位置即可。

创建分支

来到之前创建的项目MyProject2,

目前仓库的状态如下:

执行git status查看状态:

可以看到 README.md 文件被修改并添加到暂存区域(还没有提交),所以当前三棵树应该是这样:

创建分支,使用 git branch 分支名 命令:

没有任何提示说明分支创建成功(一般也不会失败啦,除非创建了同名的分支会提醒你一下),此时可以执行 git log --decorate 命令查看:

如果希望以“精简版”的方式显示,可以加上一个 --oneline 选项(即 git log --decorate --oneline),这样就只用一行来显示一个快照记录。

可以看到最新的快照后边多了一个 (HEAD -> master, feature)

它的意思是:目前有两个分支,一个是主分支(master),一个是刚才我们创建的新分支(feature),然后 HEAD 指针仍然指向默认的 master 分支。

所以目前仓库中的快照应该是这样:


切换分支

现在我们需要将工作环境切换到新创建的分支(feature)上,使用的就是之前我们欲言又止的 checkout 命令。执行 git checkout feature 命令:

这样 HEAD 指针就指向 feature 分支了:

现在我们进行一次提交(暂存区域还有一个更改的文件没有提交呢):

现在仓库中的快照应该是酱紫(提交的快照由当前HEAD指针指向的分支来管理):

然后我们将 HEAD 指针切回 master 分支:

细心的朋友会发现上一次对 README.md 文件的修改已经荡然无存了,这是因为我们的工作目录已经回到 master 分支的状态中:

现在对 README.md 文件进行修改(随便改改),然后执行 git commit -m "再次修改说明文件":

目前仓库中的快照应该变成了酱紫:

执行 git log --oneline --decorate --graph --all 命令:

--graph 选项表示让 Git 绘制分支图,--all 表示显示所有分支

Git使用教程9---合并和删除分支

合并分支

当一个子分支的使命完结之后,它就应该回归到主分支中去。

合并分支我们使用 merge 命令,执行 git merge feature 命令,将 feature 分支合并到 HEAD 所在的分支(master)上:

从 Git 提示的内容来看,我们知道这次的合并并没有成功,Git 说:

合并 README.md 文件的时候出现冲突。

所以自动合并失败;请修改冲突的内容并重新提交快照。

意思是说现在你需要先解决冲突的问题,Git 才能进行合并操作。所谓冲突,无非就是像两个分支中存在同名但内容却不同的文件,Git 不知道你要舍弃哪一个或保留哪一个,所以需要你自己来决定。
此时执行 git status 命令也会显示需要你解决的冲突:

然后 Git 会在有冲突的文件中加入一些标记,不信你打开 README.md 文件看看:

以“=======”为界,上到“<<<<<<< HEAD”的内容表示当前分支,下到“>>>>>>> feature”表示待合并的 feature 分支,之间的内容就是冲突的地方。

现在我们将 README.md 统一修改(去掉 <<<<<<< HEAD 等内容)
保存文件,然后提交快照:

执行 git log --decorate --all --graph --oneline 命令,可以看到此时的分支已经自动合并了:

当然,如果不存在冲突,就不用搞这么多了……举个例子:
执行 git checkout -b feature2 命令(相当于 git branch feature2 和 git checkout feature2 两个命令的合体):

在工作目录随便创建一个文本文件(feature2.txt)并提交快照:

执行 git log --decorate --all --graph --oneline 命令:

可以看到,feature2 分支比 master 分支快了一步。现在我们切换回 master 分支,并将 feature2 分支合并进来:

这次 Git 只显示了 Fast-forward(快进)这词儿,这是因为 feature2 这个分支的父结点是 master 分支,所以 Git 只需要简单移动 master 的指向即可。

执行 git log --decorate --all --graph --oneline 命令:

删除分支

删除分支,使用 git branch -d 分支名 命令:

执行 git log --decorate --all --graph --oneline 命令:

由于 Git 的分支原理实际上只是通过一个指针记载,所以创建和删除分支都几乎是瞬间完成。

注意:如果试图删除未合并的分支,Git 会提示你“该分支未完全合并,如果你确定要删除,请使用 git branch -D 分支名 命令。

彩蛋:Git的两种合并方式 --- Fast-forward 和 Three-way merge

Fast-forward

所谓的 Fast-forward 就是当待合并的分支位于目标分支的直接上游时,Git 只需把目标分支的指针直接移动即可实现合并。

比如下面图片中 master 分支是位于 feature2 分支的直接上游:

将 feature2 分支合并到 master 分支,只需要移动 master 的指针即可:

Three-way merge

如果待合并的两个分支不在同一条线上,那么进行合并就需要解决一个根本的问题 —— 冲突!

为何两个分支在同一条线上就不会冲突呢?

因为 Git 的快照是按时间顺序提交的,所以在同一条线上的两个快照,它们是有先后顺序的,尽管两者可能出现同名文件不同内容,Git 会认为这是“改变”而不是“冲突”。

举个例子:

合并 C3 和 C4 得到 C5,但 C5 应该如何处理“冲突”呢?

SVN 会把问题抛给用户,让用户自行解决;Git 则显得更为高明,它会找到第三个快照,然后综合三者特点自动解决冲突。

那第三个快照应该如何决定呢?

没错,应该找两者的共同“祖先”作为参照物,一比较就知道两个分支都干了些什么。

图片中 C3 和 C4 的共同祖先是 C1,可以看到 C3 和 C4 分别增加了 test2.py 和 test1.py 两个文件。因为对比之后发现三者并没有冲突,所以 C5 应该是三者的合体,即同时拥有 common.py、test1.py 和 test2.py 三个文件。

另外,值得一提的是,Git 这种合并方式也适用于同名文件的不同更改

举个例子:

这里 C3 和 C4 都只有一个文件(test.txt),但是内容却不一样。如果这样合并,你猜 Git 会不会报“冲突”?

答案是不会的!

因为 Git 找到它们的共同祖先 C1,可以看到 C3 和 C4 都是在 C1 的基础上进行添加(C4 在第 2 行添加了“I”,C3 在第 4 行增加了“FishC”,C1 第 3 行的“love”是它们共同拥有的),同时在每一行并没有产生冲突的地方,所以自动合并后的 C5 是这样的:

# test.txt
I
love
FishC

注意:如果 Git 检测到同一行有不同的内容,还是会报冲突并让你自行决定谁去谁留的!

Git使用教程10---匿名分支和checkout命令

匿名分支

创建一个新的文件夹(MyProject3),然后初始化 git。依次创建三个文件并提交(每创建一个文件提交一次):

上一节课我们讲的是使用 branch 命令创建一个分支,然后使用 checkout 命令切换分支。

如果在没创建分支的情况下执行 checkout 命令,会有怎样的事情发生呢?

我们不妨试试看,执行 git checkout HEAD~ 命令:

当前的 HEAD 指针处于分离状态,你可以环顾四周,做一些实验性修改并提交它们,并且你可以在这个状态中丢弃任何你所做的提交,而不影响任何分支,做法是执行 checkout 命令切换回别的分支。

如果你希望创建一个新分支,并保持你所做创建的提交,你可以(现在或稍后)通过使用带有 -b 选项的 checkout 命令实现。例如:

git checkout -b <new-branch-name>

HEAD 指针当前指向 52861cf... 2.txt

你使用了 checkout 命令但没有指定分支名,所以 Git 帮你创建了一个匿名分支,OK,既然是匿名,那么当你切换到别的分支时,这个匿名分支中的所有提交都会被丢弃掉(因为你都没给人家命名,反正以后都找不回了,不丢了干啥?)。因此,你可以利用匿名分支来做做实验什么的,反正不会有负面影响。

来,我们试试,在工作目录中创建一个 4.txt(你会发现 3.txt 不见了,这是因为 checkout 将环境切换到上一次提交了),然后提交

执行 git log --decorate --all --graph --oneline 命令

可以看到有两个分支,但 HEAD 所在的分支并没有名字(匿名分支),那现在我们把 HEAD 切回 master 分支:

警告:你残留一个没有连接任何分支的提交:

178d909 4.txt

如果你想通过创建一个分支来连接它,这将是一个好时机,请执行:

git branch <new-branch-name> 178d909

已经切换到 'master' 分支

现在再来查看提交日志,可以看到匿名分支已经荡然无存:

再论checkout

事实上呢,checkout 命令有两种功能:

  1. 从历史快照(或者暂存区域)中拷贝文件到工作目录
  2. 切换分支

从历史快照(或者暂存区域)中拷贝文件到工作目录

当给定某个文件名时,Git 会从指定的提交中拷贝文件到暂存区域和工作目录。比如执行 git checkout HEAD~ README.md 命令会将上一个快照中的 README.md 文件复制到工作目录和暂存区域中:

如果命令中没有指定具体的快照 ID,则将从暂存区域恢复指定文件到工作目录(git checkout README.md):

有些朋友可能会问:“上次看你在文件名的前边有加两个横杆(--),这次怎么就没有了呢?”

问得好,Git 提醒你写成 git checkout -- README.md 的形式,那是为了预防你恰好有一个分支叫做 README.md,那么它就搞不懂你要恢复文件还是切换分支了,所以约定两个横杆(--)后边跟的是文件名。

反过来说,如果你确保你没有一个叫做 README.md 的分支,你直接写 git checkout README.md 也是妥妥的没问题啦

切换分支
首先我们知道 Git 的分支其实就是添加一个指向快照的指针,其次我们还知道切换分支除了修改 HEAD 指针的指向,还会改变暂存区域和工作目录的内容。

所以执行 git checkout 373c0 命令,Git 主要就是做了下边这两件事(当然事实上 Git 还做了更多):

那回过头来,如果我们只想恢复指定的文件/路径,那么我们只需要指定具体的文件,Git 就会忽略第一步修改 HEAD 指向的操作,这不正跟之前讲 reset 命令的时候一样吗?

checkout 命令和 reset 命令的区别

恢复文件

checkout 命令和 reset 命令都可以用于恢复指定快照的指定文件,并且它们都不会改变 HEAD 指针的指向。

下面开始划重点:

它们的区别是 reset 命令只将指定文件恢复到暂存区域(--mixed),而 checkout 命令是同时覆盖暂存区域和工作目录。

注意:也许你试图使用 git reset --hard HEAD~ README.md 命令让 reset 同时覆盖工作目录,但 Git 会告诉你这是徒劳(此时 reset 不允许使用 --soft 或 --hard 选项)。

这样看来,在恢复文件方面,reset 命令要比 checkout 命令更安全一些。

恢复快照

reset 命令是用来“回到过去”的,根据选项的不同,reset 命令将移动 HEAD 指针(--soft) -> 覆盖暂存区域(--mixed,默认)-> 覆盖工作目录(--hard)。

checkout 命令虽说是用于切换分支,但前面你也看到了,它事实上也是通过移动 HEAD 指针和覆盖暂存区域、工作目录来实现的。

那问题来了:它们有什么区别呢?

下面开始划重点:

第一个区别是,对于 reset --hard 命令来说,checkout 命令更安全。因为 checkout 命令在切换分支前会先检查一下当前的工作状态,如果不是“clean”的话,Git 不会允许你这样做;而 reset --hard 命令则是直接覆盖所有数据。

另一个区别是如何更新 HEAD 指向,reset 命令会移动 HEAD 所在分支的指向,而 checkout 命令只会移动 HEAD 自身来指向另一个分支。

看文字你肯定懵,我们举例说明。

来,大家先把刚才的例子改成下边这样:

执行 git checkout feature 命令:

可以看到只是 HEAD 指针跑到 feature 分支那儿去了。

好,我们执行 git checkout master 命令将其切回。

现在执行 git reset --hard feature 命令:

彩蛋

通常情况下,Git 会尽可能地尝试使用 Fast-forward 方式来合并分支,因为这样效率非常高,只有在万不得已的时候才使用三方合并(Three-way merge)

但是,有时候 Fast-forward 的方式却很容易让我们忽略了分支的存在!

举个例子,比如下面这样:

如果我们把“feature”分支删除,就会直接丢掉分支的信息:

根本就不知道有个分支存在过……

可有时候我们确实希望保留分支的信息,应该怎么办呢?

只需要在 merge 的时候使用 --no-ff 选项即可告诉 Git 不要使用 Fast-forward 方式合并分支。

这样 Git 就会乖乖地使用三方合并(Three-way merge):

OK,这样就算删掉了“feature”分支,我们仍然可以很容易看出有个分支曾经存在过:

 

 

作者:spectre_hola
链接:https://www.jianshu.com/p/e57a4a2cf077
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
 

posted on 2020-07-28 16:46  TheKingJames  阅读(454)  评论(0编辑  收藏  举报