1. 本文面向已经了解/熟悉git基本命令但是并不熟悉如何使用GitHub进行多人协作开发项目的同学。

为了简单起见,这里假设只有两个开发人员,HuanianLiDaxiangLi。他们在GitHub上的地址和角色为:

HuanianLi将创建一个项目kaiba, 然后请DaxiangLi来帮忙做开发。 为了真实地进行场景演绎,我们将首先创建两个GitHub帐号。


1. 在GitHub上创建两个帐号(HuanianLi and DaxiangLi,这里以HuanianLi为例)

1.1 打开GitHub的主页: https://github.com/

1.2 点击右上角的Sign up

1.3 跳转到注册页面后,开始Create your personal account,按照要求输入Username, Email Address, Password, 例如:

1.4 点击页面下方的"Create an account"按钮并按照后续提示完成注册。


2. 在Linux桌面上创建两个用户(huanianli and daxiangli), (这里以huanianli为例)

2.1 创建用户huanianli

  1. root@idorax:~# useradd -d /home/huanianli -m -s /bin/bash -c "Huanian Li" huanianli

2.2 对用户huanianli的git进行设置 (这里直接编辑文件~/.gitconfig)

  1. huanianli@ThinkCentre:~$ vim ~/.gitconfig
  2. huanianli@ThinkCentre:~$ cat -n ~/.gitconfig
  3. [user]
  4. email = huanian.li@gmail.com
  5. name = Huanian Li
  6. [core]
  7. editor = vim
  8. [push]
  9. default = matching
  10. huanianli@ThinkCentre:~$
  11. huanianli@ThinkCentre:~$ git config -l
  12. user.email=huanian.li@gmail.com
  13. user.name=Huanian Li
  14. core.editor=vim
  15. push.default=matching
  16. huanianli@ThinkCentre:~$

2.3 在huanianli的HOME目录下创建一个工作空间workspace

  1. huanianli@ThinkCentre:~$ cd ~
  2. huanianli@ThinkCentre:~$ mkdir workspace
  3. huanianli@ThinkCentre:~$ ls
  4. workspace
  5. huanianli@ThinkCentre:~$

3. (Maintainer) HuanianLi在GitHub上创建一个项目kaiba

3.1 登录HuanianLi的GitHub空间,打开页面Repositories, e.g.

  1. https://github.com/HuanianLi?tab=repositories

点击页面右边的New按钮, 进入创建一个新的代码仓库的页面。

点击"Create repository"完成创建。

3.2 进入HuanianLi的Linux桌面,clone在3.1创建的项目kaiba

  1. huanianli@ThinkCentre:~$ cd workspace
  2. huanianli@ThinkCentre:~/workspace$ git clone https://github.com/HuanianLi/kaiba.git
  3. Cloning into 'kaiba'...
  4. warning: You appear to have cloned an empty repository.
  5. Checking connectivity... done.
  6. huanianli@ThinkCentre:~/workspace$ ls
  7. kaiba
  8. huanianli@ThinkCentre:~/workspace$ cd kaiba
  9. huanianli@ThinkCentre:~/workspace/kaiba$ vi README.md
  10. huanianli@ThinkCentre:~/workspace/kaiba$ cat -n README.md
  11. kaiba: A sandbox project of Kaiba
  12. huanianli@ThinkCentre:~/workspace/kaiba$
  13. huanianli@ThinkCentre:~/workspace/kaiba$ git add README.md
  14. huanianli@ThinkCentre:~/workspace/kaiba$
  15. huanianli@ThinkCentre:~/workspace/kaiba$ git commit -m "Initialize the project by adding README.md"
  16. [master (root-commit) c0bd2ed] Initialize the project by adding README.md
  17. file changed, insertion(+)
  18. create mode README.md
  19. huanianli@ThinkCentre:~/workspace/kaiba$
  20. huanianli@ThinkCentre:~/workspace/kaiba$ git log
  21. commit c0bd2ed35e10180209726199af422a63a007355f
  22. Author: Huanian Li <huanian.li@gmail.com>
  23. Date: Wed Jul :: +
  24.  
  25. Initialize the project by adding README.md
  26. huanianli@ThinkCentre:~/workspace/kaiba$
  27. huanianli@ThinkCentre:~/workspace/kaiba$ git branch
  28. * master
  29. huanianli@ThinkCentre:~/workspace/kaiba$
  30. huanianli@ThinkCentre:~/workspace/kaiba$ git push -u origin master
  31. Username for 'https://github.com': HuanianLi
  32. Password for 'https://HuanianLi@github.com':
  33. Counting objects: , done.
  34. Writing objects: % (/), bytes | bytes/s, done.
  35. Total (delta ), reused (delta )
  36. To https://github.com/HuanianLi/kaiba.git
  37. * [new branch] master -> master
  38. Branch master set up to track remote branch master from origin.
  39. huanianli@ThinkCentre:~/workspace/kaiba$

在上面的操作中,关键的步骤是:

  • clone
  1. git clone https://github.com/HuanianLi/kaiba.git
  • push
  1. git push -u origin master

注意: 因为是第一次push, ‘-u’ 是必须的。

3.3 一旦完成git push之后,我们就可以浏览GitHub上的项目了


4. (Contributor) DaxiangLi登录他的GitHub,  然后进入(Maintainer) HuanianLi的GitHub空间,fork项目kaiba

4.1 DaxiangLi登录他的GitHub

4.2 进入(Maintainer) HuanianLi的GitHub空间, 点开项目kaiba

注意: 目前的 Fork 为0。

4.3 fork项目kaiba, 直接点Fork按钮

Fork 结束后, DaxiangLi的GitHub里就有了项目kaiba


5. (Contributor)DaxiangLi贡献代码给项目kaiba

5.1 DaxiangLi在他的Linux桌面上clone代码

  1. daxiangli@ThinkPad:~/workspace$ git clone https://github.com/DaxiangLi/kaiba.git
  2. Cloning into 'kaiba'...
  3. remote: Counting objects: , done.
  4. remote: Total (delta ), reused (delta ), pack-reused
  5. Unpacking objects: % (/), done.
  6. Checking connectivity... done.

两个问题:

  • DaxiangLi 能直接clone HuanianLi的GitHub里的代码吗?  A: 能。
  • DaxiangLi 能直接clone HuanianLi的GitHub里的代码,然后做修改后push回去吗? A: 不能。

5.2 DaxiangLi新建一个开发分支

  1. daxiangli@ThinkPad:~/workspace/kaiba$ git checkout -b dev
  2. Switched to a new branch 'dev'

其中, git checkout -b dev 等同于

  1. git branch dev
  2. git checkout dev

5.3 把HuanianLi的项目添加到DaxiangLi的远程仓库

  1. daxiangli@ThinkPad:~/workspace/kaiba$ git remote add upstream https://github.com/HuanianLi/kaiba.git

5.4 将HuanianLi的分支取下来并更新到本地

  1. daxiangli@ThinkPad:~/workspace/kaiba$ git remote update
  2. Fetching origin
  3. Fetching upstream
  4. From https://github.com/HuanianLi/kaiba
  5. * [new branch] master -> upstream/master

  1. daxiangli@ThinkPad:~/workspace/kaiba$ git fetch upstream master
  2. From https://github.com/HuanianLi/kaiba
  3. * branch master -> FETCH_HEAD

5.5 合并HuanianLi的分支到本地(注意:这一步在第一次其实不需要)

  1. daxiangli@ThinkPad:~/workspace/kaiba$ git rebase upstream/master
  2. Current branch dev is up to date.

5.6 DaxiangLi添加一个文件并提交commit

  1. daxiangli@ThinkPad:~/workspace/kaiba$ git add foo.py
  2. daxiangli@ThinkPad:~/workspace/kaiba$ git commit -m "DaxiangLi: Add foo.py"
  3. daxiangli@ThinkPad:~/workspace/kaiba$ git push -u origin dev

5.7 进入DaxiangLi的GitHub, 提交一个PR

Q: 什么是PR? (参考资料来源点这里

A: PR是Pull Request的缩写,是开发者使用GitHub进行协作的利器。简单来说,Pull Request是一种机制,让开发者告诉项目成员一个功能已经完成。一旦feature分支开发完毕,开发者使用GitHub账号提交一个Pull Request。它告诉所有参与者,他们需要审查代码,并将代码并入master分支。Pull Request不只是一个通知,还是一个专注于某个提议功能的讨论版面。Pull Request 需要两个不同的分支或是两个不同的仓库, 其工作原理大概是:

  1. 开发者在他们的本地仓库中为某个功能创建一个专门的分支;
  2. 开发者将分支推送到公共的GitHub仓库;
  3. 开发者用GitHub发起一个Pull Request;
  4. 其余的团队成员审查代码,讨论并且做出修改;
  5. 项目维护者将这个功能并入官方的仓库,然后关闭这个Pull Request。

现在点击Compare & pull request按钮,就创建一个PR,

点页面下方的Create pull request按钮即可。 生成的PR看起来是这样的:


6. (Maintainer) HuanianLi 查看PR并Merge

6.1 HuanianLi查看PR

HuanianLi可能在PR中加入comment, 要求DaxiangLi做相应的修改。 这里为简单起见,直接Review通过。

6.2 HuanianLi点Merge pull request

到此为止,DaxiangLi成功地给HuanianLi贡献了一次代码!! 当然,这次贡献过程异常简单,因为未涉及到冲突解决。接下来将介绍更复杂的情况,这才是重点:-)

6.3 HuanianLi 查看kaiba并删除无用的commit

6.3.1 使用git pull更新本地空间

  1. huanianli@ThinkCentre:~/workspace/kaiba$ git pull
  2. remote: Counting objects: , done.
  3. remote: Compressing objects: % (/), done.
  4. remote: Total (delta ), reused (delta ), pack-reused
  5. Unpacking objects: % (/), done.
  6. From https://github.com/HuanianLi/kaiba
  7. c0bd2ed..b8a0b63 master -> origin/master
  8. Updating c0bd2ed..b8a0b63
  9. Fast-forward
  10. foo.py | ++++++++++++++++
  11. file changed, insertions(+)
  12. create mode foo.py

