项目管理套路:看这一篇绝对够用❤️

在这里插入图片描述

写论文必不可少的,就是创建代码并进行实验。好的项目管理可以让实验进行得更加顺利。本篇博客以一次项目实践为例,介绍项目管理的方法,以及可能遇到的问题,并提供一些可行的解决方案。

目录

  • 项目管理工具
  • 开始第一步
  • 版本管理十分关键
  • 如何进行版本管理
    • 创建分支
    • 进行改动
    • 添加改动与上传
    • 分支带来的新问题
    • 常用的git使用命令
  • 一些技巧让项目管理更简单
    • 项目结构构建
    • Commit规范
    • 文档与注释
  • 总结

项目管理工具

项目管理困难的主要原因在于,项目并非一个人构建的。许多人同时写代码,就容易出现:A改了代码的同时,B也改了代码,二人改了同一块代码,导致项目版本出现分歧的情况。这个时候,采用一个好用的项目管理工具,则可以很好地解决版本冲突的情况。Github则是一款以解决版本冲突为目标的项目管理工具,该工具跨平台皆可使用,并且简单易用,因而成为广大程序员经常使用的项目管理工具。本篇博客也就以此为工具展开对项目管理方法的经验介绍。

开始第一步

在注册完github账号之后,你就可以开始项目管理了。一般而言,项目开始之初,我们并没有一个程序项目,因而我们需要先构建一个程序项目。进入个人主页后可以在左侧个人拥有的项目库(Repositories)中找到新建(New)的按钮,点击进去后会看到这样的画面。
请添加图片描述
新建一个项目之前,需要先给项目起一个名字并填在Repository name那里,在Description那里可以填写对项目的介绍(ps: 对项目的理解越深刻,就可以用越简短的话介绍清楚这个项目到底要做什么。写Description有助于后续进行比对,并检查是否按照计划完成项目),同时还可以选择该项目是否公众可见(Public or Private),在初始化的时候可以选择添加一个README文件(ps: 建议初始化的时候就带上README文件,可以在里面写一些需要项目参与者提前知道的先验知识)。
请添加图片描述
除此之外,还可以添加.gitignore文件来指定每次git add以及git push的时候是否需要忽略一些文件(ps:每次进行实验都会产生许多中间文件,如果都把它们git push到repo里,显然会浪费很多网络资源,不利于项目开发);license这个功能限制了他人对你开源代码库的程度,不同license有不同的规则,具体请见官方文档(ps: 这个不需要在最开始就决定下来,初始化一个项目的时候并不一定要确认此项,不过为了后期开源代码能得到更多的关注,可以随着项目进展再思考license如何选择)。
请添加图片描述
建好一个代码项目,应该会有一个这样的结果。可以发现,初始化README里面的内容就是我们最开始在Description栏里写的东西。个人认为这个界面十分简洁美观,github为项目开发提供的功能其实都已经集成在这一个界面上了。菜单栏里可以看到有以下功能:

  • Code: 项目代码在这个界面里,做出的改动也会都体现在这里面
  • Issue: 这里类似于一个论坛,项目参与者可以在这里提出问题,其他参与者可以在这里进行讨论与解答问题(ps: 项目进行的过程中总会遇到许多奇奇怪怪的问题,这些问题大家共同商量出一个结果会比一个人自己闷头解决更靠谱一些,这里可以帮助项目参与者达成共识,可以有效提升项目的质量)。
  • Pull Request: 把其他分支上的代码拉到master分支上,并进行版本的融合。每个项目参与者会提供一部分功能代码,这些代码规范的写法是在不同的分支上,在各自分支上测试无误后,再由管理者将其merge到master主分支上。这一过程被称为pull request,其功能实现则可以在这个界面里实现。
  • Action: 创建工作流以自动化测试以及其他关键操作(比如pull request)。
  • Projects: 将其他相关的github repo列举在这里,方便后来的项目参与者了解情况。
  • Wiki:对与项目更加详细的介绍,好多东西无法在项目的注释里、README文档里讲清楚,这部分信息可以都放在Wiki里进行详细介绍。(ps: 文档管理做的越好,项目质量越高,但是这部分在我看了众多项目后发现,得到的关注并不是很充足)。
  • Security: 安全设置。
  • Insights: 项目流量监督。
  • Settings: 项目其他关键设置。
    请添加图片描述

