Linux下,github/git项目开发基本流程

我们的目的

场景

比如说现在有一个很牛逼的项目,我们进入项目地址,

想将这个项目复制到自己的github仓库,然后你还想将

仓库中的代码拉取到本地进行修改,修改完你还要将本地的

修改后的代码推送到自己的github仓库,更甚至你还想将自己

复制过来并修改后的代码再还给原作者,请求人家让你合并。

明确的分支名

  明确可以贡献代码后,fork项目,然后clone到本地,后在master上创建一个新的分支(branch)。好处:

  • 确保你的分支语义明确,一看就大概明白你用它来完成什么。
  • 后续可以更好的和master同步代码。

例如:

nodes/atom_improvements 
scheuduler/dirty_scheuduler_collapse
kernel/clean-history-shell

提交日志(Commit Message)

  日志(Commit Message)要尽量避繁就简,这可以让你的PR更容易被人理解和接受。

  • 首行总结要尽量少于50字符。
  • 附加的更详细的说明,保持宽度在72字符左右。
  • 使用“Fix bug"代替”Fixed bug"或“Fixes bug"。
  • 多使用列表说明问题。

代码礼仪(Code Standard)

  每个人都会有自己的代码风格,到底是用制表符(Tab)还是空格(Space)?每行是80字符还是120字符?这种圣战不应该在PR中出现,PR应该遵循项目已有的风格。例如:如果原来使用的驼峰命名变量,PR中就应该使用驼峰命名。

整理日志(Rebase)

  git rebase是一个让你可以改变历史的命令!通过它轻易地重新排列,编辑或合并历史日志。

  • 编辑以前提交过的日志。
  • 把多条日志合并成一条日志。
  • 删除或回滚一些不必要的日志。

例如:有时图个方便,会把代码分阶段性提交,到真正完成时,希望Review的人看到是最终的结果。

  git commit -am "Add Account Form"
  git commit -am "Add Passwd Form"
  git commit -am "Add Verification Code Form"

  你需要把上面的都合并成一条提交日志。可以使用rebase功能。

  git rebase -i HEAD~3
  • -i表示打开交互模式(interactive mode)。
  • HEAD~3表示检查最近3条日志。
  • 输入的数字过大会导致fatal: Need a single revision错误,可以减小数字。

  随后会通过默认的编辑器(一般是vi)打开一个文本:

  pick cee46ac Add Verification Code Form
  pick 5dd4924 Add Passwd Form
  pick 27dc5ce Add Account Form
  ​
  # Rebase 925891e..cee46ac onto 925891e (3 commands)
  #
  # Commands:
  # p, pick = use commit
  # r, reword = use commit, but edit the commit message
  # e, edit = use commit, but stop for amending
  # s, squash = use commit, but meld into previous commit
  # f, fixup = like "squash", but discard this commit's log message
  # x, exec = run command (the rest of the line) using shell
  # d, drop = remove commit
  #
  # These lines can be re-ordered; they are executed from top to bottom.
  #
  # If you remove a line here THAT COMMIT WILL BE LOST.
  #
  # However, if you remove everything, the rebase will be aborted.
  #
  # Note that empty commits are commented out

  需要重点关注的是前3行,后面带#的是注释说明,不会出现在日志中。默认是pick选项,就是保持此条日志不变,其它选项可以看上面的注释,我们的目标是把3条合成一条,并修改日志内容。所以可以使用到f(fixup)与r(reword)选项。最终效果如下。

  r cee46ac Add Verification Code Form
  f 5dd4924 Add Passwd Form
  f 27dc5ce Add Account Form

  保存后,会直接再弹出一个文本编辑器用于重写日志内容:Add login UI.
关于rebase各种选项的详细说明。

提交变更(Submit PR)

  当所有的commit都准备好时,就可以在网页上选择对应的分支创建PR。最后检查一下

  • 标题,描述是否简洁清晰?
  • 如果改动是可见的,是否需要附上一个截图或gif说明?
  • 想PR被合并后自动关闭对应的issue,可以在描述的结尾加上一行Closes #issue编号。
    如果PR改动很大,你想边改边得到别人及时的反馈,可以先创建PR后,在标题上加上[WIP]是Work In Progress的缩写,表示工作还未完成。但尽量不要把未完成的PR提交到别人的项目上(可能会引起别人反感),通常WIP的PR都是自己的项目里面使用就行了。