注意: 在顶端的commit不是我们想要的,需要把它移除掉。

  1. commit b8a0b63d8b18f8466e79284ed6022340ca5a43a8
  2. Merge: c0bd2ed 640f6f6
  3. Author: Huanian Li <+HuanianLi@users.noreply.github.com>
  4. Date: Wed Jul :: +
  5.  
  6. Merge pull request # from DaxiangLi/dev
  7.  
  8. DaxiangLi: Add foo.py

6.3.2 使用git rebase -i移除不需要的commit

  1. huanianli@ThinkCentre:~/workspace/kaiba$ git rebase -i c0bd2ed35e10180209726199af422a63a007355f
  2. Successfully rebased and updated refs/heads/master.

在弹出的交互界面中不做任何修改,直接保存退出即可。

6.3.3 使用git push --force强制更新远端的master分支

  1. huanianli@ThinkCentre:~/workspace/kaiba$ git push --force
  2. Username for 'https://github.com': HuanianLi
  3. Password for 'https://HuanianLi@github.com':
  4. Total (delta ), reused (delta )
  5. To https://github.com/HuanianLi/kaiba.git
  6. + b8a0b63...640f6f6 master -> master (forced update)

这下清爽啦!!


下面将重点讨论这两种比较复杂的场景:

  • 场景一 : PR Review过程中upstream有更新, 但没有冲突需要解决。例如: DaxiangLi继续修改foo.py, 提交一个PR, 在Review的过程中, HuanianLi增加了一个Makefile并提交了代码。
  • 场景二 : PR Review过程中upstream有更新, 而且需要解决冲突。例如: DaxiangLi继续修改foo.py, 提交一个PR, 在Review的过程中, HuanianLi也修改了foo.py并提交了代码。

这两种场景是常有的事情,因为PR提交后,在review的过程中可能改动多次。那么,在改动的过程中,别的合作伙伴给upstream里贡献了代码并导致commit增加是常有的事情。而且,别的合作伙伴很可能跟你改动了同一个文件,那么你就需要做冲突解决。


场景一: PR Review过程中upstream有更新, 但没有冲突需要解决

101 - 在开发之前,DaxiangLi先同步upstream,保证remotes/origin/master与remotes/upstream/master一致

  1. daxiangli@ThinkPad:~/workspace$
  2. daxiangli@ThinkPad:~/workspace$ git clone https://github.com/DaxiangLi/kaiba.git
  3. Cloning into 'kaiba'...
  4. remote: Counting objects: , done.
  5. remote: Compressing objects: % (/), done.
  6. remote: Total (delta ), reused (delta ), pack-reused
  7. Unpacking objects: % (/), done.
  8. Checking connectivity... done.
  9. daxiangli@ThinkPad:~/workspace$ cd kaiba
  10. daxiangli@ThinkPad:~/workspace/kaiba$ ls
  11. README.md
  12. daxiangli@ThinkPad:~/workspace/kaiba$
  13. daxiangli@ThinkPad:~/workspace/kaiba$ git remote add upstream https://github.com/HuanianLi/kaiba.git
  14. daxiangli@ThinkPad:~/workspace/kaiba$
  15. daxiangli@ThinkPad:~/workspace/kaiba$ git remote update
  16. Fetching origin
  17. Fetching upstream
  18. From https://github.com/HuanianLi/kaiba
  19. * [new branch] master -> upstream/master
  20. daxiangli@ThinkPad:~/workspace/kaiba$ ls
  21. README.md
  22. daxiangli@ThinkPad:~/workspace/kaiba$
  23. daxiangli@ThinkPad:~/workspace/kaiba$ git fetch upstream master
  24. From https://github.com/HuanianLi/kaiba
  25. * branch master -> FETCH_HEAD
  26. daxiangli@ThinkPad:~/workspace/kaiba$
  27. daxiangli@ThinkPad:~/workspace/kaiba$ git rebase upstream/master
  28. First, rewinding head to replay your work on top of it...
  29. Fast-forwarded master to upstream/master.
  30. daxiangli@ThinkPad:~/workspace/kaiba$ ls
  31. foo.py README.md
  32. daxiangli@ThinkPad:~/workspace/kaiba$
  33. daxiangli@ThinkPad:~/workspace/kaiba$ git log
  34. commit 640f6f63f4634915b4e4ed195e9a48d31cabb893
  35. Author: Daxiang Li <bjlhn@.com>
  36. Date: Wed Jul :: +
  37.  
  38. DaxiangLi: Add foo.py
  39.  
  40. commit c0bd2ed35e10180209726199af422a63a007355f
  41. Author: Huanian Li <huanian.li@gmail.com>
  42. Date: Wed Jul :: +
  43.  
  44. Initialize the project by adding README.md
  45. daxiangli@ThinkPad:~/workspace/kaiba$
  46. daxiangli@ThinkPad:~/workspace/kaiba$ git branch -a
  47. * master
  48. remotes/origin/HEAD -> origin/master
  49. remotes/origin/dev
  50. remotes/origin/master
  51. remotes/upstream/master
  52. daxiangli@ThinkPad:~/workspace/kaiba$
  53. daxiangli@ThinkPad:~/workspace/kaiba$ git push origin master
  54. Username for 'https://github.com': DaxiangLi
  55. Password for 'https://DaxiangLi@github.com':
  56. Total (delta ), reused (delta )
  57. To https://github.com/DaxiangLi/kaiba.git
  58. c0bd2ed..640f6f6 master -> master
  59. daxiangli@ThinkPad:~/workspace/kaiba$

102 - DaxiangLi 切换到dev分支

  1. daxiangli@ThinkPad:~/workspace/kaiba$ git branch -a
  2. * master
  3. remotes/origin/HEAD -> origin/master
  4. remotes/origin/dev
  5. remotes/origin/master
  6. remotes/upstream/master
  7. daxiangli@ThinkPad:~/workspace/kaiba$
  8. daxiangli@ThinkPad:~/workspace/kaiba$ git checkout dev
  9. Branch dev set up to track remote branch dev from origin.
  10. Switched to a new branch 'dev'
  11. daxiangli@ThinkPad:~/workspace/kaiba$ git log
  12. commit 640f6f63f4634915b4e4ed195e9a48d31cabb893
  13. Author: Daxiang Li <bjlhn@.com>
  14. Date: Wed Jul :: +
  15.  
  16. DaxiangLi: Add foo.py
  17.  
  18. commit c0bd2ed35e10180209726199af422a63a007355f
  19. Author: Huanian Li <huanian.li@gmail.com>
  20. Date: Wed Jul :: +
  21.  
  22. Initialize the project by adding README.md
  23. daxiangli@ThinkPad:~/workspace/kaiba$
  24. daxiangli@ThinkPad:~/workspace/kaiba$ git branch -a
  25. * dev
  26. master
  27. remotes/origin/HEAD -> origin/master
  28. remotes/origin/dev
  29. remotes/origin/master
  30. remotes/upstream/master
  31. daxiangli@ThinkPad:~/workspace/kaiba$

103 - DaxiangLi修改foo.py并commit,然后push到remotes/origin/dev

  1. daxiangli@ThinkPad:~/workspace/kaiba$ ls
  2. foo.py README.md
  3. daxiangli@ThinkPad:~/workspace/kaiba$
  4. daxiangli@ThinkPad:~/workspace/kaiba$ vi foo.py
  5. daxiangli@ThinkPad:~/workspace/kaiba$ git diff
  6. diff --git a/foo.py b/foo.py
  7. index 55568dd..4ca134c
  8. --- a/foo.py
  9. +++ b/foo.py
  10. @@ -, +, @@
  11. import sys
  12.  
  13. def main(argc, argv):
  14. + if argc != :
  15. + sys.stderr.write("Usage: %s <num>\n" % argv[])
  16. + return
  17. +
  18. i =
  19. while i < int(argv[]):
  20. print "%02d: Hello World." % i
  21. daxiangli@ThinkPad:~/workspace/kaiba$
  22. daxiangli@ThinkPad:~/workspace/kaiba$ git status
  23. On branch dev
  24. Your branch is up-to-date with 'origin/dev'.
  25. Changes not staged for commit:
  26. (use "git add <file>..." to update what will be committed)
  27. (use "git checkout -- <file>..." to discard changes in working directory)
  28.  
  29. modified: foo.py
  30.  
  31. no changes added to commit (use "git add" and/or "git commit -a")
  32. daxiangli@ThinkPad:~/workspace/kaiba$
  33. daxiangli@ThinkPad:~/workspace/kaiba$ git commit -a -m "DaxiangLi: add checking to foo.py"
  34. [dev e1bb21e] DaxiangLi: add checking to foo.py
  35. file changed, insertions(+)
  36. daxiangli@ThinkPad:~/workspace/kaiba$
  37. daxiangli@ThinkPad:~/workspace/kaiba$ git log
  38. commit e1bb21ee432a56fe83d8b3d79048d1623dde0b4d
  39. Author: Daxiang Li <bjlhn@.com>
  40. Date: Thu Jul :: +
  41.  
  42. DaxiangLi: add checking to foo.py
  43.  
  44. commit 640f6f63f4634915b4e4ed195e9a48d31cabb893
  45. Author: Daxiang Li <bjlhn@.com>
  46. Date: Wed Jul :: +
  47.  
  48. DaxiangLi: Add foo.py
  49.  
  50. commit c0bd2ed35e10180209726199af422a63a007355f
  51. Author: Huanian Li <huanian.li@gmail.com>
  52. Date: Wed Jul :: +
  53.  
  54. Initialize the project by adding README.md
  55. daxiangli@ThinkPad:~/workspace/kaiba$
  56. daxiangli@ThinkPad:~/workspace/kaiba$ git show
  57. commit e1bb21ee432a56fe83d8b3d79048d1623dde0b4d
  58. Author: Daxiang Li <bjlhn@.com>
  59. Date: Thu Jul :: +
  60.  
  61. DaxiangLi: add checking to foo.py
  62.  
  63. diff --git a/foo.py b/foo.py
  64. index 55568dd..4ca134c
  65. --- a/foo.py
  66. +++ b/foo.py
  67. @@ -, +, @@
  68. import sys
  69.  
  70. def main(argc, argv):
  71. + if argc != :
  72. + sys.stderr.write("Usage: %s <num>\n" % argv[])
  73. + return
  74. +
  75. i =
  76. while i < int(argv[]):
  77. print "%02d: Hello World." % i
  78. daxiangli@ThinkPad:~/workspace/kaiba$
  79. daxiangli@ThinkPad:~/workspace/kaiba$ git push origin dev
  80. Username for 'https://github.com': DaxiangLi
  81. Password for 'https://DaxiangLi@github.com':
  82. Counting objects: , done.
  83. Compressing objects: % (/), done.
  84. Writing objects: % (/), bytes | bytes/s, done.
  85. Total (delta ), reused (delta )
  86. remote: Resolving deltas: % (/), completed with local object.
  87. To https://github.com/DaxiangLi/kaiba.git
  88. 640f6f6..e1bb21e dev -> dev
  89. daxiangli@ThinkPad:~/workspace/kaiba$