以上就是在项目创建之初,我们要在远端(也就是网站)上进行的操作,下面我们要将远端的repo与本地进行联系。
请添加图片描述
本地打开终端,并输入指令git clone [url]就可以从远端拉取刚刚初始化的项目代码,从而使得本地与远端形成一个联系。

⚠️这里可能会遇到一些坑:

  1. 网络失败:是指loss connection这种错,一般错因在于本地机器的网络太过拉胯,重启网络服务、重启机器、更改网络设置等一些操作往往可以解决(ps:不过有时候就算真的这么处理了,网络该连不上还是连不上,我实验室机器的网络太过拉胯,一把辛酸泪)
  2. 没有权限:这要在本地设置ssh key 然后上传到远端,具体操作详见官方文档。

例如,对于How2Code这个例子,我需要输入指令git clone https://github.com/Doris404/How2Code.git 然后就可以看到本地机器就有一个名为How2Code的文件夹,里面含有一个README文档,和远端的设定一样。

接下来我们就可以进行项目开发了 ❤️

版本管理十分关键

Github解决的最核心的问题就是版本管理。我们先来了解一下这个问题究竟有多复杂。我将用一个例子来解释此问题的复杂程度。

一个三人团队要构建项目实现网上订餐功能,三人在项目初始阶段约定,一人实现一个功能,并且初步商定的功能包括:查询可点餐馆及可点菜品、下单与付款、评价与点评、纠纷处理等。

A作为项目主要负责人实现了下单与付款这个最复杂的功能,B实现查询可点餐馆及可点菜品,C实现评价与点评、纠纷处理这两个功能。

划分功能时大家一致认为,这些代码互相独立性比较强,所以三人分别在不同的机器上各自实现各自代码即可以做到版本管理。然而在项目进行过程中,出现了意想不到的情况。A下单与付款的功能实现依赖于B显示出来的界面。因此B最初实现的界面一旦发生改动,则A的代码实现也要跟着变更。在项目进行过程中则出现了以下情况:

  1. B 实现了一个初始界面
  2. A 基于初始界面进行功能实现,但于此同时B改动了一些初始界面,并形成了一个新版界面
  3. A 和 B都上传代码,此时A的代码不能在新版界面上测试通过,只能在初始界面上通过,但由于缺乏版本管理工具,此时的代码无法通过,并且我们遗失了初始界面。

Github提供了分支用于解决这个问题,同样是上述情况,如果我们使用branch,则是另一番景象:

  1. B实现了一个初始界面,并给它放在branch 1上
  2. A实现了基于初始界面的功能,传到branch 1上
  3. B改动初始界面,并形成新版界面,传到branch 2上

这样branch1的代码就是可以正常跑通的,而branch 2上则缺少A的代码,A则可以依据branch 1上自己实现的代码进行改动,并且提交到branch 2上。

相信从上述例子中,你已经明白了版本管理有多么关键。

如何进行版本管理

创建分支

Github提供了branch功能可以用于版本管理,这一部分我将介绍如何使用branch进行版本管理。在本地终端进入项目文件夹,输入git branch即查看当前分支名称。默认分支是master分支。
请添加图片描述
使用branch进行版本管理的第一步就是创建新的分支,运行git branch checkout -b [your branch name]即可以创建一个新的分支,并切换到这个新的分支上。
请添加图片描述

进行改动

此时你已经转到这个新的分支上了,就可以在这个新的分支上进行项目开发。例如,我改动了README文档,添加了一些文本。
请添加图片描述
则可以通过git status查看到我们哪些更改,然后决定是否要接受这些改动。

git add [your file name]则可以将对指定文档的改动添加到改动之中,如果在添加之后后悔了,可以使用git restore --staged [your file name]来撤销git add操作。执行结束后,你会发现刚才提交到改动中的改动被移除改动。

