mvp内粗泄露问题_如何在一小时内启动MVP服务器

mvp内粗泄露问题

by Yisroel Yakovson

通过伊斯洛尔·雅科夫森

如何在一小时内启动MVP服务器 (How to Launch Your MVP Server in an Hour)

构建全栈服务器 (Building A Full Stack Server)

This article guides you through creating a live, development quality API and back end. It should take you about an hour. And, by the way, it will be free!

本文将指导您创建实时的,开发质量良好的API和后端。 您大概需要一个小时。 而且,顺便说一句,它将是免费的!

This is the second of a series of 3 articles about full graph stacks. Check out How To Build A Cutting Edge Server Now for an introduction.

这是有关完整图形堆栈的3篇文章系列的第二篇。 立即查看如何构建最先进的服务器以获取介绍。

I’m assuming that you know how to code, but not that you’re advanced. This is a full stack project. It touches on a lot of new tools, so you need not feel intimidated if you don’t understand everything. You’ll have some learning curves ahead, but not too steep.

我假设您知道如何编码,但您不具备高级能力。 这是一个全栈项目。 它涉及许多新工具,因此,如果您不了解所有内容,则无需感到害怕。 您将获得一些学习曲线,但不要太过陡峭。

The idea, as explained in the first article, is to focus on specifying your app’s graph of data types. Then to use new tools that generate an app from it.

如第一篇文章所述 ,该想法将重点放在指定应用程序的数据类型图上。 然后使用从中生成应用程序的新工具。

As I wrote in the first article, I went with the GRANDstack project. I don’t claim that it’s the only viable approach, but I recommend that you at least check it out. My team decided on our own that we wanted to go with React, GraphQL, Apollo, and a graph database. The GRANDstack consists of these exactly, so the discovery excited me.

正如我在第一篇文章中所写,我参与了GRANDstack项目。 我并不是说这是唯一可行的方法,但我建议您至少检查一下。 我的团队独自决定要使用React,GraphQL,Apollo和图形数据库。 GRANDstack正是由这些组成,所以这个发现使我兴奋。

But the real excitement begins with the package neo4j-graphql-js. It generates (Prisma style) a set of mutations and resolvers from TypeDefs. If you don’t know what that means, read on.

但是真正的兴奋始于软件包neo4j-graphql-js 。 它从TypeDefs生成(Prisma样式)一组突变和解析器。 如果您不知道这意味着什么,请继续阅读。

On the GRANDstack Kickstarter page, a video shows how to create a full stack from start to finish. That was where I started.

在GRANDstack Kickstarter页面上,视频显示了如何从头到尾创建完整的堆栈。 那是我开始的地方。

One problem with writing these articles is that featured packages are under development. Many things that you still need to do today may be automatic within weeks. I want to summarize the steps and explain how to do some of the things you need that are still missing. But the staff at Neo4j is working on them. If you see that this info is outdated at any point, please post an update below.

撰写这些文章的一个问题是功能包正在开发中。 您今天仍然需要做的许多事情可能会在几周内自动完成。 我想总结一下步骤,并说明如何去做您仍然缺少的某些事情。 但是Neo4j的员工正在为他们工作。 如果您发现此信息在任何时候都已过时,请在下面发布更新。

替代方法 (Alternative Approaches)

Before we start, let me repeat that I’m not calling GRANDstack the only or even the best approach to a Full Graph Stack.

在开始之前,让我重复一遍,我并不是称GRANDstack为全图栈的唯一或最佳方法。

Many alternatives use Prisma to convert a GraphQL schema to an underlying database. Make sure to check out GraphCool. As of this writing, these systems are more developed and leave less work for the developer. A good example is auth.

许多替代方法使用Prisma将GraphQL模式转换为基础数据库。 确保检查出GraphCool 。 在撰写本文时,这些系统已开发得更多,而为开发人员留下的工作量却更少。 一个很好的例子是auth。

The Prisma approach also has less lock-in to a particular database. In practice, changing the database wouldn’t be that hard with GRANDstack. But the cipher queries and the directives are unique to Neo4j.

Prisma方法对特定数据库的锁定也较少。 实际上,使用GRANDstack更改数据库并不难。 但是密码查询和指令对于Neo4j是唯一的。