现在,从DaxiangLi的GitHub空间里可以看到新增加到dev分支的commit e1bb21e。

104 - DaxiangLi为dev分支的commit e1bb21e创建一个PR

105 - HuanianLi开始review DaxiangLi的PR

105.1 在HuanianLi的GitHub空间里看到的PR

105.2 HuanianLi 给PR#2做review, 要求Daxiang Li做修改,于是Daxiang Li看到的PR是

105.3 - DaxiangLi根据HuanianLi的comments做修改

  1. daxiangli@ThinkPad:~/workspace/kaiba$ vi foo.py
  2. daxiangli@ThinkPad:~/workspace/kaiba$ git diff
  3. diff --git a/foo.py b/foo.py
  4. index 4ca134c..84b0787
  5. --- a/foo.py
  6. +++ b/foo.py
  7. @@ -, +, @@ import sys
  8. def main(argc, argv):
  9. if argc != :
  10. sys.stderr.write("Usage: %s <num>\n" % argv[])
  11. - return
  12. + return (-)
  13.  
  14. i =
  15. while i < int(argv[]):
  16. print "%02d: Hello World." % i
  17. i +=
  18.  
  19. - return
  20. + return ()
  21.  
  22. if __name__ == '__main__':
  23. argv = sys.argv
  24.  
  25. daxiangli@ThinkPad:~/workspace/kaiba$
  26. daxiangli@ThinkPad:~/workspace/kaiba$ git add foo.py
  27. daxiangli@ThinkPad:~/workspace/kaiba$ git commit -m "DaxiangLi: add checking to foo.py (2)"
  28. [dev d266d6b] DaxiangLi: add checking to foo.py ()
  29. file changed, insertions(+), deletions(-)
  30. daxiangli@ThinkPad:~/workspace/kaiba$ git log
  31. commit d266d6b3f4b6569e82dcd479c020a53f2d5ef556
  32. Author: Daxiang Li <bjlhn@.com>
  33. Date: Thu Jul :: +
  34.  
  35. DaxiangLi: add checking to foo.py ()
  36.  
  37. commit e1bb21ee432a56fe83d8b3d79048d1623dde0b4d
  38. Author: Daxiang Li <bjlhn@.com>
  39. Date: Thu Jul :: +
  40.  
  41. DaxiangLi: add checking to foo.py
  42.  
  43. commit 640f6f63f4634915b4e4ed195e9a48d31cabb893
  44. Author: Daxiang Li <bjlhn@.com>
  45. Date: Wed Jul :: +
  46.  
  47. DaxiangLi: Add foo.py
  48.  
  49. commit c0bd2ed35e10180209726199af422a63a007355f
  50. Author: Huanian Li <huanian.li@gmail.com>
  51. Date: Wed Jul :: +
  52.  
  53. Initialize the project by adding README.md
  54. daxiangli@ThinkPad:~/workspace/kaiba$
  55. daxiangli@ThinkPad:~/workspace/kaiba$ git push
  56. Username for 'https://github.com': DaxiangLi
  57. Password for 'https://DaxiangLi@github.com':
  58. Counting objects: , done.
  59. Compressing objects: % (/), done.
  60. Writing objects: % (/), bytes | bytes/s, done.
  61. Total (delta ), reused (delta )
  62. remote: Resolving deltas: % (/), completed with local object.
  63. To https://github.com/DaxiangLi/kaiba.git
  64. e1bb21e..d266d6b dev -> dev
  65. daxiangli@ThinkPad:~/workspace/kaiba$

105.4 DaxiangLi在PR上做comment, 告诉HuanianLi已经改好了。 (注意: PR上出现了两个commit)

  • commit 1: e1bb21e
  • commit 2: d266d6b

105.5 HuanianLi 重新检查DaxiangLi的PR

HuanianLi一看DaxiangLi的PR包含了多个commit, 这哪成啊。。。立即给DaxiangLi写comment, 要求合并多个commits为一个commit。

105.6 DaxiangLi着手合并多个commits

  1. daxiangli@ThinkPad:~/workspace/kaiba$ git log
  2. commit d266d6b3f4b6569e82dcd479c020a53f2d5ef556
  3. Author: Daxiang Li <bjlhn@.com>
  4. Date: Thu Jul :: +
  5.  
  6. DaxiangLi: add checking to foo.py ()
  7.  
  8. commit e1bb21ee432a56fe83d8b3d79048d1623dde0b4d
  9. Author: Daxiang Li <bjlhn@.com>
  10. Date: Thu Jul :: +
  11.  
  12. DaxiangLi: add checking to foo.py
  13.  
  14. commit 640f6f63f4634915b4e4ed195e9a48d31cabb893
  15. Author: Daxiang Li <bjlhn@.com>
  16. Date: Wed Jul :: +
  17.  
  18. DaxiangLi: Add foo.py
  19.  
  20. commit c0bd2ed35e10180209726199af422a63a007355f
  21. Author: Huanian Li <huanian.li@gmail.com>
  22. Date: Wed Jul :: +
  23.  
  24. Initialize the project by adding README.md
  25. daxiangli@ThinkPad:~/workspace/kaiba$
  26. daxiangli@ThinkPad:~/workspace/kaiba$ git rebase -i 640f6f6
  27. [detached HEAD 7bab5c2] DaxiangLi: add checking to foo.py
  28. Date: Thu Jul :: +
  29. file changed, insertions(+), deletion(-)
  30. Successfully rebased and updated refs/heads/dev.
  31. daxiangli@ThinkPad:~/workspace/kaiba$ git log
  32. commit 7bab5c2d12389b6a5bf5cd602dff684ea336a52e
  33. Author: Daxiang Li <bjlhn@.com>
  34. Date: Thu Jul :: +
  35.  
  36. DaxiangLi: add checking to foo.py
  37.  
  38. commit 640f6f63f4634915b4e4ed195e9a48d31cabb893
  39. Author: Daxiang Li <bjlhn@.com>
  40. Date: Wed Jul :: +
  41.  
  42. DaxiangLi: Add foo.py
  43.  
  44. commit c0bd2ed35e10180209726199af422a63a007355f
  45. Author: Huanian Li <huanian.li@gmail.com>
  46. Date: Wed Jul :: +
  47.  
  48. Initialize the project by adding README.md
  49. daxiangli@ThinkPad:~/workspace/kaiba$ git diff
  50. daxiangli@ThinkPad:~/workspace/kaiba$ git show
  51. commit 7bab5c2d12389b6a5bf5cd602dff684ea336a52e
  52. Author: Daxiang Li <bjlhn@.com>
  53. Date: Thu Jul :: +
  54.  
  55. DaxiangLi: add checking to foo.py
  56.  
  57. diff --git a/foo.py b/foo.py
  58. index 55568dd..84b0787
  59. --- a/foo.py
  60. +++ b/foo.py
  61. @@ -, +, @@
  62. import sys
  63.  
  64. def main(argc, argv):
  65. + if argc != :
  66. + sys.stderr.write("Usage: %s <num>\n" % argv[])
  67. + return (-)
  68. +
  69. i =
  70. while i < int(argv[]):
  71. print "%02d: Hello World." % i
  72. i +=
  73.  
  74. - return
  75. + return ()
  76.  
  77. if __name__ == '__main__':
  78. argv = sys.argv
  79. daxiangli@ThinkPad:~/workspace/kaiba$
  80. daxiangli@ThinkPad:~/workspace/kaiba$ git push --force
  81. Username for 'https://github.com': DaxiangLi
  82. Password for 'https://DaxiangLi@github.com':
  83. Counting objects: , done.
  84. Compressing objects: % (/), done.
  85. Writing objects: % (/), bytes | bytes/s, done.
  86. Total (delta ), reused (delta )
  87. remote: Resolving deltas: % (/), completed with local object.
  88. To https://github.com/DaxiangLi/kaiba.git
  89. + d266d6b...7bab5c2 dev -> dev (forced update)
  90. daxiangli@ThinkPad:~/workspace/kaiba$

注意:

  1. 做git push的时候必须使用 'git push --force'
  2. 做git rebase -i <commit id>的时候, <commit id>是上一次官方merge的commit id.

关于git rebase -i <commit id>的过程,图解如下:

  • 01 - 开始做rebase

  • 02 - 进入rebase交互界面,注意阅读各个command的含义

  • 03 - 将commit d266d6b应用squash

  • 04 - 在vim里按:wq (保存退出)

  • 05 - 切换到commit交互界面

  • 06 : 删除L6-9, 然后保存退出vim

