[toc]
chapter(九)
9.1 分支冲突如何解决
9.1.1 换一种新的方式创建切换分支
上一章主要讲的是如何创建分支和合并分支。可在Git实际的使用过程中,往往会遇到分支冲突的情况。 动手实践下: 假设现在创建一个分支conflict,还记得如何创建吗?
使用命令:git branch <分支名>
可以创建分支。
然后再使用:命令git checkout <分支名>
或git switch <分支名>
切换分支。
现在我觉得有些麻烦,我重新找到了一种更加简单的方法:
那就是使用:
git checkout -b <分支名>
或者git switch -c <分支名>
直接进行创建并切换分支。
这就相当于把之前的两部直接变成一步了!是不是更加简单了点
注checkout
和 switch
都可以实现,我建议大家记一个就好。
推荐使用git switch -c <分支名>
,因为switch有切换的意思,而checkout和之前的版本回退有重复!
ps:git switch
是Git2.23版本才发布的新命令,如果出现下面的报错:git: 'switch' is not a git command. See 'git --help'
请进行如下操作:
git --version
确认下Git的版本
如果不是2.23以后的版本,请更新下Git,ubuntu环境下的升级见下面代码:
sudo apt update # 更新源
sudo apt install software-properties-common # 安装 PPA 需要的依赖
sudo add-apt-repository ppa:git-core/ppa # 向 PPA 中添加 git 的软件源
sudo apt-get update
sudo apt-get install git
9.1.2 创建冲突分支conflict
toto@pc:~/code/testGit$ git version
git version 2.31.1
toto@pc:~/code/testGit$ git switch -c conflict
Switched to a new branch 'conflict'
toto@pc:~/code/testGit$ git branch
* conflict
master
上面代码提示已经创建并切换到新的分支conflict
下面我们给helloword.cpp
增加一句话:
toto@pc:~/code/testGit$ vim helloword.cpp
toto@pc:~/code/testGit$ cat helloword.cpp
#include<iostream>
int main()
{
std::cout << "This is a program that test Git!" << std::endl;
std::cout << "test git status" << std::endl;
std::cout << "test git status2" << std::endl;// 新增的一行
std::cout << "test new branch!" << std::endl;
std::cout << "test conflict branch" << std::endl;
int a = 1;
return 0;
}
toto@pc:~/code/testGit$ git add helloword.cpp
toto@pc:~/code/testGit$ git commit -m "test conflict branch"
[conflict 33c858c] test conflict branch
1 file changed, 1 insertion(+)
再切换到master
分支中,进行如下操作:
toto@pc:~/code/testGit$ git switch master
Switched to branch 'master'
toto@pc:~/code/testGit$ git status
On branch master
nothing to commit, working tree clean
toto@pc:~/code/testGit$ vim helloword.cpp
toto@pc:~/code/testGit$ cat helloword.cpp
#include<iostream>
int main()
{
std::cout << "This is a program that test Git!" << std::endl;
std::cout << "test git status" << std::endl;
std::cout << "test git status2" << std::endl;// 新增的一行
std::cout << "test new branch!" << std::endl;
std::cout << "test conflict branch in master!" << std::endl;
int a = 1;
return 0;
}
toto@pc:~/code/testGit$ git add helloword.cpp
toto@pc:~/code/testGit$ git commit -m "test conflict branch in master"
[master d70cae4] test conflict branch in master
1 file changed, 1 insertion(+)
此时我们分别在conflict
分支和master
分支,分别进行了修改,并进行了提交。
我们合并下,看看会出现什么?
toto@pc:~/code/testGit$ git merge conflict
Auto-merging helloword.cpp
CONFLICT (content): Merge conflict in helloword.cpp
Automatic merge failed; fix conflicts and then commit the result.
看到没,Git在提示我们产生了冲突!合并的冲突在helloword.cpp
中,自动合并失败,修复冲突并重新提交结果。
git status
下:
toto@pc:~/code/testGit$ 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: helloword.cpp
no changes added to commit (use "git add" and/or "git commit -a")
也提示了我们合并产生了冲突。
查看下helloword.cpp
文件:
toto@pc:~/code/testGit$ cat helloword.cpp
#include<iostream>
int main()
{
std::cout << "This is a program that test Git!" << std::endl;
std::cout << "test git status" << std::endl;
std::cout << "test git status2" << std::endl;// 新增的一行
std::cout << "test new branch!" << std::endl;
<<<<<<< HEAD
std::cout << "test conflict branch in master!" << std::endl;
=======
std::cout << "test conflict branch" << std::endl;
>>>>>>> conflict
int a = 1;
return 0;
}
看到没,Git实在是有点智慧
它使用<<<<<<< HEAD
、=======
和>>>>>>> conflict
保存了不同分支的内容,而这就是冲突的地方。
如上所示HEAD
是当前分支,也就是master
。
而conflict
就是conflict
分支!
如何解决冲突呢?
很简单,在当前状态下,重新修改helloword.cpp
文件
toto@pc:~/code/testGit$ vim helloword.cpp
toto@pc:~/code/testGit$ cat helloword.cpp
#include<iostream>
int main()
{
std::cout << "This is a program that test Git!" << std::endl;
std::cout << "test git status" << std::endl;
std::cout << "test git status2" << std::endl;// 新增的一行
std::cout << "test new branch!" << std::endl;
std::cout << "fix conflict!" << std::endl;
int a = 1;
return 0;
}
我注释的那句话和前面的两个都不同,std::cout << "fix conflict!" << std::endl;
toto@pc:~/code/testGit$ git add helloword.cpp
toto@pc:~/code/testGit$ git commit -m "fixed conflict!"
[master 87b067d] fixed conflict!
toto@pc:~/code/testGit$ git status
On branch master
nothing to commit, working tree clean
此时的冲突就解决了!
我们可以用带参数的git log也可以看到分支的合并情况:
git log --graph --pretty=oneline --abbrev-commit
toto@pc:~/code/testGit$ git log --graph --pretty=oneline --abbrev-commit
* 87b067d (HEAD -> master) fixed conflict!
|\
| * 33c858c (conflict) test conflict branch
* | d70cae4 test conflict branch in master
|/
* 828ea5e test new branck
* 05e641d remove deleteFile.txt
* 190efbd test deleted file
* 7064df2 understand stage
* 74aada6 test git status2
* 2fe4439 add new line that test git status
* 01630fb test Git program
可以看到,git log
以类似图的样子,解释了刚才冲突的情况。
把上面的铺开,看看下面这张图,是不是有点像!
ok!如何解决冲突,我们就演示完毕!
使用命令git branch -d <分支名>
可以删除分支
9.2 分支冲突总结
- 使用
git switch -c <分支名>
可以创建并切换分支 - 使用如下命令,可以更新Git:
sudo apt update # 更新源
sudo apt install software-properties-common # 安装 PPA 需要的依赖
sudo add-apt-repository ppa:git-core/ppa # 向 PPA 中添加 git 的软件源
sudo apt-get update
sudo apt-get install git
git log --graph --pretty=oneline --abbrev-commit
可以查看- 参数
-–graph
含义:展示分支信息 - 参数
--pretty=oneline
含义:用一行展示每次提交的commit id 和 提交注释信息 - 参数
--abbrev-commit
含义:仅显示 SHA-1 的前几个字符,而非所有的 40 个字符。
- 参数
- 根据第3条,补充
git log
常用参数含义:原文链接
# 展示前n条数据
git log -n
# 展示简要的每次提交行数的变化,及其他基本信息。
git log –stat
# 展示每次提交详细的代码变化
git log -p
# 用一行展示每次提交的commit id 和 提交注释信息
git log –pretty=oneline
# 展示分支信息
git log –graph
git log –pretty=format:""
git log --pretty=format:"%h %s"
# 个人log配置个性化输出命令
git log --pretty=format:"%H %cd *%an*:%s(%ar)" --graph
展示历史最后2次提交的commit id 和 提交注释信息
git log -2 --pretty=format:"%h - %ad, %ar : %s"
%H 提交对象(commit)的完整哈希字串
%h 提交对象的简短哈希字串
%T 树对象(tree)的完整哈希字串
%t 树对象的简短哈希字串
%P 父对象(parent)的完整哈希字串
%p 父对象的简短哈希字串
%an 作者(author)的名字
%ae 作者的电子邮件地址
%ad 作者修订日期(可以用 -date= 选项定制格式)
%ar 作者修订日期,按多久以前的方式显示
%cn 提交者(committer)的名字
%ce 提交者的电子邮件地址
%cd 提交日期
%cr 提交日期,按多久以前的方式显示
%s 提交说明
# 展示指定log信息,时间参数需要用UTC格式时间。
git log –since –author –grep
-n 仅显示最近的 n 条提交
–since, –after 仅显示指定时间之后的提交。
–until, –before 仅显示指定时间之前的提交。
–author 仅显示指定作者相关的提交。
–committer 仅显示指定提交者相关的提交。
git log hash.. 可以输出指定hash之后的提交
git log 参数参考
git log 命令支持的选项
-p 按补丁格式显示每个更新之间的差异。
--stat 显示每次更新的文件修改统计信息。
--shortstat 只显示 --stat 中最后的行数修改添加移除统计。
--name-only 仅在提交信息后显示已修改的文件清单。
--name-status 显示新增、修改、删除的文件清单。
--abbrev-commit 仅显示 SHA-1 的前几个字符,而非所有的 40 个字符。
--relative-date 使用较短的相对时间显示(比如,“2 weeks ago”)。
--graph 显示 ASCII 图形表示的分支合并历史。
--pretty 使用其他格式显示历史提交信息。可用的选项包括 oneline,short,full,fuller 和 format(后跟指定格式)。