That said, the GRANDstack Project is explicitly focused on the idea of a Full Graph Stack. I recommend them because they are responsive and devoted to the vision. It is also very straightforward.

就是说,GRANDstack项目明确地专注于全图栈的思想。 我之所以推荐他们,是因为他们React灵敏,并且致力于愿景。 这也非常简单。

建立 (Setup)

创建一个项目 (Create a Project)

  1. Download the starter. Click DOWNLOAD STARTER from GRANDstack, or download it from their GitHub page. I used the GitHub page to be sure I had the latest version (it should be anyway).

    下载启动器。 从GRANDstack单击DOWNLOAD STARTER ,或从其GitHub页面下载。 我使用GitHub页面来确保我拥有最新版本(仍然应该是最新版本)。

  2. Unzip to a folder and name it for your app project

    解压缩到文件夹并为您的应用程序项目命名
  3. It is wise to move the new app folder to a general project folder.

    将新的应用程序文件夹移动到常规项目文件夹是明智的。

设置Git (Set up Git)

I recommend that you not do a thing until you start using Git to handle version control.

我建议您在开始使用Git处理版本控制之前不要做任何事情。

  1. Install Git if you don’t have it.

    安装Git的 ,如果你没有它。

  2. In a text editor, modify .gitignore in the root project directory to include under #dependencies a line for api/node_modules and a line for ui/node_modules. As of this writing, .gitignore contained only node_modules.

    在文本编辑器中,修改根项目目录中的.gitignore ,使其在#dependencies下包含api/node_modules 一行用于ui/node_modules 。 在撰写本文时, .gitignore仅包含node_modules

  3. Move to the root directory of the project in a terminal, and create a new git project:

    在终端中移动到项目的根目录,并创建一个新的git项目:
git init git add .   # adds the relevant filesgit status  # optional to view the files if you are interestedgit commit -m “Initial App Files” #or whatever name you'd like

You can perform git add . and git commit -m "some description" as often as you like. See the endless documentation about Git online. You can learn about branches, commits, reverting, and everything about version control.

您可以执行git add .git commit -m "some description" ,只要您喜欢。 在线查看有关Git的无尽文档。 您可以了解分支,提交,还原以及有关版本控制的所有信息。

制作样品后端 (Make the Sample Back End)

Note that your project code has two directories: api and ui. These articles only focus on the api directory, for creating an API server and back end. For more about the ui, check out the GRANDstack Kickstarter video. You can also view the tutorials at GRANDstack.

请注意,您的项目代码有两个目录: apiui 。 这些文章仅关注用于创建API服务器和后端的api目录。 有关ui更多信息,请查看GRANDstack Kickstarter视频。 您也可以在GRANDstack上查看教程。

建立后端 (Build the Back End)

You need to build the code. You can use npm for that. In the terminal, move to api, and perform these steps:

您需要构建代码。 您可以使用npm。 在终端中,移至api ,然后执行以下步骤:

npm install # pulls in all of the node modules needed for the apinpm start # begins the app

That should initiate the app. You should see something like this in your terminal:

那应该启动应用程序。 您应该在终端中看到以下内容:

$ npm start
> [email protected] start /home/israel/projects/events2/api> nodemon --exec babel-node src/index.js
[nodemon] 1.18.3[nodemon] to restart at any time, enter `rs`[nodemon] watching: *.*[nodemon] starting `babel-node src/index.js`GraphQL API ready at http://0.0.0.0:4000/

Open that link, and you should see a GraphQL Playground page.

打开该链接,您应该看到GraphQL Playground页面。

You can click the green SCHEMA tab on the right, and you’ll see a schema for a sample database. The only thing you’re missing is the database itself.

您可以单击右侧的绿色SCHEMA选项卡,然后将看到示例数据库的架构。 您唯一缺少的是数据库本身。

设置样本数据库 (Set up a sample database)

You’ll have to register with Neo4j to use their sandbox in the steps given below. I recommend getting onto their Slack channel from the beginning. In particular, if you follow the steps below I’d join the #grand-stack channel so that you can ask questions. The project is evolving quickly, so it’s important to stay connected. They are pretty receptive to ideas and responsive to problems. In the past few weeks, they’ve implemented several ideas that I and others have proposed.

