文章851
标签121
分类10

变基 git rebase

Reapply commits on top of another base tip
另一个基本提示上重新应用提交

如果需要获得更清晰的修订历史记录,可以使用 git rebase 命令集成分支。

变基至主分支

假设我们有两个分支,其中包含 non-fast-forward 方案。

rebase_branch_001.1c56b036.png

# 变基 rebase 与合并 merge 不同,是基于被 rebase 的 commit 上操作的
# 切换至次分支
git checkout bugfix
# 变基至主分支
git rebase master
# 切换到主分支
git checkout master
# 再合并已经变基的 bugfix
git merge bugfix

整个 bugfix 分支上的提交会移动到 master 分支的后面,有效地把所有 master 分支上新的提交并入过来。

执行 rebase 命令将导致分支历史记录看起来类似于下面的图示。

rebase_branch_002.16966dd5.png
当您将错误修复分支重新绑定到主分支时,将修复来自错误修复分支的提交并将其附加到主分支的末尾。最终结果是 bugfix 分支历史记录一个简单 commit 流。

如果在附加提交时发生代码冲突,Git 会要求您在继续重新设置其他提交之前修复冲突。

rebase_branch_003.f160d580.png

rebase 不会移动 master 分支的位置。在任何情况下,您都可以在 rebase 后执行从 bugfixmasterfast-forward 或清除合并。

对于 mergerebase 的区别,实质上:

  • merge 是对目前分叉的两条分支的合并
  • rebase 是对当前分支记录基于任何 commit 节点(不限于当前分支上的节点)的变更
    rebasebase 不能理解为分叉的基点,而是整个 git 库中存在的所有 commit 节点:
  • git pull —-rebase 的时候,这个当前分支是本地分支,commit 节点是远程分支的 head
  • git rebase master 的时候,这个当前分支是 feature 分支,commit 节点是 master 分支的 head
  • git rebase -i 的时候,这个当前分支就是当前工作分支,commit 节点是在 -i 后注明的 commit

交互式变基

交互式变基允许你更改并入新分支的提交。这比自动的变基更加强大,因为它提供了对分支上提交历史完整的控制。一般来说,这被用于将 feature 分支并入 master 分支之前,清理混乱的历史。

# 语法
git rebase -i [startpoint] [endpoint]
# 示例
git checkout feature
git rebase -i master

它会打开一个文本编辑器,显示所有将被移动的提交:

pick 33d5b7a Message for commit #1
pick 9480b3d Message for commit #2
pick 5c67e61 Message for commit #3

然后 wq 保存退出后是注释修改,编辑完注释再 wq 保存完成 commit 合并。

  • pick:保留该 commit
  • reword:保留该 commit,但我需要修改该 commit 的注释
  • edit:保留该 commit,但我要停下来修改该提交(不禁惊修改注释)
  • squash:将该 commit 和前一个 commit 合并
  • fixup:将该 commit 和前一个 commit 合并,但我不要保留该提交的注释信息
  • exec:执行 shell 命令
  • drop:我要丢弃该 commit
    忽略不重要的提交会让你的 feature 分支的历史更清晰易读,这是 git merge 做不到的。

分支合并

被合并分支只有你自己使用。

  1. 先从 master 分支切出一个 feature 分支,进行开发:git:(master) git checkout -b feature
  2. 这时同事完成一次 hotfix,且合并入 master 分支,此时 master 已经领先于你的 feature 分支
  3. 使用 git rebase master 进行分支合并

rebase 原理:

  1. 首先,git 会把 feature 分支里面的每个 commit 取消掉
  2. 其次,把上面的操作临时保存成 patch 文件,存在 .git/reabase 目录下
  3. 然后,把 feature 分支更新到最新的 master 分支
  4. 最后,把上面保存的 patch 文件应用到 feature 分支上

rebase 过程中,出现冲突 conflict 后,git 会停止 rebase 并会让你解决冲突。解决完冲突后,用 git add 命令去更新这些内容,即执行 git rebase --continue

⚠️ 注意:你无需执行 git commit,只要执行 git rebase --continue

在任何时候,我们都可以用 git rebase -abort 来终止 rebase 的行动,并且分支会回到 rebase 开始前的状态。

黄金法则

永远不要对已经推到主干分支服务器或者团队其他成员的提交进行变基,我们选择变基还是合并的范围应该在自己当前工作范围内。

原文地址 : https://tsejx.github.io/devops-guidebook/code/git/rebase/

📝 Git 由浅入深之细说变基
📝 关于 Git Rebase 你必须要知道的几件事
📝 从撤销 Rebase 谈谈 Git 原理
📝 使用 git rebase 提高 PR 质量
📝 Merge 和 Rebase 区别与项目中的选择
📝 Git Merge 和 Rebase 分支合并命令的区别
📝 你根本不懂 rebase 使用 rebase 打造可读的 git graph
📝 Git 应用详解第九讲:git cherry-pick 与 git rebase
📝 使用 Git Rebase 美化 GIt COmmit 流程

使用MySQL计算回撤率的简单方法

介绍:

回撤率是衡量投资组合或交易策略风险的重要指标。在本篇博客中,我们将演示如何使用MySQL来计算交易回撤率。我们将建立一个交易记录表,并使用MySQL查询来计算资金曲线和回撤率。

步骤:

创建交易记录表:
我们首先需要创建一个包含交易记录的表。使用MySQL的CREATE TABLE语句创建一个名为"trades"的表。该表将包含交易日期、交易金额和盈亏标志等字段。

CREATE TABLE trades (
  trade_date DATE,
  amount DECIMAL(10, 2),
  is_profit BOOLEAN
);

插入交易记录:

