看日记学git

《看日记学git》之二十一

我们已经完全掌握了建立新分支的方法,但是建立了新分支,总要利用起来吧,通俗点说,就是“领导要管得住自己的下属”。

恩,读完本文,你将完全掌握如何利用别人的分支的啦!

我们会以实例的方式,来将分支技术娓娓道来:D 请大家跟上思路。

首先,先概括说一下整体思路:

1 创建一个主分支,名称当然是默认的master,写一个小程序roc.c。

2 之后,创建新分支,命名为wukong(呵呵,你没看错,就是悟空),在wukong分支改进小程序roc.c代码并commit。

3 在wukong的基础上建立bajie(对,八戒),再改进代码roc.c,并在bajie分支commit。

4 切换到wukong,悟空修改自己的代码,并故意造成和bajie的代码冲突。

5 由悟空来操作,将bajie合并到wukong分支。(需要解决代码冲突)

6 由我操作,将wukong合并到master分支。

7 实验完毕。可以删除两个分支了。

好了,大体思路就这么简单,也基本上可以涵盖所有的分支操作情况了。下面,我们就一步一步来开始实例体验吧!

第一步:创建一个主分支,名称当然是默认的master,写一个小程序。

[rocrocket@wupengchong ~]$ mkdir git21
[rocrocket@wupengchong ~]$ cd git21/
[rocrocket@wupengchong git21]$ ls
[rocrocket@wupengchong git21]$ vi roc.c
[rocrocket@wupengchong git21]$ ls
roc.c
[rocrocket@wupengchong git21]$ cat -n roc.c
1  #include<stdio.h>
2  int main()
3  {
4          printf(“Please guess who he is.\n”);
5          return 0;
6  }
[rocrocket@wupengchong git21]$

然后进行初始化工作:

[rocrocket@wupengchong git21]$ git init
Initialized empty Git repository in .git/
[rocrocket@wupengchong git21]$ git add *
[rocrocket@wupengchong git21]$ git commit
Created initial commit d5d44dc: master:001
1 files changed, 6 insertions(+), 0 deletions(-)
create mode 100644 roc.c
[rocrocket@wupengchong git21]$
最后是例行检查:

[rocrocket@wupengchong git21]$ git diff
[rocrocket@wupengchong git21]$ git diff –cached
[rocrocket@wupengchong git21]$ git diff HEAD
[rocrocket@wupengchong git21]$ git log
commit d5d44dcdc938a263bdbc1c9cb06de24c27adebc7
Author: rocrocket <wupengchong@gmail.com>
Date:   Thu Oct 9 18:50:39 2008 +0800

master:001
[rocrocket@wupengchong git21]$ git status
# On branch master
nothing to commit (working directory clean)
[rocrocket@wupengchong git21]$ git branch
* master
[rocrocket@wupengchong git21]$

第二步:之后,创建新分支,命名为wukong(你没看错,就是孙猴子,呵呵),在wukong分支改进小程序roc.c代码并commit

[rocrocket@wupengchong git21]$ git branch wukong
[rocrocket@wupengchong git21]$ git branch
* master
wukong
[rocrocket@wupengchong git21]$ git checkout wukong
Switched to branch “wukong”
[rocrocket@wupengchong git21]$ git branch
master
* wukong
[rocrocket@wupengchong git21]$ cat .git/HEAD
ref: refs/heads/wukong
[rocrocket@wupengchong git21]$ ls
roc.c
[rocrocket@wupengchong git21]$ vi roc.c
编辑后roc.c的代码如下:

[rocrocket@wupengchong git21]$ cat -n roc.c
1  #include<stdio.h>
2  int main()
3  {
4          printf(“Please guess who he is.\n”);
5          printf(“He is a youngster.\n”);
6          return 0;
7  }
[rocrocket@wupengchong git21]$
下面进行add和例行检查:

[rocrocket@wupengchong git21]$ git add roc.c
[rocrocket@wupengchong git21]$ git diff
[rocrocket@wupengchong git21]$ git diff –cached
diff –git a/roc.c b/roc.c
index 66cb6f0..2fe0f42 100644
— a/roc.c
+++ b/roc.c
@@ -2,5 +2,6 @@
int main()
{
printf(“Please guess who he is.\n”);
+       printf(“He is a youngster.\n”);
return 0;
}
[rocrocket@wupengchong git21]$

下面在wukong分支提交此修改:

[rocrocket@wupengchong git21]$ git commit
Created commit 1ac0798: wukong:001
1 files changed, 1 insertions(+), 0 deletions(-)
[rocrocket@wupengchong git21]$ git log
commit 1ac0798784828577ecb808b03165facfb5bef3e3
Author: rocrocket <wupengchong@gmail.com>
Date:   Thu Oct 9 19:07:57 2008 +0800

wukong:001

commit d5d44dcdc938a263bdbc1c9cb06de24c27adebc7
Author: rocrocket <wupengchong@gmail.com>
Date:   Thu Oct 9 18:50:39 2008 +0800

master:001
[rocrocket@wupengchong git21]$

好了,到此时,我们来查看一下master主分支和wukong分支的代码分别是什么情况:

[rocrocket@wupengchong git21]$ git branch
master
* wukong
[rocrocket@wupengchong git21]$ cat roc.c
#include<stdio.h>
int main()
{
printf(“Please guess who he is.\n”);
printf(“He is a youngster.\n”);
return 0;
}
[rocrocket@wupengchong git21]$ git checkout master
Switched to branch “master”
[rocrocket@wupengchong git21]$ git branch
* master
wukong
[rocrocket@wupengchong git21]$ cat roc.c
#include<stdio.h>
int main()
{
printf(“Please guess who he is.\n”);
return 0;
}
[rocrocket@wupengchong git21]$

显而易见,此时两个分支的代码是不一样的。:)继续我们的实例体验。

3 在wukong的基础上建立bajie(对,八戒),再改进代码roc.c,并在bajie分支commit。

[rocrocket@wupengchong git21]$ git checkout wukong
Switched to branch “wukong”
[rocrocket@wupengchong git21]$ git branch
master
* wukong
[rocrocket@wupengchong git21]$ git branch bajie
[rocrocket@wupengchong git21]$ git branch
bajie
master
* wukong
[rocrocket@wupengchong git21]$ git checkout bajie
Switched to branch “bajie”
[rocrocket@wupengchong git21]$ git branch
* bajie
master
wukong
[rocrocket@wupengchong git21]$ vi roc.c

悟空成功建立了bajie分支,并checkout到bajie分支。

然后就是编辑bajie分支的roc.c了:

[rocrocket@wupengchong git21]$ cat -n roc.c
1  #include<stdio.h>
2  int main()
3  {
4          printf(“Please guess who he is.\n”);
5          printf(“He is a youngster.\n”);
6          printf(“He is a male.\n”);
7          return 0;
8  }
[rocrocket@wupengchong git21]$
可以看到黑体字,我们加了一句话:He is a male.(他是一个男性)。

好,八戒编辑完代码,可以提交了!

[rocrocket@wupengchong git21]$ git diff
diff –git a/roc.c b/roc.c
index 2fe0f42..05aaf78 100644
— a/roc.c
+++ b/roc.c
@@ -3,5 +3,6 @@ int main()
{
printf(“Please guess who he is.\n”);
printf(“He is a youngster.\n”);
+       printf(“He is a male.\n”);
return 0;
}
[rocrocket@wupengchong git21]$ git add roc.c
[rocrocket@wupengchong git21]$ git commit
Created commit 5a0f9ee: bajie:001
1 files changed, 1 insertions(+), 0 deletions(-)
[rocrocket@wupengchong git21]$ git log
commit 5a0f9ee71fe9ffe259b9b6cf842dd69baa95b307
Author: rocrocket <wupengchong@gmail.com>
Date:   Thu Oct 9 19:16:31 2008 +0800

bajie:001

commit 1ac0798784828577ecb808b03165facfb5bef3e3
Author: rocrocket <wupengchong@gmail.com>
Date:   Thu Oct 9 19:07:57 2008 +0800

wukong:001

commit d5d44dcdc938a263bdbc1c9cb06de24c27adebc7
Author: rocrocket <wupengchong@gmail.com>
Date:   Thu Oct 9 18:50:39 2008 +0800

master:001
[rocrocket@wupengchong git21]$ git branch
* bajie
master
wukong
[rocrocket@wupengchong git21]$
好了,已经在bajie分支提交成功了。(你应该注意到了,对于分支操作来说,不仅代码是向下继承,连log也是向下继承的。不过,log和代码一样是不会自动向上复制的,只有merge了之后才可以看到下层分支的Log和代码)

