关键字:线性回归、股票、指标、股价、相关性
时间:2017年3月

目录

前言
数据格式
代码
结果

前言

本文主要是讲述线性回归分析相关性的方法。指标数据使用的是16年第三季度的财报数据(部分股票还未公布16年全年财报数据),股价使用的是17年3月29日数据。

数据格式

eps,navps,afps,udpps,ocfps,close
0.015,3.196,1.9056,0.3219,-0.0276,10.8
-0.148,1.8565,2.1732,-1.3452,-0.1338,9.22
1.16,10.6478,2.5714,6.4652,2.3885,52.55
...

注:eps,每股收益。navps,每股净资产。afps,每股公积金。udpps,每股未分配利润。ocfps,每股经营现金流。close,最新收盘价。

代码

import pandas as pd
from sklearn import linear_model

X_train = []
y_train = []

data = pd.read_csv('~/tmp/170329.csv', header=0)
for eps, navps, afps, udpps, ocfps, price in zip(data['eps'],data['navps'],data['afps'],data['udpps'],data['ocfps'],data['close']):
    X_train.append([float(eps),float(navps),float(afps),float(udpps),float(ocfps)])
    y_train.append(float(price))

#print X_train

lr = linear_model.LinearRegression()
lr.fit(X_train,y_train)

formula = 'price = '\
          + str(lr.coef_[0]) + ' * eps + '\
          + str(lr.coef_[1]) + ' * navps + ' \
          + str(lr.coef_[2]) + ' * afps + ' \
          + str(lr.coef_[3]) + ' * udpps + ' \
          + str(lr.coef_[4]) + ' * ocfps + ' \
          + str(lr.intercept_)
print formula
print 'R^2 = ',lr.score(X_train,y_train)

结论

输出结果

price = 22.180397822 * eps + -4.84933539669 * navps + 6.92859281574 * afps + 6.13493457791 * udpps + 0.0891737524391 * ocfps + 14.2736899403
R^2 =  0.475642112179

结论
股价与每股收益相关性最大,成正相关。
R^2不到0.5,回归效果很不理想。

关键字:股票、数据、抓取、python、sgmlparser
时间:2017年3月

目录

前言
说明
代码

前言

抓取股票数据,数据项包括基本每股收益、每股净资产、每股公积金、每股未分配利润、每股经营现金流。

说明

原始页面
http://f10.eastmoney.com/f10_v2/FinanceAnalysis.aspx?code=sz000001
提取关键字
<table class=”needScroll”>
数据最终格式
格式:股票代码,财报周期,基本每股收益,每股净资产,每股公积金,每股未分配利润,每股经营现金流
代码关键点
SGMLParser库的使用请自己查阅相关资料;
httplib库可替换为urllib2等,这里为了提高抓取速度,使用httplib库,建立一个连接反复使用,减少了建立连接的开销;
提取页面上看到数据表格之后,进行了“矩阵转置”操作map(list,zip(*)),由map()和zip()函数组合而成,有点难理解,但它是python二维数组转置的标准用法,请自己查阅资料理解。

代码

# -*- coding: utf-8 -*-
import httplib
from sgmllib import SGMLParser

class EpsParser(SGMLParser):
    def __init__(self):
        SGMLParser.__init__(self)
        self.is_table = ""
        self.is_tr = ""
        self.is_span = ""
        self.row = []
        self.result =[]

    def start_table(self, attrs):
        for k,v in attrs:
            if k=='class' and v=='needScroll':
                self.is_table = 1

    def end_table(self):
        self.is_table = ""

    def start_tr(self, attrs):
        if self.is_table == 1:
            self.is_tr = 1

    def end_tr(self):
        if self.is_table == 1:
            self.is_tr = ""
            self.result.append(self.row)
            self.row = []

    def start_span(self,attrs):
        if self.is_table == 1 and self.is_tr == 1:
            self.is_span = 1

    def end_span(self):
        if self.is_table == 1 and self.is_tr == 1:
            self.is_span = ""

    def handle_data(self, text):
        if self.is_table == 1 and self.is_tr == 1 and self.is_span == 1:
            self.row.append(text)

f = open('result.csv','a')
conn = httplib.HTTPConnection("f10.eastmoney.com")

