这个问题是默认配置造成的,编辑配置文件:
vim /etc/vsftpd.conf
修改
pam_service_name=vsftpd
为
pam_service_name=ftp
之后重启服务即可。
CentOS一些基础的知识
这个问题是默认配置造成的,编辑配置文件:
vim /etc/vsftpd.conf
修改
pam_service_name=vsftpd
为
pam_service_name=ftp
之后重启服务即可。
某次在某乎上看到有人提到消息队列的问题,然后有人在回答里提到了Redis,接着便有人在评论里指出:Redis是缓存,不是消息队列。
但不幸的是,Redis的确提供一个简易的消息队列机制,可以用于一些要求不那么高的场合。
方法就是利用Redis的列表类型的push和pop操作。
我对前文所介绍的Redis Cache作了一点简单的扩展,增加了消息队列功能。
代码基本就这么点:
class RedisMQ(RedisCache):
def __init__(self, dbname, host='localhost', port=6379, db=0):
super(RedisMQ, self).__init__(dbname, host, port, db)
def push(self, channel, data):
ch = self._getkey("channel", channel)
self.db.lpush(ch, self.SERIALIZER.dumps(data))
def pop(self, channel, timeout=5):
ch = self._getkey("channel", channel)
msg = self.db.brpop(ch, timeout)
return self.SERIALIZER.loads(msg[1]) if msg else None
class Channel(object):
MQ = RedisMQ("msgqueue")
def __init__(self, channel):
self.channel = channel
def push(self, **kwargs):
Channel.MQ.push(self.channel, kwargs)
def pop(self):
return Channel.MQ.pop(self.channel)
消息生产者
ch = Channel("test")
ch.push(a=123,b="hello")
消息消费者,可能是另一个线程,甚至是另一个进程,甚至是另外一台主机——只要它们共用同一个redis即可。
ch = Channel("test")
while msg=ch.pop():
# msg: {"a": 123, "b": "hello"}
# ch is empty
192.168.42.150 redis-node1 #主
192.168.42.151 redis-node2 #从
192.168.42.152 redis-node3 #从
192.168.42.153 redis-node4 #从
将主机解析写入hosts文件,分发至每台机器
(1) 4台机器,分别安装redis
cd /usr/local/src
wget http://192.168.42.26/install_package/down/redis-3.2.3-1.el7.x86_64.rpm
yum install redis-3.2.3-1.el7.x86_64.rpm -y
(2) 4台机分别配置好,配置文件,做好备份
cp /etc/redis.conf{,.back}
vim redis.conf
daemonize yes
bind 192.168.42.150 #改为各个节点的IP
(3) 依照上面设定的从主机,在从主机配置文件中开启从配置(需要配置3台机器)
# slaveof <masterip> <masterport>
slaveof 192.168.42.150 6379
(4) 启动redis-server(4台同时启动)
redis-server /etc/redis.conf
(5) 在主机器上登录redis
[root@redis-node1 ~]# redis-cli -h 192.168.42.150
192.168.42.150:6379>
192.168.42.150:6379> keys *
1) "magedu"
192.168.42.150:6379>
192.168.42.150:6379> set ok "verygood!!!"
OK
192.168.42.150:6379> get ok
"verygood!!!"
192.168.42.150:6379>
登录其他3台从服务器
redis-cli -h 192.168.42.151
redis-cli -h 192.168.42.152
redis-cli -h 192.168.42.153
拿153做示例:
[root@redis-node4 src]# redis-cli -h 192.168.42.153
192.168.42.153:6379> keys *
1) "magedu"
192.168.42.153:6379>
192.168.42.153:6379> get ok
"verygood!!!"
192.168.42.153:6379>
至此为至redis主/从已经实现,在主节点上查看信息
192.168.42.150:6379> INFO Replication
# Replication
role:master
connected_slaves:3
slave0:ip=192.168.42.151,port=6379,state=online,offset=22806,lag=1
slave1:ip=192.168.42.152,port=6379,state=online,offset=22806,lag=1
slave2:ip=192.168.42.153,port=6379,state=online,offset=22806,lag=1
master_repl_offset:22806
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:22805
接下来在四个结点上配置sentinel,实现故障转移。此处实现累似于MariaDB的MHA 在上面我们已经配置好主从复制集群,现在我们需要添加一台机器[192.168.42.154]来做高可用 同样我们需要设置好,IP,主机名,下载安装redis
192.168.42.154 redis-sentinel #将主机解析追加至其他的4台的hosts文件中,本机也需要一份
cd /usr/local/src
wget http://192.168.42.26/install_package/down/redis-3.2.3-1.el7.x86_64.rpm
yum install redis-3.2.3-1.el7.x86_64.rpm -y
(1)配置sentinel
# sentinel monitor #法定人数
cp /etc/redis-sentinel.conf{,.back}
vim /etc/redis-sentinel.conf
daemonize yes
sentinel monitor mymaster 192.168.42.150 6379 1
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 18000
sentinel auth-pass mymaster centos.123 #这是认证选项,我们这里的主节点并没有开启认证
(2)启动sentinel
redis-sentinel /etc/redis-sentinel.conf
查看端口是否已经启动
[root@redis-sentinel src]# ss -tnl
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 *:22 *:*
LISTEN 0 100 127.0.0.1:25 *:*
LISTEN 0 511 *:26379 *:*
LISTEN 0 128 :::22 :::*
LISTEN 0 100 ::1:25 :::*
LISTEN 0 511 :::26379 :::*
(3)模拟故障:
192.168.42.150:6379
pkill redis
#查看
[root@redis-node1 ~]# ss -tnl
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 *:22 *:*
LISTEN 0 100 127.0.0.1:25 *:*
LISTEN 0 128 :::22 :::*
LISTEN 0 100 ::1:25
(4)查看故障是否转移
登录192.168.42.151:6379 #巧了,恰好151变成主了
192.168.42.151:6379>
192.168.42.151:6379> INFO Replication
# Replication
role:master
connected_slaves:2
slave0:ip=192.168.42.153,port=6379,state=online,offset=5413,lag=1
slave1:ip=192.168.42.152,port=6379,state=online,offset=5413,lag=2
master_repl_offset:5413
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:5412
192.168.42.151:6379>
登录192.168.42.152:6379查看,的确是151变成主了
192.168.42.152:6379> INFO Replication
# Replication
role:slave
master_host:192.168.42.151
master_port:6379
master_link_status:up
master_last_io_seconds_ago:1
master_sync_in_progress:0
slave_repl_offset:11402
slave_priority:100
slave_read_only:1
connected_slaves:0
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
192.168.42.152:6379>
(4)我们再把151的进程杀了,再来看一次,可以看到只有一主一从了
192.168.42.152:6379> INFO Replication
# Replication
role:master
connected_slaves:1
slave0:ip=192.168.42.153,port=6379,state=online,offset=1625,lag=1
master_repl_offset:1768
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:1767
192.168.42.152:6379>
(5)最后我们将杀死的两台redis恢复,再来查看
192.168.42.152:6379> INFO Replication
# Replication
role:master
connected_slaves:3
slave0:ip=192.168.42.153,port=6379,state=online,offset=12763,lag=1
slave1:ip=192.168.42.151,port=6379,state=online,offset=12763,lag=1
slave2:ip=192.168.42.150,port=6379,state=online,offset=12763,lag=0
master_repl_offset:12763
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:12762
192.168.42.152:6379>
可以看出此时的1主3从又回来了,不过此时主节点,是152
回到150,和151的节点查看效果
192.168.42.150:6379> INFO Replication
# Replication
role:slave
master_host:192.168.42.152
master_port:6379
master_link_status:up
master_last_io_seconds_ago:2
master_sync_in_progress:0
slave_repl_offset:23555
slave_priority:100
slave_read_only:1
connected_slaves:0
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
192.168.42.150:6379>
192.168.42.151:6379> INFO Replication
# Replication
role:slave
master_host:192.168.42.152
master_port:6379
master_link_status:up
master_last_io_seconds_ago:1
master_sync_in_progress:0
slave_repl_offset:20782
slave_priority:100
slave_read_only:1
connected_slaves:0
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
接下来我们配置有密码认证的主从和高可用
我们之前在配置sentinel,时还记得 #法定人数吗,判断为失效至少需要2个 Sentinel进程的同意,只要同意Sentinel的数量不达标,自动failover就不会执行
sentinel monitor #法定人数
我们现在将154这台干脆也做成redis的从服务器,而sentinel,是这5台的集合(150,151,152,153,154)
(1).将153的配置文件推到154一份
scp /etc/redis.conf{,.back} [email protected]:/etc/
到154这边稍微修改一下
vim /etc/redis.conf
bind 192.168.42.154
因此这次我们是要做密码认证的,因此5台机器都需要加上密码
(2).我们现在查看之前做了 sentinel后,配置文件系统自动帮我们改了,现在我们要恢复到初始状态,重新来过
所有的配置文件还需要设置我们的密码(为了方便管理,我们这里统一设置成magedu) requirepass magedu
所有从节点加上
#masterauth
masterauth magedu
slaveof 192.168.42.150 6379
(3).密码设置好之后,启动所有服务
redis-server /etc/redis.conf
ss -tnl
登录150,需要认证了
[root@redis-node1 ~]# redis-cli -h 192.168.42.150
192.168.42.150:6379> keys *
(error) NOAUTH Authentication required.
[root@redis-node1 ~]# redis-cli -h 192.168.42.150
192.168.42.150:6379> keys *
(error) NOAUTH Authentication required.
192.168.42.150:6379> keys *
(error) NOAUTH Authentication required.
192.168.42.150:6379> AUTH magedu
OK
同样的,我们需要登录认证其他机器
再150机器上设置key
192.168.42.150:6379> set zlyc "zai lai yi ci"
OK
192.168.42.150:6379> get zlyc
"zai lai yi ci"
192.168.42.150:6379>
其他机器读取OK
192.168.42.151:6379> get zlyc
"zai lai yi ci"
192.168.42.151:6379>
这篇文章主要介绍了phpmyadmin提示The mbstring extension is missing的解决方法,分析了错误提示的原因与不同平台的解决方法,具有一定的参考借鉴价值,需要的朋友可以参考下
一、问题:
phpmyadmin提示:The mbstring extension is missing. Please check your PHP configuration.
二、解决方法:
其实只要运行一段:
yum install php-mbstring
就OK了。
如果用的是linux的话,可能是这个问题:查看一下 /etc/php5/mods-available/json.ini 这个文件,把第二行开头的分号去掉,也就是去掉注释,然后保存,重启php就可以了。
进入MySQL,执行如下命令:
use mysql;
GRANT ALL PRIVILEGES ON *.* TO 'username'@'%' IDENTIFIED BY 'password' WITH GRANT OPTION;
flush privileges; //刷新
select host,user from user; //查看是否成功
退出mysql;
重新启动(命令如下):
sudo /etc/init.d/mysql restart
这样就可以远程连接了!
方法一:
在phpmyadmin官网(https://www.phpmyadmin.net/)上下载压缩包,解压至你apache根目录下(默认/var/www/html),重命名为phpmyadmin;
sudo apt-get install php-mbstring php-gettext
然后修改PHP配置文件:
sudo vim /etc/php/7.0/apache/php/ini
display_errors = On(都改为On)
extension=php_mbstring.dll (去掉前面的;)
重启apache:
sudo /etc/init.d/apache2 restart
可以用http://localhost/phpmyadmin访问了!
方法二:
sudo apt-get install phpmyadmin
建立/var/www/html 下的软连接:
sudo ln -s /usr/share/phpmyadmin /var/www/html/phpmyadmin
安装php-mbstring和php.ini配置同方法一。
sudo apt-get install php5 libapache2-mod-php5 php5-mcrypt php5-curl php5-imagick php5-cli
输入安装命令:
sudo apt-get install subversion
(由于阿里云远程链接服务器时默认登陆管理员账号,所以sudo可以不用)
(如果无法下载软件,可能是由于阿里云可能把更新源的位置改了,运行apt-get update就行)
之后选择SVN服务文件及配置文件的放置位置。我放在了/srv下的svn目录。
sudo mkdir /srv/svn(版本仓库test)
目录建好后,创建版本仓库
sudo svnadmin create /srv/svn/test
执行之后test下文件结构如下:
跳转到配置文件
sudo cd /srv/svn/test/conf
1.修改svnserver.conf
sudo vi svnserve.conf
[general]
#匿名用户不可读
anon-access = none
#权限用户可写
auth-access = write
#密码文件为passwd
password-db = passwd
#权限文件为authz
authz-db = authz
这里修改时要顶格,不然要报错
2.authz 制定管理员组
即admin组的用户为admin,admin组对test有rw(读写权限)
[groups]
admin=admin ##可以admin=admin,admin2,admin3
[test:/]
@admin=rw ##admin组对test下的文件有读写权限
[:/项目/目录] #是以项目名作为第一个单位。不写版本库可以省略‘:’,即写成[/]
权限主体可以是用户组、用户或,用户组在前面加@,表示全部用户。权限可以是w、r、wr和空,空表示没有任何权限。
3.编制passwd文件,设定用户密码
[users]
admin=admin ##用户名=密码
(注意等号两边不要留空格)
4.启动svn服务器
sudo svnserve -d -r /srv/svn/ --listen-port 3690
(这里启动服务时务必以管理员权限启动,否则用户拉取、提交文件时会提示权限不够)
-d 以守护模式启动
-r 制定svn版本库根目录,这样是便于客户端不用输入全路径,就可以访问版本库了
–listen-port 3690 监听3690端口,默认就是3690。。。所以不输也可以
5.访问代码库
svn://your ip/test
(查看IP地址:ifconfig)
注:到这里位置就可以通过svn访问了,通过https访问在后面
输入安装命令:
sudo apt-get install apache2 apache2-utils libapache2-svn
sudo a2enmod ssl 开启SSL模块
sudo a2ensite default-ssl 启用SSL站点支持
sudo a2enmod rewrite 启用rewrite模块
1.配置/etc/apach2/apache2.conf
sudo vi /etc/apache2/apache2.conf
增加对.htaccess的支持:将www目录的AllowOverride参数修改为ALL
防止访问目录:将Options中的Indexes删除
2.重启apache服务
sudo /etc/init.d/apache2 restart
Apache的默认安装,会在/var下建立一个名为www的目录,这个就是Web目录了
这里配置自动更新用的是svn的钩子,脚本是shell,也可以用其他的脚本比如python
钩子脚本的具体写法就是操作系统中shell脚本程序的写法,请根据自己SVN所在的操作系统和shell程序进行相应的写作
实现原理:当用户提交commit动作发生都让另外一处project马上从仓库中进行代码checkout一份出来!
1.在Web目录迁出代码
sudo svn co svn://127.0.0.1/test /var/www/html --username admin --password admin
2.添加脚本
在svn项目的hooks文件夹中的post-commit文件中添加脚本:用vi命令编辑一个新的post-commit(看清楚没有后缀名)千万不要用hooks文件夹里自带的post-commit文件,那是模板。
sudo vi /srv/svn/test/hooks/post-commit
在文件中添加如下内容:
#!/bin/sh
WEB=/var/www/html #web服务器下的项目不能有空格。
#说明:post-commit会接受两个参数
REPOS="$1" #/srv/svn/test 表示svn仓库的绝对路径值
REV="$2" #表示最新的一个版本号。最后一个版本号
export LANG=en_US.UTF-8
svn update $WEB --username admin --password admin #相当客户端的update操作
exit 0
如果不能判断自己写的shell脚本是否有错,可以现在hooks目录下运行./post-commit试一下
1.安装OpenSSL
sudo apt-get install openssl
2.创建证书
sudo openssl req -x509 -newkey rsa:1024 -keyout apache.pem -out apache.pem -nodes -days 999
创建证书有两种方式:一种是自签名证书,一种是第三方CA机构签名证书。由于我们这里的证书只是保证传输数据安全性,因此我们使用自签名证书。
命令执行成功后会在当前目录生成一个apache.pem的证书,将这个文件复制到apache的配置目录/etc/apache2/ssl。
sudo mkdir /etc/apache2/ssl
sudo cp apache.pem /etc/apache2/ssl/
3.配置站点证书
sudo vi /etc/apache2/sites-available/default-ssl.conf
SSLEngine on
SSLCertificateFile /etc/apache2/ssl/apache.pem
#SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key
注意: SSLCertificateKeyFile前需要加#
如果配置没有问题,那么我们通过https协议就可以访问该IP地址了。
4.4配置apache服务器
/etc/apache2/mods-available/dav_svn.conf #加在文件最后面即可
<Location /svn >
DAV svn
#SVNPath /srv/svn/test
SVNParentPath /srv/svn
SVNListParentPath On
AuthType Basic
AuthName "welcome to subversion repository"
AuthUserFile /srv/svn/test/conf/passwd
AuthzSVNAccessFile /srv/svn/test/conf/authz
#<LimitExcept GET PROPFIND OPTIONS REPORT>
Require valid-user
SSLRequireSSL #(https,否则取消)
#</LimitExcept>
</Location>
5.添加新用户或修改老用户密码
htpasswd -c /etc/subversion/passwd 用户名 //第一次设置用户时使用-c表示新建一个用户文件,之后取消-c.
回车后输入用户密码
6.重启Apache
sudo service apache2 restart
鉴于在搭建时,参考网上很多资料,网上资料在有用的同时,也坑了很多人
本文的目的,也就是想让后继之人在搭建svn服务器时不再犯错,不再被网上漫天的坑爹作品所坑害,故此总结
/******开始*********/
系统环境:Centos 6.5
>yum -y install subversion
此命令会全自动安装svn服务器相关服务和依赖,安装完成会自动停止命令运行
若需查看svn安装位置,可以用以下命令:
>rpm -ql subversion
选择在var路径下创建版本库,当前处于根目录下,一次性创建如下:
>mkdir /var/svn/svnrepos
在第二步建立的路径基础上,创建版本库,命令如下:
>svnadmin create /var/svn/svnrepos/xxxx (xxxx为你预期的版本库名称,可自定义)
创建成功后,进入xxx目录下
>cd /var/svn/svnrepos/xxxx
进入目录,可以看见如下文件信息:
进入已经创建好的版本库目录下,也就是前文说创建的xxxx
进入conf
>cd /var/svn/svnrepos/xxxx/conf
conf目录下,一共存放三份重要的配置文件,如下:
passwd:负责账号和密码的用户名单管理
svnserve.conf:svn服务器配置文件
细节修改如下:(希望大家严格按照以下信息,不用参考网络上其他资料)
修改authz文件信息,如下:
>vi authz
在文件内容的末尾,添加如下:
只需在末尾添加,无需在文件其他部分修改和添加任何东西(请忽略groups被我马赛克的地方,那其实也是条无用的记录,我忘记删掉而已),末尾内容如下:
[]
账号1 = rw
账号2 = rw
。。。。。
rw表示赋予此账号可读写的权限,请注意[]中的斜杠,一定是反斜杠,有些教程说,需添加版本库名称在括号内,我直接建议就这写,这样写允许访问的权限更大,避免一些错误
修改passwd文件信息
>vi passwd
账号密码文件无需做修改,也是直接将账号和密码信息追加到文件中即可,注意格式为:
例如:admin = 123456
修改svnserve.conf(重要)
vi svnserve.conf
原始文件内容,都被注释掉的,我们只需要去掉4条指定内容前注释即可,如下:
大多数网络资料,都会让大家将authz-db = authz这条给去掉注释,经过我本人多次被坑经验,此条去掉后,虽然svn服务器可以连接,但一直会提示“认证失败”,注释掉即可正常
还有多数资料会让大家在realm = My First Repository处填写服务器ip,经过测试,填写后并无什么用处,所以大家去掉注释即可,无需做任何修改
到此,配置已经全部完成,账号信息已经添加成功
多数情况下服务器安装完成,配置完成后,无法连接svn服务器,均是防火墙问题,大家按照如下3条命令逐一执行即可
>/sbin/iptables -I INPUT -p tcp --dport 3690 -j ACCEPT
>/etc/init.d/iptables save
>service iptables restart
执行结果如下图:
在跟目录下,执行如下命令:
>svnserve -d -r /var/svn/svnrepos
启动成功后,可用ps -aux查看服务启动是否成功
在windows客户端,输入地址:svn://ip地址:3690/xxxx (iP地址为你linux的ip,xxxx为前文创建的版本库名称,3690为svn默认端口)
弹出输入用户名和密码,输入即可访问
到此,Linux下svn服务器搭建就总结完毕,感谢大家的阅读。
1、创建一个新的仓库:(选择一个合适的地方,创建一个空目录)
$mkdir learngit //learngit是用git新建的一个目录
$cd learngit
$pwd //pwd命令用于显示当前目录
2、 通过git init命令把这个目录编程git可以管理的仓库:
$git init
3、 用git add把文件添加到仓库: (可以一次add多个文件,可反复使用,添加多个文件,其实质是把文件添加到“工作区”的“暂存区”)
$git add ** //**是文件名
4、 用git commit告诉git,把文件提交到仓库,其实质是把文件添加到“分支区”:
$git commit -m “**说明内容**” //-m后面输入的是本次提交的说明
5、$git status命令可以随时掌握工作区状态
$git status //告诉你有文件被修改过
$git diff //可以查看修改内容
6、 $git log 可以告诉我们历史记录,当前的仓库状态 (–pretty=oneline参数可以把历史记录整合到一行)
$git log //告诉我们历史记录
7、 HEAD表示当前的版本,上一版本就是HEAD^,上上一个版本就是HEAD^^,上100个版本就是HEAD~100
8、 $git reset –hard HEAD^ //退回到上一个版本,如果–hard 后面是跟commit id,就可回到该id所对应的状态
$git reset --hard HEAD^
9、查看该文件的内容
$cat ** //**是文件名
10、 查看命令历史
$git reflog //以便确定要回到未来的哪个版本
11、 撤销修改:
$git checkout -- ** //把**文件在工作区的修改全部撤销
①一种是readme.txt自修改后还没有被放到暂存区,现在,撤销修改就回到和版本库一模一样的状态;
②一种是readme.txt已经添加到暂存区后,又作了修改,现在,撤销修改就回到添加到暂存区后的状态。
12、 删除文件:
$rm ** //删除工作区的文件
$git rm //删除工作区、暂存区的文件
$git commit //删除分支的文件
13、 添加远程库:
$git remote add origin git@server-name:path/repo-name.git //关联一个远程仓库
$git push -u origin master //第一次推送master分支的所有内容
$git push origin master //此后,每次本地提交后,只要有必要,使用此命令推送最新修改
14、 从远程库克隆:
$git clone *** //***是远程仓库地址
$cd *filename*
$ls
15、 git中与分支相关:
$git branch //查看分支
$git branch //创建分支
$git checkout //切换分支
$git checkout -b //创建+切换分支
$git merge -b //合并某分支到当前分支
$git branch -d //删除分支
$git log --graph //查看分支合并图
$git merge --no-ff -m "说明" //可以用普通模式合并,合并后的历史有分支,能看出来曾经做过的合并,二fastforward合并看不出来曾经做过的合并
16、 多人协作:
1、首先,可以试图用git push origin branch-name推送自己的修改;
2、如果推送失败,则因为远程分支比你的本地更新,需要先用git pull试图合并;
3、如果合并有冲突,则解决冲突,并在本地提交;
4、没有冲突或者解决掉冲突后,再用git push origin branch-name推送就能成功!
5、如果git pull提示“no tracking information”,则说明本地分支和远程分支的链接关系没有创建,用命令git branch –set-upstream branch-name origin/branch-name。
Git 分支提供了并行工作的功能。 假设你准备同时学习 git 和 SVN,你可以用两个分支分别来学习,完成之后进行合并,你就掌握了两种工具的使用了。 Git 和 GitHub 的基本操作可以参考我的这篇博客Git 和 GitHub 使用。
创建分支 git branch dev # dev 是分支名
切换分支 git checkout dev
创建+切换 git checkout -b dev
删除分支 git branch -d dev #已合并的分支
当你从远程仓库克隆时,实际上 Git 自动把本地的 master 分支和远程的master分支对应起来了,并且,远程仓库的默认名称是origin。
如果要在远程仓库的其他分支 (如 dev 分支)上开发,就必须创建远程 origin/dev 分支到本地:
git checkout -b dev origin/dev #创建远程仓库的分支到本地,必须先克隆或关联一个远程分支
本地分支和远程分支的名字最好一致。
推送成功之后, GitHub 上的 MyRepos 仓库 dev 分支上增加了一个文件。
默认模式,在这种模式下, 删除分支后,会丢掉分支信息,看不到合并记录.。并不是任何情况都能用这种模式。
加上 --no-ff 参数就是普通模式。在普通模式下, Git 会在 merge 时生成一个新的 commit,这样从分支历史上就可以看出分支信息。
普通模式
快进模式
分支图
在分支图中, 红线是子分支 dev, 绿线是主分支 master. 子主分支分别提交了一次修改, 在将 dev 合并到 master 时发生冲突, 修改冲突文件内容之后再提交。
如果两个分支都分别有了新的提交,Git 无法执行“快速合并”,只能试图把各自的修改合并起来,但这种合并就可能会有冲突。必须手动解决冲突后再提交。git status 也可以告诉我们冲突的文件。
两个分支对同一文件的内容进行了修改并分别提交, 如果合并失败, 就必须手动解决冲突, 修改文件的内容之后再进行提交。
在冲突内容中, Git用<<<<<<>>>>>>标记出不同分支的内容. 文件的内容可以协商修改。
一个分支修改了内容, 另个一分支删除了文件, 在试图合并时就会出现树冲突。假设子分支(如 dev)是要合并到主分支 master 的, 处理的方法有:
放弃 dev 的修改:强制删除 dev 分支, 然后提交即可。
放弃 master 的修改—-分下面两种情况:
master 修改了内容, dev 删除了文件:
master 删除了文件, dev 修改了内容:
对于文件的移动(在 Git 仓库目录范围内)和重命名, Git 都可以自动合并。
建立本地分支与远程分支的连接 git branch –set-upstream dev origin/dev # dev 为分支名
如果推送出现冲突, 先将远程分支最新的提交抓取下来, 在本地解决冲突之后再推送。解决冲突的方法与本地冲突完全相同
首先这里说说git merge操作
假如有以下的情况:
我本地和远程服务器各有一个代码仓库,本地的仓库有两个分支:master和dev分支,远程仓库也有两个分支:master和dev。两者一一对应。
假如我在dev分支上添加了很多的内容,并提交到了服务器,现在想在master分支上也加上同样的内容,怎么办呢?
方法有下面两种:
切换到master分支:git checkout master
合并分支:git merge dev
切换到master分支:git checkout master
git cherry-pick -n commit号 将某一次提交的内容合并过来
git cherry-pick ..dev 将dev分支的整个提交内容都合并过来
git cherry-pick dev
这里合并代码,难免会遇到冲突,对于webstorm用户,可以直接用自带的图形界面处理冲突,我这里推介visual studio code编辑器,微软良心作品。
git代码库回滚: 指的是将代码库某分支退回到以前的某个commit id
git reset --hard commit-id :回滚到commit-id,讲commit-id之后提交的commit都去除
git reset --hard HEAD~3:将最近3次的提交回滚
对于怎么看commit-id 可以使用命令:
结果如下:
画红圈的就是commit-id
这个是重点要说的内容,过程比本地回滚要复杂
应用场景:自动部署系统发布后发现问题,需要回滚到某一个commit,再重新发布
原理:先将本地分支退回到某个commit,删除远程分支,再重新push本地分支
操作步骤:
1、git checkout master
2、git pull
3、git branch master_backup //备份一下这个分支当前的情况
4、git reset --hard the_commit_id //把master本地回滚到the_commit_id
5、git push origin :master //删除远程 master
6、git push origin master //用回滚后的本地分支重新建立远程分支
7、git branch -d master_backup //如果前面都成功了,删除这个备份分支
好,主要就这些了。