另一个git restore指令与刚才使用的git restore --staged [your file name]不一样,对没在改动中的改动git restore将撤销你在文件中做出的改动,执行结束后,在文档中的改动将消失。
请添加图片描述

添加改动与上传

git add .可以将所有的改动都添加到缓存之中,接着调用git commit -m "[your commit info]" 来添加改动的介绍,最后调用git push —-force-with-lease origin [your branch name]来将改动push到远端的指定分支。
请添加图片描述
远端可以看到,新分支创建成功,并且也有我们添加的改动请添加图片描述
请添加图片描述
可以发现,new_branch比master领先1个commit,我们可以对new_branch的改动进行比较,并决定是否merge到master分支。点击Compare & pull request则可以申请一个pull request对new_branch的改动进行融合。
请添加图片描述
填写new_branch具体做了什么改动,然后点击Create pull request即可以创建一个pull request。
请添加图片描述
创建成功后,其他参与者可以提交comment来发表对改动的建议。

值得注意的是该分支上还可以push 更多的改动。只要该分支上的改动没merge到master,在此之前该分支上的所有改动,都会集成到之前提交到pull request之中。
请添加图片描述
分支融合有3种可选方案,新手不建议选择Rebase and merge方案,建议从前2个方案中进行选择。前两个方案本质都是将改动以merge的形式加到master中,区别在于选Create a merge commit则将这两次改动分别merge进去,选Squash and merge则可以将2此commit 合并成一次commit。考虑到简洁性,建议选择Squash进行融合。

Rebase这个方法是三个方法中最为简洁的一种,它将以线性来融合改动,这同时也带来了风险。例如,如果new_branch改动和master改动出现冲突,则可能出现改动覆盖的情况,这意味着有一支的改动因为代码融合消失了。因而不建议初学者使用这个融合方式。

更多解释可以查看博客的介绍。
请添加图片描述
merge得到通过后,可以在master分支上看到之前的2次commit融合成1次commit提交到master分支上,并且commit info是第2次commit info。

至此,我们完成了一次基于分支的改动提交。

分支带来的新问题

分支提供了一个版本融合的方案,但是总会有一些菜鸟在初次使用的时候不太熟练,然后误把改动添加到master分支上,我们如何保护master分支呢?
请添加图片描述
Github提供一些规则来实现对主要分支的保护,点击Protect this branch,则可以添加规则来约束对master分支的改动(ps:这些改动也可以在setting-Branches里进行)。添加的规则种类繁多,包括每个分支的起名规则,分支提交的约束等等。
请添加图片描述
这里我选了在分支融合之前,必须要请求pull request至少1次(ps:其他的选项可以根据个人需求进行勾选)以及分支要符合标准的命名规则:name_file 分支所用者以及改动主文件名。

常用的git使用命令

git clone [url]
git branch # see which branch we are in
git checkout -b [branch name] # create a new branch and turn to this branch
git checkout [branch name] # turn to a exist branh
git add [your file name] # add your update into cache
git commit -m "[update info]" # add commit info
git push --force-with-lease origin [branch name] # push your update into [branch name]

⚠️ master分支代码就是最权威的,改动的时候一定要基于master分支,另开一个分支,然后再在这个新开的分支上改动代码,将改动push到这个新分支上,然后将此分支merge到master分支上。

一些技巧让项目管理更简单

除了上述基于Github功能的项目管理,我们也可以发动主观能动性来使得项目管理更加顺滑。

项目结构构建

在项目创建之初就应该对项目有一个明确的定位,这个项目到底实现什么功能,具体如何构建项目代码结构,才能有利于后续的代码书写,都是在项目之初有明确的定位的。这件事情非常重要!!!

至于如何获得明确的定位,是超出本篇博客的内容(ps:以我浅显的经验,明确的定位并不是一次讨论就能决定的,需要需求方和实现方多交流沟通确定)。

Commit规范

首先,就是commit info的书写规范,一般来说commit info是要做到提示参与者这次提交具体进行了哪些改动的功能,对于一个不了解情况的人而言,其能阅读的文本数量实在有限,因此需要提交者用最短的话描述出代码改动的核心。建议项目之初就总结一下commit info的书写规范,并强制要求所有参与者遵守。一个可选的例子是:

<type> (scope): describe
  • type:commit的类型说明,允许7种标识

feat: 添加新功能
fix: 修补bug
docs: 增加文档
style: 修改格式
refactor: 重构
test: 添加测试
chore: 构建过程或辅助工具的变动

  • scope:改动范围,比如某个包,某个文件
  • describe: 改动的描述,以动词开头,例如: update README.md

一个可能的例子就是:feat(train.py): add train.py表示这次改动添加了train.py文件实现了train的功能。

文档与注释

文档和注释对项目实现十分重要是所有程序员的共识,然而现实却是大家写文档和注释的意愿并不强烈。一方面是因为代码书写占据了大部分程序员的大部分时间,结束了一天辛劳工作的程序员实在没用动力去完成文档注释的书写;另一方面,文档与注释的确让项目实现变得更加简单易行,但是写文档的好处主要是体现在除去文档书写者的所有人身上,除非所有人都写文档和注释,否则文档和注释的坚持者将遗憾地发现自己做了最多的工作,而受益却是别人的。基于上述原因,文档与注释的书写情况总是不容乐观。

这篇博客不想对不写文档与注释的人进行道德上的谴责,毕竟偷懒是人之常情。本篇博客希望提供一个写文档的思路,来减少善良的程序员在写文档与注释时所承担的时间开销 ❤️

如何写文档才能提升写文档的效率呢?我的经验是,先确定文档的结构,通过子标题的形式来将文档结构简明地总结出来,然后填充每个子标题的具体内容。这样做有一个好处,可以极大地调动其他参与者的文档书写积极性。

例如,对于网上订餐项目,三人实现4个功能包括:查询可点餐馆及可点菜品、下单与付款、评价与点评、纠纷处理。A作为项目管理者,对于这个项目的结构有个非常明确的认识(至少要比B和C这两个参与者明确),因而它非常清楚本项目的代码包含从数据库获取信息模块,显示信息模块,交易模块,评价和售后模块。因而项目的文档结构也应符合项目代码结构,对这些模块进行各自的介绍。

对代码介绍的文档中则应包含这4个子标题,并且对这些模块的具体实现进行展开解释。代码实现上A对显示信息模块等非主写模块并不了解,因此他会将这部分文档书写交给给自负责的人。

上述介绍只是写文档的最基本介绍,更深入的技巧,建议读者阅读一些提升写作能力的工具书。

好消息是,文档的书写不止有手工书写这一种方法(ps:这好像是废话),一些项目文档生成工具可以帮助我们从注释生成文档。对于python代码而言,可以使用Sphinx包来轻松实现项目注释文档生成。具体使用参考博客。

注释对于我们理解函数功能有极大的作用,在写注释时可以参考一些优秀项目的注释书写规范,这里给出一个实例供读者参考。

class People(object):""" __init__Args:name(str): name of a personfather_name(str): father name of this personmother_name(str): mother name of this persongender(str): can only be male or femaleconfig(json): config file that may contain name, father_name, mother_name, genderReturns:a person from PeopleNotes:Some description of PeopleExamples:person = People(name = 'Doris404',father_name = 'Xiaoming',mother_name = 'Xiaohong',gender = 'female')"""def __init__(self, name, father_name, mother_name,gender,config):try:self.name = config['name']except:self.name = nametry:self.father_name = config['father_name']except:self.father_name = father_nametry:self.mother_name = config['mother_name']except:self.mother_name = mother_nametry:self.gender = config['gender']except:self.gender = gendertry:self.config = configexcept:pass

总结

以上是我在项目管理方面的经验,更多内容可以参考我的github repo,上述教程中的例子可以在How2Code repo中得到体现。

如果本篇博客可以帮到你的话,请给我一个赞吧,感谢 ❤️

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/168153.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【JavaWeb】TomcatJavaWebHTTP

