2017-06-23 分享几个 git 的使用场景


你真的会使用 git 吗?你能回答下面几个问题吗? 有三个 commit(顺序:CommitA、CommitB、CommitC),它们相互独立,没有依赖。

  1. 在不修改 B、C 的前提下,修改 A,怎么操作?
  2. 合并 A、B、C 为一个 commit,怎么操作?
  3. 调整 A、B、C 的顺序编程 C、B、A,怎么操作?

作为一个开发,日常工作中不可避免的要使用 git。 当然了,如果你技术无敌、独立承担一个项目、没人干预或者影响你的工作,那么你可能不需要下面这些总结。哈哈哈...

由于 xxx 原因,我认为应该给项目组的其他人讲讲 git。 因为语言障碍和技术熟练度的障碍,为了让同事们更好地理解并且愿意使用 git 。我不得不一个场景一个方法地讲解,所以有了下面总结。

这难道不是一种成长吗?

场景 1

J 写了一个功能,分成 3 次 commit(顺序:CommitA、CommitB、CommitC)。完成功能之后,他找了 B 先生进行 Code Review,B 先生觉得 CommitB 和 CommitC 没有问题,CommitA 需要进行简单修改。 那么如何在不改变 CommitB 和 CommitC 的前提下,修改 CommitA 呢? 方法:

使用 git rebase -i,操作如下

1. rebase CommitA、CommitB、CommitC 三个 commit

$ git rebase -i <parent commit of A>

2. edit CommitA,将 Commit A 前面 pick 修改为edit

edit d3d4537 CommitA
pick 498bf7a CommitB
pick 1d84bb8 CommitC

这时 HEAD 停留在 CommitA,可以对 CommitA 进行修改,然后使用下面命令覆盖 CommitA

$ git add <修改文件>
$ git commit -amend

3. 让 git 完成后续 rebase 操作

$ git rebase -continue

场景 2

J 修改了 CommitA 后,项目 leader 希望一个功能尽可能使用一个 commit 提交。 那么如何合并 CommitA、CommitB、CommitC 为一个 commit 呢?

方法:

同样使用 git rebase -i,操作如下

1. rebase CommitA、CommitB、CommitC 三个 commit

$ git rebase -i <parent commit of A>

2. 合并 Commits (1)CommitB 和 CommitC 前面 pick 修改为squash,然后:wq保存退出。

pick fa42d43 CommitA
squash 86a09b9 CommitB
squash 360d9a3 CommitC

3. 让 git 完成后续 rebase 操作

$ git rebase -continue

场景 3

J 合并 CommitA、CommitB、CommitC 后,新产生的 CommitA+需要将代码更新到 master 上。但是,同一项目组的 T 已经提交了 CommitD。 本来 J 只需要 merge 自己的 CommitA+到 master 就可以了,但是 J 下一个任务依赖于 T 提交的 CommitD。 J 希望一次性更新master和自己的 branch(branch_J_dev),一石二鸟。 那么如何在 merge 自己的 CommitA+到 master 的同时将 CommitD 也 merge 到自己的 branch(branch_J_dev)中呢?

方法:

又是使用 git rebase,操作如下

1. rebase 自己的branch_J_dev 到 master

$ git checkout branch_J_dev
$ git rebase --onto master <CommitA+>

2. master 合并 branch_J_dev 的提交

$ git checkout master
$ git merge branch_J_dev

git checkout master 和 git merge branch_J_dev 非常重要,网络上大部分教程都没有最后一步。 而且好多人都把命令写成了 git rebase --ontomaster <commit id>,看来全是抄袭同一个人的,也是醉了。哈哈哈哈... 我也是因为被坑了,所以才查了一下一下资料,发现竟然还需要一步。

场景 4(需求基本和场景 3 一致)

如何 J 本次希望提交的代码有 CommitA+、CommitB+、CommitC+三次 commit(顺序:CommitA+、CommitB+、CommitC+)。 那么如何在 merge 自己的 CommitA+、CommitB+、CommitC+到 master 的同时将 CommitD 也 merge 到自己的 branch(branch_J_dev)中呢?

方法:

基本和场景 3 一致,操作如下

1. rebase 自己的branch_J_dev 到 master

$ git checkout branch_J_dev
$ git rebase --onto master <CommitA+>^
//  ^代表,起点。<CommitA+>^表示 CommitA 为起点后面所有的 Commit。

2. CommitA 合并进master

$ git checkout master
$ git merge branch_J_dev

场景 5

如何修改 commit 记录(调整顺序+修改 message)? 其实这种操作没什么意义,但是对于对 commit log 有强迫症的人,或许有想修改 commit 记录的冲动。 哈哈哈哈...

方法:

还是使用 git rebase。惊喜不惊喜?意外不意外?操作如下

1. rebase CommitD 和 CommitA+

$ git rebase -i <parent commit of D>

2. 调整 commit 顺序,就是将 CommitD 和 CommitA+ 顺序进行调整。 3. 修改 message ,将 pick 修改为reword。 4. 让 git 完成后续 rebase 操作

$ git rebase --continue

(最后)小提示

1. 如果想中途取消 rebase 操作,后悔药 👇

$ git rebase --abort

2. git rebase 一旦结束,将丢失原本 branch 信息,非常危险。 我在做分享时,git rebase –onto就出现了失误并且没能找回原来 branch 信息,场面十分尴尬。 所以建议还是用 merge 吧,安全一点。

$ git checkout master
$ git pull
$ git merge branch_J_dev

希望这篇文章对你有帮助。