for i in range(600001,600020):
    symbol = '%06d' % i
    url = '/f10_v2/FinanceAnalysis.aspx?code=sh%s' % symbol
    #url = '/f10_v2/FinanceAnalysis.aspx?code=sz%s' % symbol
    print url
    req = conn.request('GET',url)
    content = conn.getresponse().read()
    parser = EpsParser()
    parser.feed(content)
    data = map(list,zip(*(parser.result))) # 二维数组转置
    for d in data:
        if d[0]=='16-12-31' or d[0]=='16-09-30' or d[0]=='16-06-30':
            f.write("%s,%s,%s,%s,%s,%s,%s\n"%(symbol,d[0],d[1],d[4],d[5],d[6],d[7]))
    f.flush()

conn.close()
f.close()

关键字:线性回归、python、sklearn、linear、regression
时间:2017年3月

目录

前言
数据
代码

前言

以沪深股市每股收益与股价为案例,通过线性回归分析来预测每股收益合理的股价。

数据

eps.csv

eps,price
1.09,9.12
0.748,21.27
0.175,38.28
0.126,6.42
0.0848,8.5
0.0367,8.55
0.098,9.52
0.0268,6.9
-0.0121,16.19
0.34,11.26
-0.0869,18.19
-0.0184,4.48
0.0038,10.82
0.1785,10.45
-0.061,15.96
0.0159,23.17
0.2063,9.63
0.663,20.99
0.06,29.36
0.0882,50.07
0.2469,14.52
0.3375,6.97
1.993,74.7
0.4,8.61
0.04,8.28
0.1091,7.88
0.4231,8.27
-0.11,12.21
0.4804,40.25
-0.0898,16.27
-0.0393,12.65
-0.1,13.65
0.3593,9.13
0.6498,51.49
0.15,15.07
0.07,12.59
0.054,10.17
0.7337,11.7
0.07,11.23
0.1261,11.29
0.373,26.44
0.69,17.51
0.39,36.58
0.0203,10.9
-0.031,7.82
0.3555,7.29
0.397,24.13
0.1455,6.33
0.1388,7.74
0.1996,8.86
0.1849,9.27
0.2,16.38
0.1251,12.07
0.1259,3.63
2.159,29.1
0.2552,23.78
0.3198,17.15
-0.1,4.83
-0.046,11.9
0.0242,10.87
0.19,6.27
2,33.95
0.38,11.32
0.2426,17.88
-0.336,14.5
0.27,11.1
0.21,31.72
0.3237,10.28
0.3216,16.8
-1.04,11.4
0.2876,24.07
0.2,11.23
0.0185,10.7
0.2958,9.04
1.44,40.69
0.1529,8.42
0.0258,4.11
0.2253,8.78
0.02,6.82
1.8745,64.18
0.024,4.09
0.0811,8.62
-0.12,6.8
0.43,7.34
0.3007,12.8
0.74,12.2
0.2215,8.4
1.29,22.66
-0.1874,16.56
-0.0947,33.75
-0.0507,17.37
-0.21,11.08
0.007,10.52
0.1064,7.37
-0.0406,7.69
0.0296,10.76
-0.07,6.54
1.57,56.03
0.0129,9.93
0.0064,5.25
0.0101,8.11
0.045,16.9
-0.0032,8.08
0.2164,7.24
0.04,11.33
0.108,15.46
0.0669,18.9
0.0056,9.16
0.13,10.86
0.23,11.31
0.6307,11.4
0.0867,18.05
0.023,11.1
0.1397,15.19
0.5252,11.65
0.49,9.9
2.27,86.14
0.281,5.45
0.4413,6.78
0.2202,10.65
0.4316,6.9
0.43,19.98
0.049,6.69
0.375,13.27
0.12,9.94
1.27,28.38
0.15,11.13
0.0527,3.87
0.0063,11.85
0.1344,21.11
-0.0458,6.57
0.271,12.29
0.1183,16.08
0.1134,6.28
0.0094,8.53
0.124,12.92
0.0107,32.3
1.074,41
0.1,9.02
0.0794,7.93
0.1271,6.04
0.0383,8.67
-0.1603,17.77
1.3,23.1
0.408,18.15
-0.0268,8.02
0.014,19.3
0.66,15.51
0.009,6.26
0.0552,20.15
0.3387,14.37
0.011,6.37
0.015,10.63
1.16,52
0.25,5.84
0.12,8.23
0.917,9.48
0.4244,8.35
0.26,16.66
0.1643,20.73
0.0281,11.49
0.125,10.19
-0.45,7.95
0.4252,18.55
0.0071,14.69
0.036,10.19
-0.1249,13.74
-0.0173,5.03
-0.72,20.57
0.2528,12.43
0.08,7.75
-0.0446,9.06
1.4472,30.45
0.766,22.74
0.098,13.93
-0.1414,2.52
0.01,3.17
0.12,4.92
0.0031,8.77
-0.0957,11.45
0.136,26.6
0.12,10.63
0.065,8.01
0.027,13.5
0.26,22.8
0.22,6.88
1.87,30.8
0.0483,5.94
-0.24,9.17
0.2144,5.69
0.0351,14.43
-0.062,6.04
2.48,115.51
0.2422,19
0.03,14.92
0.37,14.9
0.6,23.27
0.1218,3.72
-0.27,21.45
...

