Git 和声

冲突解决

只要有合并就可能会有冲突。

自动合并

修改不同的文件

有时候我们在push代码到远程仓库时,会遇到一些小麻烦。

git_part3_1.png

图为出现非快进式推送时的日志。

这时我们查看当前版本库和远程版本库的commit哈希值,可以发现二者的不同,即出现了非快进式推送。

git_part3_2.png

非快进式推送(nor-fast-forwardupdates) 在远程版本库和当前版本库内容不一致时推送所致,引起原因一般为在多成员协同工作下,其他用户在当前用户版本库上次commit和本次commit之间向远程版本库执行了推送所致。

解决方法

  • 先执行pull,再继续push,即合并后推送。这才是多成员协同工作推荐的方式。
  • 使用 git push origin master --force强制推送。这种方式存在覆盖掉其他人提交的危险,不推荐使用。

修改相同文件的不同区域

解决方法基本如上。但是如果追溯一下文件每一行的来源,可以看到分别是 dingmingk 和 root 用户更改的第一和最后的一行。

git_part3_3.png

同时更改文件名和文件内容

解决方法如上。最新版本的文件名和内容都为修改后。

冲突解决

如果两个用户修改了同一文件的同一区域,则在合并的时候会遇到冲突而导致合并过程中端。这是因为 Git 并不能越俎代庖地替用户做出决定,而是把决定权交给用户。在这种情况下,Git 标识出合并冲突,等待用户对冲突做出抉择。

git_part3_4.png

如图所示,特殊标识 <<<<<<<(七个小于号)和 =======(七个等号)之间的内容是当前分支所更改的内容。特殊标识 =======(七个等号)和 >>>>>>>(七个大于号)之间的内容是所合并的版本更改内容。

冲突解决的实质就是通过编辑操作,将冲突标识符所标识的冲突内容替换为合适的内容,并去掉冲突标识符。编辑完后再重新提交即可。

里程碑

里程碑即 Tag,是人为对提交进行的命名。相比于 Git 默认的提交ID,使用一个直观的表意的字符串会方便得多。

1
2
3
4
5
git tag <tagname> [<commit>]
git tag -a <tagname> [<commit>]
git tag -m <msg> <tagname> [<commit>]
git tag -s <tagname> [<commit>]
git tag -u <key-id> <tagname> [<commit>]
  • 第一种是创建轻量级里程碑。
  • 第二种和第三种想同,都是创建带说明的里程碑。其中第三种直接通过 -m 参数提供里程碑创建说明。
  • 第四种和第五种相同,都是创建带 GNUPG 签名的里程碑。其中第五种用 -u 参数选择指定的私钥进行签名。
  • 创建里程碑需要输入里程碑的名字()和一个可选的提交ID()。如果没有提供提交ID,则基于头指针 HEAD 创建里程碑。

轻量级里程碑

带说明的里程碑

带签名的里程碑

删除里程碑

里程碑命名规范

Git 分支

分支命令

1
2
3
4
5
6
7
git branch
git branch <branchname>
git branch <branchname> <start-point>
git branch -d <branchname>
git branch -D <branchname>
git branch -m <oldbranch> <branchname>
git branch -M <oldbranch> <newbranch>
  • 第一种用于显示本地分支列表。当前分支在输出中会显示为特别的颜色,并用星号“*”标识出来。
  • 第二种和第三种用于创建分支。用法2基于当前头指针(HEAD)指向的提价创建分支,新分支的分支名 。第三种基于提交 创建新分支,新分支的分支名为
  • 第四种和第五种用户删除分支。第四种在删除分支 时会检查所要删除的分支是否已经合并到其它分支种,否则拒绝删除。第五种会强制删除分支。
  • 第六种和第七种用于重命名分支。如果版本库中已经存在名为 的分支,第六种会拒绝执行重命名,而第七种会强制执行。

分支变基

1
2
$ git checkout develop
$ git rebase master

这两条命令会把你的 develop 分支里的每个提交(commit)取消掉,并且把它们临时保存为补丁(这些patch放到 .git/rebase 目录中),然后把 develop 分支更新为最新的 master 分支,最后把保存的这些补丁应用到 develop 分支上。

远程版本库

代码回滚

本地代码库回滚

git reset 命令回滚有三种方式:

  • mixed: 默认方式。它回退到某个版本,只保留源码,回退commit和index信息。
  • soft: 只回退commit信息,不会恢复index file一级。
  • hard: 彻底回退到某个版本,本地的源码也会变为上一个版本的内容。
1
2
3
4
5
* $ git reset --[hard|soft|mixed] <commit> 回滚所有内容到某个提交
* $ git reset --[hard|soft|mixed] HEAD^ 回滚所有内容到上一个版本
* $ git reset --[hard|soft|mixed] HEAD^^ xxx 回滚xxx这个文件到上两个版本
* $ git reset --[hard|soft|mixed] HEAD~3 回滚所有内容到第三个版本
* $ git reset --[hard|soft|mixed] origin/master 回滚到和远程一样

远程代码库回滚

远程代码库回滚比本地回滚要复杂一些,建议操作前先备份分支。

操作步骤:

1
2
3
4
5
6
7
1. $ git checkout <branch> 切换到分支
2. $ git pull 拉取最新代码
3. $ git branch <branch> <branch_backup> 备份分支
4. $ git reset --hard <commit> 回滚本地代码库
5. $ git push origin :<branch> 删除远程分支
6. $ git push origin <branch> 将本地分支推送到远程
7. $ git push origin :<branch_backup> 删除远程备份分支

反转提交

1
2
* $ git revert <commit> 用一次新的反转提交来消除一个历史提交所做的任何修改
$ git revert -m 1 <commit> “-m 1”参数表示某次历史提交的父提交