Tomcat&JavaWeb&HTTP 文章目录 Tomcat&JavaWeb&HTTP一、Tomcat1.1 版本选择及安装1.2 目录1.3 WEB项目部署的方式 二、IDEA中Java Web开发部署流程三、HTTP协议3.1 发展历程3.2 HTTP协议的会话方式3.3 请求报文3.4 响应报文 一、Tomcat Tomcat是Apache 软件基…

php xml数据转数组两种方式

目录 方法一、可以使用simplexml_load_string()函数将XML数据转换为数组。 方法二、使用PHP内置的DOMDocument类来将XML数据转换为数组的方法 方法一、可以使用simplexml_load_string()函数将XML数据转换为数组。 $xmlData <root><name>John Doe</name>&l…

NX二次开发UF_CSYS_create_matrix 函数介绍

文章作者&#xff1a;里海 来源网站&#xff1a;https://blog.csdn.net/WangPaiFeiXingYuan UF_CSYS_create_matrix Defined in: uf_csys.h int UF_CSYS_create_matrix(const double matrix_values [ 9 ] , tag_t * matrix_id ) overview 概述 Creates a 3 x 3 matrix. 创建…

nodejs+vue+python+PHP+微信小程序-青云商场管理系统的设计与实现-安卓-计算机毕业设计

研究步骤、措施&#xff1a; &#xff08;1&#xff09;与指导老师确定系统主要功能&#xff1b; &#xff08;2&#xff09;做需求分析及功能模块划分&#xff1b; &#xff08;3&#xff09;指导老师通过后&#xff0c;设计出用例图&#xff0c;E-R图&#xff0c;功能模块图 …

【XSLVGL2.0】如何新增一种语言和词条

XSLVGL2.0 开发手册 【XSLVGL2.0】如何新增一种语言和词条 1、概述2、以外置资源的方式增加词条3、以内置资源的方式增加词条4、使用方法1、概述 本文件旨在介绍新增一种语言词条的方法 2、以外置资源的方式增加词条 假设项目需要增加一种英文的词条。一般地,我们采用国际…

老牌开源 SVG 编辑器 SVGEdit 是如何架构的?

大家好&#xff0c;我是前端西瓜哥。这次简单看看 SVGEdit 的架构。 SVGEdit 的版本为 7.2.0。 SVGEdit 一款非常老牌的 SVG 图形编辑器&#xff0c;用于编辑处理 SVG&#xff0c;start 数目前是 5.8k。 它的优点在于经过多年的开发&#xff0c;完成度高&#xff0c;较为成熟&a…

大众博客系统测试报告【改】

一、项目背景 大众博客系统采用前后端分离的方法来实现&#xff0c;同时使用了数据库来存储相关的数据&#xff0c;同时将其部署到云服务器上。前端主要有四个页面构成&#xff1a;登录页、列表页、详情页以及编辑页&#xff0c;以上模拟实现了最简单的大众博客系统。其结合后端…

Tars-GO 开发

默认环境是安装好的 创建服务: tarsgo make App Server Servant GoModuleName Tars 实例的名称&#xff0c;有三个层级&#xff0c;分别是 App&#xff08;应用&#xff09;、Server&#xff08;服务&#xff09;、Servant&#xff08;服务者&#xff0c;有时也称 Object&am…

数据结构——堆的实现

堆的实现-----C语言版 目录&#xff1a;一、堆的实现1.1堆的定义1.2堆的实现1.2.1堆的各个接口1.2.2堆的向上调整1.2.3堆的向下调整1.2.4堆的定义声明和初始化1.2.5堆的数据处理1.2.6堆的判空和堆的数据个数以及堆销毁1.2.7堆的代码实现 二、TOP—K问题 目录&#xff1a; 一、…

vscode项目推送到git

1、打开项目文件 打开文件后点击vs code左侧工具栏中第三个源代码管理图标&#xff0c;点击初始化仓库&#xff0c;此时会创建一个本地仓库会检查该项目中的文件变更 2、创建远程仓库 点击克隆/下载&#xff0c;复制HTTPS地址 3、添加远程地址 1&#xff09;图形化操作 2…

Leetcode刷题之用队列实现栈(C语言版)