您必须在Neo4j中注册,才能在下面提供的步骤中使用其沙盒。 我建议从一开始就进入他们的Slack频道 。 特别是,如果您按照以下步骤操作,我将加入#grand-stack频道,以便您提出问题。 该项目发展Swift,因此保持联系非常重要。 他们非常乐于接受想法并能对问题做出React。 在过去的几周中,他们实施了我和其他人提出的一些想法。

启动一个空白数据库 (Spin up a Blank Database)

  1. Login at Neo4j Sandbox. (As stated at the beginning, you need to create an account if you don’t have one.)

    登录Neo4j Sandbox 。 (如开头所述,如果您没有帐户,则需要创建一个帐户。)

  2. Find “Blank Database” and click on it. It should generate and show up after a minute under Your Current Sandboxes.

    找到“空白数据库”,然后单击它。 一分钟后,它会生成并显示在“当前沙箱”下

  3. Click the Details tab, and you’ll see something like this:

    单击详细信息选项卡,您将看到以下内容:

You’ve now generated a live database. You can visit it in the browser at the top link.

现在,您已经生成了一个实时数据库。 您可以在顶部链接的浏览器中访问它。

将您的项目连接到数据库 (Connect Your Project to the Database)

Open the api/.env file, which contains some global variables used in the API:

打开api/.env文件,其中包含API中使用的一些全局变量:

NEO4J_URI=bolt://localhost:7687NEO4J_USER=neo4jNEO4J_PASSWORD=letmeinGRAPHQL_LISTEN_PORT=4000GRAPHQL_URI=http://localhost:4000

You need to set some of these from the Details tab of your sandbox

您需要从沙箱的“详细信息”标签中设置其中一些设置

  1. Copy the IP Address (e.g. in the example shown above it is 174.129.54.148), and then the bolt port e.g. 33199. Use them together to create a new value for NEO4J_URI in the api/.env file, replacing bolt://localhost:7687. Note that a colon separates them. E.g. the first line in this case would be NEO4J_URI=bolt://174.129.54.148:33199.

    复制IP地址(例如,在上面显示的示例中为174.129.54.148 ),然后33199螺栓端口,例如33199 。 一起使用它们在api/.env文件中为NEO4J_URI创建一个新值,代替bolt://localhost:7687 。 请注意,冒号将它们分开。 例如,在这种情况下,第一行是NEO4J_URI=bolt://174.129.54.148:33199

  2. Also, copy from Details the sandbox db password (e.g. in this case adhesives-casualties-loads) and replace the default password letmein.

    同样,从Details复制出sandbox db密码(例如,在本例中为adhesives-casualties-loads letmein adhesives-casualties-loads ),并替换默认密码letmein

  3. Of course, make sure you’ve saved your changes. Then return to your terminal, hit ctrl-c, once again enter npm start, and return to http://0.0.0.0:4000/ and reload.

    当然,请确保已保存更改。 然后返回到您的终端,按ctrl-c ,再次输入npm start ,然后返回http://0.0.0.0:4000/并重新加载。

  4. Now enter the following mutation in the left pane:

    现在,在左窗格中输入以下突变:
# Try to write your query heremutation {  CreateUser (id: "borris", name: "borris the spider") {    id  }}

Hit the arrow button in the middle to execute, and you should see the results of the mutation in the right button:

点击中间的箭头按钮以执行,然后您应该在右侧的按钮中看到突变的结果:

If so, congratulations! You already have a functional API server running locally.

如果是这样,恭喜! 您已经具有在本地运行的功能性API服务器。

Don’t forget to commit your changes to Git. Back in the root directory of your app (not in API), enter:

不要忘记将更改提交到Git。 返回您应用的根目录(不在API中),输入:

git add .git commit -m "Working Sandbox Db"

直接检查数据 (Inspect the Data Directly)