代码

import matplotlib.pyplot as plt
import pandas as pd
from sklearn import linear_model

X_train = []
y_train = []

data = pd.read_csv('eps.csv', header=0)
for eps, price in zip(data['eps'],data['price']):
    X_train.append([float(eps)])
    y_train.append(float(price))

lr = linear_model.LinearRegression()
lr.fit(X_train,y_train)

formula = 'y = ' + str(lr.coef_[0]) + ' * x + ' + str(lr.intercept_)
print formula

plt.scatter(X_train,y_train,color='blue')
plt.plot(X_train,lr.predict(X_train),color='red')
plt.text(-2.5,140,formula)
plt.show()

关键字:MRD、市场需求文档、模板
时间:2017年3月

MRD/Market Requirement Document/市场需求文档

市场的问题和机会

市场、产品、技术面临的问题和机会

市场特征

目标市场特征
目标市场趋势
目标市场细分
目标市场结束时间

用户特征

客户、购买者
特征、细分、动机、影响因素以及用户期望(目标)

使用者特征

产品的最终享受者,他们的特征、现实需要和相关关系

市场的需求

功能分类、开发环境说明、兼容性说明、性能说明、国际性说明、文档说明、外观说明、发布说明、支持与培训说明;其他说明;方案概述;
需求概要表:实现目标;约束条件;需求联系;原型;类型;优先级。

关键字:oscommerce、2.3.4、osc、安装
时间:2017年3月

目录

前言
安装步骤
简单使用

前言

系统Debian8.7
主机IP:192.168.3.67

安装步骤

安装mysql

root@debian:~# apt-get install mysql-server

安装apache和php

root@debian:~# apt-get install apache2 php5
root@debian:~# vim /etc/apache2/sites-enabled/000-default.conf
...
DocumentRoot /var/www
...
root@debian:~# systemctl restart apache2

安装osCommerce包

root@debian:~# unzip oscommerce-2.3.4.zip
root@debian:~# cd oscommerce-2.3.4
root@debian:~/oscommerce-2.3.4# cp -r catalog/ /var/www/

注:建议不要改变catalog目录的名字,也不要把catalog里面的内容放到网站根目录下,因为catalog本身指的是商品目录的意思。最好的做法就是在/var/www/下建一个index.html作为商店的封面,点击跳转至/var/www/catalog/。

配置osCommerce

http://192.168.3.67/catalog/install/

服务器能力检查

a)报错1,PHP扩展MySQL、GD、cURL未安装,解决办法:

root@debian:~# apt-get install php5-mysql php5-gd php5-curl

b)报错2,两个configure.php文件权限不够,解决办法:

root@debian:~# cd /var/www/catalog/
root@debian:/var/www/catalog# chmod 777 includes/configure.php
root@debian:/var/www/catalog# chmod 777 admin/includes/configure.php

c)刷新页面,点击start按钮。

第一步:数据库服务器设置

a)需要手工在MySQL上为osCommerce创建一个库和用户

root@debian:~# mysql -uroot -p
mysql> create database oscommerce default charset=utf8mb4;
Query OK, 1 row affected (0.00 sec)
mysql> grant all privileges on oscommerce.* to 'osc'@'%' identified by '123456';
Query OK, 0 rows affected (0.00 sec)

b)填写数据库配置表单
Database Server: localhost
Username: osc
Password: 123456
Database Name: oscommerce
c)点击continue按钮,耐心等待

第二步:网站路径配置页面

a)填写表单(使用默认值,不做修改)
WWW Address: http://192.168.3.67/catalog/
Webserver Root Directory: /var/www/catalog/
b)点击continue按钮

第三步:Web服务器设置

