前言
本文为Git的安装,理论基础与基本使用相关知识,下边将对Git的安装与环境配置
,Git相关理论基础
(包含:Git 是什么
,Git的三种状态
,Git保证完整性
),以及Git的相关操作
(包括:初始化Git
、基础命令
、时光回退
、版本对比法
、删除文件
、重命名文件
、忽略文件
、创建和切换分支
、合并分支
、删除分支
、变基
)等进行详尽介绍~
📌博主主页:小新要变强 的主页
👉Java全栈学习路线可参考:【Java全栈学习路线】最全的Java学习路线及知识清单,Java自学方向指引,内含最全Java全栈学习技术清单~
👉算法刷题路线可参考:算法刷题路线总结与相关资料分享,内含最详尽的算法刷题路线指南及相关资料分享~
👉Java微服务开源项目可参考:企业级Java微服务开源项目(开源框架,用于学习、毕设、公司项目、私活等,减少开发工作,让您只关注业务!)
目录
文章标题
- 前言
- 目录
- 一、Git的安装与环境配置
- 1️⃣安装
- 2️⃣环境配置
- 二、Git相关理论基础
- 1️⃣Git 是什么
- 2️⃣Git的三种状态
- 3️⃣Git保证完整性
- 三、Git的相关操作
- 1️⃣初始化Git
- 2️⃣基础命令
- 3️⃣时光回退
- 4️⃣版本对比
- 5️⃣删除文件
- 6️⃣重命名文件
- 7️⃣忽略文件
- 8️⃣创建和切换分支
- 9️⃣合并分支
- 🔟删除分支
- 1️⃣1️⃣变基
- 后记
一、Git的安装与环境配置
1️⃣安装
🍀(1)进入网站https://git-scm.com/下载安装,选择相应版本(本机windows版本)
🍀(2)双击安装程序进行安装,
🍀(3)安装好后在桌面界面点击鼠标右键,会出现如下界面
🍀(4)检查git是否安装成功
打开命令行,输入git,回车;如果弹出下图所示界面就说明安装成功:
然后在cmd命令行配置
git config --global user.name “itnanls”
git config --global user.email “itnanls@163.com”
#检查信息是否写入成功
git config --list
2️⃣环境配置
🍀(1)Git安装好去GitHub(或Gitee,我以Gitee为例)上注册一个账号,注册好后,点击桌面上的Git Bash快捷图标,我们要用账号进行环境配置
🍀(2)在Git Bash中执行以下命令
# 配置用户名
git config --global user.name "username" //( "username"是自己的账户名,)
# 配置邮箱
git config --global user.email "username@email.com" //("username@email.com"注册账号时用的邮箱)
以上命令执行结束后,可用 git config --global --list 命令,若提示以下信息则配置成功:
🍀(3)生成ssh,在Git Bash命令框中输入以下命令
ssh-keygen -t rsa
然后连敲三次回车键,结束后去系统盘目录下(一般在 C:\Users\你的用户名.ssh)(mac: /Users/用户/.ssh)查看是否有。ssh文件夹生成,此文件夹中以下两个文件:
🍀(4)将ssh文件夹中的公钥( id_rsa.pub)添加到GitHub(Gitee)管理平台中,在GitHub(Gitee)的个人账户的设置中找到如下界面:
Gitee:
GitHub:
标题(title)随便起一个,将公钥( id_rsa.pub)文件中内容复制粘贴到公钥(key)中,然后点击确定(Ass SSH key)就好啦。
🍀(5)测试一下配置是否成功,在Git Bush命令框(就是刚才配置账号和邮箱的命令框)中继续输入以下命令(用Gitee注册后边为git@gitee.com,用Github注册后边为git@github.com),回车。
出现以下提示就说明配置好了。
🍀(6)其他配置
ubuntu配置:apt-get install git
centos配置:yum install git
官网:https://gitee.com/
官网教程:https://gitee.com/help/articles/4122
二、Git相关理论基础
1️⃣Git 是什么
那么,简单地说,Git 究竟是怎样的一个系统呢? 请注意接下来的内容非常重要,若你理解了 Git 的思想和基本工作原理,用起来就会知其所以然,游刃有余。 在学习 Git 时,请尽量理清你对其它版本管理系统已有的认识,如 CVS、Subversion 或 Perforce, 这样能帮助你使用工具时避免发生混淆。尽管 Git 用起来与其它的版本控制系统非常相似, 但它在对信息的存储和认知方式上却有很大差异,理解这些差异将有助于避免使用中的困惑。
2️⃣Git的三种状态
Git 有三种状态,你的文件可能处于其中之一: 已提交(committed)、已修改(modified) 和 已暂存(staged)。
- 已修改表示修改了文件,但还没保存到数据库中。
- 已暂存表示对一个已修改文件的当前版本做了标记,使之包含在下次提交的快照中。
- 已提交表示数据已经安全地保存在本地数据库中。
这会让我们的 Git 项目拥有三个阶段:工作区、暂存区以及 Git 目录。
- 工作区是对项目的某个版本独立提取出来的内容。 这些从 Git 仓库的压缩数据库中提取出来的文件,放在磁盘上供你使用或修改。
- 暂存区是一个文件,保存了下次将要提交的文件列表信息,一般在 Git 仓库目录中。 按照 Git
的术语叫做“索引”,不过一般说法还是叫“暂存区”。 - Git 仓库目录是 Git 用来保存项目的元数据和对象数据库的地方。 这是 Git
中最重要的部分,从其它计算机克隆仓库时,复制的就是这里的数据。
基本的 Git 工作流程如下:
- (1)在工作区中修改文件。
- (2)将你想要下次提交的更改选择性地暂存,这样只会将更改的部分添加到暂存区。
- (3)提交更新,找到暂存区的文件,将快照永久性存储到 Git 目录。
如果 Git 目录中保存着特定版本的文件,就属于 已提交 状态。 如果文件已修改并放入暂存区,就属于 已暂存 状态。 如果自上次检出后,作了修改但还没有放到暂存区域,就是 已修改 状态。 在 Git 基础 一章,你会进一步了解这些状态的细节, 并学会如何根据文件状态实施后续操作,以及怎样跳过暂存直接提交。
如上,如果每个版本中有文件发生变动,Git 会将整个文件复制并保存起来。这种设计看似会多消耗更多的空间,但在分支管理时却是带来了很多的益处和便利。
3️⃣Git保证完整性
Git 中所有的数据在存储前都计算校验和,然后以校验和来引用。 这意味着不可能在 Git 不知情时更改任何文件内容或目录内容。 这个功能建构在 Git 底层,是构成 Git 哲学不可或缺的部分。 若你在传送过程中丢失信息或损坏文件,Git 就能发现。
Git 用以计算校验和的机制叫做 SHA-1 散列(hash,哈希)。 这是一个由 40 个十六进制字符(0-9 和 a-f)组成的字符串,基于 Git 中文件的内容或目录结构计算出来。 SHA-1 哈希看起来是这样:
24b9da6552252987aa493b52f8696cd6d3b00373
Git 中使用这种哈希值的情况很多,你将经常看到这种哈希值。 实际上,Git 数据库中保存的信息都是以文件内容的哈希值来索引,而不是文件名。
三、Git的相关操作
1️⃣初始化Git
🍀(1)初次运行 Git 前的配置
既然已经在系统上安装了 Git,你会想要做几件事来定制你的 Git 环境。 每台计算机上只需要配置一次,程序升级时会保留配置信息。 你可以在任何时候再次通过运行命令来修改它们。
Git 自带一个 git config 的工具来帮助设置控制 Git 外观和行为的配置变量。
在 Windows 系统中,Git 会查找 $HOME 目录下(一般情况下是 C:\Users$USER )的 .gitconfig 文件。
你可以通过以下命令查看所有的配置以及它们所在的文件:
$ git config --list --show-origin
🍀(2)用户信息
安装完 Git 之后,要做的第一件事就是设置你的用户名和邮件地址。 这一点很重要,因为每一个 Git 提交都会使用这些信息,它们会写入到你的每一次提交中,不可更改:
$ git config --global user.name "itnanls"
$ git config --global user.email "510180298@qq.com"
再次强调,如果使用了--global
选项,那么该命令只需要运行一次,因为之后无论你在该系统上做任何事情, Git 都会使用那些信息。 当你想针对特定项目使用不同的用户名称与邮件地址时,可以在那个项目目录下运行没有 --global
选项的命令来配置。
很多 GUI 工具都会在第一次运行时帮助你配置这些信息。
🍀(3)检查配置信息
如果想要检查你的配置,可以使用git config --list
命令来列出所有 Git 当时能找到的配置。
$ git config --list
user.name=John Doe
user.email=johndoe@example.com
color.status=auto
color.branch=auto
color.interactive=auto
color.diff=auto
...
你可能会看到重复的变量名,因为 Git 会从不同的文件中读取同一个配置(例如:/etc/gitconfig 与 ~/.gitconfig)。 这种情况下,Git 会使用它找到的每一个变量的最后一个配置。
你可以通过输入 git config <key>
来检查 Git 的某一项配置
$ git config user.name
John Doe
🍀(4)尝试
在自己方便的盘中新建一个文件夹,这里以MyProject为例,注意路径中不要含有中文字符。打开cmd命令窗口,操作如下:
找一个空文件夹:
点击鼠标右键-----》git bash here
// 初始化 仓库
51018@DESKTOP-6R8BLO2 MINGW64 ~/Desktop/git-study
$ git init
Initialized empty Git repository in C:/Users/51018/Desktop/git-study/.git/
51018@DESKTOP-6R8BLO2 MINGW64 ~/Desktop/git-study (master)// 添加一个文件
$ touch a.txt
$ echo 123 > a.txt
51018@DESKTOP-6R8BLO2 MINGW64 ~/Desktop/git-study (master)// 提交至缓存区
$ git add a.txt
51018@DESKTOP-6R8BLO2 MINGW64 ~/Desktop/git-study (master)// 提交到本地仓库
$ git commit -m 'first'
[master (root-commit) ac41d06] first1 file changed, 0 insertions(+), 0 deletions(-)create mode 100644 a.txt51018@DESKTOP-6R8BLO2 MINGW64 ~/Desktop/git-study (master)
🍀(5)获取帮助
若你使用 Git 时需要获取帮助,有三种等价的方法可以找到 Git 命令的综合手册(manpage):
$ git help <verb>
$ git <verb> --help
例如,要想获得 git config 命令的手册,执行
$ git help config
此外,如果你不需要全面的手册,只需要可用选项的快速参考,那么可以用-h
选项获得更简明的 “help” 输出:
$ git add -h
usage: git add [<options>] [--] <pathspec>...-n, --dry-run dry run-v, --verbose be verbose-i, --interactive interactive picking-p, --patch select hunks interactively-e, --edit edit current diff and apply-f, --force allow adding otherwise ignored files-u, --update update tracked files--renormalize renormalize EOL of tracked files (implies -u)-N, --intent-to-add record only the fact that the path will be added later-A, --all add changes from all tracked and untracked files--ignore-removal ignore paths removed in the working tree (same as --no-all)--refresh don't add, only refresh the index--ignore-errors just skip files which cannot be added because of errors--ignore-missing check if - even missing - files are ignored in dry run--chmod (+|-)x override the executable bit of the listed files
2️⃣基础命令
我们怎么知道哪些文件是新添加的,哪些文件已经加入了暂存区域呢?总不能让我们自己拿个本本记下来吧? 当然不,作为世界上最伟大的版本控制系统,你能遇到的囧境,Git 早已有了相应的解决方案。随时随地都可以使用git status
查看当前状态
$ git status
On branch master
nothing to commit, working tree clean
$ git add b.txt
如果代码报错:git上传代码报错-The file will have its original line endings in your working directory
原因是因为文件中换行符的差别导致的。
🍀CRLF和LF的区别:
windows下的换行符是CRLF而Unix的换行符格式是LF。git默认支持LF。
上面的报错的意思是会把CRLF(也就是回车换行)转换成Unix格式(LF),这些是转换文件格式的警告,不影响使用。
一般commit代码时git会把CRLF转LF,pull代码时LF换CRLF。
解决方案:
git rm -r --cached .
git config core.autocrlf false
然后重新上传代码即可。
为true时,Git会将你add的所有文件视为文本问价你,将结尾的CRLF转换为LF,而checkout时会再将文件的LF格式转为CRLF格式。
为false时,line endings不做任何改变,文本文件保持其原来的样子。
为input时,add时Git会把CRLF转换为LF,而check时仍旧为LF,所以Windows操作系统不建议设置此值。
输入git status
命令,提示如下:
51018@DESKTOP-6R8BLO2 MINGW64 ~/Desktop/git-study (master)
$ echo 1234 > b.txt51018@DESKTOP-6R8BLO2 MINGW64 ~/Desktop/git-study (master)
$ git add b.txt$ git status
On branch master
Changes to be committed:(use "git reset HEAD <file>..." to unstage)new file: b.txt51018@DESKTOP-6R8BLO2 MINGW64 ~/Desktop/git-study (master)
Untracked files 说明存在未跟踪的文件(下边红色的那个)
所谓的“未跟踪”文件,是指那些新添加的并且未被加入到暂存区域或提交的文件。它们处于一个逍遥法外的状态,但你一旦将它们加入暂存区域或提交到 Git 仓库,它们就开始受到 Git 的“跟踪”。
这里圆括号中的英文是 git 给我们的建议:使用 git add file 命令将待提交的文件添加到暂存区域。
F:\MyProject>git add LICENSEF:\MyProject>git status
On branch master
Changes to be committed:(use "git reset HEAD <file>..." to unstage)new file: LICENSE(绿色)
再次添加到暂存区域,然后执行 git commit -m “b.txt” 命令:
修改数据
51018@DESKTOP-6R8BLO2 MINGW64 ~/Desktop/git-study (master)
$ echo 123 > b.txt$ 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: b.txtno changes added to commit (use "git add" and/or "git commit -a")51018@DESKTOP-6R8BLO2 MINGW64 ~/Desktop/git-study (master)
修改文件后,使用git status查看数据。
🍀git log 查看历史操作记录
$ git log
commit 5da78a44017dda030d1fe273e2a470792534ba9a (HEAD -> master)
Author: zhangnan <510180298@qq.com>
Date: Sat Mar 13 16:01:01 2021 +0800123commit c7c0e3bf6d64404e3e68632c24ca13eac38b02e2
Author: zhangnan <510180298@qq.com>
Date: Sat Mar 13 15:53:38 2021 +0800first51018@DESKTOP-6R8BLO2 MINGW64 ~/Desktop/git-study (master)
* d5a12d8a966da5bf36c1f4a080c5d507398f5f59 (HEAD -> master) first
结果中:有head代表当前所处的分之,master代表当前是master分支。可以按下不表。
两次的提交记录看到了。–pretty=oneline
head git 中的分支,其实本质上仅仅是个指向 commit 对象的可变指针。git 是如何知道你当前在哪个分支上工作的呢? 其实答案也很简单,它保存着一个名为 HEAD 的特别指针。在 git 中,它是一个指向你正在工作中的本地分支的指针,可以将 HEAD 想象为当前分支的别名。
$ git log --graph
3️⃣时光回退
有关回退的命令有两个:reset 和 checkout
🍀(1)回滚快照
注:快照即提交的版本,每个版本我们称之为一个快照。
现在我们利用 reset 命令回滚快照,并看看 Git 仓库和三棵树分别发生了什么。
执行 git reset HEAD~
命令:
注:HEAD 表示最新提交的快照,而 HEAD~ 表示 HEAD 的上一个快照,HEAD~~表示上上个快照,如果表示上10个快照,则可以用HEAD ~10
此时我们的快找回滚到了第二棵数(暂存区域)
记住:head永远指向当前分支的当前快照
$ git --hard reset head~51018@DESKTOP-6R8BLO2 MINGW64 ~/Desktop/git-study (master)
$ git log
commit c7c0e3bf6d64404e3e68632c24ca13eac38b02e2 (HEAD -> master)
Author: zhangnan <510180298@qq.com>
Date: Sat Mar 13 15:53:38 2021 +0800first51018@DESKTOP-6R8BLO2 MINGW64 ~/Desktop/git-study (master)
可以看到,只剩下一个记录了。
参数选择:
- hard : 回退版本库,暂存区,工作区。(因此我们修改过的代码就没了,需要谨慎使用)reset 不仅移动 HEAD
的指向,将快照回滚动到暂存区域,它还将暂存区域的文件还原到工作目录。 - mixed: 回退版本库,暂存区。(–mixed为git reset的默认参数,即当任何参数都不加的时候的参数)
- soft: 回退版本库。就相当于只移动 HEAD 的指向,但并不会将快照回滚到暂存区域。相当于撤消了上一次的提交(commit)。
🍀(2)回滚指定快照
reset 不仅可以回滚指定快照,还可以回滚个别文件。
命令格式为:
git reset --hard c7c0e3bf6d64404e3e68632c24ca13eac38b02e2
这样,它就会将忽略移动 HEAD 的指向这一步(因为你只是回滚快照的部分内容,并不是整个快照,所以 HEAD 的指向不应该发生改变),直接将指定快照的指定文件回滚到暂存区域。
不仅可以往回滚,还可以往前滚!
这里需要强调的是:reset 不仅是一个“复古”的命令,它不仅可以回到过去,还可以去到“未来”。
唯一的一个前提条件是:你需要知道指定快照的 ID 号。
那如果不小心把命令窗口关了不记得ID号怎么办? 命令:
git reflog
Git记录的每一次操作的版本ID号。
$ git reset --hard 7ce4954
4️⃣版本对比
🍀(1)暂存区与工作树
目的:对比版本之间有哪些不同
在已经存在的文件b.txt中添加内容:
$ git diff
diff --git a/b.txt b/b.txt
index 9ab39d5..4d37a8a 100644
--- a/b.txt
+++ b/b.txt
@@ -2,3 +2,4 @@1212123123123234234234
+手动阀手动阀
现在来解释一下上面每一行的含义:
第一行: diff --git a/b.txt b/b.txt 表示对比的是存放在暂存区域和工作目录的b.txt
第二行: index 9ab39d5…4d37a8a 100644 表示对应文件的 ID 分别是 9ab39d5和 4d37a8a,左边暂存区域,后边当前目录。最后的 100644 是指定文件的类型和权限
第三行: — a/b.txt ,— 表示该文件是旧文件(存放在暂存区域)
第四行: +++ b/b.txt ,+++ 表示该文件是新文件(存放在工作区域)
第五行: @@ -2,3 +2,4 @@ ,以 @@ 开头和结束,中间的“-”表示旧文件,“+”表示新文件,后边的数字表示“开始行号,显示行数”
内容:+代表新增的行 -代表少了的行,直接执行 git diff 命令是比较暂存区域与工作目录的文件内容。
🍀(2)工作树和最新提交
$ git diff head
warning: LF will be replaced by CRLF in b.txt.
The file will have its original line endings in your working directory
diff --git a/b.txt b/b.txt
new file mode 100644
index 0000000..4d37a8a
--- /dev/null
+++ b/b.txt
@@ -0,0 +1,5 @@
+123
+1212
+123123123
+234234234
+手动阀手动阀51018@DESKTOP-6R8BLO2 MINGW64 ~/Desktop/git-study (master)
🍀(3)两个历史快照
$ git diff 5da78a4 c7c0e3b
diff --git a/b.txt b/b.txt
deleted file mode 100644
index 81c545e..0000000
--- a/b.txt
+++ /dev/null
@@ -1 +0,0 @@
-1234
🍀(4)比较仓库和暂存区
$ git diff --cached c7c0e3b
diff --git a/b.txt b/b.txt
new file mode 100644
index 0000000..9ab39d5
--- /dev/null
+++ b/b.txt
@@ -0,0 +1,4 @@
+123
+1212
+123123123
+234234234
5️⃣删除文件
🍀不小心删除文件怎么办?
现在从工作目录中手动删除 b.txt 文件,然后执行 git status 命令:
$ git status
On branch master
Changes not staged for commit:(use "git add/rm <file>..." to update what will be committed)(use "git checkout -- <file>..." to discard changes in working directory)deleted: b.txtno changes added to commit (use "git add" and/or "git commit -a")
提醒使用 checkout 命令可以将暂存区域的文件恢复到工作目录:
$ git checkout -- b.txt
文件就会重新返回。
🍀那么如何彻底删除一个文件呢?
假如你不小心把小黄图下载到了工作目录,然后又不小心提交到了 Git 仓库:
新增一个c.txt文件
51018@DESKTOP-6R8BLO2 MINGW64 ~/Desktop/git-study (master)
$ echo 123 > c.txt51018@DESKTOP-6R8BLO2 MINGW64 ~/Desktop/git-study (master)
$ git add .
51018@DESKTOP-6R8BLO2 MINGW64 ~/Desktop/git-study (master)
$ git commit -m 'third'
[master 3bd84d8] third1 file changed, 1 insertion(+)create mode 100644 c.txt
还有方法:
执行 git rm a.txt 命令:
$ git rm c.txt
rm 'c.txt'
此时工作目录中的c.txt已经被删除……
51018@DESKTOP-6R8BLO2 MINGW64 ~/Desktop/git-study (master)
$ ls
a.txt b.txt mintty.exe.stackdump
但执行 git status 命令,你仍然发现 Git 还不肯松手:
$ git status
On branch master
Changes to be committed:(use "git reset HEAD <file>..." to unstage)deleted: c.txt
意思是说它在仓库的快照中发现有个叫 c.txt 的东西,但似乎在暂存区域和当前目录不见了!
此时可以执行 git reset --soft HEAD~ 命令将快照回滚到上一个位置,然后重新提交,就好了:
注意:rm 命令删除的只是工作目录和暂存区域的文件(即取消跟踪,在下次提交时不纳入版本管理)
🍀缓冲区和工作树的内容不一致,怎么删除
- (1)修改b.txt 添加至缓冲区
- (2)再修改b.txt
- (3)git rm c.txt
$ echo 123 > b.txt51018@DESKTOP-6R8BLO2 MINGW64 ~/Desktop/git-study (master)
$ git add b.txt51018@DESKTOP-6R8BLO2 MINGW64 ~/Desktop/git-study (master)
$ echo 123 > b.txt51018@DESKTOP-6R8BLO2 MINGW64 ~/Desktop/git-study (master)
$ git rm b.txt
error: the following file has changes staged in the index:b.txt
(use --cached to keep the file, or -f to force removal)
因为两个不同内容的同名文件,谁知道你是不是搞清楚了都要删掉?还是提醒一下好,别等一下出错了又要赖机器…… 根据提示,执行 git rm -f b.txt命令就可以把两个都删除。
🍀我只想删除暂存区域的文件,保留工作目录的,应该怎么操作?
执行 git rm --cached
文件名 命令。
6️⃣重命名文件
直接在工作目录重命名文件,执行git status出现错误:
$ git status
On branch master
Changes to be committed:(use "git reset HEAD <file>..." to unstage)modified: b.txtChanges not staged for commit:(use "git add/rm <file>..." to update what will be committed)(use "git checkout -- <file>..." to discard changes in working directory)deleted: b.txtUntracked files:(use "git add <file>..." to include in what will be committed)n.txt
正确的姿势应该是:
git mv 旧文件名 新文件名
$ git mv b.txt c.txt51018@DESKTOP-6R8BLO2 MINGW64 ~/Desktop/git-study (master)
$ git status
On branch master
Changes to be committed:(use "git reset HEAD <file>..." to unstage)renamed: b.txt -> c.txt
7️⃣忽略文件
如何让Git 识别某些格式的文件,然后自主不跟踪它们? 比如工作目录中有三个文件1.temp、2.temp 和 3.temp,我们不希望后缀名为 temp 的文件被追踪,可是每次执行git status
都会出现:
解决办法:在工作目录创建一个名为 .gitignore 的文件。
然后你发现 Windows 压根儿不允许你在文件管理器中创建以点(.)开头的文件。windows需要在命令行窗口创建(.)开头的文件。执行 echo *.temp > .gitignore
命令,创建一个 .gitignore 文件,并让 Git 忽略所有 .temp 后缀的文件:
$ echo *.temp > .gitignore
在工作目录创建 a.temp
$ git status
On branch master
Changes to be committed:(use "git reset HEAD <file>..." to unstage)renamed: b.txt -> c.txtUntracked files:(use "git add <file>..." to include in what will be committed).gitignore51018@DESKTOP-6R8BLO2 MINGW64 ~/Desktop/git-study (master)
好了,Git 已经忽略了所有的 *.temp 文件(你还可以把 .gitignore 文件也一并忽略)。
8️⃣创建和切换分支
🍀(1)分支是什么?
假设你的大项目已经上线了(有上百万人在使用),过了一段时间
你突然觉得应该添加一些新的功能,但是为了保险起见,你肯定不能在当前项目上直接进行开发,这时候你就有创建分支的需要了。
对于其它版本控制系统而言,创建分支常常需要完全创建一个源代码目录的副本,项目越大,耗费的时间就越多;而 Git 由于每一个结点都已经是一个完整的项目,所以只需要创建多一个“指针”(像 master)指向分支开始的位置即可。
🍀(2)创建分支
执行git status查看状态:
$ git status
On branch master
创建分支,使用 git branch 分支名 命令:
$ git branch feature01
没有任何提示说明分支创建成功(一般也不会失败啦,除非创建了同名的分支会提醒你一下),此时可以执行 git log --decorate
命令查看:
如果希望以“精简版”的方式显示,可以加上一个 --oneline
选项(即 git log --decorate --oneline
),这样就只用一行来显示一个快照记录。
$ git log
commit 432621d36faf270eae133cfe2e976fc99df479a5 (HEAD -> master, feature01)
Author: zhangnan <510180298@qq.com>
Date: Sat Mar 13 17:43:53 2021 +08001commit 4c9e83b6d4ca3ca3d8b0b77bb5aca614dd755413
Author: zhangnan <510180298@qq.com>
Date: Sat Mar 13 17:11:51 2021 +0800123
可以看到最新的快照后边多了一个 (HEAD -> master, feature01)
它的意思是:目前有两个分支,一个是主分支(master),一个是刚才我们创建的新分支(feature),然后 HEAD 指针仍然指向默认的 master 分支。
$ git log --decorate --oneline
432621d (HEAD -> master, feature01) 1
4c9e83b 123
8af2e68 secong
c7c0e3b first
所以目前仓库中的快照应该是这样:head --》 master feature01
🍀(3)切换分支
现在我们需要将工作环境切换到新创建的分支(feature)上,使用的就是之前我们欲言又止的 checkout
命令。执行 git checkout feature
命令:
$ git checkout feature01
Switched to branch 'feature01'51018@DESKTOP-6R8BLO2 MINGW64 ~/Desktop/git-study (feature01)
$ git status
On branch feature01
nothing to commit, working tree clean
现在我们进行一次提交(暂存区域还有一个更改的文件没有提交呢):
创建d.txt文件
$ git add d.txt51018@DESKTOP-6R8BLO2 MINGW64 ~/Desktop/git-study (feature01)
$ git commit -am 'feature01'
[feature01 f5e0b68] feature011 file changed, 1 insertion(+)create mode 100644 d.txt
现在仓库中的快照应该是酱紫(提交的快照由当前HEAD指针指向的分支来管理):
然后我们将 HEAD 指针切回 master 分支:
51018@DESKTOP-6R8BLO2 MINGW64 ~/Desktop/git-study (feature01)
$ ls
a.temp a.txt c.txt d.txt mintty.exe.stackdump51018@DESKTOP-6R8BLO2 MINGW64 ~/Desktop/git-study (feature01)
$ git checkout master
Switched to branch 'master'51018@DESKTOP-6R8BLO2 MINGW64 ~/Desktop/git-study (master)
$ ls
a.temp a.txt c.txt mintty.exe.stackdump
细心的朋友会发现上一次对 README.md 文件的修改已经荡然无存了,这是因为我们的工作目录已经回到 master 分支的状态中:
在不同的分支分别提交
$ git status
On branch master
nothing to commit, working tree clean51018@DESKTOP-6R8BLO2 MINGW64 ~/Desktop/git-study (master)
$ echo 333 >> c.txt51018@DESKTOP-6R8BLO2 MINGW64 ~/Desktop/git-study (master)
$ git add c.txt
warning: LF will be replaced by CRLF in c.txt.
The file will have its original line endings in your working directory51018@DESKTOP-6R8BLO2 MINGW64 ~/Desktop/git-study (master)
$ git commit -m 'master'
[master baccb7f] master1 file changed, 1 insertion(+)51018@DESKTOP-6R8BLO2 MINGW64 ~/Desktop/git-study (master)
$ git checkout feature01
Switched to branch 'feature01'51018@DESKTOP-6R8BLO2 MINGW64 ~/Desktop/git-study (feature01)
$ echo 333 >> c.txt51018@DESKTOP-6R8BLO2 MINGW64 ~/Desktop/git-study (feature01)
$ git add c.txt
warning: LF will be replaced by CRLF in c.txt.
The file will have its original line endings in your working directory51018@DESKTOP-6R8BLO2 MINGW64 ~/Desktop/git-study (feature01)
$ git commit -m 'feature01'
[feature01 b134862] feature011 file changed, 1 insertion(+)51018@DESKTOP-6R8BLO2 MINGW64 ~/Desktop/git-study (feature01)
$ got log --graph| Author: zhangnan <510180298@qq.com>
| Date: Sat Mar 13 18:00:03 2021 +0800
|
| feature01
|
* commit f5e0b68217b66d959bf9eeed7ad7631e4365f355
| Author: zhangnan <510180298@qq.com>
| Date: Sat Mar 13 17:50:20 2021 +0800
|
| feature01
|
| * commit baccb7f29da8143adebc79ca4c10e15204e79411 (master)
|/ Author: zhangnan <510180298@qq.com>
| Date: Sat Mar 13 17:59:20 2021 +0800
|
| master
|
* commit 432621d36faf270eae133cfe2e976fc99df479a5
| Author: zhangnan <510180298@qq.com>
| Date: Sat Mar 13 17:43:53 2021 +0800
|
| 1
|
* commit 4c9e83b6d4ca3ca3d8b0b77bb5aca614dd755413
| Author: zhangnan <510180298@qq.com>
| Date: Sat Mar 13 17:11:51 2021 +0800
|
| 123
|
9️⃣合并分支
新建一个仓库
// 初始化一个仓库
$ git init
// 创建一个a.txt 文件,并且修改他的内容
$ touch a.txt// 提交该分支
$ git add a.txt
$ git commit -m 'master'// 切出一个分支
$ git branch feature1
// 切换到该分支
$ git checkout feature1
Switched to branch 'feature1'
// 随意修改a.txt的内容
。。。
// 切换回主分支
$ git checkout master
Switched to branch 'master'
// 合并分支
$ git merge feature1
Updating 540e027..cae5dfc
Fast-forwarda.txt | 8 +++++++-1 file changed, 7 insertions(+), 1 deletion(-)
当一个子分支的使命完结之后,它就应该回归到主分支中去。
$ git log --decorate --all --graph --online
fatal: unrecognized argument: --online51018@DESKTOP-6R8BLO2 MINGW64 ~/Desktop/git-study (feature01)
$ git log --decorate --all --graph --oneline
* b134862 (HEAD -> feature01) feature01
* f5e0b68 feature01
| * baccb7f (master) master
|/
* 432621d 1
* 4c9e83b 123
* 8af2e68 secong
* c7c0e3b first
合并分支我们使用 merge 命令,执行 git merge feature01命令,将 feature 分支合并到 HEAD 所在的分支(master)上:
第一步: 切出一个feature2分支,修改master分支中a.txt第一行数据。
// 先切出一个分支
$ git branch feature2// 在master分支做修改,修改a.txt的第一行数据
$ git add a.txt//提交master分支
$ git commit -m 'master'// 切换到feature2 分支
$ git checkout feature2
Switched to branch 'feature2'// 同样修改a.txt的第一行数据
$ git add a.txt
// 提交
$ git commit -m feature2
[feature2 0ebb84a] feature21 file changed, 1 insertion(+), 1 deletion(-)// 切换到master分支
$ git checkout master
Switched to branch 'master'// 将feature2合并到master分支上
$ git merge feature2
// 发生了问题
Auto-merging a.txt
CONFLICT (content): Merge conflict in a.txt
Automatic merge failed; fix conflicts and then commit the result.
a.txt内容变成了如下:
<<<<<<< HEAD
123123
=======
123345
>>>>>>> feature2
意思是说现在你需要先解决冲突的问题,Git 才能进行合并操作。所谓冲突,无非就是像两个分支中存在同名但内容却不同的文件,Git 不知道你要舍弃哪一个或保留哪一个,所以需要你自己来决定。 此时执行 git status
命令也会显示需要你解决的冲突:
$ git status
On branch master
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: a.txtno changes added to commit (use "git add" and/or "git commit -a")
以“=======”为界,上到“<<<<<<< HEAD”的内容表示当前分支,下到“>>>>>>> feature”表示待合并的 feature 分支,之间的内容就是冲突的地方。
我们就需要手动修改:
123123
51018@DESKTOP-6R8BLO2 MINGW64 ~/Desktop/git-study (master|MERGING)
$ git add a.txt51018@DESKTOP-6R8BLO2 MINGW64 ~/Desktop/git-study (master|MERGING)
$ git commit -m '解决冲突'
[master 569943e] 解决冲突
🔟删除分支
当一个功能开发完成,并且成功合并到主分支,我们应该删除分支
使用 git branch -d
分支名 命令:
执行 git log --decorate --all --graph --oneline
命令:
由于 Git 的分支原理实际上只是通过一个指针记载,所以创建和删除分支都几乎是瞬间完成。
注意:如果试图删除未合并的分支,Git 会提示你“该分支未完全合并,如果你确定要删除,请使用 git branch -D 分支名
命令。
1️⃣1️⃣变基
当我们开发一个功能时,可能会在本地有无数次commit,而你实际上在你的master分支上只想显示每一个功能测试完成后的一次完整提交记录就好了,其他的提交记录并不想将来全部保留在你的master分支上,那么rebase将会是一个好的选择,他可以在rebase时将本地多次的commit合并成一个commit,还可以修改commit的描述等。
// 合并前两次的commit
git rebase -i head~~// 合并此次commit在最新commit的提交
git rebaser -i hash值
后记
👉Java全栈学习路线可参考:【Java全栈学习路线】最全的Java学习路线及知识清单,Java自学方向指引,内含最全Java全栈学习技术清单~
👉算法刷题路线可参考:算法刷题路线总结与相关资料分享,内含最详尽的算法刷题路线指南及相关资料分享~