审查/合并(Review/Merge)

  PR提交后,维护者会对它进行逐行的审查(review),大家可以共同讨论,看是否有考虑不周或者更好的方案,在这过程中,你可以根据建议随时改进代码,然后push到分支上,PR就会同步改动。当所有的改动都被批准后,PR应该就会被合并啦!

同步上游分支(Upstream)

如何保持fork分支与上游分支(upstream)同步?
先查看一下你目前git状态。

 $ git remote -v
 origin  https://github.com/YOUR_USERNAME/YOUR_FORK.git (fetch)
 origin  https://github.com/YOUR_USERNAME/YOUR_FORK.git (push)

以上说明: 你的origin分支指向的是你fork的分支。

指定上游地址。

$ git remote add upstream https://github.com/ORIGINAL_OWNER/ORIGINAL_REPOSITORY.git

upstream分支指向上游地址,这里的upstream名字可以任意指定,只是一般都把上游地址都叫upstream

检查地址是否设置成功。

 $ git remote -v
 origin    https://github.com/YOUR_USERNAME/YOUR_FORK.git (fetch)
 origin    https://github.com/YOUR_USERNAME/YOUR_FORK.git (push)
 upstream  https://github.com/ORIGINAL_OWNER/ORIGINAL_REPOSITORY.git (fetch)
 upstream  https://github.com/ORIGINAL_OWNER/ORIGINAL_REPOSITORY.git (push)

从upstream分支上拉取最新代码。

 $ git fetch upstream
 remote: Counting objects: 75, done.
 remote: Compressing objects: 100% (53/53), done.
 remote: Total 62 (delta 27), reused 44 (delta 9)
 Unpacking objects: 100% (62/62), done.
 From https://github.com/ORIGINAL_OWNER/ORIGINAL_REPOSITORY
  * [new branch]      master     -> upstream/master

切换到自己的master上,然后把upstream分支上更新内容合并到master上。

 $ git checkout master
 Switched to branch 'master'
 $ git merge upstream/master
 Updating a422352..5fdff0f
 Fast-forward
  README                    |    9 -------
  README.md                 |    7 ++++++
  2 files changed, 7 insertions(+), 9 deletions(-)
  delete mode 100644 README
  create mode 100644 README.md

这时你的本地master就和上游同步成功啦,但是这只是表示你的本地master,一般你还需要把本地master同步到GitHub下的远程分支上。

  $ git  push origin master

项目协作者视角

  首先Fork一个项目,把它变成你自己GitHub下的项目。

  成功后可在自己GitHub账户下看到刚才fork过来的项目。将项目用命令行clone到本地。

$ git clone https://github.com/你自己GitHub用户名/project.git
$ cd project

  更新代码至本地,与源码保持一致:默认本地为origin,一般远程为upstream

$ git remote add upstream https://github.com/sourcename/project.git

  查看本地分支和 远程分支对应名称是否正确:即orgin为本地fork的地址,upstream为远程的项目地址

$  git remote -v

基于master分支进行开发

  执行 git clone 命令后我们会默认处于 master 分支下,同时系统会自动将 origin 设置成该远程仓库的标识符。也就是说,当前本地仓库的 master 分支与 GitHub 端远程仓库(origin)的 master 分支在内容上是完全相同的。

  拉取远程的master到本地:注意每次提交之前都要先进行拉取,防止代码冲突(防止upstream仓库的实时更新)

$  git pull upstream master

  基于master(start point)分支,创建一个开发分支dev,此时的dev分支和master分支一般无二。

$ git checkout -b dev

  请注意,此时在dev分支上进行所有的更改,如果不进行一个版本创建的话,即使使用了git add命令将更改添加到暂缓区,而没有下一步git commit进行版本创建,切回master分支,你会发现你在dev分支上做的修改,怎么也在master分支上出现了,所以在某个分支上完成一个阶段的开发一定要创建版本,避免混乱。

  若开发一半时,接到通知需要修复master分支上的bug,此时的开发才进行一半,确实没办法进行版本创建时,请参考git stash命令。

  在origin仓库创建dev分支。

$ git push origin dev:dev

  项目前期准备工作就已经处理好了,接下来就是正常的项目开发了:

 // 写代码
 $ vim xxx
 ....写写写写写写写写......
 
 // 每次提交项目之前一定要拉取,防止冲突(基于哪个分支开发,就拉哪个分支)
 $ git pull upstream master
 $ git push origin dev:dev
 // 拉取之后在进行自己代码的提交
 $ git add .
 $ git commit -m "我的第一个PR实验"
 $ git push origin dev:dev

  然后在网页上,发起pull request,注意pull request到你基于开发的那个分支,这里是master,否则可能会有冲突。
  被合并后马上就能在项目中看到你的名字啦~