a)填写表单
Store Name: George’s Store
Store Owner Name: George
Store Owner E-mail Address: admin@xxx.com
Administrator Username: admin
Administrator Password: 123456
Time Zone: (Asia)Shanghai
b)点击continue。

第四步,完成

一下操作可以不做,但严重威胁网站的安全。

root@debian:/var/www/catalog# rm -rf install/
root@debian:/var/www/catalog# chmod 644 includes/configure.php
root@debian:/var/www/catalog# chmod 644 admin/includes/configure.php

简单使用

商店http://192.168.3.67/catalog/
管理后台http://192.168.3.67/catalog/admin/
Administrators -> Configuration -> Administrators

关键字:软件产品、团队、构成、产品经理
日期:2017年3月

目录

前言
角色及职责
构成比例

前言

本总结来源于《启示录》。

角色及职责

角色 职责
产品经理 评估产品机会、定义产品
用户体验设计师(交互设计师) 深入理解用户,设计有价值、可用的功能,设计用户导航和产品使用流程
项目管理人员 定制计划和跟踪进度
开发团队 开发产品
运维团队 保证服务正常运行
产品营销人员 发布信息、宣传产品,为拓展渠道、组织营销活动、促进产品销售提供支持

构成比例

角色 构成比例
产品经理 1
交互设计师 0.5
视觉设计师 0.125
开发人员 5~10
项目经理 0~1

注:超过十名开发人员参与的重大项目,应该配备专职项目经理。火车模型发布模式,必须为每次产品发布配备专职项目经理。

关键字:窗口管理器、轻量级、openbox、安装
时间:2017年3月

目录

openbox介绍
安装及使用

openbox介绍

openbox是一个超轻量级的窗口管理器,系统资源占用非常小。
适合:
a)需要使用图形界面的服务器;
b)树莓派等设备。

安装及使用

root@debian:~# apt-get install xorg openbox
...
root@debian:~# startx

关键字:jstorm、helloworld、hello
时间:2017年3月

目录

前言
jar包
主要代码
集群上运行

前言

1、spout的关键代码是nextTuple(),一个任务开始后,集群会不停的调用nextTuple()。nextTuple()应当有collector.emit(),emit()会让下游的bolt接收到tuple。
2、bolt的关键代码是execute(Tuple input),参数input来自上游调用collector.emit()。bolt也可以调用collector.emit()传一个tuple给下游bolt。
3、本程序构建了一个spout-001 -> bolt-001 -> bolt-002拓扑。

jar包

1、jstorm程序需要使用jar包jstorm-core,目前版本为2.1.1;
2、jstorm-core依赖于slf4j-api,但只兼容slf4j-api的1.5.5或以下版本。

<dependency>
    <groupId>com.alibaba.jstorm</groupId>
    <artifactId>jstorm-core</artifactId>
    <version>2.1.1</version>
    <scope>provided</scope>
</dependency>
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>1.5.5</version>
    <scope>provided</scope>
</dependency>

主要代码

/*
 * App.java
 */
public class App 
{
    public static void main( String[] args ) throws AlreadyAliveException, InvalidTopologyException
    {
        TopologyBuilder builder = new TopologyBuilder();
        builder.setSpout("spout-001", new FirstSpout());
        builder.setBolt("bolt-001", new FirstBolt()).shuffleGrouping("spout-001");
        builder.setBolt("bolt-002", new SecondBolt()).shuffleGrouping("bolt-001");
        Config config = new Config();
        config.setDebug(false);
        config.setNumWorkers(5);
        config.setMaxTaskParallelism(3);

        /* 本地环境调试 */
        LocalCluster cluster = new LocalCluster();
        cluster.submitTopology("hello", config, builder.createTopology());

        /* JStorm集群环境运行 */
        //StormSubmitter.submitTopology("hello", config, builder.createTopology());
        }
    }
}
/*
 * FirstSpout.java
 */
public class FirstSpout extends BaseRichSpout {

	private static final long serialVersionUID = 2097335660808026799L;
	private SpoutOutputCollector collector;
	
        @Override
	public void open(Map conf, TopologyContext context, SpoutOutputCollector collector) {
		this.collector = collector;
	}

