03【远程协作开发、TortoiseGit、IDEA绑定Git插件的使用】

上一篇02【Git分支的使用、Git回退、还原】

下一篇【已完结】

目录【Git系列教程-目录大纲】


文章目录

  • 一、远程协作开发
    • 1.1 远程仓库简介
      • 1.1.1 Github
      • 1.1.2 Gitee
      • 1.1.3 其他托管平台
    • 1.2 发布远程仓库
      • 1.2.1 创建项目
        • 1) 新建远程仓库
        • 2) 推送项目
      • 1.2.2 添加项目成员
    • 1.3 协同开发
      • 1.3.1 remote命令
      • 1.3.2 clone命令
      • 1.3.3 fetch命令
      • 1.3.4 pull命令
    • 1.4 远程跟踪分支
      • 1.4.1 远程分支
        • 1) 创建本地分支
        • 2) 创建远程分支
        • 3) 远程分支的拉取
      • 1.4.2 远程跟踪分支创建时机
        • 1) push
        • 2) clone
        • 3) fetch
        • 4) pull
    • 1.5 远程协作代码冲突
      • 1.5.1 分支合并代码冲突
        • 1) 快进合并冲突
        • 2) 典型合并冲突
      • 1.5.2 远程协作代码冲突
        • 1) 创建远程仓库
        • 2) clone项目
        • 3) 协同开发
        • 4) 模拟协同开发冲突
  • 二、TortoiseGit的使用
    • 2.1 TortoiseGit 的基本使用
      • 2.1.1 创建仓库
      • 2.1.2 添加
      • 2.1.3 提交
      • 2.1.4 对比
      • 2.1.5 查看状态
      • 2.1.6 改名
      • 2.1.6 删除
      • 2.1.7 日志
      • 2.1.7 还原
        • 1) 还原工作空间
        • 2) 还原提交对象
      • 2.1.8 回退
        • 1)回退HEAD指针
        • 2)回退HEAD指针、暂存区
        • 3)回退HEAD指针、暂存区、工作空间
      • 2.1.9 添加忽略
    • 2.2 TortiseGit操作分支
      • 2.2.1 创建分支
      • 2.2.2 切换分支
      • 2.2.3 合并分支
      • 2.2.3 分支合并冲突
      • 2.2.4 分支状态存储
        • 1) 使用存储
        • 2) 查看存储
        • 3) 读取存储
        • 4) 删除存储
    • 2.3 TortiseGit协同开发
      • 2.3.1 remote
      • 2.3.2 push
      • 2.2.3 clone
      • 2.3.4 fetch
      • 2.3.5 pull
      • 2.3.6 模拟协同开发冲突
  • 三、IDEA集成Git插件
    • 3.1 Git插件的基本使用
      • 3.1.1 提交项目
        • 1)绑定Git插件
        • 2)添加忽略文件
        • 3)提交项目
      • 3.1.2 比较
      • 3.1.3 还原
        • 1)还原工作空间
        • 2)还原提交对象
      • 3.1.4 回退
        • 1)回退HEAD指针
        • 2)回退HEAD、暂存区
        • 3)回退HEAD、暂存区、工作空间
    • 3.2 分支的操作
      • 3.2.1 创建分支
      • 3.2.2 切换分支
      • 3.3.2 合并分支
      • 3.3.3 合并分支解决冲突
      • 3.3.4 使用分支状态存储
    • 3.3 协同开发
      • 3.3.1 remote
      • 3.3.2 push
      • 3.3.3 clone
      • 3.3.4 fetch
      • 3.3.5 pull
      • 3.3.6 模拟协同开发
        • 1) push冲突
        • 2) pull冲突

一、远程协作开发

1.1 远程仓库简介

到目前为止,我们的项目都是基于本地开发,团队协作开发则需要将自己的代码发布到远程仓库,它是一个存储Git代码的远程服务器。同时我们也需要拉取远程仓库中其他团队成员开发的功能到本地;有了远程仓库,我们的项目才能算真正意义上的协同开发;

远程仓库是一个代码托管中心,市面上有非常多比较出名的代码托管中心,比如Github、Gitee等;这些远程仓库都是基于互联网的,只要接入了互联网就可以创建属于自己的远程仓库。另外,我们也可以搭建自身的远程仓库,这些远程仓库一般用于某些公司存储自身代码。

1.1.1 Github

Github:GitHub是一个面向开源及私有软件项目的托管平台,因为只支持Git作为唯一的版本库格式进行托管,故名GitHub。GitHub拥有1亿以上的开发人员,400万以上组织机构和3.3亿以上资料库。GitHub 是全球最大的 Git 版本库托管商,是成千上万的开发者和项目能够合作进行的中心。 大部分 Git 版本库都托管在 GitHub,很多开源项目使用 GitHub 实现 Git 托管、问题追踪、代码审查以及其它事情。

Github官网:https://github.com/

1.1.2 Gitee

Gitee(码云)是开源中国于2013年推出的基于Git的代码托管平台、企业级研发效能平台,提供中国本土化的代码托管服务。Gitee 是国内最大的 Git 版本库托管商

由于Github在国外受网络限制等原因,我们后续的远程仓库均采用Gitee作为托管平台。

Gitee官网:https://gitee.com/

1.1.3 其他托管平台

由于Github、Gitee等平台面向于互联网用于,虽说这些网站可以对仓库本身有很好的权限控制,但总归不如在自己公司内部搭建代码托管服务来得安心,因此还是有很多互联网公司会在公司内网大家属于自己公司的代码托管平台;

  • gogs:Gogs 是一款极易搭建的自助 Git 服务。Gogs 的目标是打造一个最简单、最快速和最轻松的方式搭建自助 Git 服务。

官网:https://gogs.io

  • gitlab:GitLab 是一个用于仓库管理系统的开源项目,使用Git作为代码管理工具,并在此基础上搭建起来的Web服务。Gitlab是被广泛使用的基于git的开源代码管理平台, 基于Ruby on Rails构建

官网:https://gitlab.cn/

1.2 发布远程仓库

等到本地代码提交成功后就应该推送(push)到远程仓库供团队其他成员拉取(pull)。同样的,其他成员代码编写完毕后也应该推送到远程仓库,我们也可以从远程仓库中拉取其他成员的代码到本地进行合并,这样一个完整的功能就集成到项目中了。

1.2.1 创建项目

远程仓库就是代码托管中心的仓库,我们本次采用Gitee作为代码托管中心;注册Gitee账号,创建一个新的仓库:

1) 新建远程仓库
  • 1)新建远程仓库:

  • 2)填写仓库资料:

  • 3)创建成功:

2) 推送项目
  • 1)首先初始化一个本地项目:
rm -rf .git ./*		
git init			
echo "111" >> aaa.txt
git add ./
git commit -m "111" ./
echo "222" >> aaa.txt
git commit -m "222" ./
echo "333" >> aaa.txt
git commit -m "333" ./

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)		# 产生三个版本
$ git log --oneline
e5fec93 (HEAD -> master) 333
8b6f1a7 222
1bbbf3b 111
  • 2)推送到远程仓库:
git push https://gitee.com/lvshuichangliu/test01.git master

推送成功:

刷新Gitee页面:

填写完毕用户信息后,我们的信息被记录到Windows凭据中,查看推送就不需要再次添加用户名和密码了

有的人的电脑在推送之后,windows凭据中并不会保存用户信息,再次推送仍然需要填写用户信息,我们可以通过配置Git的方式来强制保存凭证:

# 永久保存凭证(后续执行push/pull/clone等指令不需要再重新输入用户名和密码了)
git config --global credential.helper store

# 清除凭证
git config --global --unset credential.helper

有了windows凭证之后,再次推送就不需要输入用户信息了:

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)
$ echo "444" >> aaa.txt

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)
$ git commit -m "444" ./
warning: LF will be replaced by CRLF in aaa.txt.
The file will have its original line endings in your working directory
warning: LF will be replaced by CRLF in aaa.txt.
The file will have its original line endings in your working directory
[master c771aae] 444
 1 file changed, 1 insertion(+)

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)
$ git push https://gitee.com/lvshuichangliu/test01.git master
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Writing objects: 100% (3/3), 246 bytes | 246.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
remote: Powered by GITEE.COM [GNK-6.4]
To https://gitee.com/lvshuichangliu/test01.git
   e5fec93..c771aae  master -> master

1.2.2 添加项目成员

默认情况下创建好的项目只允许创建人对项目进行编辑其他人均不可对项目进行操作,因此我们需要添加项目成员,来允许其他人操作该项目;

  • 1)在项目管理中添加开发者:

  • 2)登录开发者账号,加入:

1.3 协同开发

1.3.1 remote命令

我们之前使用push指令推送本地项目到远程仓库;我们需要知道远程仓库的地址才可以推送,而远程仓库的地址太长不易记忆;

remote命令则可以帮助我们为远程仓库的地址添加别名。

  • 语法:
# 查看所有别名
git remote -v 

# 为一个远程仓库起一个别名
git remote add {remote-name} {url}	

# 查看指定的远程仓库的详细信息
git remote show {remote-name | url}

# 重命名别名
git remote rename {old-remote-name} {new-remote-name} 

# 删除别名
git remote rm {remote-name}

【代码示例】

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)			# 添加别名
$ git remote add test01 https://gitee.com/lvshuichangliu/test01.git

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)			# 查看别名列表,remote指令会为仓库添加两个别名
$ git remote -v
test01  https://gitee.com/lvshuichangliu/test01.git (fetch)		# 用于fetch操作
test01  https://gitee.com/lvshuichangliu/test01.git (push)		# 用于push操作

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)			# 查看仓库信息
$ git remote show test01
* remote test01
  Fetch URL: https://gitee.com/lvshuichangliu/test01.git
  Push  URL: https://gitee.com/lvshuichangliu/test01.git
  HEAD branch: master
  Remote branch:
    master new (next fetch will store in remotes/test01)
  Local ref configured for 'git push':
    master pushes to master (up to date)


Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)			# 重命名仓库
$ git remote rename test01 test01Project

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)			# 查看别名列表
$ git remote -v
test01Project   https://gitee.com/lvshuichangliu/test01.git (fetch)
test01Project   https://gitee.com/lvshuichangliu/test01.git (push)

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)			# 删除别名
$ git remote rm test01Project

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)
$ git remote -v

1.3.2 clone命令

git clone顾名思义就是将远程仓库克隆到本地,包括被clone仓库的版本变化。此时本地无需执行git init,等待git clone执行完毕会自动生成.git文件夹。因为是clone来的,所以.git文件夹里存放着与远程仓库一模一样的版本库记录。

  • 语法:
# 克隆远程仓库到本地
git clone {url}

# 默认情况下克隆到本地的项目名称和远程库一样,如果想要自己指定名称可以在后面指定项目的名称
git clone {url} {projectName}

使用clone命令将远程仓库的项目克隆到本地之后,会将项目取个默认的别名,为origin,同时创建远程分支对应的远程跟踪分支;

Tips:关于远程跟踪分支我们后面再详细介绍;

【代码示例】

rm -rf .git ./*		# 删除本地仓库

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui			# 克隆项目
$ git clone https://gitee.com/lvshuichangliu/test01.git
Cloning into 'test01'...
remote: Enumerating objects: 12, done.
remote: Counting objects: 100% (12/12), done.
remote: Compressing objects: 100% (4/4), done.
remote: Total 12 (delta 0), reused 0 (delta 0), pack-reused 0
Receiving objects: 100% (12/12), done.

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui			# 进入项目
$ cd test01/

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)		# 查看项目别名
$ git remote -v
origin  https://gitee.com/lvshuichangliu/test01.git (fetch)
origin  https://gitee.com/lvshuichangliu/test01.git (push)

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ git log --oneline
c771aae (HEAD -> master, origin/master, origin/HEAD) 444						# 创建了两个远程跟踪分支,origin/master就是master对应的远程跟踪分支
e5fec93 333
8b6f1a7 222
1bbbf3b 111

1.3.3 fetch命令

fetch指令用于获取远程库的代码,默认情况下,获取的最新代码在本地分支对应的远程跟踪分支上,并不在当前的分支。因此我们一般在使用完fetch命令后,还要将本地分支与远程跟踪分支进行合并,这样才能确保代码能够更新到本地仓库;

  • 语法:
# 拉取远程仓库的代码到本地的远程跟踪分支
    # branchName: 本地分支名称
    # remoteBranchName: 远程分支名称
git fetch { url | remoteName } [branchName[:remoteBranchName]]

# 拉取远程仓库的代码到本地的远程跟踪分支(本地分支和远程分支名称一致的情况)
git fetch { url | remoteName } [branchName]

# 拉取远程仓库的代码到本地的远程跟踪分支(操作的分支是master的情况下)
git fetch { url | remoteName }

【代码示例】

在一个新的目录(xiaolan)从新拉取一份代码到本地:

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaolan
$ git clone https://gitee.com/lvshuichangliu/test01.git

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaolan	# 进入项目
$ cd test01/

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaolan/test01 (master)		# 查看别名
$ git remote -v
origin  https://gitee.com/lvshuichangliu/test01.git (fetch)
origin  https://gitee.com/lvshuichangliu/test01.git (push)

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaolan/test01 (master)		# 查看日志
$ git log --oneline
c771aae (HEAD -> master, origin/master, origin/HEAD) 444	
e5fec93 333
8b6f1a7 222
1bbbf3b 111

【在xiaolan工作空间编辑代码,提交、推送】

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaolan/test01 (master)			# 编辑文件
$ echo "555" >> aaa.txt

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaolan/test01 (master)			# 提交到本地库
$ git commit -m "555" ./

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaolan/test01 (master)			# 推送master分支到远程仓库
$ git push origin master

【在xiaohui工作空间使用fetch命令拉取代码】

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ git log --oneline --all
c771aae (HEAD -> master, origin/master, origin/HEAD) 444
e5fec93 333
8b6f1a7 222
1bbbf3b 111

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ cat aaa.txt
111
222
333
444

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)		# 使用fetch拉取远程仓库的代码
$ git fetch origin

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ git log --oneline --all
48ae5b2 (origin/master, origin/HEAD) 555				# 最新代码被拉取到origin/master分支上了
c771aae (HEAD -> master) 444							# master分支还在原地
e5fec93 333
8b6f1a7 222
1bbbf3b 111

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)		# 查看当前分支(master)的工作空间,发现代码并没有被合并到master分支
$ cat aaa.txt
111
222
333
444

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)		# 合并origin/master分支
$ git merge origin/master
Updating c771aae..48ae5b2
Fast-forward
 aaa.txt | 1 +
 1 file changed, 1 insertion(+)

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)		# 查看日志
$ git log --oneline --all
48ae5b2 (HEAD -> master, origin/master, origin/HEAD) 555
c771aae 444
e5fec93 333
8b6f1a7 222
1bbbf3b 111

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)		# 查看工作空间代码
$ cat aaa.txt
111
222
333
444
555

1.3.4 pull命令

pull也是用于获取远程仓库的代码,与fetch命令不同的是,pull命令拉取远程仓库的最新代码到本地后,然后再与本地分支进行merge(合并),这样就不需要我们人为的进行合并了;

  • 语法:
# 拉取代码到本地分支并将本地分支与远程跟踪分支合并
    # branchName: 本地分支的名称
    # remoteBranchName: 远程分支的名称
git pull { url | project-name} [branchName[:remoteBranchName]]

# 拉取代码到本地分支并将本地分支与远程跟踪分支合并(本地分支和远程分支名称一致的情况)
git pull { url | project-name} [branchName]

# 拉取代码到本地分支并将本地分支与远程跟踪分支合并(操作的分支是master的情况下)
git pull { url | project-name}

【在xiaolan工作空间编辑代码,提交、推送】

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaolan/test01 (master)			# 编辑文件
$ echo "666" >> aaa.txt

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaolan/test01 (master)			# 提交到本地库
$ git commit -m "666" ./

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaolan/test01 (master)			# 推送master分支到远程仓库
$ git push origin master

【在xiaohui工作空间使用pull命令拉取代码】

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ git log --oneline --all
48ae5b2 (HEAD -> master, origin/master, origin/HEAD) 555
c771aae 444
e5fec93 333
8b6f1a7 222
1bbbf3b 111

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ cat aaa.txt
111
222
333
444
555

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)			# 使用pull来取代码
$ git pull origin

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)			# master分支与origin/master分支已经合并
$ git log --oneline --all
f67c377 (HEAD -> master, origin/master, origin/HEAD) 666
48ae5b2 555
c771aae 444
e5fec93 333
8b6f1a7 222
1bbbf3b 111

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ cat aaa.txt
111
222
333
444
555
666

1.4 远程跟踪分支

1.4.1 远程分支

在Git中,存在三种分支,分别为本地分支、远程分支、远程跟踪分支;

1) 创建本地分支

本地分支:存在与本地工作空间的分支,每一个Git仓库都会存在一个master分支,该master分支就是本地分支;我们也可以通过git branch命令来创建本地分支;

【示例代码】

在一个新的工作空间(test)测试:

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/test
$ git init # 初始化仓库
Initialized empty Git repository in C:/Users/Admin/Desktop/workspace/test/.git/

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/test (master)
$ echo "111" >> a.txt

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/test (master)
$ git add ./

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/test (master)
$ git commit -m "111" ./

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/test (master)
$ git log --oneline --all
5aec3e0 (HEAD -> master) 111		# 每个Git仓库都会有一个master本地分支

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/test (master)			# 创建一个本地分支
$ git branch b1

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/test (master)
$ git log --oneline --all
5aec3e0 (HEAD -> master, b1) 111
2) 创建远程分支

存在于远程仓库的分支,我们可以将本地的分支提交到远程仓库中,这样就变成了远程分支;

【在xiaohui工作空间创建一个本地分支,然后推送到远程仓库】

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ git log --oneline --all
f67c377 (HEAD -> master, origin/master, origin/HEAD) 666
48ae5b2 555
c771aae 444
e5fec93 333
8b6f1a7 222
1bbbf3b 111

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)		# 创建b1分支
$ git branch b1

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ git log --oneline --all
f67c377 (HEAD -> master, origin/master, origin/HEAD, b1) 666
48ae5b2 555
c771aae 444
e5fec93 333
8b6f1a7 222
1bbbf3b 111

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)		# 查看项目名
$ git remote -v
origin  https://gitee.com/lvshuichangliu/test01.git (fetch)
origin  https://gitee.com/lvshuichangliu/test01.git (push)

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)		# 推送b1分支到远程仓库
$ git push origin b1
Total 0 (delta 0), reused 0 (delta 0), pack-reused 0
remote: Powered by GITEE.COM [GNK-6.4]
remote: Create a pull request for 'b1' on Gitee by visiting:
remote:     https://gitee.com/lvshuichangliu/test01/pull/new/lvshuichangliu:b1...lvshuichangliu:master
To https://gitee.com/lvshuichangliu/test01.git
 * [new branch]      b1 -> b1

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ git log --oneline
f67c377 (HEAD -> master, origin/master, origin/b1, origin/HEAD, b1) 666		# 推送完成之后创建了b1的远程跟踪分支
48ae5b2 555
c771aae 444
e5fec93 333
8b6f1a7 222
1bbbf3b 111

打开远程仓库,查看分支:

3) 远程分支的拉取

当本地分支被提交到远程仓库后,就会建立远程分支,需要注意的时,我们在clone项目时,远程分支并不会被克隆下来,被克隆下来的只有远程分支对应的远程跟踪分支;

在一个新的工作空间(xiaolv)使用克隆远程仓库:

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaolv
$ git clone https://gitee.com/lvshuichangliu/test01.git
Cloning into 'test01'...
remote: Enumerating objects: 18, done.
remote: Counting objects: 100% (18/18), done.
remote: Compressing objects: 100% (6/6), done.
remote: Total 18 (delta 0), reused 0 (delta 0), pack-reused 0
Receiving objects: 100% (18/18), done.

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaolv
$ cd test01/

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaolv/test01 (master)
$ git log --oneline --all
f67c377 (HEAD -> master, origin/master, origin/b1, origin/HEAD) 666		# 拉取到本地的只有远程跟踪分支
48ae5b2 555
c771aae 444
e5fec93 333
8b6f1a7 222
1bbbf3b 111

虽然clone时远程分支并不会被clone到本地,但是我们可以根据远程跟踪分支来创建本地分支

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaolv/test01 (master)		# 在当前位置创建b1分支
$ git branch b1

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaolv/test01 (master)		# 查看日志
$ git log --oneline --all
f67c377 (HEAD -> master, origin/master, origin/b1, origin/HEAD, b1) 666
48ae5b2 555
c771aae 444
e5fec93 333
8b6f1a7 222
1bbbf3b 111

1.4.2 远程跟踪分支创建时机

远程跟踪分支作为本地分支与远程分支中的媒介,记录的是上次连接到远程仓库时,远程分支所处的状态。远程跟踪分支的作用是告诉用户其所跟踪的远程分支的状态(即指向哪一个commit),因而它在本地是只读的,用户是无法自行修改它的指向

远程跟踪分支以"远程仓库名/分支名"命名;

远程分支的创建时机有:

  • push:当执行push操作后,会将本地分支提交到远程仓库中并创建远程分支,与此同时会创建远程分支对应的远程跟踪分支;
  • clone:当执行clone操作后,远程分支并不会被拉取到本地,但本地会创建其他分支对应的远程跟踪分支;
  • fetch:当执行fetch操作拉取指定远程分支代码到本地时,会在本地创建该远程分支对应的远程跟踪分支;远程分支的代码就被拉取到这个远程跟踪分支上,我们通常需要使用当前分支来合并远程跟踪分支来更新工作空间。
  • pull:当执行pull操作拉取指定远程分支代码到本地时,会在本地创建该远程分支对应的远程跟踪分支;然后将当前分支与远程跟踪分支合并。

【准备本地项目环境】

在xiaolan工作空间创建本地项目:

rm -rf .git ./*		
git init			
echo "111" >> aaa.txt
git add ./
git commit -m "111" ./
echo "222" >> aaa.txt
git commit -m "222" ./
echo "333" >> aaa.txt
git commit -m "333" ./
git branch b1

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)		# 产生3个版本
$ git log --oneline --all
7225a2f (HEAD -> master, b1) 333
37a2682 222
3106882 111

创建远程仓库test02:

添加项目别名:

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ git remote add test02 https://gitee.com/lvshuichangliu/test02.git

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ git remote -v
test02  https://gitee.com/lvshuichangliu/test02.git (fetch)
test02  https://gitee.com/lvshuichangliu/test02.git (push)
1) push

当执行push操作后,会将本地分支提交到远程仓库中并创建远程分支,与此同时会创建远程分支对应的远程跟踪分支;

【将本地项目推送到远程仓库】

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)		# 将项目推送到远程仓库
$ git push test02 master

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)		# 查看日志
$ git log --oneline --all
7225a2f (HEAD -> master, test02/master, b1) 333		# 创建了master分支对应的远程跟踪分支(test02/master)
37a2682 222
3106882 111

【查看远程分支】

【再次推送b1分支到远程仓库】

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)		# 推送b1分支到远程仓库
$ git push test02 b1

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)		
$ git log --oneline --all
7225a2f (HEAD -> master, test02/master, test02/b1, b1) 333		# 创建了b1分支对应的远程跟踪分支(test02/b1)
37a2682 222
3106882 111

【查看远程分支】

2) clone

当执行clone操作后,远程分支并不会被拉取到本地,但本地会创建其他分支对应的远程跟踪分支;

【创建一个新的工作空间xiaolan,使用clone克隆远程仓库到本地】

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaolan						# 克隆项目
$ git clone https://gitee.com/lvshuichangliu/test02.git

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaolan						# 进入项目
$ cd test02/

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaolan/test02 (master)		# 查看项目别名
$ git remote -v
origin  https://gitee.com/lvshuichangliu/test02.git (fetch)
origin  https://gitee.com/lvshuichangliu/test02.git (push)

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaolan/test02 (master)		# 查看日志
$ git log --oneline
7225a2f (HEAD -> master, origin/master, origin/b1, origin/HEAD) 333		# 远程分支对应的远程跟踪分支被拉取下来了
37a2682 222
3106882 111
3) fetch

当执行fetch操作拉取指定远程分支代码到本地时,会在本地创建该远程分支对应的远程跟踪分支;远程分支的代码就被拉取到这个远程跟踪分支上,我们通常需要使用当前分支来合并远程跟踪分支来更新工作空间。

【先使用xiaohui工作空间创建一个新分支b2,然后再推送到远程仓库】

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)		# 创建b2分支
$ git branch b2

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)		# 切换到b2分支
$ git checkout b2
Switched to branch 'b2'

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (b2)
$ echo "444-b2" >> aaa.txt

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (b2)
$ git commit -m "444-b2" ./

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (b2)			# 推送b2分支到远程仓库
$ git push test02 b2

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (b2)		
$ git log --oneline --all
b8374b1 (HEAD -> b2, test02/b2) 444-b2					# 在本地创建了b2分支对应的远程跟踪分支
7225a2f (test02/master, test02/b1, master) 333
37a2682 222
3106882 111

【到xiaolan工作空间,使用fetch拉取远程仓库代码到本地】

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaolan/test02 (master)
$ git log --oneline --all
7225a2f (HEAD -> master, origin/master, origin/b1, origin/HEAD, b1) 333
37a2682 222
3106882 111

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaolan/test02 (master)
$ git fetch origin b2

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaolan/test02 (master)
$ git log --oneline --all
b8374b1 (origin/b2) 444-b2													# 创建了b2分支的远程跟踪分支
7225a2f (HEAD -> master, origin/master, origin/b1, origin/HEAD, b1) 333		# HEAD指针指向的是这里
37a2682 222
3106882 111

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaolan/test02 (master)		# 在当前位置创建b2分支
$ git branch b2

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaolan/test02 (master)		# 切换到b2分支
$ git checkout b2
Switched to branch 'b2'

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaolan/test02 (b2)
$ git log --oneline --all
b8374b1 (origin/b2) 444-b2
7225a2f (HEAD -> b2, origin/master, origin/b1, origin/HEAD, master, b1) 333				# HEAD指针指向了b2分支
37a2682 222
3106882 111

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaolan/test02 (b2)			# 合并远程跟踪分支
$ git merge origin/b2
Updating 7225a2f..b8374b1
Fast-forward
 aaa.txt | 1 +
 1 file changed, 1 insertion(+)

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaolan/test02 (b2)
$ git log --oneline --all
b8374b1 (HEAD -> b2, origin/b2) 444-b2
7225a2f (origin/master, origin/b1, origin/HEAD, master, b1) 333
37a2682 222
3106882 111
4) pull

当执行pull操作拉取指定远程分支代码到本地时,会在本地创建该远程分支对应的远程跟踪分支;然后将当前分支与远程跟踪分支合并。

【使用xiaohui工作空间创建新分支b3,然后再推送到远程仓库】

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (b2)		# 查看日志
$ git log --oneline --all
b8374b1 (HEAD -> b2, test02/b2) 444-b2				# HEAD指针指向这里
7225a2f (test02/master, test02/b1, master) 333
37a2682 222
3106882 111

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (b2)		# 在当前HEAD指针指向的位置创建b3分支
$ git branch b3

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (b2)
$ git checkout b3
Switched to branch 'b3'

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (b3)
$ echo "555-n3" >> aaa.txt

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (b3)
$ git commit -m "555-b3" ./

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (b3)		# 推送到远程仓库
$ git push test02 b3

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (b3)
$ git log --oneline --all
31b62a6 (HEAD -> b3, test02/b3) 555-b3						# 创建了b3分支对应的远程跟踪分支
b8374b1 (test02/b2, b2) 444-b2
7225a2f (test02/master, test02/b1, master) 333
37a2682 222
3106882 111

查看远程分支b3:

【到xiaolan工作空间,使用pull拉取远程仓库代码到本地】

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaolan/test02 (b2)	
$ git log --oneline --all					# 当前HEAD指针的位置
b8374b1 (HEAD -> b2, origin/b2) 444-b2
7225a2f (origin/master, origin/b1, origin/HEAD, master, b1) 333
37a2682 222
3106882 111

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaolan/test02 (b2)		# 拉取b3远程分支到本地
$ git pull origin b3

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaolan/test02 (b2)		
$ git log --oneline --all
31b62a6 (HEAD -> b2, origin/b3) 555-b3			# 创建了b3的远程跟踪分支(origin/b3),并且当前分支(b2)与origin/b3分支合并了
b8374b1 (origin/b2) 444-b2
7225a2f (origin/master, origin/b1, origin/HEAD, master, b1) 333
37a2682 222
3106882 111

1.5 远程协作代码冲突

在Git中,代码冲突分为协同开发时的代码冲突分支合并时的代码冲突两大类;

  • 其关系如图所示:

1.5.1 分支合并代码冲突

其中分支合并代码冲突又分为快进合并与典型合并;

另外需要注意的是:Git判断代码是否冲突的逻辑并非指的是两个分支/两个用户是否操作同一行,而是只要有两个分支/两个用户操作的文件内容不一样,不管是否是同一行都会造成代码冲突。

1) 快进合并冲突

快进合并指的是前面的版本需要合并后面的版本;但需要注意的是==前面的版本并非是"旧版本",后面的版本并非是"新版本"==,这主要取决于是否是同轴开发。对于同轴开发,后面的版本自然是新版本,其内容肯定包含前面版本的内容。但对于非同轴开发,后面的版本内容大概率是不包含前面的版本内容的;

快进合并存在同轴开发与非同轴开发的快进合并,对于同轴开发来说,快进合并不会造成代码冲突,

master分支test分支
创建abc.txt
内容为:
111
222
执行add
执行commit
创建分支 – 此时test分支的abc.txt的内容也是111、222
修改内容为:
111aaa
222
执行commit
切换到test分支
修改内容为:
111
222bbb
执行commit – 此时test分支和master分支已经不同轴了
切换回master分支,合并test分支,属于快进合并,但会出现冲突

上面案例属于很常见的==非同轴开发的快进合并==。前面的版本合并后面的版本,虽然两个分支操作的文件内容不是同一行,但依旧会出现冲突;

【初始化项目】

rm -rf ./* .git
git init
echo "111" >> aaa.txt
echo "222" >> aaa.txt
git add ./
git commit -m "111 222" ./

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ git log --oneline --all
d0a757e (HEAD -> master) 111 222

【创建test分支】

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ git branch test

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ git log --oneline --all
d0a757e (HEAD -> master, test) 111 222

【使用master分支继续开发】

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ vi aaa.txt

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ cat aaa.txt
111aaa
222

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ git commit -m "aaa" ./

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ git log --oneline --all
58c48b6 (HEAD -> master) aaa
d0a757e (test) 111 222

【切换到test分支,使用test分支开发。此时master分支与test分支不同轴】

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ git checkout test
Switched to branch 'test'

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (test)
$ vi aaa.txt

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (test)
$ git commit -m "bbb" ./

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (test)		# 不同轴
$ git log --oneline --all --graph
* 52527cf (HEAD -> test) bbb
| * 58c48b6 (master) aaa
|/
* d0a757e 111 222

【切换到master分支合并test分支的内容,属于不同轴的快进合并,出现代码冲突】

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (test)
$ git checkout master
Switched to branch 'master'

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ git log --oneline --all --graph
* 52527cf (test) bbb
| * 58c48b6 (HEAD -> master) aaa
|/
* d0a757e 111 222

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ git merge test
Auto-merging aaa.txt
CONFLICT (content): Merge conflict in aaa.txt
Automatic merge failed; fix conflicts and then commit the result.

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master|MERGING)
$ cat aaa.txt
<<<<<<< HEAD
111aaa
222
=======
111
222bbb
>>>>>>> test

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master|MERGING)
$ vi aaa.txt

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master|MERGING)
$ cat aaa.txt
111aaa
222bbb

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master|MERGING)
$ git commit -a -m "master合并test分支,并解决冲突"
[master 5c341f6] master合并test分支,并解决冲突

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ git log --oneline --all --graph
*   5c341f6 (HEAD -> master) master合并test分支,并解决冲突
|\
| * 52527cf (test) bbb
* | 58c48b6 aaa
|/
* d0a757e 111 222

【切换回test分支,合并master分支,此时并不会出现代码冲突】

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ git checkout test
Switched to branch 'test'

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (test)
$ git log --oneline --all --graph
*   5c341f6 (master) master合并test分支,并解决冲突
|\
| * 52527cf (HEAD -> test) bbb
* | 58c48b6 aaa
|/
* d0a757e 111 222

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (test)
$ git merge master
Updating 52527cf..5c341f6
Fast-forward
 aaa.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (test)
$ git log --oneline --all --graph
*   5c341f6 (HEAD -> test, master) master合并test分支,并解决冲突
|\
| * 52527cf bbb
* | 58c48b6 aaa
|/
* d0a757e 111 222
2) 典型合并冲突

典型合并只存在于非同轴开发的情况,并且是后面的版本要合并前面的版本;

在非同轴开发的情况下,后面版本的内容未必包含前面版本的内容,两个文件大概率是不一样的,因此典型合并一般情况下都会出现冲突;

master分支test分支
创建abc.txt
内容为:
111
222
执行add
执行commit
创建分支 – 此时test分支的abc.txt的内容也是111、222
修改内容为:
111aaa
222
执行commit
切换到test分支
修改内容为:
111
222bbb
执行commit – 此时test分支和master分支已经不同轴了
合并master分支,属于典型合并,会出现冲突

上面案例属于很常见的==典型合并时的代码冲突==,属于后面的版本合并前面的版本。

【项目初始化】

rm -rf ./* .git
git init
echo "111" >> aaa.txt
echo "222" >> aaa.txt
git add ./
git commit -m "111 222" ./

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ git log --oneline --all --graph
* e8e0f3a (HEAD -> master) 111 222

【创建test分支】

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ git branch test

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ git log --oneline --all --graph
* e8e0f3a (HEAD -> master, test) 111 222

【使用master分支继续开发】

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ vi aaa.txt

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ cat aaa.txt
111aaa
222

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ git commit -m "aaa" ./

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ git log --oneline --all --graph
* ed86aca (HEAD -> master) aaa
* e8e0f3a (test) 111 222

【切换到test分支,继续开发。此时master与test分支不同轴】

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ git checkout test
Switched to branch 'test'

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (test)
$ git log --oneline --all --graph
* ed86aca (master) aaa
* e8e0f3a (HEAD -> test) 111 222

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (test)
$ vi aaa.txt

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (test)
$ git commit -m "bbb" ./

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (test)
$ git log --oneline --all --graph
* 908668e (HEAD -> test) bbb
| * ed86aca (master) aaa
|/
* e8e0f3a 111 222

【使用test分支合并master分支,出现代码冲突】

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (test)
$ git merge master
Auto-merging aaa.txt
CONFLICT (content): Merge conflict in aaa.txt
Automatic merge failed; fix conflicts and then commit the result.

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (test|MERGING)
$ cat aaa.txt
<<<<<<< HEAD
111
222bbb
=======
111aaa
222
>>>>>>> master

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (test|MERGING)
$ vi aaa.txt

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (test|MERGING)
$ cat aaa.txt
111aaa
222bbb

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (test|MERGING)
$ git commit -a -m "test分支合并master分支,并解决冲突"
[test 3cbf22b] test分支合并master分支,并解决冲突

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (test)
$ git log --oneline --all --graph
*   3cbf22b (HEAD -> test) test分支合并master分支,并解决冲突
|\
| * ed86aca (master) aaa
* | 908668e bbb
|/
* e8e0f3a 111 222

【切换回master分支合并test分支,此时并不会出现代码冲突】

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (test)
$ git checkout master
Switched to branch 'master'

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ git merge test

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ git log --oneline --all --graph
*   3cbf22b (HEAD -> master, test) test分支合并master分支,并解决冲突
|\
| * ed86aca aaa
* | 908668e bbb
|/
* e8e0f3a 111 222

1.5.2 远程协作代码冲突

我们在执行push指令之前应该确保当前工作空间分支处于最新状态,因此执行push指令之前我们都会先执行一遍pull指令来拉取远程仓库的代码到本地仓库,以确保当前工作空间的分支是最新的状态;但如果本地仓库的代码与远程仓库的代码不一致,这个时候就会出现代码冲突问题;

观察下面代码流程:

xiaohui用户xiaolan用户
创建abc.txt
内容为:
111
222
执行add、commit、push
clone项目到本地
修改内容为:
111aaa
222
执行commit、push
修改内容为:
111
222bbb
执行commit
执行pull,出现代码冲突
1) 创建远程仓库

【在当前工作空间(xiaohui),初始化本地项目】

rm -rf .git ./*		
git init			
echo "111" >> aaa.txt
git add ./
git commit -m "111" ./
echo "222" >> aaa.txt
git commit -m "222" ./
echo "333" >> aaa.txt
git commit -m "333" ./

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test03 (master)
$ git log --oneline --all --graph
* 792e65d (HEAD -> master) 333
* 61b5869 222
* bcbb013 111

【创建远程仓库】

【推送仓库】

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test03 (master)
$ git remote add origin https://gitee.com/lvshuichangliu/test03.git

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test03 (master)
$ git remote -v
origin  https://gitee.com/lvshuichangliu/test03.git (fetch)
origin  https://gitee.com/lvshuichangliu/test03.git (push)

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test03 (master)
$ git push origin master
2) clone项目

【创建一个xiaolan工作空间,clone项目】

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaolan
$ git clone https://gitee.com/lvshuichangliu/test03.git

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaolan
$ cd test03/

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaolan/test03 (master)
$ git remote -v
origin  https://gitee.com/lvshuichangliu/test03.git (fetch)
origin  https://gitee.com/lvshuichangliu/test03.git (push)

【配置用户信息】

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaolan/test03 (master)
$ git config user.name "xiaolan"			# local配置,只针对当前项目生效,会覆盖global、system配置

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaolan/test03 (master)
$ git config user.email "xiaolan@aliyun.com"

注意:目前在本地存在两个工作副本,但都是使用当前windows凭证所保存的用户来进行拉取、推送操作;虽然用的是同一个账号,但是由于本地仓库的用户信息不同,因此在远程仓库并不能察觉这两个用户是不是使用同一个凭证推送的;

3) 协同开发

使用xiaohui工作空间,开发一些代码,然后提交

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaolan/test03 (master)
$ git log --oneline --all --graph
* 792e65d (HEAD -> master, origin/master, origin/HEAD) 333
* 61b5869 222
* bcbb013 111

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaolan/test03 (master)
$ echo "444" >> aaa.txt

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaolan/test03 (master)
$ git commit -m "444" ./

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaolan/test03 (master)
$ git push origin master

打开远程仓库,查看提交日志:

【在xiaohui工作空间,使用pull拉取代码】

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test03 (master)
$ git pull origin master

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test03 (master)
$ git log --oneline --all --graph
* 4fdb115 (HEAD -> master, origin/master) 444
* 792e65d 333
* 61b5869 222
* bcbb013 111
4) 模拟协同开发冲突

【在xiaohui工作空间编辑代码,然后推送】

文件内容改为:

111aaa
222
333
444

示例:

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test03 (master)
$ vi aaa.txt

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test03 (master)
$ cat aaa.txt
111aaa
222
333
444

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test03 (master)
$ git commit -m "aaa" ./

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test03 (master)			# 推送到远程仓库
$ git push origin master

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test03 (master)
$ git log --oneline --all --graph
* 7813dd8 (HEAD -> master, origin/master) aaa
* 4fdb115 444
* 792e65d 333
* 61b5869 222
* bcbb013 111

【在xiaolan工作空间先编辑文件、提交到本地仓库,然后再拉取远程仓库的代码】

文件内容改为:

111
222bbb
333
444

Tips:执行push必须保证本地仓库的代码是最新版本,否则不能执行push命令,因此我们执行push指令之前要先执行一遍pull命令

示例:

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaolan/test03 (master)
$ vi aaa.txt

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaolan/test03 (master)
$ cat aaa.txt
111
222bbb
333
444

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaolan/test03 (master)
$ git commit -m "bbb" ./

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaolan/test03 (master)		# 执行push必须保证本地代码是最新版本
$ git push origin master
To https://gitee.com/lvshuichangliu/test03.git
 ! [rejected]        master -> master (fetch first)
error: failed to push some refs to 'https://gitee.com/lvshuichangliu/test03.git'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.


Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaolan/test03 (master)			# 执行pull,出现代码冲突
$ git pull origin master
remote: Enumerating objects: 5, done.
remote: Counting objects: 100% (5/5), done.
remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (3/3), 229 bytes | 19.00 KiB/s, done.
From https://gitee.com/lvshuichangliu/test03
 * branch            master     -> FETCH_HEAD
   4fdb115..7813dd8  master     -> origin/master
Auto-merging aaa.txt
CONFLICT (content): Merge conflict in aaa.txt
Automatic merge failed; fix conflicts and then commit the result.

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaolan/test03 (master|MERGING)
$ cat aaa.txt
<<<<<<< HEAD
111
222bbb
=======
111aaa
222
>>>>>>> 7813dd8184245cca013458aa0292696ebb3ba4fe
333
444

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaolan/test03 (master|MERGING)
$ git log --oneline --all --graph
* 0061a58 (HEAD -> master) bbb						# 已经成功拉取远程仓库的代码到本地了(只不过还有冲突需要解决),产生了一个新的版本
| * 7813dd8 (origin/master, origin/HEAD) aaa
|/
* 4fdb115 444
* 792e65d 333
* 61b5869 222
* bcbb013 111

【解决代码冲突,然后再推送】

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaolan/test03 (master|MERGING)			# 解决代码冲突
$ vi aaa.txt

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaolan/test03 (master|MERGING)
$ cat aaa.txt
111aaa
222bbb
333
444

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaolan/test03 (master|MERGING)
$ git commit -a -m "执行pull,出现冲突,并且已经解决冲突"			# 解决冲突,产生了一个新的版本
[master f4b7445] 执行pull,出现冲突,并且已经解决冲突

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaolan/test03 (master)
$ git log --oneline --all --graph
*   f4b7445 (HEAD -> master) 执行pull,出现冲突,并且已经解决冲突
|\
| * 7813dd8 (origin/master, origin/HEAD) aaa
* | 0061a58 bbb
|/
* 4fdb115 444
* 792e65d 333
* 61b5869 222
* bcbb013 111

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaolan/test03 (master)		# 解决完冲突后,提交到远程仓库
$ git push origin master

【使用xiaohui工作空间,拉取最新代码】

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test03 (master)		# 拉取之前的日志
$ git log --oneline --all --graph
* 7813dd8 (HEAD -> master, origin/master) aaa
* 4fdb115 444
* 792e65d 333
* 61b5869 222
* bcbb013 111

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test03 (master)		# 拉取代码
$ git pull origin master

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test03 (master)		# 已经成功拉取下来了
$ cat aaa.txt
111aaa
222bbb
333
444

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test03 (master)		# 拉取之后的日志
$ git log --oneline --all --graph
*   f4b7445 (HEAD -> master, origin/master) 执行pull,出现冲突,并且已经解决冲突
|\
| * 7813dd8 aaa
* | 0061a58 bbb
|/
* 4fdb115 444
* 792e65d 333
* 61b5869 222
* bcbb013 111

二、TortoiseGit的使用

Git 我们在前面的教程中已经介绍了, 它是一个强大的版本控制系统,但我们每次都在bash中通过指令操作,这无疑是在考验我们的记忆力,因此我们迫切的需要一款图形界面软件,安装Git时自带的Git GUI就是这样一款软件,但是我们这里要介绍更好用的一款Git客户端软件,它就是TortoiseGit

TortoiseGit是Git版本控制系统的客户端,它是开源且免费的,文件存储在本地存储库中,存储库很像普通的文件服务器,除了它会记住对文件和目录所做的每一次更改,这使您可以恢复文件的旧版本并检查数据更改方式和时间以及更改者的历史记录。

安装好TortoiseGit之后,查看右键菜单:

点击Settings,打开Git全局配置,配置用户信息:

2.1 TortoiseGit 的基本使用

2.1.1 创建仓库

  • Git命令:
git init

在一个工作空间右击菜单,选择Git Create repository here...

仓库创建成功:

2.1.2 添加

  • Git命令:
git add { 文件 | 文件夹}

创建文件,文件内容为:111,然后右击鼠标:

2.1.3 提交

  • Git命令:
git commit -m {注释} { 文件 | 文件夹}

我们暂时不推送到远程仓库,直接点击close按钮;

2.1.4 对比

  • Git命令:
git diff							# 对工作空间和暂存区的内容
git diff [ --cached | --staged]		# 对比暂存区和版本库的内容

注意:TortoiseGit只能对比工作空间和版本库的内容,不能对比暂存区的内容;

打开Git Bash Here控制台,编辑文件:

echo "222" >> aaa.txt

使用TortoiseGit对比工作空间和版本库的内容:

提交文件

git commit -m "222" ./

2.1.5 查看状态

Git的工作空间有四种状态,分别为:

  • nothing to commit : 表示当前工作空间没有还未提交的操作,属于一个干净的工作空间;(工作空间的所有文件均已提交)
  • Untracked files :表示当前空间空间有文件文件处于"未追踪"状态,需要使用add命令添加;(工作空间中含有没有执行add的文件)
  • Changes to be committed : 表示更改的操作已经被追踪到了,但操作还未被提交;(修改的文件执行了add操作,但是还未提交)
  • Changes not staged for commit : 表示当前工作目录中有文件被修改了,但是还未被Git追踪到;需要使用add命令来追踪(已经执行过add的文件被修改但了还未执行add操作)

但这四种状态在TortoiseGit中为:

  • Changes not staged for commit --> Modified
  • Untracked files -> Unknown
  • Changes to be committed -> Added

【代码示例】

编辑aaa.txt文件(Changes not staged for commit):

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ echo "333" >> aaa.txt

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ git status
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   aaa.txt

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

查看日志:

日志窗口:

提交操作:

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ git commit -m "333" ./

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ git status
On branch master
nothing to commit, working tree clean

日志窗口:

新增一个bbb.txt文件(Untracked files ):

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ echo "111" >> bbb.txt

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ git status
On branch master
Untracked files:
  (use "git add <file>..." to include in what will be committed)
        bbb.txt

日志窗口:

将操作添加到暂存区(Changes to be committed):

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ git add ./

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ git status
On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        new file:   bbb.txt

日志窗口:

提交操作:

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ git commit -m "111-bbb" ./

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ git status
On branch master
nothing to commit, working tree clean

日志窗口:

2.1.6 改名

  • Git命令:
git mv newName oldName

使用TortoiseGit操作:

查看Git状态:

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ git status
On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        renamed:    aaa.txt -> ccc.txt

Changes to be committed : 有修改的操作已经被追踪,但还未提交;

查看日志:

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ git log --oneline --all
d52d172 (HEAD -> master) 将aaa.txt文件修改为ccc.txt文件
5b4b6a7 111-bbb
f3d0218 333
c301016 222
43e816b 111

Tips:查看TortoiseGit日志也是一样的效果

2.1.6 删除

  • Git命令:
git rm { 文件 | 文件夹 }

使用TortoiseGit操作:

查看Git状态,提交:

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ git status
On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        deleted:    ccc.txt


Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ git commit -m "删除ccc.txt文件" ./
[master dd499de] 删除ccc.txt文件
 1 file changed, 3 deletions(-)
 delete mode 100644 ccc.txt

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ git log --oneline --all
dd499de (HEAD -> master) 删除ccc.txt文件
d52d172 将aaa.txt文件修改为ccc.txt文件
5b4b6a7 111-bbb
f3d0218 333
c301016 222
43e816b 111

2.1.7 日志

右击查询日志:

日志查询面板:

2.1.7 还原

使用Git语法可以还原工作空间、暂存区、提交对象;其中还原提交对象分为修正提交日志、修正提交内容、修正提交文件;

1) 还原工作空间
  • Git命令:
git restore {文件|目录}					# 还原工作空间
git restore --staged {文件|目录}		# 仅还原暂存区,该命令不会还原工作空间

git commit --amend -m "注释"				# 还原(重置)提交对象信息
  • 编辑文件:
Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ echo "222-bbb" >> bbb.txt

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ git status
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   bbb.txt

再次查看工作空间状态:

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ git status
On branch master
nothing to commit, working tree clean
2) 还原提交对象
  • 语法:
git commit --amend -m "注释"				# 还原(重置)提交对象信息

【修正提交日志】

编辑文件提交:

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master|REVERTING)
$ echo "222 333" >> bbb.txt

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master|REVERTING)
$ git commit -m "222" ./

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ git log --oneline --all
9330e37 (HEAD -> master) 222
dd499de 删除ccc.txt文件
d52d172 将aaa.txt文件修改为ccc.txt文件
5b4b6a7 111-bbb
f3d0218 333
c301016 222
43e816b 111

查看日志:

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ git log --oneline --all
6a7f91f (HEAD -> master) 222 333			# 修改了日志
dd499de 删除ccc.txt文件
d52d172 将aaa.txt文件修改为ccc.txt文件
5b4b6a7 111-bbb
f3d0218 333
c301016 222
43e816b 111

【修正提交内容】

修改提交内容:

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ cat bbb.txt
111
222 333

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ vi bbb.txt

再次查看日志:

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)		# 并没有增加日志
$ git log --oneline --all
49129dd (HEAD -> master) 222 333
dd499de 删除ccc.txt文件
d52d172 将aaa.txt文件修改为ccc.txt文件
5b4b6a7 111-bbb
f3d0218 333
c301016 222
43e816b 111

【修改提交文件】

新建一个文件:

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ echo "000" >> new.txt

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ git add ./
warning: LF will be replaced by CRLF in new.txt.
The file will have its original line endings in your working directory

再次查看日志:

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)		# 并没有新增日志
$ git log --oneline --all
ba1ff26 (HEAD -> master) bbb.txt文件的内容新增了222、333 新增了一个new.txt文件		# 日志更新了
dd499de 删除ccc.txt文件
d52d172 将aaa.txt文件修改为ccc.txt文件
5b4b6a7 111-bbb
f3d0218 333
c301016 222
43e816b 111

2.1.8 回退

Git命令:

  • 只移动HEAD,不改变暂存区和工作空间
git reset --soft {CommitHash}		# 回退到指定的Commit对象

git reset --soft HEAD~				# 回退到上一个版本	
git reset --soft HEAD~~				# 回退到上上个版本
  • 移动HEAD、更改暂存区,不改变工作空间
git reset --mixed HEAD~				# 回退到上一个版本
git reset --mixed HEAD~~			# 回退到上上一个版本

git reset --mixed {CommitHash}		# 回退到指定的Commit对象
  • 移动HEAD、更改暂存区、更改工作空间
git reset --hard HEAD~				# 回退到上一个版本
git reset --hard HEAD~~			# 回退到上上一个版本

git reset --hard {CommitHash}		# 回退到指定的Commit对象

初始化一个新的项目:

rm -rf ./* .git
git init
echo '111' >> aaa.txt
git add ./
git commit -m '111' ./
echo "222" >> aaa.txt
git add ./
git commit -m "222" ./
echo "333" >> aaa.txt
git add ./
git commit -m "333" ./

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ git log --oneline --all
12f7e5d (HEAD -> master) 333
00d4ac3 222
3adc1b0 111

打开日志窗口,进行回退:

1)回退HEAD指针

查看日志:

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)		# 查看日志
$ git log --oneline --all
00d4ac3 (HEAD -> master) 222		# HEAD指针发生变化了
3adc1b0 111

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)		# 查看暂存区
$ git ls-files -s
100644 641d57406d212612a9e89e00db302ce758e558d2 0       aaa.txt

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ git cat-file -p 641d574			# 暂存区并没有改变
111
222
333

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)		# 工作空间也没有改变
$ cat aaa.txt
111
222
333
2)回退HEAD指针、暂存区

使用同样的办法回到333版本:

然后再回到222版本:

查看日志:

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)		# 指针改变了
$ git log --oneline --all			
00d4ac3 (HEAD -> master) 222
3adc1b0 111

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ git ls-files -s
100644 a30a52a3be2c12cbc448a5c9be960577d13f4755 0       aaa.txt

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)		# 暂存区也改变了
$ git cat-file -p a30a52
111
222

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)		# 工作空间没有改变
$ cat aaa.txt
111
222
333
3)回退HEAD指针、暂存区、工作空间

使用同样的办法回到333版本,然后再回到222版本:

查看日志:

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)		# HEAD指针变了
$ git log --oneline --all
00d4ac3 (HEAD -> master) 222		
3adc1b0 111

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ git ls-files -s
100644 a30a52a3be2c12cbc448a5c9be960577d13f4755 0       aaa.txt		

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)		# 暂存区变了
$ git cat-file -p a30a52
111
222

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)		# 工作空间也变了
$ cat aaa.txt
111
222

2.1.9 添加忽略

2.2 TortiseGit操作分支

【初始仓库】

rm -rf ./* .git
git init
echo '111' >> aaa.txt
git add ./
git commit -m '111' ./
echo "222" >> aaa.txt
git add ./
git commit -m "222" ./
echo "333" >> aaa.txt
git add ./
git commit -m "333" ./

2.2.1 创建分支

直接创建:

指定日志来创建分支:

查看日志:

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ git log --oneline --all
2c38cda (HEAD -> master, b1) 333
edb3b67 222
51e4674 111

2.2.2 切换分支

查看日志:

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ git log --oneline --all
2c38cda (HEAD -> b1, master) 333
edb3b67 222
51e4674 111

Tips:注意新分支和新文件切换分支带来的工作空间及暂存区的影响;

2.2.3 合并分支

使用master分支开发:

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ echo "333" >> aaa.txt

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ git commit -m "333" ./

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ git log --oneline --all
c038a5e (HEAD -> master) 333
2c38cda (b1) 333
edb3b67 222
51e4674 111

首先先切换到b1分支,使用ToritoseGit合并分支:

查看日志:

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (b1)
$ git log --oneline --all
c038a5e (HEAD -> b1, master) 333
2c38cda 333
edb3b67 222
51e4674 111

2.2.3 分支合并冲突

分支合并冲突分为快进合并冲突和典型合并冲突,TortoiseGit解决冲突的方式都是一样的,我们本章只演示快进合并冲突;

【初始化仓库,准备快进合并冲突案例】

rm -rf ./* .git
git init
echo "111" >> aaa.txt
echo "222" >> aaa.txt
git add ./
git commit -m "111 222" ./
git branch b1

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ vi aaa.txt

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ cat aaa.txt
111aaa
222

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ git commit -m "aaa" ./

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ git checkout b1
Switched to branch 'b1'

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (b1)
$ vi aaa.txt

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (b1)
$ cat aaa.txt
111
222bbb

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (b1)
$ git commit -m "bbb" ./

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (b1)
$ git checkout master
Switched to branch 'master'

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)		# 非同轴开发的快进合并
$ git log --oneline --all --graph
* b33f9b6 (b1) bbb
| * b9f54a5 (HEAD -> master) aaa
|/
* ae8933b 111 222

使用TortoiseGit合并:

编辑冲突文件:

解决冲突:

提交:

查看日志:

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master|MERGING)
$ git log --oneline --all --graph
*   8eac439 (HEAD -> master) b1合并master分支,并解决冲突
|\
| * b33f9b6 (b1) bbb
* | b9f54a5 aaa
|/
* ae8933b 111 222

2.2.4 分支状态存储

1) 使用存储

编辑文件:

echo "666" >> aaa.txt

使用Git存储:

查看git工作空间状态,发现变为干净状态:

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ git status
On branch master
nothing to commit, working tree clean

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)			# 文件并没有666内容
$ cat aaa.txt
111aaa
222bbb
2) 查看存储

3) 读取存储

查看日志:

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)		# 工作区的状态
$ git status
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   aaa.txt

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

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)		# 文件内容又回来了
$ cat aaa.txt
111aaa
222bbb
666

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)		# 提交内容
$ git commit -m "666" ./
[master ca32a2c] 666
 1 file changed, 1 insertion(+)

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ git status
On branch master
nothing to commit, working tree clean
4) 删除存储

2.3 TortiseGit协同开发

【初始化项目库】

rm -rf .git ./*		
git init			
echo "111" >> aaa.txt
git add ./
git commit -m "111" ./
echo "222" >> aaa.txt
git commit -m "222" ./
echo "333" >> aaa.txt
git commit -m "333" ./

创建一个远程仓库:

2.3.1 remote

  • 语法:
# 查看所有别名
git remote -v 

# 为一个远程仓库起一个别名
git remote add {remote-name} {url}	

# 查看指定的远程仓库的详细信息
git remote show {remote-name | url}

# 重命名别名
git remote rename {old-remote-name} {new-remote-name} 

# 删除别名
git remote rm {remote-name}

使用TortoiseGit:

查看日志:

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ git remote -v
test05  https://gitee.com/lvshuichangliu/test05.git (fetch)
test05  https://gitee.com/lvshuichangliu/test05.git (push)

2.3.2 push

  • 语法:
# 将本地仓库推送到远程仓库
    # branchName: 本地分支的名称
    # remoteBranchName: 远程分支的名称
git push { url | remoteName } [branchName[:remoteBranchName]]

# 将本地仓库推送到远程仓库(本地分支和远程分支名称一致的情况)
git push { url | remoteName } branchName

# 将本地仓库推送到远程仓库(操作的分支是master的情况下)
git push { url | remoteName }

使用TortoiseGit:

推送成功:

查看日志:

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ git log --oneline --all
2926c83 (HEAD -> master, test05/master) 333		# 创建了远程跟踪分支
9ddd8f5 222
bfd0f29 111

2.2.3 clone

  • 语法:
# 克隆远程仓库到本地
git clone {url}

# 默认情况下克隆到本地的项目名称和远程库一样,如果想要自己指定名称可以在后面指定项目的名称
git clone {url} {projectName}

在一个新的工作空间【xiaolan】clone远程仓库到本地:

查看日志:

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaolan/test05 (master)
$ git log --oneline --all
2926c83 (HEAD -> master, origin/master, origin/HEAD) 333		# 创建了远程跟踪分支
9ddd8f5 222
bfd0f29 111

2.3.4 fetch

  • 语法:
# 拉取远程仓库的代码到本地的远程跟踪分支
    # branchName: 本地分支名称
    # remoteBranchName: 远程分支名称
git fetch { url | remoteName } [branchName[:remoteBranchName]]

# 拉取远程仓库的代码到本地的远程跟踪分支(本地分支和远程分支名称一致的情况)
git fetch { url | remoteName } [branchName]

# 拉取远程仓库的代码到本地的远程跟踪分支(操作的分支是master的情况下)
git fetch { url | remoteName }

首先使用xiaohui工作空间编辑代码,提交,然后推送到远程仓库:

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ echo "444" >> aaa.txt

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ git commit -m "444" ./

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ git push test05 master

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ git log --oneline --all
75a91c9 (HEAD -> master, test05/master) 444
2926c83 333
9ddd8f5 222
bfd0f29 111

在xiaolan工作空间使用TortoiseGit的fetch命令拉取远程仓库的代码:

查看日志:

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaolan/test05 (master)
$ git log --oneline --all
75a91c9 (origin/master, origin/HEAD) 444			# 代码被拉取到远程跟踪分支上了
2926c83 (HEAD -> master) 333
9ddd8f5 222
bfd0f29 111

合并远程分支的代码:

查看日志:

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaolan/test05 (master)
$ git log --oneline --all
75a91c9 (HEAD -> master, origin/master, origin/HEAD) 444
2926c83 333
9ddd8f5 222
bfd0f29 111

2.3.5 pull

  • 语法:
# 拉取代码到本地分支并将本地分支与远程跟踪分支合并
    # branchName: 本地分支的名称
    # remoteBranchName: 远程分支的名称
git pull { url | project-name} [branchName[:remoteBranchName]]

# 拉取代码到本地分支并将本地分支与远程跟踪分支合并(本地分支和远程分支名称一致的情况)
git pull { url | project-name} [branchName]

# 拉取代码到本地分支并将本地分支与远程跟踪分支合并(操作的分支是master的情况下)
git pull { url | project-name}

使用xiaohui工作空间编辑代码,提交,推送:

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ echo "555" >> aaa.txt

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ git commit -m "555" ./

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ git push test05 master

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ git log --oneline --all
1f665de (HEAD -> master, test05/master) 555
75a91c9 444
2926c83 333
9ddd8f5 222
bfd0f29 111

在xiaolan工作空间使用TortoiseGit的pull命令来拉取代码:

查看xiaolan工作空间的日志:

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaolan/test05 (master)
$ git log --oneline --all
1f665de (HEAD -> master, origin/master, origin/HEAD) 555			# 代码不仅拉取到了远程跟踪分支上,并且master分支已经合并了远程跟踪分支的代码
75a91c9 444
2926c83 333
9ddd8f5 222
bfd0f29 111

2.3.6 模拟协同开发冲突

使用xiaohui工作空间编辑代码,提交,推送:

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ echo "666" >> aaa.txt

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ git commit -m "666" ./

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ git push test05 master

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/test01 (master)
$ git log --oneline --all
0dd8aff (HEAD -> master, test05/master) 666
1f665de 555
75a91c9 444
2926c83 333
9ddd8f5 222
bfd0f29 111

在xiaolan工作空间,编辑代码,然后执行pull:

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaolan/test05 (master)
$ echo "777" >> aaa.txt

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaolan/test05 (master)
$ git commit -m "777" ./

查看xiaolan工作空间日志:

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaolan/test05 (master|MERGING)
$ git log --oneline --all
d5c2102 (HEAD -> master, origin/master, origin/HEAD) 拉取代码时出现冲突,已经解决冲突
626b865 777
0dd8aff 666
1f665de 555
75a91c9 444
2926c83 333
9ddd8f5 222
bfd0f29 111

三、IDEA集成Git插件

3.1 Git插件的基本使用

首先一定要配置Git的一些基本信息:

# 配置用户信息,如果已经配置将会覆盖
git config --global user.name "xiaohui"
git config --global user.email "xiaohui@aliyun.com"

3.1.1 提交项目

1)绑定Git插件

1)打开Settings—>Version Control—>Git;选择Git命令

2)打开VCS—>Enable Version Control Integration...;开启版本控制:

3)选择Git:

4)添加成功:

2)添加忽略文件

Tips:有的时候在.gitignore文件中添加了忽略文件,但并没有以暗黄色显示这些文件,需要关闭项目重新打开;

3)提交项目

提交成功:

如果不想在idea中看到被忽略的文件,我们可以打开Settings—>Editor—>File Types

选择要忽略的文件:

3.1.2 比较

将文件内容编辑为:

public class Main {
    public static void main(String[] args) {
        System.out.println("Hello world!");
        System.out.println(111);
    }
}

Tips:IDEA的Git插件只能对比工作空间和版本库中的文件,不能对比暂存区的;

查看对比:

3.1.3 还原

1)还原工作空间
  • Git语法:
git restore {文件|目录}					# 还原工作空间
git restore --staged {文件|目录}		# 仅还原暂存区,该命令不会还原工作空间
git commit --amend -m "注释"				# 还原(重置)提交对象信息

编辑Main.java文件(不能提交),然后右击Git–>Rollback...

然后查看文件,发现之前编辑的内容被撤销了;

2)还原提交对象

还原提交对象主要有三种:提交日志修正、提交内容修正、提交文件修正;

  • Git语法:
git commit --amend -m "注释"				# 还原(重置)提交对象信息

【编辑文件】

public class Main {
    public static void main(String[] args) {
        System.out.println("Hello world!");
        System.out.println(111);
        System.out.println(222);
        System.out.println(333);
    }
}

提交;

重新提交:

重新查看日志:

该操作同样适用于修正文件内容,修正提交文件等;只需要在提交的时候勾选Amend本次提交就会自动和上一个提交合并,生成一条提交日志;

3.1.4 回退

Git语法:

  • 只移动HEAD,不改变暂存区和工作空间
git reset --soft {CommitHash}		# 回退到指定的Commit对象

git reset --soft HEAD~				# 回退到上一个版本	
git reset --soft HEAD~~				# 回退到上上个版本
  • 移动HEAD、更改暂存区,不改变工作空间
git reset --mixed HEAD~				# 回退到上一个版本
git reset --mixed HEAD~~			# 回退到上上一个版本

git reset --mixed {CommitHash}		# 回退到指定的Commit对象
  • 移动HEAD、更改暂存区、更改工作空间
git reset --hard HEAD~				# 回退到上一个版本
git reset --hard HEAD~~			# 回退到上上一个版本

git reset --hard {CommitHash}		# 回退到指定的Commit对象
1)回退HEAD指针

在文件上右击Git—>Reset HEAD...

选择回退的版本:

查看Git日志,发现HEAD指针移动了:

可以查看暂存区和工作空间,发现都没有变化:

【暂存区】

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/Project (master)
$ git ls-files -s
100644 82b7e88a225af2f782bc913c3c518b259bca6f5d 0       .gitignore
100644 aeeaf8f581fa1f1d7f1c7721c5560f251517a599 0       src/Main.java

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/Project (master)
$ git cat-file -p aeeaf8f581fa1f1d7f1c7721c5560f251517a599
public class Main {
    public static void main(String[] args) {
        System.out.println("Hello world!");
        System.out.println(111);
        System.out.println(222);
        System.out.println(333);
    }
}

【工作空间】

可以使用git命令查看reflog日志:

重新回退:

2)回退HEAD、暂存区

查看日志:

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/Project (master)		# HEAD指针移动了
$ git log --oneline --all
fb3bce1 (HEAD -> master) 新增功能111
cdc90be 初始化项目

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/Project (master)
$ git ls-files -s
100644 82b7e88a225af2f782bc913c3c518b259bca6f5d 0       .gitignore
100644 6f5d1f47dc1d0ce1981fc68b8d202980e6824cae 0       src/Main.java

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/Project (master)		# 暂存区的内容变化了
$ git cat-file -p 6f5d1f47dc1d0ce1981fc68b8d202980e6824cae
public class Main {
    public static void main(String[] args) {
        System.out.println("Hello world!");
        System.out.println(111);
    }
}

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/Project (master)		# 工作空间没有变化
$ cat src/Main.java
public class Main {
    public static void main(String[] args) {
        System.out.println("Hello world!");
        System.out.println(111);
        System.out.println(222);
        System.out.println(333);
    }
}

回退到最新版本:

查看Git日志:

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/Project (master)
$ git log --oneline --all
f15afdb (HEAD -> master) 新增功能222和333
fb3bce1 新增功能111
cdc90be 初始化项目
3)回退HEAD、暂存区、工作空间

查看Git日志:

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/Project (master)		# HEAD指针移动了
$ git log --oneline --all
fb3bce1 (HEAD -> master) 新增功能111
cdc90be 初始化项目

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/Project (master)
$ git ls-files -s
100644 82b7e88a225af2f782bc913c3c518b259bca6f5d 0       .gitignore
100644 6f5d1f47dc1d0ce1981fc68b8d202980e6824cae 0       src/Main.java

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/Project (master)		# 暂存区变化了
$ git cat-file -p 6f5d1f47dc1d0ce1981fc68b8d202980e6824cae
public class Main {
    public static void main(String[] args) {
        System.out.println("Hello world!");
        System.out.println(111);
    }
}
Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/Project (master)		# 工作空间变化了
$ cat src/Main.java
public class Main {
    public static void main(String[] args) {
        System.out.println("Hello world!");
        System.out.println(111);
    }
}

回退到最新版本:

查看日志:

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/Project (master)
$ git log --oneline --all
f15afdb (HEAD -> master) 新增功能222和333
fb3bce1 新增功能111
cdc90be 初始化项目

3.2 分支的操作

3.2.1 创建分支

在项目上右击—>Git—>Branches...

默认在当前HEAD指针位置创建,并且自动切换到该分支:

也可以在指定的版本上右击来创建分支:

3.2.2 切换分支

3.3.2 合并分支

  • 修改master分支的Main.java文件,然后提交:
public class Main {
    public static void main(String[] args) {
        System.out.println("Hello world!");
        System.out.println(111);
        System.out.println(222);
        System.out.println(333);
        System.out.println(444);
    }
}

切换到b1分支,合并master分支的内容:

b1分支合并前的内容:

public class Main {
    public static void main(String[] args) {
        System.out.println("Hello world!");
        System.out.println(111);
        System.out.println(222);
        System.out.println(333);
    }
}

b1分支的Main.java:

3.3.3 合并分支解决冲突

修改b1分支的内容,然后提交:

public class Main {
    public static void main(String[] args) {
        System.out.println("Hello world!");
        System.out.println(111);
        System.out.println(222);
        System.out.println(333);
        System.out.println(444);
        System.out.println(555);
    }
}

切换到master分支,修改master分支的内容,然后提交:

public class Main {
    public static void main(String[] args) {
        System.out.println("Hello world!");
        System.out.println(111);
        System.out.println(222);
        System.out.println(333);
        System.out.println(444);
        System.out.println(666);
    }
}

使用master分支合并b1分支的内容:

解决冲突:

合并完成,填写日志提交:

3.3.4 使用分支状态存储

添加自己的功能,但还未完成:

public class Main {
    public static void main(String[] args) {
        System.out.println("Hello world!");
        System.out.println(111);
        System.out.println(222);
        System.out.println(333);
        System.out.println(444);
        System.out.println(555);
        System.out.println(666);
        System.out.println(777);
    }
}

使用Git分支存储先将这个状态存储起来:

工作空间也是干净的状态:

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace/xiaohui/Project (master)
$ git status
On branch master
nothing to commit, working tree clean

可以继续编辑文件,处理临时任务:

public class Main {
    public static void main(String[] args) {
        System.out.println("Hello world!");
        System.out.println(111);
        System.out.println(222);
        System.out.println(333);
        System.out.println(444);
        System.out.println(555);
        System.out.println(666);
        System.out.println(888);
        System.out.println(999);
    }
}

提交;

查看日志:

读取存储:

查看日志:

3.3 协同开发

首先在Gitee创建一个仓库:

3.3.1 remote

打开菜单栏中的Git—>Manage Remotes

3.3.2 push

在项目上右击—>Git—>Push...

查看远程仓库:

推送成功后,查看Git日志,发现master的远程跟踪分支创建成功:

通过Gi命令查看日志:

Tips:刚刚使用push命令仅仅是把master分支推送到远程仓库了,b1和b2分支并没有推送到远程仓库,因此没有创建b1和b2分支的远程跟踪分支

3.3.3 clone

点击菜单栏上的File—>New—>Project from Version Control...

克隆好了之后,发现创建了master对应的远程跟踪分支:

3.3.4 fetch

  • 1)在xiaohui工作空间创建Demo01.java文件,内容如下:
public class Demo01 {
    public static void main(String[] args) {
        System.out.println(111);
    }
}

然后执行add、commit、push;

  • 2)在xiaolan工作空间执行fetch:

查看Git日志,新功能在远程跟踪分支origin/master上,本地分支还在之前的位置:

使用本地分支合并远程跟踪分支的内容,将功能集成到本地分支上:

合并成功:

3.3.5 pull

  • 1)在xiaohui空间编辑代码:
public class Demo01 {
    public static void main(String[] args) {
        System.out.println(111);
        System.out.println(222);
    }
}

提交、推送;

  • 2)在xiaolan工作空间执行pull操作:

查看Git日志和工作空间:

3.3.6 模拟协同开发

1) push冲突
  • 1)在xiaolan工作空间编辑代码:
public class Demo01 {
    public static void main(String[] args) {
        System.out.println(111);
        System.out.println(222);
        System.out.println(333);
    }
}

提交、推送;

  • 2)在xiaolan工作空间编辑代码:
public class Demo01 {
    public static void main(String[] args) {
        System.out.println(111);
        System.out.println(222);
        System.out.println(444);
    }
}

提交,推送,出现如下冲突:

Tips:在使用Git原始命令时,如果本地仓库的版本不是最新版本则不允许执行push,但IDEA做了优化,本地仓库即使不是最新版本也允许提交,但可能会出现冲突;

解决冲突:

解决冲突:

点击保存后,自动产生了一条提交记录,提交日志是默认的:

我们可以使用amend来修改提交日志:

查看新的日志:

重新推送到远程仓库:

本次是产生了两个版本,一个是提交444功能的,另一个是推送到远程仓库出现问题然后合并远程仓库内容之后产生的一个版本

在xiaolan工作空间执行pull命令:

2) pull冲突
  • 1)在xiaohui工作空间编辑代码:
public class Demo01 {
    public static void main(String[] args) {
        System.out.println(111);
        System.out.println(222);
        System.out.println(333);
        System.out.println(444);
        System.out.println(555);
    }
}

提交、推送;

  • 2)在xiaolan工作空间编辑代码:
public class Demo01 {
    public static void main(String[] args) {
        System.out.println(111);
        System.out.println(222);
        System.out.println(333);
        System.out.println(444);
        System.out.println(666);
    }
}

提交到本地仓库,然后执行pull确保本地仓库是最新的版本,但是执行完pull之后出现冲突:

解决冲突:

解决冲突之后,和之前一样还是产生了一条新的提交记录,提交日志是默认的:

我们可以使用amend来修改提交日志:

查看最新日志:

推送到远程仓库:

本次操作同样是产生了两个版本,一个是本身自己提交的666功能,另一个是合并远程仓库代码是产生冲突之后解决冲突生成的一个版本;

在xiaohui空间使用pull拉取最新代码:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/126553.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

解决:AttributeError: ‘WebDriver‘ object has no attribute ‘find_element_by_xpath‘

解决&#xff1a;AttributeError: ‘WebDriver’ object has no attribute ‘find_element_by_xpath’ 背景 在使用之前的代码通过selenium定位元素时&#xff0c;报错&#xff1a;selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to l…

Altium Designer学习笔记1

一、新建项目和文件&#xff1a; 1、新建Project项目&#xff1b; 2、新建原理图文件&#xff1b; 3、新建PCB项目&#xff1b; 在工程文件上点击右键&#xff0c;保存为&#xff0c;可以依次保存三个文件。选择需要保存的路径&#xff0c;新建文件夹。 依次是原理图文件、…

如何用Java高效地存入一万条数据?这可能是你面试成功的关键!

大家好&#xff0c;我是你们的小米&#xff0c;一个热爱技术、喜欢分享的29岁程序猿。今天我要和大家聊一聊一个常见的面试题&#xff1a;在Java中&#xff0c;当我们需要将一万条数据存储到数据库时&#xff0c;如何能够提高存储效率呢&#xff1f; 在面试过程中&#xff0c;…

事务(本地事务与分布式事务)

事务 1 本地事务1.1 事务的特性1.2 事务的隔离级别1.3 事务的传播属性 2 分布式事务2.1 分布式事务基础2.1.1 CAP定理2.1.2 BASE定理 2.2 分布式事务的解决方案2.2.1 两阶段提交&#xff08;2PC&#xff09;2.2.2 TCC补偿式事务2.2.3 消息事务最终一致性 1 本地事务 1.1 事务的…

Mysql视图应用

现在&#xff0c;我们将创建一个视图&#xff0c;将员工的姓名、部门和工资信息组合在一起。 CREATE VIEW EmployeeSalaryView AS SELECT e.FirstName, e.LastName, e.Department, s.MonthlySalary FROM Employees e JOIN Salary s ON e.EmployeeID s.EmployeeID;通过这个视图…

SQLChat 的 RBAC 之旅

去年 ChatGPT 在科技圈大火&#xff0c;到今年彻底破圈。各个领域都有相应的一些产品&#xff0c;数据库领域集中在 AI SQL&#xff0c;自然语言转 SQL&#xff0c;或者利用自然语言来管理数据库等。今天我们来体验一下该领域的 SQLChat 这款 AI 数据库客户端。 今天我们预设一…

招聘信息采集

首先&#xff0c;我们需要使用PHP的curl库来发送HTTP请求。以下是一个基本的示例&#xff1a; <?php // 初始化curl $ch curl_init();// 设置代理 curl_setopt($ch, CURLOPT_PROXY, "jshk.com.cn");// 设置URL curl_setopt($ch, CURLOPT_URL, "http://www…

不同语言采集【淘宝1688拼多多API】平台数据的方式

首先我们以taobao商品页面采集商品详情数据为例&#xff1a; 请求方式&#xff1a;HTTPS POST GET 请求地址&#xff1a;API接口 请求参数 请求参数&#xff1a;num_iid669646899650&is_promotion1 参数说明&#xff1a;num_iid:淘宝商品ID is_promotion:是否获取取…

web前端JS基础------制作一个获取验证码

1&#xff0c;需要一个定时器&#xff0c;和一个button&#xff0c;通过点击事件启动获取验证码 2&#xff0c;参考代码如下 <!DOCTYPE html> <html><head><meta charset"utf-8"><title></title></head><body><…

RapidSSL证书

RapidSSL是一家经验丰富的证书颁发机构&#xff0c;主要专注于提供标准和通配符SSL证书的域验证SSL证书。在2017年被DigicertCA收购后&#xff0c;RapidSSL改进了技术并开始使用现代基础设施。专注于为小型企业和网站提供基本安全解决方案的SSL加密。RapidSSL它具有强大的浏览器…

Python中的Socket编程

目录 一、概述 二、Socket的基本概念 三、Python中的Socket编程 四、Socket的高级功能 1、多路复用&#xff08;multiplexing&#xff09;&#xff1a; 2、非阻塞式IO&#xff1a; 3、SSL加密&#xff1a; 4、服务端编程&#xff1a; 五、Socket编程的常见问题及解决方…

基于Quartz实现动态定时任务

生命无罪&#xff0c;健康万岁&#xff0c;我是laity。 我曾七次鄙视自己的灵魂&#xff1a; 第一次&#xff0c;当它本可进取时&#xff0c;却故作谦卑&#xff1b; 第二次&#xff0c;当它在空虚时&#xff0c;用爱欲来填充&#xff1b; 第三次&#xff0c;在困难和容易之…

深入探析隔离CAN收发器NSI1050-DDBR各项参数

NSI1050-DDBR是一个隔离的CAN收发器&#xff0c;可以完全与ISO11898-2标准兼容。 NSI1050-DDBR集成了两个通道的数字隔离器和一个高电平可靠性CAN收发器。 数字隔离器是基于Novosense电容隔离技术的氧化硅隔离。 高度集成的解决方案可以帮助简化系统设计并提高可靠性。 NSI1050…

Yolov8模型训练报错:torch.cuda.OutOfMemoryError

最近在使用自己的数据训练Yolov8模型的时候遇到了很多错误&#xff0c;下面将逐一解答。 问题报错 在训练过程中红字报错&#xff1a;torch.cuda.OutOfMemoryError: CUDA out of memory. 后面还会跟着一大段报错&#xff1a; Tried to allocate XXX MiB (GPU 0; XXX GiB to…

Vue23-props配置功能

Vue2&3-props配置功能 Vue2-props配置 功能&#xff1a;接收从其他组件传过来的数据&#xff0c;将数据从静态转为动态注意&#xff1a; 同一层组件不能使用props&#xff0c;必须是父组件传子组件的形式。父组件传数据&#xff0c;子组件接收数据。不能什么数据都接收&a…

EMNLP2023 | LLM作用下的成分句法分析基础研究

深度学习自然语言处理 原创作者&#xff1a;cola 自训练已被证明是一种有效的针对跨域任务的方法。传统的自训练方法依赖于有限且低质量的源语料库。为克服这一限制&#xff0c;本文提出用大型语言模型(LLM)增强自训练&#xff0c;以迭代地生成特定领域的语料库。并针对句法成分…

JavaEE初阶学习:Linux 基本使用和 web 程序部署

1.Linux的基本认识 Linux 是一个操作系统.(搞管理的系统) 和Windows都是同类产品~~ Linux 实际的场景: 1.服务器 2.嵌入式设备 3.移动端(手机)Android 其实就是Linux 1991年,还在读大学的 芬兰人 Linus Benedict Torvalds,搞了一个Linux 这样的系统0.01版,正式发布了~ 后…

Docker学习——⑥

文章目录 1、什么是存储卷?2、为什么需要存储卷?3、存储卷分类4、管理卷 Volume5、绑定卷 bind mount6、临时卷 tmpfs7、综合实战-MySQL 灾难恢复8、常见问题 1、什么是存储卷? 存储卷就是将宿主机的本地文件系统中存在的某个目录直接与容器内部的文件系统上的某一目录建立…

js各种简单事件处理(整理)

**## 获取当天昨天日期** // 当天日期 const today new Date();// 格式化当天日期为 YYYY-MM-DD 格式 const formattedToday today.toISOString().slice(0, 10);// 昨天日期 const yesterday new Date(); yesterday.setDate(yesterday.getDate() - 1);// 格式化昨天日期为 Y…

并查集模版以及两道例题

&#x1f4af; 博客内容&#xff1a;并查集 &#x1f600; 作  者&#xff1a;陈大大陈 &#x1f680; 个人简介&#xff1a;一个正在努力学技术的准C后端工程师&#xff0c;专注基础和实战分享 &#xff0c;欢迎私信&#xff01; &#x1f496; 欢迎大家&#xff1a;这里是C…
最新文章