使用Git时一些问题的处理

更新日志:

  • 2016.06.04 晚
    添加 git push --force (用于删除高版本的commit)

  • 2015.11.29 晚
    添加冲突处理工具Meld的教程
    添加在GitHub上Revert一个Pull Request的介绍

  • 2015.11.18 下午
    重构初版博客

在我的另一篇博客 GitHub团队项目合作流程 中,描述了一个团队如何使用GitHub来管理团队项目。但是操作中,可能会遇到一些问题,于是把那些问题放在这里说明。
关于Git使用过程中出现的问题的处理也会更新在这里。

目录:


一、 解决merge时出现的冲突

当你和其他团队成员对同一个文件进行修改后,merge的时候有可能会出现冲突。你可以打开每个冲突的文件,手工解决冲突;也可以借助冲突处理工具来解决冲突。这里分别介绍这两种方式:

  1. 手工解决冲突
    冲突提示如下图所示:
    使用Git时一些问题的处理
    CONFLICT表示有冲突,在这一行的末尾,显示冲突文件。这里有两个文件冲突,分别是README.md和app.iml
    这里以README.md为例,解决冲突:
    ----------------------------------------------------------------------------------------
    使用Git时一些问题的处理
    ----------------------------------------------------------------------------------------
    被红框框住的符号 ======= 是冲突的分割线。
    <<<<<<< HEAD 和分割线之间的是本地的文本
    分割线和 >>>>>>> upstream/dev 之间的是远程分支的文本
    你可以选择保留其中一个版本的文本,然后将三个冲突符号都删除。这样表示已解决冲突。
    如果你想同时保留两个版本,那么只需将冲突符号删除。
    解决冲突后如下图所示:
    ---------------------------------------------------------------------------------------
    使用Git时一些问题的处理
    ---------------------------------------------------------------------------------------

  2. 借助冲突处理工具
    个人认为Meld这个工具比较好用,Android Studio自带的冲突处理工具和它很相似。我用过tortoisegit的工具,感觉没有Meld好用,这里就不介绍了。
    (1) 首先去Meld的官网下载安装文件并安装。->点此进入Meld官网
    (2) 安装完后,打开你的git工具,比如msysgit。执行 git config --edit --global ,此时会打开一个配置文件。在文件最后添加以下四行:
    [merge]
    tool = meld
    [mergetool "meld"]
    path = e:/software/MeldMergeTool/Meld.exe
    提示:path是根据你安装Meld的路径来决定的,同时要把路径中的 \ 改成 / 。从上面可以看出我的安装路径为 e:\software\MeldMergeTool\
    (3) 在merge的时候,如果出现冲突,运行命令 git mergetool 这时就会打开Meld。
    (4) Meld的界面如下:
    使用Git时一些问题的处理
    冲突的地方会显示红色,如果你想保留本地的代码,则点击左边的 箭头。
    把所有红色(冲突)区域解决后,可以根据实际情况去解决绿色(添加)和灰色(更改)。
    一般保存中间的修改就行。如上图红框处。


二、 回退一个merge

  1. 如果是merge一个GitHub的Pull Request,可以进入要回退的那个Pull Request,在下面有一个revert按钮,可以用来revert一个Pull Request。如下图红框处:
    使用Git时一些问题的处理
  2. 在命令行里revert
    (1)用 git log 看commit记录
    ----------------------------------------------------------------------------------------
    使用Git时一些问题的处理
    ----------------------------------------------------------------------------------------
    现在我们要回退 commit 561dab (也就是图中第一个commit),该commit将Pull Request #113 merge到项目中。
    (2)使用 git revert HEAD -m 1 命令回退
    ----------------------------------------------------------------------------------------
    使用Git时一些问题的处理
    ----------------------------------------------------------------------------------------
    如果是非merge的回退,用 git revert 版本号 就行了。但是这里是对merge操作进行revert,需要加上参数 -m 。命令最后加个 1
    为什么要加上 1 呢?看上面(1)的图中的第二个红框,这个 1 对应红框中的 6a3c30c 版本。而如果填 2 ,则对应 b7831df
    继续看log,会发现 6a3c30c 是merge这个Pull Request之前的状态。而 b7831df 则是当前版本之前的一个merge。
    输入命令回车后,会跳出一个文本。
    ----------------------------------------------------------------------------------------
    使用Git时一些问题的处理
    ----------------------------------------------------------------------------------------
    目前无视它就行。关闭文本,回到shell,回车。
    ----------------------------------------------------------------------------------------
    使用Git时一些问题的处理
    ----------------------------------------------------------------------------------------
    回退成功!这个回退不会删除掉中间的commit记录,而是将这次revert作为一个commit加到commit记录上面。

三、 获取某一commit的修改

假设有commit a b c ,从左到右,c 为最新版。
这时你发现 b 的一个修改有问题,想回退到 a 。但是如果回退到 ac 的commit也会被取消。
这时可以用 git cherry-pick 版本号 这个命令获取 c 的commit。

下图是示例的log记录,从①可以看出,这里从②回退到⑤。


使用Git时一些问题的处理


现在我想获取④的commit。使用 git cherry-pick 版本号 将选定版本的提交合并到当前版本。


使用Git时一些问题的处理


四、 将低版本push到Github(删掉高版本Commit)

有时候会因为各种原因,想要回退版本。如果没有关联Github或者没有push上去,那问题不大。但是如果你已经push到Github上了,这时候就比较尴尬了,因为普通的push是会被Github拒绝的。虽然Github提供了Revert功能,但是这并不能完全消去一个commit。

先看看reset后被拒绝的样子:

使用Git时一些问题的处理

解决方法就是:

  1. 先用 git reset --hard 版本号 回到你想要的版本
  2. 执行 git push --force
    使用Git时一些问题的处理
    再看看Github:
    使用Git时一些问题的处理

    当然,一般是推荐用 git push origin HEAD --force 的,能防止因为其他没配置好而产生错误。对我来说差别并不大……

上一篇:Python从文件中读取字符串,用正则表达式匹配中文字符的问题


下一篇:剑指Offer——网易笔试之解救小易