        @Override
	public void nextTuple() {
		collector.emit(new Values("hello"));
		try {
			Thread.sleep(500);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

        @Override
	public void declareOutputFields(OutputFieldsDeclarer declarer) {
		declarer.declare(new Fields("field1"));
	}
}
/*
 * FirstBolt.java
 */
public class FirstBolt extends BaseRichBolt {

	private static final long serialVersionUID = -7866785982451843573L;
	private OutputCollector collector;
	
	@Override
	public void prepare(Map stormConf, TopologyContext context, OutputCollector collector) {
		this.collector = collector;
	}

	@Override
	public void execute(Tuple input) {
		String s = (String)input.getValueByField("field1");
		System.out.printf("bolt-001 received '%s' from spout-001.\n", s);
                s += " world";
		collector.emit(new Values(s));
	}

	@Override
	public void declareOutputFields(OutputFieldsDeclarer declarer) {
		declarer.declare(new Fields("field2"));
	}
}
/*
 *  SecondBolt.java
 */
public class SecondBolt extends BaseRichBolt {

	private static final long serialVersionUID = 8910534863307440929L;

	@Override
	public void prepare(Map stormConf, TopologyContext context, OutputCollector collector) {

	}

	@Override
	public void execute(Tuple input) {
            String s = (String)input.getValueByField("field1");
            System.out.printf("bolt-002 received '%s' from bolt-001\n", s); 
        }

        @Override public void declareOutputFields(OutputFieldsDeclarer declarer) {

        }
}

集群上运行

1、代码中必须要执行StormSubmitter.submitTopology();
2、生成一个jar包,上传至nimbus节点;
3、nimbus上执行shell执行jstorm jar hello.jar com.xxxx.hello.App。
注:com.xxxx.hello.App为main()所在的类。

关键字:jstorm、2.1.0、安装、nimbus、supervisor
时间:2017年3月

目录

基本概念
主机准备
安装、配置nimbus和supervisor
安装、配置WebUI
查看集群状态

基本概念

a)JStorm依赖于zookeeper。
b)JStorm节点有nimbus、supervisor、web-ui三种类型。nimbus负责调度任务。supervisor负责执行任务。web-ui只是一个监控界面,不是必须的。

主机准备

主机操作系统Debian 8.7

ip hostname
192.168.7.7 zookeeper1
192.168.7.8 zookeeper2
192.168.7.9 zookeeper3
192.168.7.10 nimbus1 java、python
192.168.7.11 nimbus2 java、python
192.168.7.12 supervisor1 java、python
192.168.7.13 supervisor2 java、python
192.168.7.13 web-ui tomcat

zookeeper集群安装请查阅相关资料,或阅读我的文章《Debian下搭建zookeeper集群》。

安装、配置nimbus和supervisor

a)添加jstorm用户

root@xxx:~# adduser jstorm

b)下载并解压安装包

jstorm@xxx:~$ wget https://github.com/alibaba/jstorm/releases/download/2.1.0/jstorm-2.1.0.tar.bz2
jstorm@xxx:~# tar -zxvf jstorm-2.1.0.tar.bz2
jstorm@xxx:~# mv deploy/jstorm ./jstorm-2.1.0

c)配置环境变量

jstorm@xxx:~$ vim .profile
...
export JSTORM_HOME=/home/jstorm/jstorm-2.1.0
export PATH=$PATH:$JSTORM_HOME/bin
jstorm@xxx:~$ . .profile
jstorm@xxx:~$ echo $JSTORM_HOME
/home/jstorm/jstorm-2.1.0

d)修改nimbus主机配置文件

jstorm@nimbus1:~# cd jstorm-2.1.0/conf
jstorm@nimbus1:~/jstorm-2.1.0/conf# cp storm.yaml.example storm.yaml
jstorm@nimbus1:~/jstorm-2.1.0/conf# vim storm.yaml
 storm.zookeeper.servers:
     - "192.168.7.7"
     - "192.168.7.8"
     - "192.168.7.9"
 storm.zookeeper.root: "/jstorm"
 nimbus.host: "192.168.7.10, 192.168.7.11"   # 只能用ip
 storm.local.dir: "%JSTORM_HOME%/data"

e)修改supervisor配置文件

jstorm@supervisor1:~# cd jstorm-2.1.0/conf
jstorm@supervisor1:~/jstorm-2.1.0/conf# cp storm.yaml.example storm.yaml
jstorm@supervisor1:~/jstorm-2.1.0/conf# vim storm.yaml
 storm.zookeeper.servers:
     - "192.168.7.7"
     - "192.168.7.8"
     - "192.168.7.9"
 storm.zookeeper.root: "/jstorm"
 nimbus.host: "192.168.7.10, 192.168.7.11"   # 只能用ip
 storm.local.dir: "%JSTORM_HOME%/data"
 supervisor.slots.ports:
    - 6800
    - 6801
    - 6802
    - 6803

