Unsplash
Photo by Alex Holyoake on Unsplash

Contents
  1. 1. 前言
  2. 2. rebase
    1. 2.1. rebase过程
    2. 2.2. rebase中可能会遇到的问题
    3. 2.3. rebase后可能会遇到的问题
  3. 3. cherry-pick
    1. 3.1. 摘樱桃流程
    2. 3.2. 遇到冲突
  4. 4. 测试过程中遇到的其他问题
    1. 4.1. 中文乱码
  5. 5. 总结
  6. 6. Reference

前言

在开发过程中,难免遇到提交完了却发现漏改了什么东西,或者PM又来找…,要小小修改一下,之类的事情。
如rebase就是用来合并提交的,它可以合并多个提交,使log看起来更整洁。
而有时又会碰到极端的情况,比如新开发了一个功能,但是功能还未完善,却有一部分先要上线,这时就可以用cherry-pick,提取其他分支的提交放入本分支内。

rebase

rebase过程

  1. 先切换到开发分支下建一个分支test_fix
    git checkout -b test_fix
  2. 再模拟提交一个修改
    ==些许修改==
    git add .
    git commit -m "fix css float"
    此时log如下
    git log after commit fix css float
  3. 接着模拟提交几个漏改忘改的或临时增加的修改
    ==漏改==
    git add .
    git commit -m "fix css float, ie"
    git log after commit fix css float ie
    ==临时增加==
    git add .
    git commit -m "pm kindly asked to change some text"
    此时log如下
    git log after several commits
  4. 仔细看会发现倒数连续的3个提交显得非常累赘,这时可以使用rebase来合并提交
    git rebase -i 2eb8922
    git rebase -i
  5. 我们要使用squash(可以简写为s)来融合提交
    git rebase ing
  6. 对文本保存退出后,git bash又会打开一个新的vim来合并提交信息。
    combine commits
    只需留下任意一条文本信息即可,也可以随意修改提交信息。
  7. 保存退出后rebase即成功
    rebase finish

rebase中可能会遇到的问题

rebase遇到问题时,分支名后面会显示| REBASE-i的提示。同时会打印错误信息。
warning: squelched 10 whitespace errors
warning: 15 lines add whitespace errors.
这条警告的含义是,代替列出10/15条错误信息,git以这样一条错误信息展示错误数量。参考了so的同问回答
对这样的错误,尝试配置
git config core.whitespace nowarn禁止显示whitespace错误【建议】

git config core.whitespace fix修复whitespace错误
在这条so解答中,答主建议设置禁止显示whitespace错误。

rebase后可能会遇到的问题

假如rebase了一条或几条已经push过的commit后再push难免会遇到下面这个问题。

1
2
3
4
5
6
7
8
$ git push
To 192.168.1.*:some/www.git
! [rejected] icecream -> icecream (non-fast-forward)
error: failed to push some refs to 'git@192.168.1.*:some/www.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

根据错误查询,得到2种解法
由于是我个人的开发分支,于是用了强推法(多人合作项目中不推荐使用)。

1
2
3
4
5
6
7
8
9
10
11
12
$ git push -f
Counting objects: 62, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (41/41), done.
Writing objects: 100% (62/62), 16.16 KiB | 0 bytes/s, done.
Total 62 (delta 25), reused 0 (delta 0)
remote:
remote: To create a merge request for icecream, visit:
remote: http://192.168.1.*/some/www/merge_requests/new?merge_request%5Bsource_branch%5D=icecream
remote:
To 192.168.1.*:some/www.git
+ 2506d5d5...5d98f9c8 icecream -> icecream (forced update)

总体来说,不建议这样做,引用该答主的说明。

IN other words, if others are pulling AND pushing, it’s better that you stick with git merge, or AVOID PUSHING until after the rebase (and only rebase your work).

假如要rebase的话,最好先rebase完最后提交,而且最好只rebase自己提交的那部分。

cherry-pick

摘樱桃流程

  1. 先从master基础上建两个测试分支,rb1与rb2,两个分支里都提交一些修改。
  2. 切换到rb2,使用git log查看需要摘取的commit id
  3. 切换到rb1,使用git cherry-pick rb2_COMMENT_ID将rb2中的提交摘到rb1里。
  4. 假如摘过来的rb2的提交所涉及的文件和rb1的没有冲突,则摘樱桃完成。

    遇到冲突

    假如rb2的提交所涉及的文件和rb1提交过的文件有冲突,git会出现提示。
    cherry pick conflict
    有冲突的话会出现error提示,并且分支名后面会出现| CHERRY-PICKING,表示现在处于摘樱桃过程中。
    可以使用git status -s查看冲突涉及的文件名。
    此时有2个做法:
  5. 手动修改,使用vim或IDE查看涉及冲突的文件,文件中会以图中的形式区别本分支代码和樱桃分支的代码。
    vim comment
    手动解决冲突,删除不想要的代码,并add+commit。提交完成后分支名后的| CHERRY-PICKING会消失,此时表示摘樱桃完成。
  6. 先中止本次摘取
    git cherry-pick --abort
    再使用参数设置全部使用对方的。
    git cherry-pick --strategy=recursive -X theirs rb2_COMMENT_ID
    所有可用的合并策略

测试过程中遇到的其他问题

中文乱码

使用git log查看记录时发现中文字符乱码

1
2
3
4
5
$ git log --oneline
88962305 Merge branch 'icecream'
5d98f9c8 澧<9E>▒<8A>犲<89><8D>绔▒<90>▒<8E><85>▒<9F>ヨ椤佃▒<86>娴<86>绛涢<80>
涢<89>椤▒
d50313e2 rebase▒<90><8E>▒<8F><90>浜▒

查询后获得解答,系统是win7
设置
git config --global i18n.commitencoding utf-8将提交的字符编码设为utf-8
git config --global i18n.logoutputencoding gbk将log打印的字符编码设为gbk
即可解决问题,正常样例。

1
2
3
4
$ git log --oneline
88962305 Merge branch 'icecream'
5d98f9c8 增加前端选项
d50313e2 rebase后提交

注:假如log在logoutputencoding设为gbk后依然乱码,可以尝试查看git bash-Options-Text下的locale设置

此处的Locale和Character Set都应选为默认(Default)zh_CN, GBK(Chinese)

总结

练习git的过程中遇到不少问题,但是基本查几次就能找到答案。

Reference

Pro Git简体中文版
分支的衍合 - Pro Git
git, whitespace errors, squelching and autocrlf, the definitive answers - so
What does “1 line adds whitespace errors” mean when applying a patch? - so
Git for windows 中文乱码解决方案 - seg
hint: after resolving the conflicts, mark the corrected paths - so
How do I resolve cherry-pick conflicts using their changes? - so
git rebase and git push: non-fast forward, why use? - so

Contents
  1. 1. 前言
  2. 2. rebase
    1. 2.1. rebase过程
    2. 2.2. rebase中可能会遇到的问题
    3. 2.3. rebase后可能会遇到的问题
  3. 3. cherry-pick
    1. 3.1. 摘樱桃流程
    2. 3.2. 遇到冲突
  4. 4. 测试过程中遇到的其他问题
    1. 4.1. 中文乱码
  5. 5. 总结
  6. 6. Reference