基于其他分支(非master)下进行开发

  上面说了,执行 git clone 命令后我们会默认处于 master 分支下

  我们用 git branch -a 命令查看当前分支的相关信息。添加 -a 参数可以同时显示本地仓库和远程仓库的分支信息。

$ git branch -a
* master
  remotes/origin/HEAD -> origin/master
  remotes/origin/dev
  remotes/origin/其他分支名1
  remotes/origin/其他分支名2
  remotes/origin/其他分支名3
  .....
  remotes/upstream/dev
  remotes/upstream/其他分支名1
  remotes/upstream/其他分支名2
  remotes/upstream/其他分支名3
  remotes/upstream/其他分支名4
  .......
  这里的origin分支和upstream的分支如果你没有新建分支的话是没有区别的,如果新建分支则origin会存在你新建的分支,而upstream内没有

  一般来说,一个优秀的项目会有多个分支,这些分支都具有不同的功能,且正在开发,如果我们需要协作开发其中一个分支,则需要将该分支拉下来,即获取远程分支,例如这里的dev分支。

$ git checkout -b dev origin/dev
Branch dev set up to track remote branch dev from origin.
Switched to a new branch 'dev'

  -b 参数的后面是本地仓库中新建分支的名称。为了便于理解,我们仍将其命名为 dev,让它与远程仓库的对应分支保持同名。新建分支名称后面是获取来源的分支名称。
  例子中指定了origin/dev,就是说以名为 origin 的仓库(这里指GitHub 端的仓库)的 dev 分支为来源,在本地仓库中创建并切换至dev 分支。

  这些工作完成后,就可以按照自己的思路进行在该分支下进行二次开发,在代码写完之后,先在本地创建一个版本,然后push,最后在网页上发起pull request。

仓库管理者视角

当有人通过上述步骤发送PR至你的github仓库时,你会得到这样的界面
在这里插入图片描述
如果你对他的提交无任何异议,你可以直接点击Merge pull request进行直接合并。

如果你想调试一下看看请求者所提交的功能的正确性,请点击图片中红框的可点击链接,你会得到以下的提示,
在这里插入图片描述
现在我们回到本地linux系统进行操作,

步骤1:

新建并切换至一个新的分支,起点为master分支

//git checkout -b|-B <new_branch> [<start point>]
//如果是-b,则branch-name分支不存在,git会在start-point上创建它,如果branch-name分支已经存在,那么会将操作失败。
//如果是-B,如果它不存在则创建<new_branch>; 否则,它被重置。
$ git checkout -b xCodeleaner-master master

现在新的分支是创建好了,但是它只是本地master分支的一个拷贝,并没有任何区别,所以这个时候就要将提交者的更改从提交者的仓库中拉取下来。

//git pull <远程主机名> <远程分支名>:<本地分支名>
//如果远程分支是与当前分支合并,则冒号后面的部分可以省略:
$ git pull https://github.com/xCodeleaner-master master

此时,如果你觉得他写的有点问题,有些内容需要修改,那你就修改,修改完别忘了创建版本

$ vim xxx
$ git add .
$ git commit -m 'fix bug'

步骤2:

切换至master分支(也可以是别的分支,你想将提交合并进去的分支),然后进行合并

//切换至master分支,并进行合并
$ git checkout master
$ git merge --no-ff xCodeleaner-master

然后会突然跳出一个可怕的界面,不要慌,它只是让你写一下将该分支合并到master分支的必要性,也就是让你解释一下,你为啥要合并这个分支到master,毕竟master分支很重要。默认的解释的Merge branch ‘pull request的请求名’
在这里插入图片描述
如果你没啥可以解释的直接ctrl+x,按提示离开该界面就行。

接着你git log看一眼,

$ git log

在这里插入图片描述
最后,再将本地Linux的改变推送到远程github上

$ git push origin master

然后网页上的github直接就同步了,对,就是这么快
在这里插入图片描述
在这里插入图片描述

参考链接(Reference)

https://zhuanlan.zhihu.com/p/51199833
https://blog.csdn.net/JxiaoZhang/article/details/84820147

请把大鹤真细心打在公屏上!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值