Now, click the link to Neo4j Browser at the top of the Details in your Neo4j Sandbox. (In the case shown above, it is https://10-0-1-68-33200.neo4jsandbox.com/.)

现在,在Neo4j沙箱中的“详细信息”顶部,单击指向Neo4j Browser的链接。 (在上面显示的情况下,它是https://10-0-1-68-33200.neo4jsandbox.com/ 。)

You can read about how to use it at Neo4j. But for our purposes, enter the following query at the prompt: MATCH (n) RETURN n. That query returns all of the nodes in the database. Click the arrow button on the right to execute, and you should see the new node that you created:

您可以在Neo4j上了解如何使用它。 但出于我们的目的,请在提示符下输入以下查询: MATCH (n) RETURN n 。 该查询返回数据库中的所有节点。 单击右侧的箭头按钮执行,您将看到创建的新节点:

You can get back to a terminal in your api directory and enter npm seedDb if you like. After a minute or so you’ll see the seed data that comes with the starter package for their sample database. You can then play with Playground making queries like this:

您可以返回api目录中的终端,并根据需要输入npm seedDb 。 大约一分钟后,您将看到其示例数据库的入门包随附的种子数据。 然后,您可以使用Playground进行查询,如下所示:

{  users(name: "Will") {    id    name  }}

Or, you can just move on to the next step.

或者,您可以继续进行下一步。

添加您自己的GraphQL模式 (Add your Own GraphQL Schema)

Click on the green SCHEMA button in the Playground interface. You will see a schema that came with the sample database:

在Playground界面中点击绿色的SCHEMA按钮。 您将看到示例数据库随附的模式:

Now it’s time to replace that with your own schema.

现在是时候用您自己的模式替换它了。

  1. Open the current sample schema api/src/graphql-schema.js, and see the source for that data. It’s in the typeDefs declaration.

    打开当前的示例架构api/src/graphql-schema.js ,然后查看该数据的源。 它在typeDefs声明中。

  2. Learn minimally what you must about GraphQL Type Schemas. You must be able to implement your own needed types and some queries. It’s straightforward.

    至少了解有关GraphQL类型架构的知识。 您必须能够实现自己所需的类型和一些查询。 很简单。

  3. Start with one or two types and experiment, building it up gradually. To create a query, you’re going to have to change both typeDefs and resolvers (beneath typeDefs in the same file). Fortunately, your resolvers will be simple. Just call neo4jgraphql from the neo4j-graphql-ps package, as in the sample database.

    从一种或两种类型开始并进行试验,然后逐步进行构建。 要创建查询,您将必须同时更改typeDefsresolvers (在同一文件中的typeDefs下)。 幸运的是,您的解析器将很简单。 只需从示例数据库中的neo4j-graphql-ps包中调用neo4jgraphql

  4. Save changes to the file, and confirm that npm is updating. Then refresh the Playground tab and confirm that the new Schema is showing up.

    将更改保存到文件,并确认npm正在更新。 然后刷新“操场”选项卡并确认正在显示新的架构。

The introductory article about full graph stacks mentioned a sample app for events. Here was its sample app data type graph:

关于完整图形堆栈的介绍性文章提到了事件示例应用程序。 这是其示例应用程序数据类型图:

That’s a lot to add all at once, but it’s not hard to start. We work from the top down, and GraphQL is extremely forgiving.

一次添加很多东西,但是开始并不难。 我们自上而下地工作,而GraphQL非常宽容。

了解neo4j-graphql-js (Understanding neo4j-graphql-js)

It would help to understand a bit about how the server uses neo4j-graphql-js.

了解服务器如何使用neo4j-graphql-js会有所帮助。

The call to augmentSchema in index.js is what is creating all the mutations. That includes the CRUD functions (Create, Update and Delete) for each of the types created. Also, the Add and Remove functions for creating relationships.

index.jsaugmentSchema的调用是创建所有突变的原因。 其中包括针对所创建的每种类型的CRUD函数(创建,更新和删除)。 另外,添加和删除功能用于创建关系。

Relationships between types generate relationship functions. When a type X returns Type Y as a field, that indicates a relationship. Add and Remove functions are generated when the precise relationship is defined using:

类型之间的关系生成关系函数。 当类型X返回类型Y作为字段时,表示关系。 使用以下方法定义精确关系时,将生成添加和删除功能:

  1. a @cypher directive or

    @cypher指令或

  2. a @relation directive with a direction of “OUT”.

    @relation指令的方向为“ OUT”。

The other important function is neo4jgraphql, which implements a resolver. The documentation of the package explains the details.

另一个重要功能是neo4jgraphql ,它实现了一个解析器。 软件包的文档说明了详细信息。

The documentation was updated just last week on the GRANDstack documentation page. (This writing is August 19, 2018). The documentation is still a bit minimal. For instance, the critical augmentSchema function is not discussed in the documentation. They do discuss mutations and they show an example using it. But the documentation is helpful. So are the examples contained in the starter package and in the examples brought there.

该文档已于上周在GRANDstack文档页面上更新。 (本文写作2018年8月19日)。 该文档仍然很少。 例如,文档中未讨论关键的augmentSchema功能。 他们确实讨论了突变,并给出了使用突变的例子。 但是文档很有帮助。 入门包和附带的示例中包含的示例也是如此。

You might also check the documentation for neo4j-graphql. but some things there may not have made it into the ps version yet.

您还可以查看neo4j-graphql的文档。 但是有些东西可能还没有进入ps版本。

初始变更 (Initial Changes)

You can remove all the types in the example, but note that you should not entirely remove the Query type. You will need it for your queries, as you can see in GraphQL documentation.

您可以删除示例中的所有类型,但是请注意,您不应该完全删除查询类型。 您可以在查询中使用它,如GraphQL文档中所见。

Here’s an example of the simplest possible beginning for the events app schema:

这是事件应用模式最简单的开始的示例:

export const typeDefs = `type Event {  id: ID!  name: String}type Query {    events(id: ID, name: String): [Event]}`;export const resolvers = {  Query: {    events: neo4jgraphql,  }};

After saving, check for a reassuring message in the terminal where npm start is running. Something like this:

保存后,在npm start的终端中检查是否有保证消息。 像这样:

[nodemon] restarting due to changes…[nodemon] starting `babel-node src/index.js`GraphQL API ready at http://0.0.0.0:4000/

Refresh Playground in the browser and clicking the SCHEMA buttons. You should see the new schema:

在浏览器中刷新Playground,然后单击SCHEMA按钮。 您应该看到新的架构:

You can then start adding more types.

然后,您可以开始添加更多类型。

添加您自己的数据 (Add your own data)

  1. At your Sandbox prompt, enter MATCH (n) DETACH DELETE n. That will delete any data you added for the sample schema that came with the project.

    在您的沙盒提示下,输入MATCH (n) DETACH DELETE n 。 这将删除您为项目随附的示例架构添加的所有数据。

  2. Use the generated mutations in your new schema to create some data. For instance:

    在新模式中使用生成的变异来创建一些数据。 例如:
mutation {  CreateEvent(id: "my event", name: "The Big Event") {    id    name  }}

上线 (Go Live)

The only thing left is to move your server to a live site so that your front end can call it. (Oh, and you will have to create the front end — go to the ui directory of your app folder to deal with that). The video in the GRANDstack Kickstart page recommends using Now.

剩下的唯一一件事就是将您的服务器移至实时站点,以便您的前端可以调用它。 (哦,您将必须创建前端-转到您的应用文件夹的ui目录以进行处理)。 建议在GRANDstack Kickstart页面上的视频使用Now 。

Go to Now Desktop and click download. But: the desktop app doesn’t currently work for Linux. I’m on Ubuntu, so I just used their command line interface. That’s what I use in this instructions.

转到立即桌面 ,然后单击下载。 但是 :桌面应用当前不适用于Linux。 我在Ubuntu上,所以我只用了他们的命令行界面 。 这就是我在本说明中使用的。

  1. Once you’ve installed on your machine, log in. You should be able to return to the Now site and see your name or picture at the top right.

    在计算机上安装后,登录。您应该可以返回到“ 立即”站点,并在右上角看到您的姓名或图片。

  2. Go to the api directory and type now. You’ll be prompted a few times to enter things. If all goes well, you’ll get a long series of output in the terminal ending with a success message:

    转至api目录,然后键入now 。 系统会多次提示您输入内容。 如果一切顺利,您将在终端中获得一连串的输出,并以一条成功消息结尾:

$ now> Read more about how to update here: https://zeit.co/update-cli> Deploying ~/projects/events2/api under [email protected]> Your deployment's code and logs will be publicly accessible because you are subscribed to the OSS plan.> NOTE: You can use `now --public` or upgrade your plan (https://zeit.co/account/plan) to skip this prompt> Upload [=============-------] 66% 0.1s (192.48KB) [4 files]> Using Node.js 8.11.3 (default)> https://grand-stack-starter-api-qibrvosvuh.now.sh [in clipboard] (bru1) [7s]> Synced 4 files (192.48KB) [7s]> Building…> ▲ npm install> ✓ Using "package-lock.json"> ⧗ Installing 13 main dependencies…> Building "[email protected]" remotely> Building "[email protected]" remotely> Building "[email protected]" remotely> Building "[email protected]" remotely> Error: Error parsing `package.json` for nodemon-1.18.1.tar>     at extract (/snapshot/ace/lib/extract.js:36:11)>     at process._tickCallback (internal/process/next_tick.js:188:7)>     at > ▲ npm install> > [email protected] postinstall /home/nowuser/src/node_modules/protobufjs> node scripts/postinstall> > > [email protected] postinstall /home/nowuser/src/node_modules/nodemon> node bin/postinstall || exit 0> > Love nodemon? You can now support the project via the open collective:>  > https://opencollective.com/nodemon/donate> > npm WARN [email protected] No repository field.> npm WARN optional SKIPPING OPTIONAL DEPENDENCY: [email protected] (node_modules/fsevents):> npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for [email protected]: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"})> > added 564 packages in 9.426s> ▲ Snapshotting deployment> ▲ Saving deployment image (9.0M)> Build completed> Verifying instantiation in bru1> [0] > [0] [email protected] start /home/nowuser/src> [0] nodemon --exec babel-node src/index.js> [0] > [0] [nodemon] 1.18.1> [0] [nodemon] to restart at any time, enter `rs`> [0] [nodemon] watching: *.*> [0] [nodemon] starting `babel-node src/index.js`> ✔ Scaled 1 instance in bru1 [13s]Open that url, and you should see your playground. Try it to be sure that it’s working:

The most important thing is a line indicating your live endpoint:

最重要的是一行指示您的活动端点:

https://grand-stack-starter-api-qibrvosvuh.now.sh [in clipboard]

Open that URL, and you should see your playground. Try it to be sure that it’s working:

打开该URL,您应该看到您的游乐场。 尝试一下以确保它可以正常工作:

您所取得的成就 (What You Have Achieved)

That’s it — a live development server, with very little time and no money down! You have a full stack. But unlike a LAMP stack, this stack includes the API itself. Note that all you had to modify was was typeDefs and resolvers.

就是这样-实时开发服务器,只需很少的时间,也没有钱! 你有一个完整的堆栈。 但是与LAMP堆栈不同,该堆栈包含API本身。 注意,您只需要修改typeDefsresolvers

Understand that this is not yet production quality:

了解这还不是生产质量:

  • Your time is very limited to use this without setting up a permanent database. You can now play with this on your front end until your Neo4j Sandbox expires. That will be 3 days, but you can request an extra seven. And of course, you can always create a new Sandbox. If you like, you can also store a set of mutations at api/src/seed/seed-mutations.js. You can run it with the command npm seedDb whenever you change to a new sandbox.

    您在没有建立永久数据库的情况下使用它的时间非常有限。 现在,您可以在前端使用它,直到Neo4j Sandbox到期为止。 这将是3天,但您可以请求额外的7天。 当然,您始终可以创建一个新的沙箱。 如果愿意,还可以在api/src/seed/seed-mutations.js存储一组api/src/seed/seed-mutations.js 。 每当更改到新的沙箱时,都可以使用命令npm seedDb运行它。

  • Whenever you want to change your version on now, the URL will change. You can set up an alias to allow your code to handle that, but it’s not ideal long-term.

    每当您现在要更改版本时,URL都会更改。 您可以设置一个别名,以允许您的代码处理该别名 ,但是长期而言,这并不是理想的选择。

But for an MVP, and for initial development, it is enough and is free. If you have a domain, you can use any hosting service set up a CNAME record to run your Now page from it.

但是对于MVP和初始开发来说,它是足够的,而且是免费的。 如果您拥有域,则可以使用任何托管服务来设置CNAME记录,以从中运行“现在”页面。

Check out Making Your Full Graph Stack Production Quality to learn how to deploy for release.

查看提高您的完整图形堆栈的生产质量,以了解如何进行发布。

翻译自: https://www.freecodecamp.org/news/building-a-full-graph-stack-f95590ade5af/

mvp内粗泄露问题

你可能感兴趣的:(数据库,python,java,linux,git)