一.什么是Git
在学习工作中,我们经常会遇到改文档的场景。一个文档可能会被我们修改多次,而最终真正使用的可能是最先的几版。而如果我们直接在原文档上修改,就会导致无法找到最先的几次。这也就导致我们要对我们所有的版本进行维护,而Git就是一个版本控制器。
git会为我们创建一个仓库,用来保存、管理、记录我们对各种格式资源的修改。而这个git仓库是要依托于一个目录的。
二.git安装
centos:sudo yum -y install git
ubuntu:sudo apt-get install git -y
安装成功使用:git --version查看git版本
三.初始化本地git仓库
1.创建本地仓库
要想建立一个本地的git仓库,我们首先得有一个目录,在该目录内创建git仓库。
git init
创建成功后,会在当前目录下创建一个隐藏目录
xsc@xsc-VMware-Virtual-Platform:~/code/git$ ll
总计 12
drwxrwxr-x 3 xsc xsc 4096 7月 31 14:56 ./
drwxrwxr-x 5 xsc xsc 4096 7月 31 14:56 ../
drwxrwxr-x 7 xsc xsc 4096 7月 31 14:56 .git/
这个隐藏目录,才是真正的git仓库。不要手动对该隐藏目录做任何修改。
xsc@xsc-VMware-Virtual-Platform:~/code/git$ tree .git
.git
├── branches
├── config
├── description
├── HEAD
├── hooks
│ ├── applypatch-msg.sample
│ ├── commit-msg.sample
│ ├── fsmonitor-watchman.sample
│ ├── post-update.sample
│ ├── pre-applypatch.sample
│ ├── pre-commit.sample
│ ├── pre-merge-commit.sample
│ ├── prepare-commit-msg.sample
│ ├── pre-push.sample
│ ├── pre-rebase.sample
│ ├── pre-receive.sample
│ ├── push-to-checkout.sample
│ ├── sendemail-validate.sample
│ └── update.sample
├── info
│ └── exclude
├── objects
│ ├── info
│ └── pack
└── refs
├── heads
└── tags
10 directories, 18 files
2.配置本地仓库
git config [--global] user.name "your name"
git config [--global] user.email "your email"
--global:表示该配置在该机器上的所有仓库有效
不带则只在当前仓库有效
使用git config -l查看当前git配置
sc@xsc-VMware-Virtual-Platform:~/code/git$ git config -l
user.name=夏思成
user.email=3330826680@qq.com
core.repositoryformatversion=0
core.filemode=true
core.bare=false
core.logallrefupdates=true
取消某个配置,如果但是以global配置的,则取消配置也要带上global
git config --unset user.name/user.email
四.工作区、暂存区、版本库
git仓库是要依托于目录的。
- 工作区:git仓库所属的目录,git仓库不会主动追踪工作区中的修改
- 暂存区:版本库中的一段临时空间,可以理解为待提交的修改清单
- 版本库:Git 用来存储所有版本历史记录的地方,是 Git 的核心。本地版本库位于工作区目录下的
.git
隐藏文件夹中(不要手动修改里面的内容)
当我们创建一个本地仓库,git会为我们创建一个唯一的master分支,head指针指向master分支。
我们想要让git帮我们管理文件,不是说放在工作区,git就帮我们管理了,我们需要通过git add将需要追踪的文件添加到暂存区,然后通过git commit将暂存区的内容进行提交,此时git就能帮我们追踪这些文件了。
而被追踪的文件其实是被保存到了objects分区,也是.git隐藏目录下一个目录中。暂存区和master分支存储的其实都是索引,真正的内容存放在objects中。
五.git基本操作
我们这里新建一个readme文件,并初始化为hello git
xsc@xsc-VMware-Virtual-Platform:~/code/git$ cat readme
hello git
1.git status
查看仓库状态
- 红色文件:在工作区,未添加到暂存区;
- 绿色文件:在暂存区,未提交到版本库;
- 无特殊标记:已提交到版本库(工作区与版本库一致)。
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git status
位于分支 master
尚无提交
未跟踪的文件:
(使用 "git add <文件>..." 以包含要提交的内容)
readme
提交为空,但是存在尚未跟踪的文件(使用 "git add" 建立跟踪)
2.git add
将文件添加到暂存区中,该文件必须是被修改的(新增,删除,修改)。add之后,会在objects中新增一个git对象,该对象描述的就是本次的修改。
git add [file1] [file2]... // 将一个/多个文件同时添加到暂存区
git add . // 将当前目录下所有修改的文件添加到暂存区
xsc@xsc-VMware-Virtual-Platform:~/code/git$ tree .git/
.git/
├── branches
├── config
├── description
├── HEAD
├── hooks
│ ├── applypatch-msg.sample
│ ├── commit-msg.sample
│ ├── fsmonitor-watchman.sample
│ ├── post-update.sample
│ ├── pre-applypatch.sample
│ ├── pre-commit.sample
│ ├── pre-merge-commit.sample
│ ├── prepare-commit-msg.sample
│ ├── pre-push.sample
│ ├── pre-rebase.sample
│ ├── pre-receive.sample
│ ├── push-to-checkout.sample
│ ├── sendemail-validate.sample
│ └── update.sample
├── index
├── info
│ └── exclude
├── objects
│ ├── 8d
│ │ └── 0e41234f24b6da002d962a26c2495ea16a425f
│ ├── info
│ └── pack
└── refs
├── heads
└── tags
11 directories, 20 files
当我们提交之后,在查看仓库状态,此时就没有未跟踪的文件,而是没有提交的变更。
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git add readme
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git status
位于分支 master
尚无提交
要提交的变更:
(使用 "git rm --cached <文件>..." 以取消暂存)
新文件: readme
使用git reset filename 可以将暂存区中的文件删除,退回到工作区
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git reset readme
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git status
位于分支 master
尚无提交
未跟踪的文件:
(使用 "git add <文件>..." 以包含要提交的内容)
readme
提交为空,但是存在尚未跟踪的文件(使用 "git add" 建立跟踪)
3.git commit
将暂存区的内容提交到本地仓库
git commit -m "提交描述"
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git commit -m "add readme"
[master (根提交) 5b1b851] add readme
1 file changed, 1 insertion(+)
create mode 100644 readme
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git status
位于分支 master
无文件要提交,干净的工作区
4.git log
查看该仓库的历史提交记录
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git log
commit 5b1b8515d2f8355d8f7cfa59e07ffdb1c34b0819 (HEAD -> master)
Author: 夏思成 <3330826680@qq.com>
Date: Thu Jul 31 15:32:02 2025 +0800
add readme
5..git目录中的HEAD指针
当我们完成一次提交之后再来查看git仓库
xsc@xsc-VMware-Virtual-Platform:~/code/git$ tree .git/
.git/
├── branches
├── COMMIT_EDITMSG
├── config
├── description
├── HEAD
├── hooks
│ ├── applypatch-msg.sample
│ ├── commit-msg.sample
│ ├── fsmonitor-watchman.sample
│ ├── post-update.sample
│ ├── pre-applypatch.sample
│ ├── pre-commit.sample
│ ├── pre-merge-commit.sample
│ ├── prepare-commit-msg.sample
│ ├── pre-push.sample
│ ├── pre-rebase.sample
│ ├── pre-receive.sample
│ ├── push-to-checkout.sample
│ ├── sendemail-validate.sample
│ └── update.sample
├── index
├── info
│ └── exclude
├── logs
│ ├── HEAD
│ └── refs
│ └── heads
│ └── master
├── objects
│ ├── 4b
│ │ └── 825dc642cb6eb9a060e54bf8d69288fbee4904
│ ├── 5b
│ │ └── 1b8515d2f8355d8f7cfa59e07ffdb1c34b0819
│ ├── 6e
│ │ └── 84d6a5ed71a327ba3376cac9801558d9ea2e80
│ ├── 8d
│ │ └── 0e41234f24b6da002d962a26c2495ea16a425f
│ ├── info
│ └── pack
└── refs
├── heads
│ └── master
└── tags
17 directories, 27 files
HEAD指针指向的其实是master分支,而master分支其实保存的是最近一次的commit id。该id是通过哈希算法计算而来的。
xsc@xsc-VMware-Virtual-Platform:~/code/git$ cat .git/HEAD
ref: refs/heads/master
xsc@xsc-VMware-Virtual-Platform:~/code/git$ cat .git/refs/heads/master
5b1b8515d2f8355d8f7cfa59e07ffdb1c34b0819
而我们使用git cat-file -p来查看这个commit id的内容,其实就是我们的最新一次提交
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git cat-file -p 5b1b8515d2f8355d8f7cfa59e07ffdb1c34b0819
tree 6e84d6a5ed71a327ba3376cac9801558d9ea2e80
author 夏思成 <3330826680@qq.com> 1753947122 +0800
committer 夏思成 <3330826680@qq.com> 1753947122 +0800
add readme
git仓库追踪的并不是一个文件,而是该文件的修改,而文件的修改包括,新增/删除/修改。当一个文件被修改时,我们可以使用git diff file 来查看工作区与版本库之间的差异:
xsc@xsc-VMware-Virtual-Platform:~/code/git$ cat readme hello git hello world xsc@xsc-VMware-Virtual-Platform:~/code/git$ git diff readme diff --git a/readme b/readme index 8d0e412..05fe86c 100644 --- a/readme +++ b/readme @@ -1 +1,2 @@ hello git +hello world
此时我们将本地修改,添加到暂存区,再进行提交
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git status 位于分支 master 尚未暂存以备提交的变更: (使用 "git add <文件>..." 更新要提交的内容) (使用 "git restore <文件>..." 丢弃工作区的改动) 修改: readme 修改尚未加入提交(使用 "git add" 和/或 "git commit -a") xsc@xsc-VMware-Virtual-Platform:~/code/git$ git add readme xsc@xsc-VMware-Virtual-Platform:~/code/git$ git commit -m "modify readme" [master fbffb1c] modify readme 1 file changed, 1 insertion(+)
6.版本回退
git reset [--soft | --mixed | --hard] cimmit id
- soft:只将版本库中的内容回退
- mixed:只回退版本库和暂存区 (默认行为)
- hard:全部回退,慎用
git reset HEAD/*表示当前版本,即最新;带^表示上一个版本*/ [filename]
当前我们对readme文件进行了两次修改,版本1只有hello git,版本2还新增了hello world。
当我们使用soft,此时提示我们一个为提交的修改,因为此时我们只回退了版本库,暂存区与工作区一致。
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git reset --soft 5b1b8515d2f8355d8f7cfa59e07ffdb1c34b0819 xsc@xsc-VMware-Virtual-Platform:~/code/git$ git status 位于分支 master 要提交的变更: (使用 "git restore --staged <文件>..." 以取消暂存) 修改: readme xsc@xsc-VMware-Virtual-Platform:~/code/git$ cat readme hello git hello world
如果我们回退错了,想回到没有回退之前,只要我们知道之前的commit id就可以回到回退之前。但是当我们回退之后,其实git log就会丢弃最新的几次日志。没有commid id就无法撤销回退。但其实git还有一个git reflog,可以查看历史上git命令的commit id。
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git reflog
5b1b851 (HEAD -> master) HEAD@{0}: reset: moving to HEAD
5b1b851 (HEAD -> master) HEAD@{1}: reset: moving to 5b1b8515d2f8355d8f7cfa59e07ffdb1c34b0819
fbffb1c HEAD@{2}: commit: modify readme
5b1b851 (HEAD -> master) HEAD@{3}: commit (initial): add readme
我们通过这些短的commit id依旧可以撤销回退。
值得说的是,Git版本回退速度非常快,因为git在内部维护了一个指向当前分支的head指针,refs/heads/master分支存储的就是最新一次的commit id。当我们进行版本回退的时候,可以简单的理解为,只是将master分支指向了之前的commit id而已。
7.撤销修改
当我们完成一个功能后,提交了修改之后。产品经理又提了新要求,此时我们就需要在对代码进行修改,但是我们越写越乱,最后导致之前的逻辑都出了问题。所以,我们就打算从上一次的提交版本开始重新写。
如果我们直接手动删的话,代码量一多,就有可能误删。我们可以使用git来帮助我们来撤销这一次的修改。
如果本次修改还未add:git checkout -- filename
xsc@xsc-VMware-Virtual-Platform:~/code/git$ cat readme hello git hello world xsc@xsc-VMware-Virtual-Platform:~/code/git$ vim readme xsc@xsc-VMware-Virtual-Platform:~/code/git$ cat readme hello git hello world aaaa xsc@xsc-VMware-Virtual-Platform:~/code/git$ git checkout -- readme xsc@xsc-VMware-Virtual-Platform:~/code/git$ cat readme hello git hello world
如果已经add,还没commit:git reset 使用默认选项即可
git reset HEAD readme // 回退到当前版本,即最新的一次,然后我们看到暂存区为空,即回到了上一种情况,我们在使用git checkout -- readme即可
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git reset HEAD readme 重置后取消暂存的变更: M readme xsc@xsc-VMware-Virtual-Platform:~/code/git$ git status 位于分支 master 尚未暂存以备提交的变更: (使用 "git add <文件>..." 更新要提交的内容) (使用 "git restore <文件>..." 丢弃工作区的改动) 修改: readme 修改尚未加入提交(使用 "git add" 和/或 "git commit -a")
已经add,并且commit:前提条件是没有被push到远程仓库
我们可以直接使用 git reset --hard HEAD readme,将工作区,暂存区,版本库,都回退到最新版本
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git status 位于分支 master 无文件要提交,干净的工作区 xsc@xsc-VMware-Virtual-Platform:~/code/git$ git reset --hard HEAD^ HEAD 现在位于 d8afe07 md readme xsc@xsc-VMware-Virtual-Platform:~/code/git$ cat readme hello git hello world
8.删除文件
在git中,删除文件也是修改的一种,删除文件有两种原因:不小心删除了;确实不想管理该文件了。
对于不小心删除了,我们直接使用git checkout -- filename,即可将本次删除修改,撤销
xsc@xsc-VMware-Virtual-Platform:~/code/git$ ll
总计 16
drwxrwxr-x 3 xsc xsc 4096 7月 31 16:19 ./
drwxrwxr-x 5 xsc xsc 4096 7月 31 14:56 ../
drwxrwxr-x 8 xsc xsc 4096 7月 31 16:19 .git/
-rw-rw-r-- 1 xsc xsc 22 7月 31 16:19 readme
xsc@xsc-VMware-Virtual-Platform:~/code/git$ rm readme
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git status
位于分支 master
尚未暂存以备提交的变更:
(使用 "git add/rm <文件>..." 更新要提交的内容)
(使用 "git restore <文件>..." 丢弃工作区的改动)
删除: readme
修改尚未加入提交(使用 "git add" 和/或 "git commit -a")
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git checkout -- readme
xsc@xsc-VMware-Virtual-Platform:~/code/git$ ll
总计 16
drwxrwxr-x 3 xsc xsc 4096 7月 31 16:22 ./
drwxrwxr-x 5 xsc xsc 4096 7月 31 14:56 ../
drwxrwxr-x 8 xsc xsc 4096 7月 31 16:22 .git/
-rw-rw-r-- 1 xsc xsc 22 7月 31 16:22 readme
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git status
位于分支 master
无文件要提交,干净的工作区
xsc@xsc-VMware-Virtual-Platform:~/code/git$
如果我们是真的想要删除该文件,则我们还要提交删除修改。
xsc@xsc-VMware-Virtual-Platform:~/code/git$ rm readme
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git status
位于分支 master
尚未暂存以备提交的变更:
(使用 "git add/rm <文件>..." 更新要提交的内容)
(使用 "git restore <文件>..." 丢弃工作区的改动)
删除: readme
修改尚未加入提交(使用 "git add" 和/或 "git commit -a")
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git add .
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git commit -m "delete readme"
[master c9237b9] delete readme
1 file changed, 2 deletions(-)
delete mode 100644 readme
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git status
位于分支 master
无文件要提交,干净的工作区
如果直接使用git rm file则不需要add,只用commit即可。
六.分支管理
1.理解分支
你出生在斗宗村,这个村子里面的人都会分身。而在你的世界中,每个人从10岁开始就修行功法,并且只能修炼一门。而村子里的人8岁就可以分身了,你在10岁的时候,一边学习焚决,一边又让你的分身学习炼药术,然后修行完毕后,你有进行了合体。这样,你就有了两种功法,天下无敌了。
而对于我们直接所有的提交来说,都只有一个master主分支,而head直线master主分支,master指向最新的一次提交。
所以,我们要理解haed和master的区别。head指向当前正在使用的分支,而master指向自己最新的一次提交。
所以,我们也可以在master主分支上创建分支,在该分支上进行提交。但是需要注意的是,在该分支上提交的东西,并不会影响主分支,主分支看不到新分支上的修改。除非主分支主动merge新分支。
2.创建分支
使用git branch 可以查看当前仓库的分支,*表示当前处于哪个分支上,即head指向那个分支
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git branch
* master
创建分支:git branch 分支名
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git branch dev
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git branch
dev
* master
创建分支后,.git/refs/heads/就会多一个dev分支
└── refs
├── heads
│ ├── dev
│ └── master
└── tags
新建的分支可以看到master分支之前所有的提交,且是最新的。
3.切换分支
git checkout dev
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git checkout dev
切换到分支 'dev'
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git branch
* dev
master
我们在dev分支上,新建一个readme文件,添加hello git并提交。
xsc@xsc-VMware-Virtual-Platform:~/code/git$ echo hello git > readme
xsc@xsc-VMware-Virtual-Platform:~/code/git$ ls
readme
xsc@xsc-VMware-Virtual-Platform:~/code/git$ cat readme
hello git
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git add .
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git commit -m "touch readme"
[dev d0cad69] touch readme
1 file changed, 1 insertion(+)
create mode 100644 readme
我们赶紧切换为master分支,查看当前目录下,却没有readme这个文件,这是为什么?文件怎么丢了?
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git checkout master
切换到分支 'master'
xsc@xsc-VMware-Virtual-Platform:~/code/git$ ll
总计 12
drwxrwxr-x 3 xsc xsc 4096 7月 31 16:50 ./
drwxrwxr-x 5 xsc xsc 4096 7月 31 14:56 ../
drwxrwxr-x 8 xsc xsc 4096 7月 31 16:50 .git/
这是为什么呢?dev上面能看见,master分支上却看不见。
这是因为我们进行一次提交之后,dev分支的时间线已经变了,而master的时间线还是原来的,这就导致master看不到最新的变化。
4.合并分支
为了让master分支可以看到dev分支做出的提交,这就需要将dev分支合并到master分支上。想让master合并dev,需要先切换到master分支上,然后使用git merge dev进行合并。
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git branch
dev
* master
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git merge dev
更新 c9237b9..d0cad69
Fast-forward
readme | 1 +
1 file changed, 1 insertion(+)
create mode 100644 readme
xsc@xsc-VMware-Virtual-Platform:~/code/git$ ll
总计 16
drwxrwxr-x 3 xsc xsc 4096 7月 31 16:54 ./
drwxrwxr-x 5 xsc xsc 4096 7月 31 14:56 ../
drwxrwxr-x 8 xsc xsc 4096 7月 31 16:54 .git/
-rw-rw-r-- 1 xsc xsc 10 7月 31 16:54 readme
xsc@xsc-VMware-Virtual-Platform:~/code/git$ cat readme
hello git
我们可以看到合并的时候出现了一个Fast-forward,这是本次合并所使用的模式——快进模式,该模式只是将master指向dev的当前提交,所以合并速度非常快。
5.删除分支
合并完分支后,dev分支对我们来说就没有用了,此时直接使用git branch -d dev删除掉该分支。删除分支时,不能处于要删除的分支上。
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git branch
dev
* master
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git branch -d dev
已删除分支 dev(曾为 d0cad69)。
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git branch
* master
因为创建、合并和删除分⽀⾮常快,所以Git⿎励你使⽤分⽀完成某个任务,合并后再删掉分⽀,这和 直接在master分⽀上⼯作效果是⼀样的,但过程更安全
6.合并冲突
当我们首次创建分支时,此时master分支和dev分支都指向最新的提交。但如果此时dev分支和master分支同时对某个文件进行修改时,在合并时就会发送冲突。
创建dev分支,并修改readme,我们可以使用git checkout -b dev 来创建并切换到一个新分支上
xsc@xsc-VMware-Virtual-Platform:~/code/git$ cat readme
hello git
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git checkout -b dev
切换到一个新分支 'dev'
xsc@xsc-VMware-Virtual-Platform:~/code/git$ vim readme
xsc@xsc-VMware-Virtual-Platform:~/code/git$ cat readme
hello git
dev modify readme
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git add .
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git commit -m "dev md readme"
[dev 70ef405] dev md readme
1 file changed, 1 insertion(+)
切换到master分支,看到的是旧版本,复合预期,然后对readme文件继续修改
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git checkout master
切换到分支 'master'
xsc@xsc-VMware-Virtual-Platform:~/code/git$ cat readme
hello git
xsc@xsc-VMware-Virtual-Platform:~/code/git$ vim readme
xsc@xsc-VMware-Virtual-Platform:~/code/git$ cat readme
hello git
master modify readme
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git add .
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git commit -m "master md readme"
[master 84a1ed8] master md readme
1 file changed, 1 insertion(+)
此时,我们提交之后,master和head就处于这种状态:
此时,我们直接合并,就会合并失败,提醒我们手动处理冲突:
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git merge dev
自动合并 readme
冲突(内容):合并冲突于 readme
自动合并失败,修正冲突然后提交修正的结果。
我们打开readme文件,就会出现以下格式:<~=表示当前分支内容,=~>表示合并分支内容,我们需要手动选择保留那些内容,删除那些内容。我们这里选择保留两者
hello git
<<<<<<< HEAD
master modify readme
=======
dev modify readme
>>>>>>> dev
hello git
dev modify readme
master modify readme
解决完冲突后,需要我们重新add,commit
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git add .
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git commit -m "merge readme"
[master 130148d] merge readme
我们可以使用git log的参数,来打印同样的合并图
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git log --graph --pretty=oneline --abbrev-commit
* 130148d (HEAD -> master) merge readme
|\
| * 70ef405 (dev) dev md readme
* | 84a1ed8 master md readme
|/
* d0cad69 touch readme
* c9237b9 delete readme
* d8afe07 md readme
* 7ef8d0f add
* 5b1b851 add readme
重新提交之后,master分支指向最新的提交,dev分支仍指向自己刚才的提交
此时如何想要和dev同步,则切换到dev分支,重新进行merge
最后不要忘记,删除dev分支。
7.合并策略
当我们新创建的分支dev是master分支的直接后继,即master分支没有提交新内容,dev有新内容,此时直接合并就会默认使用Fast-forward模式,直接将master指针指向dev最新提交,最终合并之后还是一个线性结构。
但是使用Fast-forward模式,当我们删除了分支之后,我们无法知道最新的提交是正常提交的,还是合并进来的。
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git checkout -b dev
切换到一个新分支 'dev'
xsc@xsc-VMware-Virtual-Platform:~/code/git$ vim readme
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git add .
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git commit -m "aaaaaaaaaaaaaa"
[dev 40faff8] aaaaaaaaaaaaaa
1 file changed, 1 insertion(+)
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git checkout master
切换到分支 'master'
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git merge dev
更新 130148d..40faff8
Fast-forward
readme | 1 +
1 file changed, 1 insertion(+)
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git branch -d dev
已删除分支 dev(曾为 40faff8)。
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git log --graph --pretty=oneline --abbrev-commit
* 40faff8 (HEAD -> master) aaaaaaaaaaaaaa
* 130148d merge readme
|\
| * 70ef405 dev md readme
* | 84a1ed8 master md readme
|/
* d0cad69 touch readme
* c9237b9 delete readme
* d8afe07 md readme
* 7ef8d0f add
* 5b1b851 add readme
而在我们产生冲突的时候,此时合并时,会要求我们重新进行一次提交,我们很明显可以知道时合并进来的。
为了可以更好的追溯提交记录和保存分支结构,我们可以在合并的时候,指定--no-ff合并,这样会要求我们在合并之后进行提交。
新建dev并提交:
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git branch
* dev
master
xsc@xsc-VMware-Virtual-Platform:~/code/git$ cat readme
hello git
dev modify readme
master modify readme
aaaaaaaaaaaaaaaaaaaaaa
xsc@xsc-VMware-Virtual-Platform:~/code/git$ vim readme
xsc@xsc-VMware-Virtual-Platform:~/code/git$ cat readme
hello git
dev modify readme
master modify readme
aaaaaaaaaaaaaaaaaaaaaa
bbbbbbbbbbbbbbbbbbbb
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git add .
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git commit -m "bbbb"
[dev a8dd2d2] bbbb
1 file changed, 1 insertion(+)
切换master,进行--no-ff,进行合并 并 提交:
我们可以看到,即使我们删除了dev分支,并且没有发生合并冲突,使用-no-ff合并时,在打印日志时,我们可以看出这是一个合并提交
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git branch
* dev
master
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git checkout master
切换到分支 'master'
xsc@xsc-VMware-Virtual-Platform:~/code/git$ cat readme
hello git
dev modify readme
master modify readme
aaaaaaaaaaaaaaaaaaaaaa
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git merge --no-ff dev -m "merge no-ff"
Merge made by the 'ort' strategy.
readme | 1 +
1 file changed, 1 insertion(+)
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git branch -d dev
已删除分支 dev(曾为 a8dd2d2)。
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git log --graph --pretty=oneline --abbrev-commit
* ae48c12 (HEAD -> master) merge no-ff
|\
| * a8dd2d2 bbbb
|/
* 40faff8 aaaaaaaaaaaaaa
* 130148d merge readme
|\
| * 70ef405 dev md readme
* | 84a1ed8 master md readme
|/
* d0cad69 touch readme
* c9237b9 delete readme
* d8afe07 md readme
* 7ef8d0f add
* 5b1b851 add readme
8.分支策略
在生产过程中,master分支是最稳定的,它是真正用来发行的版本。所以,我们在日常开发过程中,应该避免直接对master主分支进行修改,而是创建其他分支,在其他分支上进行开发,等到开发的这部分测试通过了,我们再将其合并到master主分支上。
9.bug分支
当我们正在dev分支开发新功能时,master分支出现了bug,但我们此时 dev分支上的代码还没有写完,此时我们先修复bug,再继续开发。我们解决bug也和开发一样,要重新新建分支,用来修复bug,当测试该bug解决后,然后合并回去。
0x1.dev下开发代码
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git checkout -b dev
切换到一个新分支 'dev'
xsc@xsc-VMware-Virtual-Platform:~/code/git$ cat readme
hello git
hello world
xsc@xsc-VMware-Virtual-Platform:~/code/git$ vim readme
xsc@xsc-VMware-Virtual-Platform:~/code/git$ cat readme
hello git
hello world
i am coding TODO
0x2.出现bug,将dev下还未写完的代码利用git stash命令将dev下工作区的修改临时存储起来,此时git status查出来工作区就是干净的,然后切回master分支,创建新分支,修改bug
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git stash
保存工作目录和索引状态 WIP on dev: b7845cf history
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git status
位于分支 dev
无文件要提交,干净的工作区
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git checkout master
切换到分支 'master'
xsc@xsc-VMware-Virtual-Platform:~/code/git$ cat readme
hello git
hello world
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git checkout -b fix/bug
切换到一个新分支 'fix/bug'
xsc@xsc-VMware-Virtual-Platform:~/code/git$ vim readme
xsc@xsc-VMware-Virtual-Platform:~/code/git$ cat readme
hello git
hello world
fix bug!!!!
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git add .
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git commit -m "fix bug"
[fix/bug 7fc1656] fix bug
1 file changed, 1 insertion(+)
0x3.bug修复后,将fix/bug分支与master分支进行合并。但为了避免合并冲突,我们可以先让fix/bug合并master,然后再让master合并fix/bug。
我们在合并的时候,发现已经是最新的了,所以就可以放心让master合并fix/bug了。
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git merge master
已经是最新的。
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git checkout master
切换到分支 'master'
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git merge fix/bug
更新 b7845cf..7fc1656
Fast-forward
readme | 1 +
1 file changed, 1 insertion(+)
xsc@xsc-VMware-Virtual-Platform:~/code/git$ cat readme
hello git
hello world
fix bug!!!!
0x4.修复完bug后,删除fix/bug分支
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git branch -d fix/bug
已删除分支 fix/bug(曾为 7fc1656)。
0x5.继续开发dev,发现开发区是干净的,我们使用git stash list查看临时区列表,发现有东西,我们使用git stash pop取出临时区的内容,并删除临时区
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git checkout dev
切换到分支 'dev'
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git status
位于分支 dev
无文件要提交,干净的工作区
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git stash list
stash@{0}: WIP on dev: b7845cf history
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git stash pop
位于分支 dev
尚未暂存以备提交的变更:
(使用 "git add <文件>..." 更新要提交的内容)
(使用 "git restore <文件>..." 丢弃工作区的改动)
修改: readme
修改尚未加入提交(使用 "git add" 和/或 "git commit -a")
丢弃了 refs/stash@{0}(8f49e00fb32b95e957f5a775d360af9f305f8168)
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git stash list
xsc@xsc-VMware-Virtual-Platform:~/code/git$
0x6.继续开发,开发完毕进行提交
xsc@xsc-VMware-Virtual-Platform:~/code/git$ cat readme
hello git
hello world
i am coding TODO
xsc@xsc-VMware-Virtual-Platform:~/code/git$ vim readme
xsc@xsc-VMware-Virtual-Platform:~/code/git$ cat readme
hello git
hello world
i am coding TODO
Done
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git add .
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git commit -m "develop over"
[dev fca3cba] develop over
1 file changed, 2 insertions(+)
0x7.合并时与合并bug时一致,避免冲突,先让dev合并master,然后master合并dev
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git merge master
自动合并 readme
冲突(内容):合并冲突于 readme
自动合并失败,修正冲突然后提交修正的结果。
hello git
hello world
<<<<<<< HEAD
i am coding TODO
Done
=======
fix bug!!!!
>>>>>>> master
xsc@xsc-VMware-Virtual-Platform:~/code/git$ vim readme
xsc@xsc-VMware-Virtual-Platform:~/code/git$ cat readme
hello git
hello world
fix bug!!!!
i am coding TODO
Done
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git add .
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git commit -m "merge over"
[dev bc3f194] merge over
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git checkout master
切换到分支 'master'
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git merge --no-ff dev
Merge made by the 'ort' strategy.
readme | 2 ++
1 file changed, 2 insertions(+)
xsc@xsc-VMware-Virtual-Platform:~/code/git$ cat readme
hello git
hello world
fix bug!!!!
i am coding TODO
Done
master合并dev时,会出现下面的界面,这样表示合并成功,直接ctrl+x返回
0x8.删除dev分支
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git branch -d dev
已删除分支 dev(曾为 bc3f194)。
10.删除临时分支
当我们在开发过程中,有了一个新需求,我们并不直接在master分支上修改,而是创建一个新分支feature,在该分支上进行开发。但是开发了一半,经理说不需要该功能了,此时我们就需要将这个分支给删除掉。
但是因为这个分支上有了修改,并且我们没有merge,此时直接git branch -d 删除不掉
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git checkout -b feature/1
切换到一个新分支 'feature/1'
xsc@xsc-VMware-Virtual-Platform:~/code/git$ vim readme
xsc@xsc-VMware-Virtual-Platform:~/code/git$ cat readme
hello git
hello world
fix bug!!!!
i am coding TODO
Done
new feature11111
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git add .
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git commit -m "new feature"
[feature/1 06ff531] new feature
1 file changed, 2 insertions(+)
突然叫停,不需要该功能了
删除该分支
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git checkout master
切换到分支 'master'
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git branch -d feature/1
error: the branch 'feature/1' is not fully merged.
If you are sure you want to delete it, run 'git branch -D feature/1'
我们使用git branch -D 来删除该分支
xsc@xsc-VMware-Virtual-Platform:~/code/git$ git branch -D feature/1
已删除分支 feature/1(曾为 06ff531)。
七.小结
分⽀在实际中有什么⽤呢?假设你准备开发⼀个新功能,但是需要两周才能完成,第⼀周你写了50% 的代码,如果⽴刻提交,由于代码还没写完,不完整的代码库会导致别⼈不能⼲活了。如果等代码全部写完再⼀次提交,⼜存在丢失每天进度的巨⼤⻛险。 现在有了分⽀,就不⽤怕了。你创建了⼀个属于你⾃⼰的分⽀,别⼈看不到,还继续在原来的分⽀上 正常⼯作,⽽你在⾃⼰的分⽀上⼲活,想提交就提交,直到开发完毕后,再⼀次性合并到原来的分⽀ 上,这样,既安全,⼜不影响别⼈⼯作。 并且Git⽆论创建、切换和删除分⽀,Git在1秒钟之内就能完成!⽆论你的版本库是1个⽂件还是1万个 ⽂件。