105.7 DaxiangLi更改一下commit的comment, 重新push

  1. daxiangli@ThinkPad:~/workspace/kaiba$ git commit --amend
  2. [dev 254347c] DaxiangLi: Add checking to foo.py
  3. Date: Thu Jul :: +
  4. file changed, insertions(+), deletion(-)
  5. daxiangli@ThinkPad:~/workspace/kaiba$ git log
  6. commit 254347cbe57fa043ffcc774e26eabdcd63ea8b30
  7. Author: Daxiang Li <bjlhn@.com>
  8. Date: Thu Jul :: +
  9.  
  10. DaxiangLi: Add checking to foo.py
  11.  
  12. commit 640f6f63f4634915b4e4ed195e9a48d31cabb893
  13. Author: Daxiang Li <bjlhn@.com>
  14. Date: Wed Jul :: +
  15.  
  16. DaxiangLi: Add foo.py
  17.  
  18. commit c0bd2ed35e10180209726199af422a63a007355f
  19. Author: Huanian Li <huanian.li@gmail.com>
  20. Date: Wed Jul :: +
  21.  
  22. Initialize the project by adding README.md
  23. daxiangli@ThinkPad:~/workspace/kaiba$ git push --force
  24. Username for 'https://github.com': DaxiangLi
  25. Password for 'https://DaxiangLi@github.com':
  26. Counting objects: , done.
  27. Compressing objects: % (/), done.
  28. Writing objects: % (/), bytes | bytes/s, done.
  29. Total (delta ), reused (delta )
  30. remote: Resolving deltas: % (/), completed with local object.
  31. To https://github.com/DaxiangLi/kaiba.git
  32. + db73315...254347c dev -> dev (forced update)

105.8 DaxiangLi重新在PR上加comment, 请HuanianLi再次review (注意: PR上现在只有一个commit了)

105.9 HuanianLi 给kaiba.git里添加一个Makefile, 在检查DaxiangLi的PR最近改动之前

  1. huanianli@ThinkCentre:~/workspace/kaiba$ ls
  2. foo.py README.md
  3. huanianli@ThinkCentre:~/workspace/kaiba$ git log
  4. commit 640f6f63f4634915b4e4ed195e9a48d31cabb893
  5. Author: Daxiang Li <bjlhn@.com>
  6. Date: Wed Jul :: +
  7.  
  8. DaxiangLi: Add foo.py
  9.  
  10. commit c0bd2ed35e10180209726199af422a63a007355f
  11. Author: Huanian Li <huanian.li@gmail.com>
  12. Date: Wed Jul :: +
  13.  
  14. Initialize the project by adding README.md
  15. huanianli@ThinkCentre:~/workspace/kaiba$
  16. huanianli@ThinkCentre:~/workspace/kaiba$ vi Makefile
  17. huanianli@ThinkCentre:~/workspace/kaiba$ make
  18. cp foo.py foo && chmod +x foo
  19. huanianli@ThinkCentre:~/workspace/kaiba$ ls
  20. foo foo.py Makefile README.md
  21. huanianli@ThinkCentre:~/workspace/kaiba$
  22. huanianli@ThinkCentre:~/workspace/kaiba$ git add Makefile
  23. huanianli@ThinkCentre:~/workspace/kaiba$ git commit -m "HuanianLi: Add Makefile"
  24. [master 3609dff] HuanianLi: Add Makefile
  25. file changed, insertions(+)
  26. create mode Makefile
  27. huanianli@ThinkCentre:~/workspace/kaiba$ git log
  28. commit 3609dff98de5a17a09484738328a0e9db1784e0d
  29. Author: Huanian Li <huanian.li@gmail.com>
  30. Date: Thu Jul :: +
  31.  
  32. HuanianLi: Add Makefile
  33.  
  34. commit 640f6f63f4634915b4e4ed195e9a48d31cabb893
  35. Author: Daxiang Li <bjlhn@.com>
  36. Date: Wed Jul :: +
  37.  
  38. DaxiangLi: Add foo.py
  39.  
  40. commit c0bd2ed35e10180209726199af422a63a007355f
  41. Author: Huanian Li <huanian.li@gmail.com>
  42. Date: Wed Jul :: +
  43.  
  44. Initialize the project by adding README.md
  45. huanianli@ThinkCentre:~/workspace/kaiba$ git branch -a
  46. * master
  47. remotes/origin/master
  48. huanianli@ThinkCentre:~/workspace/kaiba$ git push
  49. Username for 'https://github.com': HuanianLi
  50. Password for 'https://HuanianLi@github.com':
  51. Counting objects: , done.
  52. Compressing objects: % (/), done.
  53. Writing objects: % (/), bytes | bytes/s, done.
  54. Total (delta ), reused (delta )
  55. To https://github.com/HuanianLi/kaiba.git
  56. 640f6f6..3609dff master -> master
  57. huanianli@ThinkCentre:~/workspace/kaiba$

这时候, HuanianLi的master里包含了3个commits, 而DaxiangLi的master里包含了2个commits, dev分支里包含了3个commits。 那么,如果DaxiangLi的dev分支里的top commit (254347c) 被合并到HuanianLi的master分支的时候,这一commit可能成为top commit, 也就是第4个commit,当然也可能成为第3个commit。

  1. --- HuanianLi's master branch ---
  2. commit 3609dff HuanianLi: Add Makefile
  3. commit 640f6f6 DaxiangLi: Add foo.py
  4. commit c0bd2ed Initialize the project by adding README.md
  5.  
  6. --- DaxiangLi's master branch ---
  7. commit 640f6f6 DaxiangLi: Add foo.py
  8. commit c0bd2ed Initialize the project by adding README.md
  9.  
  10. --- DaxiangLi's dev branch ---
  11. commit 254347c DaxiangLi: Add checking to foo.py
  12. commit 640f6f6 DaxiangLi: Add foo.py
  13. commit c0bd2ed Initialize the project by adding README.md
  14.  
  15. #
  16. # After commit 7bab5c2 from DaxiangLi's dev branch
  17. # is merged into HuanianLi's master branch
  18. #
  19. --- HuanianLi's master branch looks like ---
  20. commit 254347c DaxiangLi: Add checking to foo.py
  21. commit 3609dff HuanianLi: Add Makefile
  22. commit 640f6f6 DaxiangLi: Add foo.py
  23. commit c0bd2ed Initialize the project by adding README.md
  24.  
  25. # OR
  26. commit 3609dff HuanianLi: Add Makefile
  27. commit 254347c DaxiangLi: Add checking to foo.py
  28. commit 640f6f6 DaxiangLi: Add foo.py
  29. commit c0bd2ed Initialize the project by adding README.md

105.10 HuanianLi再次检查DaxiangLi的PR, 发现只有一个commit了,而且与他的master分支没有冲突,决定merge!!

点击Merge pull request按钮右边的向下箭头,我们可看到有三种Merge方式,这一次,我们将采用Rebase and merge。

105.11 HuanianLi采用Rebase and merge选项处理DaxiangLi的PR

Merge 完毕后,在HuanianLi的GitHub空间可以看到

HuanianLi重新clone一下kaiba.git, 通过git检查Merge:

  1. huanianli@ThinkCentre:~/workspace$ git clone https://github.com/HuanianLi/kaiba.git
  2. Cloning into 'kaiba'...
  3. remote: Counting objects: , done.
  4. remote: Compressing objects: % (/), done.
  5. remote: Total (delta ), reused (delta ), pack-reused
  6. Unpacking objects: % (/), done.
  7. Checking connectivity... done.
  8. huanianli@ThinkCentre:~/workspace$ cd kaiba
  9. huanianli@ThinkCentre:~/workspace/kaiba$
  10. huanianli@ThinkCentre:~/workspace/kaiba$ git log
  11. commit 27aca2bcc0fcffb26828cac1eebe517439ef49c9
  12. Author: Daxiang Li <bjlhn@.com>
  13. Date: Thu Jul :: +
  14.  
  15. DaxiangLi: Add checking to foo.py
  16.  
  17. commit 3609dff98de5a17a09484738328a0e9db1784e0d
  18. Author: Huanian Li <huanian.li@gmail.com>
  19. Date: Thu Jul :: +
  20.  
  21. HuanianLi: Add Makefile
  22.  
  23. commit 640f6f63f4634915b4e4ed195e9a48d31cabb893
  24. Author: Daxiang Li <bjlhn@.com>
  25. Date: Wed Jul :: +
  26.  
  27. DaxiangLi: Add foo.py
  28.  
  29. commit c0bd2ed35e10180209726199af422a63a007355f
  30. Author: Huanian Li <huanian.li@gmail.com>
  31. Date: Wed Jul :: +
  32.  
  33. Initialize the project by adding README.md
  34. huanianli@ThinkCentre:~/workspace/kaiba$