4 切换到wukong,悟空修改自己的代码,并故意造成和bajie的代码冲突。

[rocrocket@wupengchong git21]$ git branch
* bajie
master
wukong
[rocrocket@wupengchong git21]$ git checkout wukong
Switched to branch “wukong”
[rocrocket@wupengchong git21]$ git branch
bajie
master
* wukong
[rocrocket@wupengchong git21]$ vi roc.c
好了,成功切换到wukong,开始在roc.c中加入代码吧!

[rocrocket@wupengchong git21]$ cat -n roc.c
1  #include<stdio.h>
2  int main()
3  {
4          printf(“Please guess who he is.\n”);
5          printf(“He is a youngster.\n”);
6          printf(“He is a female.\n”);
7          return 0;
8  }
[rocrocket@wupengchong git21]$

可以看到,呵呵,wukong写了一句He is a female. 很明显,这句话是捣乱的,也就是要故意引起冲突。因为在bajie分支里已经有He is a male.这句话了。好,下面好戏来了,看看怎么解决这个冲突吧!

朋友要注意一点:要合并两个分支的话,两个分支都必须是commit的状态。否则merge可会报错的哦!来,看看merge报错时的样子:

[rocrocket@wupengchong git21]$ git merge bajie
Updating 1ac0798..5a0f9ee
roc.c: needs update
error: Entry ‘roc.c’ not uptodate. Cannot merge.

就是这样,告诉你roc.c需要升级,不能merge。

下面,来将wukong修改的内容commit吧!

[rocrocket@wupengchong git21]$ git diff
diff –git a/roc.c b/roc.c
index 2fe0f42..b8066c1 100644
— a/roc.c
+++ b/roc.c
@@ -3,5 +3,6 @@ int main()
{
printf(“Please guess who he is.\n”);
printf(“He is a youngster.\n”);
+       printf(“He is a female.\n”);
return 0;
}
[rocrocket@wupengchong git21]$ git commit -a
Created commit 4f6ba4e: wukong:002
1 files changed, 1 insertions(+), 0 deletions(-)
[rocrocket@wupengchong git21]$ git log
commit 4f6ba4e96db6110405f615a5ea5d3119faf64d45
Author: rocrocket <wupengchong@gmail.com>
Date:   Thu Oct 9 23:35:31 2008 +0800

wukong:002

commit 1ac0798784828577ecb808b03165facfb5bef3e3
Author: rocrocket <wupengchong@gmail.com>
Date:   Thu Oct 9 19:07:57 2008 +0800

wukong:001

commit d5d44dcdc938a263bdbc1c9cb06de24c27adebc7
Author: rocrocket <wupengchong@gmail.com>
Date:   Thu Oct 9 18:50:39 2008 +0800

master:001
5 由悟空来操作,将bajie合并到wukong分支。(需要解决代码冲突)

[rocrocket@wupengchong git21]$ git merge bajie
Auto-merged roc.c
CONFLICT (content): Merge conflict in roc.c
Automatic merge failed; fix conflicts and then commit the result.
[rocrocket@wupengchong git21]$

可以看到提示,是在抱怨bajie的代码和当前分支(wukong)的代码有冲突(conflict)。只好来解决一下了。

可以看到在merge报冲突之后roc.c的内容是这样:

[rocrocket@wupengchong git21]$ cat roc.c
#include<stdio.h>
int main()
{
printf(“Please guess who he is.\n”);
printf(“He is a youngster.\n”);
<<<<<<< HEAD:roc.c
printf(“He is a female.\n”);
=======
printf(“He is a male.\n”);
>>>>>>> bajie:roc.c
return 0;
}
显然是在等待人脑去判断代码是选择male还是female。呵呵 那我们就来选择正确的,删除错误的,当然是选择male了!修改后的代码如下:

[rocrocket@wupengchong git21]$ cat roc.c
#include<stdio.h>
int main()
{
printf(“Please guess who he is.\n”);
printf(“He is a youngster.\n”);
printf(“He is a male.\n”);
return 0;
}
好,我们解决了冲突,这回可以放心提交了!(注意这回就不用merge了哦,直接commit就可以了!)

[rocrocket@wupengchong git21]$ git diff
diff –cc roc.c
index b8066c1,05aaf78..0000000
— a/roc.c
+++ b/roc.c
[rocrocket@wupengchong git21]$ git add roc.c
[rocrocket@wupengchong git21]$ git diff
[rocrocket@wupengchong git21]$ git commit
Created commit e1ca782: wukong:003
[rocrocket@wupengchong git21]$
好了,commit成功!