f)启动所有节点

jstorm@nimbus1:~$ nohup jstorm nimbus &
jstorm@nimbus1:~$ jps
937 NimbusServer
980 Jps
jstorm@nimbus2:~$ nohup jstorm nimbus &
jstorm@nimbus2:~$ jps
1302 NimbusServer
1310 Jps
jstorm@supervisor1:~$ nohup jstorm supervisor &
jstorm@supervisor1:~$ jps
1102 Supervisor
1115 Jps
jstorm@supervisor2:~$ nohup jstorm supervisor &
jstorm@supervisor2:~$ jps
1127 Supervisor
1156 Jps

安装、配置WebUI

在jstorm安装包中有一个war包,设置好war需要的配置文件,并该war包放到tomcat环境下,及完成web-ui的安装。
配置文件

tomcat@web-ui:~$ mkdir .jstorm
tomcat@web-ui:~$ vim ./jstorm/storm.yaml   # 该文件内容来自于conf/storm.yaml最后一部分
# UI MultiCluster
# Following is an example of multicluster UI configuration
 ui.cluseters:
     - {
          name: "jstorm.share",
          zkRoot: "/jstorm",
          zkServers:
              [ "192.168.7.7", "", ""],
          zkPort: 2181,
        }
tomcat@web-ui:~$ tar -zxvf jstorm-2.1.0.tar.bz2
tomcat@web-ui:~$ mv deploy/jstorm ./jstorm-2.1.0
tomcat@web-ui:~$ cp jstorm-2.1.0/jstorm-ui-2.1.0.war apache-tomcat-7.0.75/webapps/
tomcat@web-ui:~/apache-tomcat-7.0.75$ bin/startup.sh

查看集群状态

浏览器打开http://192.168.7.13:8080/jstorm-2.1.0/

关键字:git、svn、服务器端
时间:2017年3月

目录

1、基本概念
2、准备
3、全新库的建库方法
4、已有本地库的建库方法
5、Windows系统客户端注意事项

基本概念

a)svn与git的区别
svn的commit是提交到服务器仓库,而git的commit是提交到本地仓库,git需要执行push才能提交到服务器仓库;
svn使用update把服务器仓库的最新版本更新到本地,而git使用pull把服务器仓库的最新版本拉取并更新到本地。
b)hello/.git/与hello.git/
在客户端本地,能看到hello/.git/目录,而在github.com上,通常看到的都是hello.git/这样的目录,两者的功能完全一样。
可以这样理解,把hello/看成工作目录,服务器上是不需要工作目录的,加上url中出现”/.”看似有些不不合法,因此采用了hello.git/的形式。
服务器上用”hello/.git/”也是没有问题的,例如:git clone ssh://user1@server/~/hello/.git

准备

主机 系统 用途
server linux 公共仓库
workstation linux/macOS 工作站

全新库的建库方法

仓库名:hello

服务器端

user1@server:~$ mkdir hello.git
user1@server:~$ cd hello.git
user1@server:~/hello.git$ git init --bare
...

客户端

user2@workstation:~$ git clone ssh://user1@server/~/hello.git
Cloning into 'hello'...
user1@server's password: 
warning: You appear to have cloned an empty repository.
user2@workstation:~$ cd hello
user2@workstation:~/hello$ ls -a # 
.       ..      .git
user2@workstation:~/hello$ echo "hello" > readme
user2@workstation:~/hello$ git add readme
user2@workstation:~/hello$ git commit -m "some description"
...
user2@workstation:~/hello$ git push origin master  # 把当前commit的版本推交到服务器
...

已有本地库的建库方法

服务器端

user1@server:~$ mkdir hello.git
user1@server:~$ cd hello.git
user1@server:~/hello.git$ git init --bare
...

注:必须是空仓库,否则客户端无法push。

客户端

user2@workstation:~/hello$ ls -a # 
.       ..      .git    readme
user2@workstation:~/hello$ git remote add origin ssh://user1@server/~/hello.git
user2@workstation:~/hello$ git push origin master  # 把当前commit的版本推交到服务器
...

注:如果remote地址错了,可以执行”git remote remove origin”删除。

Windows系统客户端注意事项

Windows系统,需要进行相应配置才能正常使用git客户端。

$ git config --global user.name "Your Name"
$ git config --global user.email "email@example.com"