106 - DaxiangLi 需要重新sync一下master (这一过程我们在前面介绍过,按照基本套路执行即可)

  1. daxiangli@ThinkPad:~/workspace/kaiba$
  2. daxiangli@ThinkPad:~/workspace/kaiba$ git branch
  3. * dev
  4. master
  5. daxiangli@ThinkPad:~/workspace/kaiba$ git checkout master
  6. Switched to branch 'master'
  7. Your branch is up-to-date with 'origin/master'.
  8. daxiangli@ThinkPad:~/workspace/kaiba$
  9. daxiangli@ThinkPad:~/workspace/kaiba$ git branch
  10. dev
  11. * master
  12. daxiangli@ThinkPad:~/workspace/kaiba$
  13. daxiangli@ThinkPad:~/workspace/kaiba$ git remote -v
  14. origin https://github.com/DaxiangLi/kaiba.git (fetch)
  15. origin https://github.com/DaxiangLi/kaiba.git (push)
  16. upstream https://github.com/HuanianLi/kaiba.git (fetch)
  17. upstream https://github.com/HuanianLi/kaiba.git (push)
  18. daxiangli@ThinkPad:~/workspace/kaiba$
  19. daxiangli@ThinkPad:~/workspace/kaiba$ git remote update
  20. Fetching origin
  21. Fetching upstream
  22. remote: Counting objects: , done.
  23. remote: Compressing objects: % (/), done.
  24. remote: Total (delta ), reused (delta ), pack-reused
  25. Unpacking objects: % (/), done.
  26. From https://github.com/HuanianLi/kaiba
  27. 640f6f6..27aca2b master -> upstream/master
  28. daxiangli@ThinkPad:~/workspace/kaiba$
  29.  
  30. daxiangli@ThinkPad:~/workspace/kaiba$ git log
  31. commit 640f6f63f4634915b4e4ed195e9a48d31cabb893
  32. Author: Daxiang Li <bjlhn@.com>
  33. Date: Wed Jul :: +
  34.  
  35. DaxiangLi: Add foo.py
  36.  
  37. commit c0bd2ed35e10180209726199af422a63a007355f
  38. Author: Huanian Li <huanian.li@gmail.com>
  39. Date: Wed Jul :: +
  40.  
  41. Initialize the project by adding README.md
  42. daxiangli@ThinkPad:~/workspace/kaiba$
  43. daxiangli@ThinkPad:~/workspace/kaiba$ git fetch upstream master
  44. From https://github.com/HuanianLi/kaiba
  45. * branch master -> FETCH_HEAD
  46. daxiangli@ThinkPad:~/workspace/kaiba$
  47. daxiangli@ThinkPad:~/workspace/kaiba$ git rebase upstream/master
  48. First, rewinding head to replay your work on top of it...
  49. Fast-forwarded master to upstream/master.
  50. daxiangli@ThinkPad:~/workspace/kaiba$
  51. daxiangli@ThinkPad:~/workspace/kaiba$ git log
  52. commit 27aca2bcc0fcffb26828cac1eebe517439ef49c9
  53. Author: Daxiang Li <bjlhn@.com>
  54. Date: Thu Jul :: +
  55.  
  56. DaxiangLi: Add checking to foo.py
  57.  
  58. commit 3609dff98de5a17a09484738328a0e9db1784e0d
  59. Author: Huanian Li <huanian.li@gmail.com>
  60. Date: Thu Jul :: +
  61.  
  62. HuanianLi: Add Makefile
  63.  
  64. commit 640f6f63f4634915b4e4ed195e9a48d31cabb893
  65. Author: Daxiang Li <bjlhn@.com>
  66. Date: Wed Jul :: +
  67.  
  68. DaxiangLi: Add foo.py
  69.  
  70. commit c0bd2ed35e10180209726199af422a63a007355f
  71. Author: Huanian Li <huanian.li@gmail.com>
  72. Date: Wed Jul :: +
  73.  
  74. Initialize the project by adding README.md
  75. daxiangli@ThinkPad:~/workspace/kaiba$
  76. daxiangli@ThinkPad:~/workspace/kaiba$ git push origin master
  77. Username for 'https://github.com': DaxiangLi
  78. Password for 'https://DaxiangLi@github.com':
  79. Counting objects: , done.
  80. Compressing objects: % (/), done.
  81. Writing objects: % (/), bytes | bytes/s, done.
  82. Total (delta ), reused (delta )
  83. remote: Resolving deltas: % (/), completed with local object.
  84. To https://github.com/DaxiangLi/kaiba.git
  85. 640f6f6..27aca2b master -> master
  86. daxiangli@ThinkPad:~/workspace/kaiba$