查看一下日志,即git log一下:

[rocrocket@wupengchong git21]$ git log
commit e1ca782d95176e83d1013361ba88d0b4c2f51f50
Merge: 4f6ba4e… 5a0f9ee…
Author: rocrocket <wupengchong@gmail.com>
Date:   Thu Oct 9 23:43:06 2008 +0800

wukong:003
Merge branch ‘bajie’ into wukong

Conflicts:

roc.c

commit 4f6ba4e96db6110405f615a5ea5d3119faf64d45
Author: rocrocket <wupengchong@gmail.com>
Date:   Thu Oct 9 23:35:31 2008 +0800

wukong:002

commit 5a0f9ee71fe9ffe259b9b6cf842dd69baa95b307
Author: rocrocket <wupengchong@gmail.com>
Date:   Thu Oct 9 19:16:31 2008 +0800

bajie:001

commit 1ac0798784828577ecb808b03165facfb5bef3e3
Author: rocrocket <wupengchong@gmail.com>
Date:   Thu Oct 9 19:07:57 2008 +0800

wukong:001

commit d5d44dcdc938a263bdbc1c9cb06de24c27adebc7
Author: rocrocket <wupengchong@gmail.com>
Date:   Thu Oct 9 18:50:39 2008 +0800

master:001
看到了么,log好多阿!这回你可以推出一个结论,那就是:git merge的不仅仅是代码,而且还包括log!呵呵

6 由我操作,将wukong合并到master分支。

该到衣锦还乡的时候了!

悟空和八戒折腾了半天,是该回头找master(师傅)了。

先切换到master:

[rocrocket@wupengchong git21]$ git checkout master
Switched to branch “master”
[rocrocket@wupengchong git21]$ git branch
bajie
* master
wukong
[rocrocket@wupengchong git21]$

然后就是merge了!

[rocrocket@wupengchong git21]$ git merge wukong
Updating d5d44dc..e1ca782
Fast forward
roc.c |    2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
[rocrocket@wupengchong git21]$

很好,成功了!看看你的master分支的roc.c代码,是不是已经把悟空和八戒的劳动成果吸纳过来了 呵呵~

[rocrocket@wupengchong git21]$ cat -n roc.c
1    #include<stdio.h>
2    int main()
3    {
4        printf(“Please guess who he is.\n”);
5        printf(“He is a youngster.\n”);
6        printf(“He is a male.\n”);
7        return 0;
8    }
[rocrocket@wupengchong git21]$

很明显,youngster和male都已经到来了。

7 实验完毕。可以删除两个分支了。

好了,实验完毕了,master(师傅)已经将悟空和八戒的劳动成果吸纳为己有了(呵呵),看来悟空和八戒已经可以自由的去玩了。

我们先来删除bajie:

[rocrocket@wupengchong git21]$ git branch -d bajie
Deleted branch bajie.

很好,成功删除。我们使用了前面提到的-d选项,这个选项用于在分支成功合并后删除分支。

还有一个选项叫-D,是大写的d,它主要用于在分支失败后删除分支。

我们用-D删除wukong:

[rocrocket@wupengchong git21]$ git branch -D wukong
Deleted branch wukong.

看,也成功了!这是因为这两个分支都已经成功merge了。

那么在什么时候-D和-d不同呢。下次重点讲解。:)

今天写了很多内容,超级累了,读者一步一步跟下来,一定会对git的工作原理有更深的理解。欣慰欣慰~~ You can count on me!^_^

===
如果你对git感兴趣,请继续阅读:

《看日记学git》之二十二

《看日记学git》之二十三

《看日记学git》之二十四

over~

3条评论

  1. 我看了20章,也确实看到 git diff, git diff –cached, git diff HEAD 的区别,但是21章中,我试了几遍,branch experimental 出来的main.c 是最新的修改的,而不是commit的,也不是index file的。

  2. 请教:
    我现在有这种情况:

    有两个人使用windows进行开发,并且想通过网络进行代码提交操作,
    能否使用svn的那种方式,有一个server,两个开发人员都提交到这个server上,

    我不知道该如何做 :(

发表您的评论

请您放心,您的信息会被严格保密。必填项已标识 *