在"trades"表中插入实际的交易记录。每条记录应包含交易日期、交易金额和盈亏标志。这些记录将用于计算资金曲线和回撤率。

INSERT INTO trades (trade_date, amount, is_profit)
VALUES
  ('2021-01-01', 100.00, TRUE),
  ('2021-01-02', -50.00, FALSE),
  ('2021-01-03', 75.00, TRUE),
  ('2021-01-04', -30.00, FALSE),
  ('2021-01-05', 120.00, TRUE);

计算资金曲线的最高和最低值:

使用MySQL的查询语句,我们可以计算资金曲线的最高和最低值。通过按照交易日期的顺序累计计算交易金额,我们可以得到资金曲线的变化情况,并从中选择最高和最低值。

SELECT MAX(balance) AS highest_balance, MIN(balance) AS lowest_balance
FROM (
  SELECT trade_date, @balance := @balance + amount AS balance
  FROM trades, (SELECT @balance := 0) AS b
  ORDER BY trade_date
) AS balance_table;

计算回撤率:

在计算了资金曲线的最高和最低值后,我们可以使用MySQL的查询语句计算回撤率。通过减去最低值并除以最高值,我们可以得到回撤率的百分比表示。

SELECT (highest_balance - lowest_balance) / highest_balance * 100 AS drawdown_rate
FROM (
  SELECT MAX(balance) AS highest_balance, MIN(balance) AS lowest_balance
  FROM (
    SELECT trade_date, @balance := @balance + amount AS balance
    FROM trades, (SELECT @balance := 0) AS b
    ORDER BY trade_date
  ) AS balance_table
) AS drawdown_table;

总结:

本篇博客介绍了如何使用MySQL计算交易回撤率。我们通过创建交易记录表、插入交易记录,并使用MySQL的查询语句计算资金曲线的最高和最低值,最终计算得出回撤率。回撤率是一个重要的风险指标,它可以帮助我们评估投资组合或交易策略的风险水平。

请注意,本篇博客提供了一个基本的框架,您可以根据实际需求进行适当的调整和扩展。在实际应用中,您可能需要考虑性能优化、数据完整性等方面的问题。通过使用MySQL的强大功能,我们可以方便地进行交易回撤率的计算和分析。

Mysql - InnoDB自增列重复值问题 (Mysql 5.7以下)

MySQL - InnoDB自增列重复值问题 (Mysql 5.7以下)

问题重现

先从问题入手,重现下这个 bug

MySQL> use test;
MySQL> drop table if exists t1;
MySQL> create table t1(id int auto_increment, a int, primary key (id)) engine=innodb;
MySQL> insert into t1 values (1,2);
MySQL> insert into t1 values (null,2);
MySQL> insert into t1 values (null,2);
MySQL> select * from t1;

+----+------+
| id | a    |
+----+------+
| 1 | 2     |
| 2 | 2     |
| 3 | 2     |
+----+------+

MySQL> delete from t1 where id=2;
MySQL> delete from t1 where id=3;
MySQL> select * from t1;

+----+------+
| id | a    |
+----+------+
| 1 | 2     |
+----+------+

这里我们关闭MySQL,再启动MySQL,然后再插入一条数据

MySQL> insert into t1 values (null,2);
MySQL> select * FROM T1;

+----+------+
| id | a     |
+----+------+
| 1 | 2     |
+----+------+
| 2 | 2     |
+----+------+

我们看到插入了(2,2),而如果我没有重启,插入同样数据我们得到的应该是(4,2)。 上面的测试反映了MySQLd重启后,InnoDB存储引擎的表自增id可能出现重复利用的情况。

自增id重复利用在某些场景下会出现问题。依然用上面的例子,假设t1有个历史表t1_history用来存t1表的历史数据,那么MySQLd重启前,ti_history中可能已经有了(2,2)这条数据,而重启后我们又插入了(2,2),当新插入的(2,2)迁移到历史表时,会违反主键约束。

原因分析

InnoDB 自增列出现重复值的原因:

MySQL> show create table t1\G;

*************************** 1. row ***************************

Table: t1

Create Table: CREATE TABLE `t1` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`a` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=innodb AUTO_INCREMENT=4 DEFAULT CHARSET=utf8

1 row in set (0.00 sec)

建表时可以指定 AUTO_INCREMENT值,不指定时默认为1,这个值表示当前自增列的起始值大小,如果新插入的数据没有指定自增列的值,那么自增列的值即为这个起始值。对于InnoDB表,这个值没有持久到文件中。而是存在内存中(dict_table_struct.autoinc)。那么又问,既然这个值没有持久下来,为什么我们每次插入新的值后, show create table t1看到AUTO_INCREMENT值是跟随变化的。其实show create table t1是直接从dict_table_struct.autoinc取得的(ha_innobase::update_create_info)。

知道了AUTO_INCREMENT是实时存储内存中的。那么,MySQLd 重启后,从哪里得到AUTO_INCREMENT呢? 内存值肯定是丢失了。实际上MySQL采用执行类似select max(id)+1 from t1;方法来得到AUTO_INCREMENT。而这种方法就是造成自增id重复的原因。

MyISAM自增值

MyISAM也有这个问题吗?MyISAM是没有这个问题的。myisam会将这个值实时存储在.MYI文件中(mi_state_info_write)。MySQLd重起后会从.MYI中读取AUTO_INCREMENT值(mi_state_info_read)。因此,MyISAM表重启是不会出现自增id重复的问题。

诶 网上很多解决方案 都没说mysql版本问题.

innodb_autoinc_persistent=on
innodb_autoinc_persistent_interval=1

通过mysql 设置这个配置 就可以解决自增键持久化问题. 但前提是 mysql 8.0.13后在支持该参数. 而且8.0.13后默认就是持久化的.....

">