注意: 这里用到的关键命令是:

  1. $ git checkout master
  2. $[ git remote add upstream https://github.com/HuanianLi/kaiba.git ]
  3. $ git remote -v
  4. $ git remote update
  5. $ git fetch upstream master
  6. $ git rebase upstream/master
  7. $ git push origin master

107 - DaxiangLi将dev分支也sync一下(跟origin master同步即可),以便下一次做开发

  1. daxiangli@ThinkPad:~/workspace/kaiba$
  2. daxiangli@ThinkPad:~/workspace/kaiba$ git branch
  3. dev
  4. * master
  5. daxiangli@ThinkPad:~/workspace/kaiba$ git checkout dev
  6. Switched to branch 'dev'
  7. Your branch is up-to-date with 'origin/dev'.
  8. daxiangli@ThinkPad:~/workspace/kaiba$
  9. daxiangli@ThinkPad:~/workspace/kaiba$ git branch
  10. * dev
  11. master
  12. daxiangli@ThinkPad:~/workspace/kaiba$
  13. daxiangli@ThinkPad:~/workspace/kaiba$ git log
  14. commit 254347cbe57fa043ffcc774e26eabdcd63ea8b30
  15. Author: Daxiang Li <bjlhn@.com>
  16. Date: Thu Jul :: +
  17.  
  18. DaxiangLi: Add checking to foo.py
  19.  
  20. commit 640f6f63f4634915b4e4ed195e9a48d31cabb893
  21. Author: Daxiang Li <bjlhn@.com>
  22. Date: Wed Jul :: +
  23.  
  24. DaxiangLi: Add foo.py
  25.  
  26. commit c0bd2ed35e10180209726199af422a63a007355f
  27. Author: Huanian Li <huanian.li@gmail.com>
  28. Date: Wed Jul :: +
  29.  
  30. Initialize the project by adding README.md
  31. daxiangli@ThinkPad:~/workspace/kaiba$
  32. daxiangli@ThinkPad:~/workspace/kaiba$ git fetch origin master
  33. From https://github.com/DaxiangLi/kaiba
  34. * branch master -> FETCH_HEAD
  35. daxiangli@ThinkPad:~/workspace/kaiba$ git rebase origin/master
  36. First, rewinding head to replay your work on top of it...
  37. daxiangli@ThinkPad:~/workspace/kaiba$
  38. daxiangli@ThinkPad:~/workspace/kaiba$ git log
  39. commit 27aca2bcc0fcffb26828cac1eebe517439ef49c9
  40. Author: Daxiang Li <bjlhn@.com>
  41. Date: Thu Jul :: +
  42.  
  43. DaxiangLi: Add checking to foo.py
  44.  
  45. commit 3609dff98de5a17a09484738328a0e9db1784e0d
  46. Author: Huanian Li <huanian.li@gmail.com>
  47. Date: Thu Jul :: +
  48.  
  49. HuanianLi: Add Makefile
  50.  
  51. commit 640f6f63f4634915b4e4ed195e9a48d31cabb893
  52. Author: Daxiang Li <bjlhn@.com>
  53. Date: Wed Jul :: +
  54.  
  55. DaxiangLi: Add foo.py
  56.  
  57. commit c0bd2ed35e10180209726199af422a63a007355f
  58. Author: Huanian Li <huanian.li@gmail.com>
  59. Date: Wed Jul :: +
  60.  
  61. Initialize the project by adding README.md
  62. daxiangli@ThinkPad:~/workspace/kaiba$
  63. daxiangli@ThinkPad:~/workspace/kaiba$
  64. daxiangli@ThinkPad:~/workspace/kaiba$ git push origin dev
  65. Username for 'https://github.com': DaxiangLi
  66. Password for 'https://DaxiangLi@github.com':
  67. To https://github.com/DaxiangLi/kaiba.git
  68. ! [rejected] dev -> dev (non-fast-forward)
  69. error: failed to push some refs to 'https://github.com/DaxiangLi/kaiba.git'
  70. hint: Updates were rejected because the tip of your current branch is behind
  71. hint: its remote counterpart. Integrate the remote changes (e.g.
  72. hint: 'git pull ...') before pushing again.
  73. hint: See the 'Note about fast-forwards' in 'git push --help' for details.
  74. daxiangli@ThinkPad:~/workspace/kaiba$
  75. daxiangli@ThinkPad:~/workspace/kaiba$
  76. daxiangli@ThinkPad:~/workspace/kaiba$ git push origin dev --force
  77. Username for 'https://github.com': DaxiangLi
  78. Password for 'https://DaxiangLi@github.com':
  79. Total (delta ), reused (delta )
  80. To https://github.com/DaxiangLi/kaiba.git
  81. + 254347c...27aca2b dev -> dev (forced update)
  82. daxiangli@ThinkPad:~/workspace/kaiba$

注意: 这里用到的关键命令是:

  1. $ git checkout dev
  2. $ git fetch origin master
  3. $ git rebase origin/master
  4. $ git push origin dev --force

到这里,场景一我们就介绍完毕了, 接下来介绍场景二


场景二: PR Review过程中upstream有更新, 而且需要解决冲突

201 - DaxiangLi第一次更改foo.py

  1. daxiangli@ThinkPad:~$
  2. daxiangli@ThinkPad:~$ rm -rf workspace/kaiba
  3. daxiangli@ThinkPad:~$ cd workspace
  4. daxiangli@ThinkPad:~/workspace$
  5. daxiangli@ThinkPad:~/workspace$ git clone https://github.com/DaxiangLi/kaiba.git
  6. Cloning into 'kaiba'...
  7. remote: Counting objects: , done.
  8. remote: Compressing objects: % (/), done.
  9. remote: Total (delta ), reused (delta ), pack-reused
  10. Unpacking objects: % (/), done.
  11. Checking connectivity... done.
  12. daxiangli@ThinkPad:~/workspace$ cd kaiba
  13. daxiangli@ThinkPad:~/workspace/kaiba$
  14. daxiangli@ThinkPad:~/workspace/kaiba$ git remote -v
  15. origin https://github.com/DaxiangLi/kaiba.git (fetch)
  16. origin https://github.com/DaxiangLi/kaiba.git (push)
  17. daxiangli@ThinkPad:~/workspace/kaiba$
  18. daxiangli@ThinkPad:~/workspace/kaiba$ git remote add upstream https://github.com/HuanianLi/kaiba.git
  19. daxiangli@ThinkPad:~/workspace/kaiba$
  20. daxiangli@ThinkPad:~/workspace/kaiba$ git remote -v
  21. origin https://github.com/DaxiangLi/kaiba.git (fetch)
  22. origin https://github.com/DaxiangLi/kaiba.git (push)
  23. upstream https://github.com/HuanianLi/kaiba.git (fetch)
  24. upstream https://github.com/HuanianLi/kaiba.git (push)
  25. daxiangli@ThinkPad:~/workspace/kaiba$
  26.  
  27. daxiangli@ThinkPad:~/workspace/kaiba$ git branch
  28. * master
  29. daxiangli@ThinkPad:~/workspace/kaiba$ git branch -a
  30. * master
  31. remotes/origin/HEAD -> origin/master
  32. remotes/origin/dev
  33. remotes/origin/master
  34. daxiangli@ThinkPad:~/workspace/kaiba$ git checkout dev
  35. Branch dev set up to track remote branch dev from origin.
  36. Switched to a new branch 'dev'
  37. daxiangli@ThinkPad:~/workspace/kaiba$
  38. daxiangli@ThinkPad:~/workspace/kaiba$ git branch
  39. * dev
  40. master
  41. daxiangli@ThinkPad:~/workspace/kaiba$
  42. daxiangli@ThinkPad:~/workspace/kaiba$ vi foo.py
  43. daxiangli@ThinkPad:~/workspace/kaiba$ git diff foo.py
  44. diff --git a/foo.py b/foo.py
  45. index 84b0787..44635b7
  46. --- a/foo.py
  47. +++ b/foo.py
  48. @@ -, +, @@ def main(argc, argv):
  49. sys.stderr.write("Usage: %s <num>\n" % argv[])
  50. return (-)
  51.  
  52. - i =
  53. - while i < int(argv[]):
  54. + for i in range(int(argv[])):
  55. print "%02d: Hello World." % i
  56. - i +=
  57.  
  58. return ()
  59.  
  60. daxiangli@ThinkPad:~/workspace/kaiba$
  61. daxiangli@ThinkPad:~/workspace/kaiba$ git add foo.py
  62. daxiangli@ThinkPad:~/workspace/kaiba$ git commit -m "DaxiangLi: Update foo.py to use for instead of while"
  63. [dev 099cfc7] DaxiangLi: Update foo.py to use for instead of while
  64. file changed, insertion(+), deletions(-)
  65. daxiangli@ThinkPad:~/workspace/kaiba$
  66. daxiangli@ThinkPad:~/workspace/kaiba$ git log
  67. commit 099cfc7de963a4cbe8ceb7088a710bdb4815dd9d
  68. Author: Daxiang Li <bjlhn@.com>
  69. Date: Thu Jul :: +
  70.  
  71. DaxiangLi: Update foo.py to use for instead of while
  72.  
  73. commit 27aca2bcc0fcffb26828cac1eebe517439ef49c9
  74. Author: Daxiang Li <bjlhn@.com>
  75. Date: Thu Jul :: +
  76.  
  77. DaxiangLi: Add checking to foo.py
  78.  
  79. commit 3609dff98de5a17a09484738328a0e9db1784e0d
  80. Author: Huanian Li <huanian.li@gmail.com>
  81. Date: Thu Jul :: +
  82.  
  83. HuanianLi: Add Makefile
  84.  
  85. commit 640f6f63f4634915b4e4ed195e9a48d31cabb893
  86. Author: Daxiang Li <bjlhn@.com>
  87. Date: Wed Jul :: +
  88.  
  89. DaxiangLi: Add foo.py
  90.  
  91. commit c0bd2ed35e10180209726199af422a63a007355f
  92. Author: Huanian Li <huanian.li@gmail.com>
  93. Date: Wed Jul :: +
  94.  
  95. Initialize the project by adding README.md
  96. daxiangli@ThinkPad:~/workspace/kaiba$
  97. daxiangli@ThinkPad:~/workspace/kaiba$ git push origin dev
  98. Username for 'https://github.com': DaxiangLi
  99. Password for 'https://DaxiangLi@github.com':
  100. Counting objects: , done.
  101. Compressing objects: % (/), done.
  102. Writing objects: % (/), bytes | bytes/s, done.
  103. Total (delta ), reused (delta )
  104. remote: Resolving deltas: % (/), completed with local objects.
  105. To https://github.com/DaxiangLi/kaiba.git
  106. 27aca2b..099cfc7 dev -> dev
  107. daxiangli@ThinkPad:~/workspace/kaiba$

202 - DaxiangLi第二次更改foo.py

提交更新到remotes/origin/dev分支后不满意,于是做第二次修改再提交,这里为了保持只有一个commit, 将会用到

  1. $ git commit -a -m "comments" --amend

全部修改过程如下:

  1. daxiangli@ThinkPad:~/workspace/kaiba$
  2. daxiangli@ThinkPad:~/workspace/kaiba$ git log
  3. commit 099cfc7de963a4cbe8ceb7088a710bdb4815dd9d
  4. Author: Daxiang Li <bjlhn@.com>
  5. Date: Thu Jul :: +
  6.  
  7. DaxiangLi: Update foo.py to use for instead of while
  8.  
  9. commit 27aca2bcc0fcffb26828cac1eebe517439ef49c9
  10. Author: Daxiang Li <bjlhn@.com>
  11. Date: Thu Jul :: +
  12.  
  13. DaxiangLi: Add checking to foo.py
  14.  
  15. commit 3609dff98de5a17a09484738328a0e9db1784e0d
  16. Author: Huanian Li <huanian.li@gmail.com>
  17. Date: Thu Jul :: +
  18.  
  19. HuanianLi: Add Makefile
  20.  
  21. commit 640f6f63f4634915b4e4ed195e9a48d31cabb893
  22. Author: Daxiang Li <bjlhn@.com>
  23. Date: Wed Jul :: +
  24.  
  25. DaxiangLi: Add foo.py
  26.  
  27. commit c0bd2ed35e10180209726199af422a63a007355f
  28. Author: Huanian Li <huanian.li@gmail.com>
  29. Date: Wed Jul :: +
  30.  
  31. Initialize the project by adding README.md
  32. daxiangli@ThinkPad:~/workspace/kaiba$
  33. daxiangli@ThinkPad:~/workspace/kaiba$
  34. daxiangli@ThinkPad:~/workspace/kaiba$ git diff
  35. daxiangli@ThinkPad:~/workspace/kaiba$
  36. daxiangli@ThinkPad:~/workspace/kaiba$ vi foo.py
  37. daxiangli@ThinkPad:~/workspace/kaiba$
  38. daxiangli@ThinkPad:~/workspace/kaiba$ git add foo.py
  39. daxiangli@ThinkPad:~/workspace/kaiba$
  40. daxiangli@ThinkPad:~/workspace/kaiba$ git commit -m "DaxiangLi: Update foo.py to use 'for' instead of 'while'" --amend
  41. [dev 3b9d809] DaxiangLi: Update foo.py to use 'for' instead of 'while'
  42. Date: Thu Jul :: +
  43. file changed, insertions(+), deletions(-)
  44. daxiangli@ThinkPad:~/workspace/kaiba$ git log
  45. commit 3b9d809f249abfd4d5a53d35006d63f341efbacf
  46. Author: Daxiang Li <bjlhn@.com>
  47. Date: Thu Jul :: +
  48.  
  49. DaxiangLi: Update foo.py to use 'for' instead of 'while'
  50.  
  51. commit 27aca2bcc0fcffb26828cac1eebe517439ef49c9
  52. Author: Daxiang Li <bjlhn@.com>
  53. Date: Thu Jul :: +
  54.  
  55. DaxiangLi: Add checking to foo.py
  56.  
  57. commit 3609dff98de5a17a09484738328a0e9db1784e0d
  58. Author: Huanian Li <huanian.li@gmail.com>
  59. Date: Thu Jul :: +
  60.  
  61. HuanianLi: Add Makefile
  62.  
  63. commit 640f6f63f4634915b4e4ed195e9a48d31cabb893
  64. Author: Daxiang Li <bjlhn@.com>
  65. Date: Wed Jul :: +
  66.  
  67. DaxiangLi: Add foo.py
  68.  
  69. commit c0bd2ed35e10180209726199af422a63a007355f
  70. Author: Huanian Li <huanian.li@gmail.com>
  71. Date: Wed Jul :: +
  72.  
  73. Initialize the project by adding README.md
  74. daxiangli@ThinkPad:~/workspace/kaiba$
  75. daxiangli@ThinkPad:~/workspace/kaiba$ git push origin dev --force
  76. Username for 'https://github.com': DaxiangLi
  77. Password for 'https://DaxiangLi@github.com':
  78. Counting objects: , done.
  79. Compressing objects: % (/), done.
  80. Writing objects: % (/), bytes | bytes/s, done.
  81. Total (delta ), reused (delta )
  82. remote: Resolving deltas: % (/), completed with local objects.
  83. To https://github.com/DaxiangLi/kaiba.git
  84. + 099cfc7...3b9d809 dev -> dev (forced update)
  85. daxiangli@ThinkPad:~/workspace/kaiba$

203 - DaxiangLi创建一个PR

204 - HuanianLi更新foo.py并提交到upstream/master分支

  1. huanianli@ThinkCentre:~/workspace/kaiba$
  2. huanianli@ThinkCentre:~/workspace/kaiba$ git log
  3. commit 27aca2bcc0fcffb26828cac1eebe517439ef49c9
  4. Author: Daxiang Li <bjlhn@.com>
  5. Date: Thu Jul :: +
  6.  
  7. DaxiangLi: Add checking to foo.py
  8.  
  9. commit 3609dff98de5a17a09484738328a0e9db1784e0d
  10. Author: Huanian Li <huanian.li@gmail.com>
  11. Date: Thu Jul :: +
  12.  
  13. HuanianLi: Add Makefile
  14.  
  15. commit 640f6f63f4634915b4e4ed195e9a48d31cabb893
  16. Author: Daxiang Li <bjlhn@.com>
  17. Date: Wed Jul :: +
  18.  
  19. DaxiangLi: Add foo.py
  20.  
  21. commit c0bd2ed35e10180209726199af422a63a007355f
  22. Author: Huanian Li <huanian.li@gmail.com>
  23. Date: Wed Jul :: +
  24.  
  25. Initialize the project by adding README.md
  26. huanianli@ThinkCentre:~/workspace/kaiba$
  27. huanianli@ThinkCentre:~/workspace/kaiba$ vi foo.py
  28. huanianli@ThinkCentre:~/workspace/kaiba$ git diff foo.py
  29. diff --git a/foo.py b/foo.py
  30. index 84b0787..a9aa6fe
  31. --- a/foo.py
  32. +++ b/foo.py
  33. @@ -, +, @@ import sys
  34. def main(argc, argv):
  35. if argc != :
  36. sys.stderr.write("Usage: %s <num>\n" % argv[])
  37. - return (-)
  38. + return -
  39.  
  40. i =
  41. while i < int(argv[]):
  42. print "%02d: Hello World." % i
  43. i +=
  44.  
  45. - return ()
  46. + return
  47.  
  48. if __name__ == '__main__':
  49. argv = sys.argv
  50. huanianli@ThinkCentre:~/workspace/kaiba$
  51. huanianli@ThinkCentre:~/workspace/kaiba$
  52. huanianli@ThinkCentre:~/workspace/kaiba$ git commit -a -m "HuanianLi: Update foo.py to use return N instead of return (N)"
  53. [master c5221d8] HuanianLi: Update foo.py to use return N instead of return (N)
  54. file changed, insertions(+), deletions(-)
  55. huanianli@ThinkCentre:~/workspace/kaiba$
  56. huanianli@ThinkCentre:~/workspace/kaiba$ git log
  57. commit c5221d81c91d45cda15e33c3bf0e82874d7fcc97
  58. Author: Huanian Li <huanian.li@gmail.com>
  59. Date: Thu Jul :: +
  60.  
  61. HuanianLi: Update foo.py to use return N instead of return (N)
  62.  
  63. commit 27aca2bcc0fcffb26828cac1eebe517439ef49c9
  64. Author: Daxiang Li <bjlhn@.com>
  65. Date: Thu Jul :: +
  66.  
  67. DaxiangLi: Add checking to foo.py
  68.  
  69. commit 3609dff98de5a17a09484738328a0e9db1784e0d
  70. Author: Huanian Li <huanian.li@gmail.com>
  71. Date: Thu Jul :: +
  72.  
  73. HuanianLi: Add Makefile
  74.  
  75. commit 640f6f63f4634915b4e4ed195e9a48d31cabb893
  76. Author: Daxiang Li <bjlhn@.com>
  77. Date: Wed Jul :: +
  78.  
  79. DaxiangLi: Add foo.py
  80.  
  81. commit c0bd2ed35e10180209726199af422a63a007355f
  82. Author: Huanian Li <huanian.li@gmail.com>
  83. Date: Wed Jul :: +
  84.  
  85. Initialize the project by adding README.md
  86. huanianli@ThinkCentre:~/workspace/kaiba$
  87. huanianli@ThinkCentre:~/workspace/kaiba$ git push origin master
  88. Username for 'https://github.com': HuanianLi
  89. Password for 'https://HuanianLi@github.com':
  90. Counting objects: , done.
  91. Compressing objects: % (/), done.
  92. Writing objects: % (/), bytes | bytes/s, done.
  93. Total (delta ), reused (delta )
  94. remote: Resolving deltas: % (/), completed with local objects.
  95. To https://github.com/HuanianLi/kaiba.git
  96. 27aca2b..c5221d8 master -> master
  97. huanianli@ThinkCentre:~/workspace/kaiba$

205 - DaxiangLi再次更新foo.py,故意制造一个冲突

  1. daxiangli@ThinkPad:~/workspace/kaiba$
  2. daxiangli@ThinkPad:~/workspace/kaiba$ git remote update
  3. Fetching origin
  4. Fetching upstream
  5. remote: Counting objects: , done.
  6. remote: Compressing objects: % (/), done.
  7. remote: Total (delta ), reused (delta ), pack-reused
  8. Unpacking objects: % (/), done.
  9. From https://github.com/HuanianLi/kaiba
  10. * [new branch] master -> upstream/master
  11. daxiangli@ThinkPad:~/workspace/kaiba$
  12. daxiangli@ThinkPad:~/workspace/kaiba$ git branch -a
  13. * dev
  14. master
  15. remotes/origin/HEAD -> origin/master
  16. remotes/origin/dev
  17. remotes/origin/master
  18. remotes/upstream/master
  19.  
  20. daxiangli@ThinkPad:~/workspace/kaiba$ vi foo.py
  21. daxiangli@ThinkPad:~/workspace/kaiba$
  22. daxiangli@ThinkPad:~/workspace/kaiba$ git commit -a --amend
  23. [dev 924729d] DaxiangLi: Update foo.py to use 'for' instead of 'while'
  24. Date: Thu Jul :: +
  25. file changed, insertions(+), deletions(-)
  26.  
  27. daxiangli@ThinkPad:~/workspace/kaiba$ git diff remotes/origin/master..
  28. diff --git a/foo.py b/foo.py
  29. index 84b0787..b1070a5
  30. --- a/foo.py
  31. +++ b/foo.py
  32. @@ -, +, @@ import sys
  33. def main(argc, argv):
  34. if argc != :
  35. sys.stderr.write("Usage: %s <num>\n" % argv[])
  36. - return (-)
  37. + return (-)
  38.  
  39. - i =
  40. - while i < int(argv[]):
  41. - print "%02d: Hello World." % i
  42. - i +=
  43. + for i in range(int(argv[])):
  44. + print "%02d: Hello World." % (i + )
  45.  
  46. return ()
  47.  
  48. daxiangli@ThinkPad:~/workspace/kaiba$
  49. daxiangli@ThinkPad:~/workspace/kaiba$ git diff remotes/upstream/master..
  50. diff --git a/foo.py b/foo.py
  51. index a9aa6fe..b1070a5
  52. --- a/foo.py
  53. +++ b/foo.py
  54. @@ -, +, @@ import sys
  55. def main(argc, argv):
  56. if argc != :
  57. sys.stderr.write("Usage: %s <num>\n" % argv[])
  58. - return -
  59. + return (-)
  60.  
  61. - i =
  62. - while i < int(argv[]):
  63. - print "%02d: Hello World." % i
  64. - i +=
  65. + for i in range(int(argv[])):
  66. + print "%02d: Hello World." % (i + )
  67.  
  68. - return
  69. + return ()
  70.  
  71. if __name__ == '__main__':
  72. argv = sys.argv
  73. daxiangli@ThinkPad:~/workspace/kaiba$
  74. daxiangli@ThinkPad:~/workspace/kaiba$ git push --force
  75. Username for 'https://github.com': DaxiangLi
  76. Password for 'https://DaxiangLi@github.com':
  77. Counting objects: , done.
  78. Compressing objects: % (/), done.
  79. Writing objects: % (/), bytes | bytes/s, done.
  80. Total (delta ), reused (delta )
  81. remote: Resolving deltas: % (/), completed with local objects.
  82. To https://github.com/DaxiangLi/kaiba.git
  83. + 671404d...924729d dev -> dev (forced update)
  84. daxiangli@ThinkPad:~/workspace/kaiba$
  • 制造的冲突是故意将return (-1)改成return (-11)

  • 接下来我们发现,PR上就会显示有冲突了!!

  • 冲突的细节在于foo.py的第8行

好吧,接下来DaxiangLi就需要去解决冲突了!

206 - DaxiangLi解决冲突 (P.S. 解决冲突不是很容易,请仔细看)

206.1 创建一个临时分支dev-scratch (为了演示得更清晰,这里故意删除旧的空间,重新clone一遍,然后从头开始)

  1. daxiangli@ThinkPad:~/workspace/kaiba$ git checkout -b dev-scratch dev
  2. Switched to a new branch 'dev-scratch'

206.2 给临时分支dev-scratch添加upstream的repo

  1. daxiangli@ThinkPad:~/workspace/kaiba$ git remote add upstream https://github.com/HuanianLi/kaiba.git

206.3 让临时分支dev-scratch与upstream/master同步

  1. daxiangli@ThinkPad:~/workspace/kaiba$ git remote update
  2. Fetching origin
  3. Fetching upstream
  4. remote: Counting objects: , done.
  5. remote: Compressing objects: % (/), done.
  6. remote: Total (delta ), reused (delta ), pack-reused
  7. Unpacking objects: % (/), done.
  8. From https://github.com/HuanianLi/kaiba
  9. * [new branch] master -> upstream/master

  1. daxiangli@ThinkPad:~/workspace/kaiba$ git fetch upstream master
  2. From https://github.com/HuanianLi/kaiba
  3. * branch master -> FETCH_HEAD

  1. daxiangli@ThinkPad:~/workspace/kaiba$ git merge upstream/master
  2. Auto-merging foo.py
  3. CONFLICT (content): Merge conflict in foo.py
  4. Automatic merge failed; fix conflicts and then commit the result.

206.4 在临时分支dev-scratch里合并冲突

  1. daxiangli@ThinkPad:~/workspace/kaiba$ git add foo.py
  2. daxiangli@ThinkPad:~/workspace/kaiba$ git commit -m "DaxiangLi: Merge confilict in foo.py"
  3. [dev-scratch c9af088] DaxiangLi: Merge confilict in foo.py

206.5 将本地的临时分支dev-scratch与本地开发分支dev做比较

  1. daxiangli@ThinkPad:~/workspace/kaiba$ git diff dev..dev-scratch

206.6 切换到本地开发分支dev

  1. daxiangli@ThinkPad:~/workspace/kaiba$ git checkout dev
  2. Switched to branch 'dev'
  3. Your branch is up-to-date with 'origin/dev'.

206.7 将临时分支dev-scratch合并到开发分支dev

  1. daxiangli@ThinkPad:~/workspace/kaiba$ git merge --squash dev-scratch
  2. Updating 924729d..c9af088
  3. Fast-forward
  4. Squash commit -- not updating HEAD
  5. foo.py | ++--
  6. file changed, insertions(+), deletions(-)

  1. daxiangli@ThinkPad:~/workspace/kaiba$ git commit -a --amend
  2. [dev 5055a77] DaxiangLi: Update foo.py to use 'for' instead of 'while'
  3. Date: Thu Jul :: +
  4. file changed, insertions(+), deletions(-)
  5. daxiangli@ThinkPad:~/workspace/kaiba$
  6. daxiangli@ThinkPad:~/workspace/kaiba$ git diff dev..dev-scratch
  7. daxiangli@ThinkPad:~/workspace/kaiba$

206.8 把本地的开发dev强制推送到远端的开发dev

  1. daxiangli@ThinkPad:~/workspace/kaiba$ git push origin dev --force
  2. Username for 'https://github.com': DaxiangLi
  3. Password for 'https://DaxiangLi@github.com':
  4. Counting objects: , done.
  5. Compressing objects: % (/), done.
  6. Writing objects: % (/), bytes | bytes/s, done.
  7. Total (delta ), reused (delta )
  8. remote: Resolving deltas: % (/), completed with local objects.
  9. To https://github.com/DaxiangLi/kaiba.git
  10. + 924729d...5055a77 dev -> dev (forced update)

206.9 删除本地的临时分支dev-scratch

  1. daxiangli@ThinkPad:~/workspace/kaiba$ git branch dev-scratch -D
  2. Deleted branch dev-scratch (was c9af088).

OKAY, 冲突解决完成! 重新刷新PR, 发现冲突已经不存在啦。。。

207 - HuanianLi再次检查PR,发现没有冲突,将代码Rebase and merge

208 - DaxiangLi重新sync远端的master分支

  • 使用下面一组命令即可 (其中, [*]为关键命令)
  1. [ ] $ git branch
  2. [*] $ git checkout master
  3. [ ] $ git branch
  4. [ ] $ git log
  5. [*] $ git remote add upstream https://github.com/HuanianLi/kaiba.git
  6. [ ] $ git remote -v
  7. [ ] $ git remote update
  8. [*] $ git fetch upstream master
  9. [*] $ git rebase upstream/master
  10. [ ] $ git log
  11. [ ] $ git diff remotes/origin/master..
  12. [*] $ git push origin master

209 - DaxiangLi重新sync远端的dev分支 (前面其实已经介绍过)

  • 使用下面的命令即可 (其中, [*]为关键命令)
  1. [*] $ git clone https://github.com/DaxiangLi/kaiba.git
  2. [*] $ git checkout dev
  3. [ ] $ git remote -v
  4. [*] $ git remote add upstream https://github.com/HuanianLi/kaiba.git
  5. [ ] $ git remote -v
  6. [ ] $ git log
  7. [ ] $ git remote update
  8. [*] $ git fetch upstream master
  9. [*] $ git rebase upstream/master
  10. [ ] $ git log --graph
  11. [*] $ git push origin dev --force

说明: git remote update可以不做,直接使用git fetch upstream master也okay.


总结:

  1. 从upstream fork出代码空间后,总是创建一个dev分支并保存到远端比较好,这样master分支用来与upstream保持同步,dev分支用来做开发
  2. 提交PR的时候请在dev分支中总是保存一个用来被合作伙伴review的commit,如不小心提交了多个commit, 需要进行合并,合并的方法是使用git rebase -i
  3. 保持PR中只有一个commit的秘诀是使用git commit -a --amend,然后使用git push origin dev --force
  4. 养成总是让origin/master与upstream同步的好习惯
  5. 不用总是让origin/dev与upstream保持同步,如果PR中显示有冲突就解决冲突,没有就不用管,即使origin/dev与upstream不同步 (P.S. git没有recommit功能,所以你无法总是把你的commit放置到top位置)
  6. 当一个PR被合并后,不妨也让origin/dev分支与upstream同步,同步的秘诀还是git push origin dev --force
  7. 可以认为origin/dev分支是一个沙箱,可以用来随便玩, 玩坏了大不了删除远端的origin/dev分支再重新创建一个;但是请认真对待origin/master
  8. 尽可能地使用git rebase upstream/master, 不使用git merge upstream/master, 在做同步的时候
  9. 解决冲突请创建一个本地临时分支dev-scratch, 然后将临时分支合并到本地开发分支dev,合并的秘诀是使用 git merge --squash dev-scratch
  10. 不需要的临时分支dev-scratch用git branch dev-scratch -D删除,养成不留垃圾分支的好习惯
  11. 不小心关掉一个PR可以Re-open, 但是尽量不要在review的过程中删除被review的commit,那样会导致PR被自动关闭

参考资料:

GitHub多人协作简明教程的更多相关文章

  1. github多人协作

    1.字符串处理(编码原理) git clone git@github.com:lookphp/LaravelCms.git git add . git commit -m "修改的内容-需要 ...

  2. GitHub 多人协作开发 三种方式:

    GitHub 多人协作开发 三种方式: 一.Fork 方式 网上介绍比较多的方式(比较大型的开源项目,比如cocos2d-x) 开发者 fork 自己生成一个独立的分支,跟主分支完全独立,pull代码 ...

  3. GitHub:多人协作下的分支处理

    GitHub上的团队协作 远程信息 git remote:查看远程库的信息 git remote -v:查看远程库的详细信息 推送分支 git push origin 要推送的分支:比如git pus ...

  4. github 多人协作

    1.本地生成私钥: ssh-keygen -C "YourEmail@example.com" (这里的email使用github账号)生成公钥和私钥 2.查看私钥,并添加到自己的 ...

  5. GitHub 多人协作开发 三种方式(转)

    一.Fork 方式 网上介绍比较多的方式(比较大型的开源项目,比如cocos2d-x) 开发者 fork 自己生成一个独立的分支,跟主分支完全独立,pull代码后,项目维护者可根据代码质量决定是否me ...

  6. Android github 快速实现多人协作

    前言:最近要做github多人协作,也就是多人开发.搜索了一些资料,千篇一律,而且操作麻烦.今天就整理一下,github多人协作的简单实现方法. 下面的教程不会出现:公钥.组织.team.pull r ...

  7. Git版本控制:Github的使用之 多人协作及参与项目

    版权声明:本文为博主皮皮http://blog.csdn.net/pipisorry原创文章,未经博主允许不得转载.   目录(?)[-] Git多人协作 从远程库克隆 使用GitHub参与开源项目- ...

  8. Git教程之多人协作

    当你从远程仓库克隆时,实际上Git自动把本地的master分支和远程的master分支对应起来了,并且,远程仓库的默认名称是origin.要查看远程库的信息,用git remote:

  9. 【前端】Github Pages 与域名关联简明教程

    Github Pages 与域名关联简明教程 1. 向你的 Github Pages 仓库添加一个CNAME(一定要*大写*)文件 其中只能包含一个顶级域名,像这样: example.com 如果你是 ...

随机推荐

  1. mysql同时使用order by和limit查询时的一个严重隐患 -- 丢失数据

    转自: https://blog.csdn.net/tsxw24/article/details/44994835 我经常使用order by和limit来做数据分页显示并排序,一直也没发现过什么问题 ...

  2. SRM479

    250pt: 题意:有一排一共44,777,777个人,每个人需要咖啡或者茶,队伍的头部有一台饮料机,有一个空姐负责给所有人送饮料,她一开始在也头部.空姐拿一个水壶,一开始是空的,可以在饮料机的地方加 ...

  3. ASP.NET Web API 框架研究 IoC容器 DependencyResolver

    一.概念 1.IoC(Inversion of Control),控制反转 即将依赖对象的创建和维护交给一个外部容器来负责,而不是应用本身.如,在类型A中需要使用类型B的实例,而B的实例的创建不是由A ...

  4. Implementation of WC in JAVA

    Implementation of WC in JAVA github地址 相关要求 基本功能 -c [文件名] 返回文件的字符数 (实现) -w [文件名] 返回文件的词的数目 (实现) -l [文 ...

  5. cxgrid动态创建列

    cxgrid动态创建列 procedure TFrmRuleEdit.CreateCols;varColumn: TcxGridDBColumn;begincdsPowerPrj.First;whil ...

  6. 附加题:将四则运算源代码上传到Github账户上

    1.创建仓库用于存储管理本地文件 2.远程添加github上的Blog仓库. 3.获取github中Blog仓库的地址. 4.在Add Remote窗口中填写名字.Location. 5.将本地文件通 ...

  7. RouteOS 频繁自启

      本来是一个美好的大周末,突然却被一个突如其来的电话把我从美梦中惊醒,然而一切还不止这么简单......   本来刚开始了解到信息是客户的一台RouteOS设备挂了,听到这个消息时觉得自己应该可以很 ...

  8. AJPFX:外汇的点差和点值

    外汇“点差”就是交易商买卖货币之间产生的差值. 要了解点差我们先解释一下“点”的含义:为了精确和方便地表示汇价,一般用5位数字表示,其中最小变化的单位就称为"点".例如:英镑美元货 ...

  9. “全栈2019”Java多线程第三十一章:中断正在等待显式锁的线程

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...

  10. Windows安装python3.x后,pip list警告!DEPRECATION: The default format will switch to columns in the future.

    前言(凑字数专用) 这个警告虽然不影响你的正常使用,但是每次都好几行红色警告,总是给人一种怪怪的感觉(当然不是FBI的警告了……),所以咱们还是把他解决掉~ 网上好多解决办法都是Ubuntu的解决办法 ...