Leetcode刷题之用队列实现栈&#xff08;C语言版&#xff09; 一、题目描述二、题目要求三、题目示例四、题目解析Ⅰ、MyStack* myStackCreateⅡ、void myStackPush(MyStack* obj, int x)Ⅲ、int myStackPop(MyStack* obj)Ⅳ、int myStackTop(MyStack* obj)Ⅴ、bool myStackEmp…

文件夹重命名:彻底摆脱数字困扰,批量修改文件夹名去除数字

在日常生活和工作中&#xff0c;经常会遇到需要修改文件夹名称的情况。有时候是因为文件夹名称中包含了数字&#xff0c;有时候是因为文件夹名称不符合规范。无论出于什么原因&#xff0c;修改文件夹名称都是一件非常繁琐的事情。尤其是需要修改大量文件夹名称时&#xff0c;手…

Jenkins 整合 Docker 自动化部署

Docker 安装 Jenkins 配置自动化部署 1. Docker 安装 Jenkins 1.1 拉取镜像文件 docker pull jenkins/jenkins1.2 创建挂载文件目录 mkdir -p $HOME/jenkins_home1.3 启动容器 docker run -d -p 8080:8080 -v $HOME/jenkins_home:/var/jenkins_home --name jenkins jenkin…

k8s部署的java服务查看连接nacos缓存的配置文件

一、问题描述 k8s部署的java服务&#xff0c;使用nacos中的配置文件&#xff0c;需要在缓存中查看该服务具体是使用到了哪些配置文件 二、解决 参考文档: https://nacos.io/zh-cn/docs/system-configurations.html 文档描述如下: 进入java服务容器进入用户目录下的nacos&a…

Java枚举详解

一、什么是枚举类型 枚举类型是一种特殊的数据类型&#xff0c;用于定义一组固定的命名常量。枚举类型提供了一种更强大、更安全和更易读的方式来表示一组相关的常量。 在Java中&#xff0c;枚举类型是通过使用enum关键字来定义的。枚举类型可以包含一个或多个枚举常量&#xf…

vue005——vue组件入门(非单文件组件和单文件组件)

一、非单文件组件 1.1、单文件组件的使用 1.1.1、局部注册 1、第一步&#xff1a;创建school组件 2、第二步&#xff1a;注册组件&#xff08;局部注册&#xff09; 3、第三步&#xff1a;使用组件&#xff08;编写组件标签&#xff09; <!DOCTYPE html> <html>…

设计模式—里氏替换原则

1.概念 里氏代换原则(Liskov Substitution Principle LSP)面向对象设计的基本原则之一。 里氏代换原则中说&#xff0c;任何基类可以出现的地方&#xff0c;子类一定可以出现。 LSP是继承复用的基石&#xff0c;只有当衍生类可以替换掉基类&#xff0c;软件单位的功能不受到影…

Mac Ubuntu双系统解决WiFi和WiFi 5G网络不可用问题

文章目录 设备信息1. Ubuntu WiFi不可用解决方式查看Mac的网卡型号根据网卡型号搜索获取到的解决方法查看WiFi名字问题参考链接 2. 解决WiFi重启后失效问题打开终端创建.sh脚本文件编辑脚本文件复制粘贴脚本修改脚本权限创建并编辑systemd service文件复制粘贴下文到systemd se…

只考数据结构,计算机评级C+,成都信息工程大学考情分析

成都信息工程大学(C) 考研难度&#xff08;☆☆&#xff09; 内容&#xff1a;23考情概况&#xff08;拟录取和复试分析&#xff09;、院校概况、24专业目录、23复试详情、各专业考情分析、各科目考情分析。 正文1715字&#xff0c;预计阅读&#xff1a;3分钟 2023考情概况 …

Java实现求最大值

1 问题 接收用户输入的3个整数&#xff0c;如何将最大值作为结果输出。 2 方法 采用“截图文字代码”的方式描述。 引入输入包调用main()函数&#xff0c;提示并接收用户输入的3个整数&#xff0c;并交由变量a b c来保存。对接收的3个数据进行比较&#xff0c;先比较a和b&#…