feat: git retime 改为在 --start-date/--end-date 区间内均匀分布提交
- 新增 --end-date:提交按比例铺满 [start-date, end-date],第 i 个提交 落在第 i×天数÷提交数 天,提交远少于天数时也不会堆在第一天 - 移除 --per-day / --day-gap:原先的“每天一个、日期顺延”语义不直观 - 只给 --start-date 时集中在该日;--end-date 需配合 --start-date 且不早于它 - 同一天的多条提交仍按顺序落在 21:00-23:00 之间 - 文档与预览文案同步为区间语义
This commit is contained in:
@@ -328,76 +328,85 @@ func TestBuildPlanListsEachSqueezedDayOnce(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestPlanRetimeRedateStartingFromDay(t *testing.T) {
|
||||
// Three commits originally on 2026-10-01, re-dated from 2026-11-01 with one
|
||||
// commit per day.
|
||||
func TestPlanRetimeInRangeSpreadsEvenly(t *testing.T) {
|
||||
// 6 commits over 3 days: 2 commits per day, in order.
|
||||
date := day(2026, 10, 1)
|
||||
commits := []gitCommit{
|
||||
commitAt("c1", date, 9, 0, 0),
|
||||
commitAt("c2", date, 10, 0, 0),
|
||||
commitAt("c3", date, 11, 0, 0),
|
||||
var commits []gitCommit
|
||||
for i := 0; i < 6; i++ {
|
||||
commits = append(commits, commitAt("c", date, 9, i, 0))
|
||||
}
|
||||
opts := defaultRetimeOptions(3)
|
||||
opts.StartDate = day(2026, 11, 1)
|
||||
opts.PerDay = 1
|
||||
opts.DayGap = 1
|
||||
opts.EndDate = day(2026, 11, 3)
|
||||
|
||||
plan := planRetime(commits, opts)
|
||||
if len(plan) != 3 {
|
||||
t.Fatalf("plan has %d entries", len(plan))
|
||||
}
|
||||
for i, want := range []string{"2026-11-01", "2026-11-02", "2026-11-03"} {
|
||||
got := plan[i].NewTime.In(cst).Format("2006-01-02")
|
||||
if got != want {
|
||||
t.Errorf("commit %d re-dated to %s, want %s", i+1, got, want)
|
||||
wantDays := []string{"2026-11-01", "2026-11-01", "2026-11-02", "2026-11-02", "2026-11-03", "2026-11-03"}
|
||||
for i, want := range wantDays {
|
||||
if got := plan[i].NewTime.In(cst).Format("2006-01-02"); got != want {
|
||||
t.Errorf("commit %d on %s, want %s", i, got, want)
|
||||
}
|
||||
if h := plan[i].NewTime.In(cst).Hour(); h < 21 || h > 22 {
|
||||
t.Errorf("commit %d at hour %d, want 21-22", i+1, h)
|
||||
t.Errorf("commit %d at hour %d, want 21-22", i, h)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestPlanRetimeRedateHonoursDayGap(t *testing.T) {
|
||||
func TestPlanRetimeInRangeDistributesRemainder(t *testing.T) {
|
||||
// 7 commits over 3 days: 3, 2, 2 from the earliest day.
|
||||
date := day(2026, 10, 1)
|
||||
var commits []gitCommit
|
||||
for i := 0; i < 7; i++ {
|
||||
commits = append(commits, commitAt("c", date, 9, i, 0))
|
||||
}
|
||||
opts := defaultRetimeOptions(4)
|
||||
opts.StartDate = day(2026, 11, 1)
|
||||
opts.EndDate = day(2026, 11, 3)
|
||||
|
||||
plan := planRetime(commits, opts)
|
||||
counts := map[string]int{}
|
||||
for _, r := range plan {
|
||||
counts[r.NewTime.In(cst).Format("2006-01-02")]++
|
||||
}
|
||||
if counts["2026-11-01"] != 3 || counts["2026-11-02"] != 2 || counts["2026-11-03"] != 2 {
|
||||
t.Fatalf("distribution = %v, want 3/2/2", counts)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPlanRetimeInRangeSpreadsFewCommitsAcrossTheRange(t *testing.T) {
|
||||
// 2 commits over 4 days must not bunch on day one: they land on the first
|
||||
// and the third day (floor(i*days/total)).
|
||||
date := day(2026, 10, 1)
|
||||
commits := []gitCommit{
|
||||
commitAt("c1", date, 9, 0, 0),
|
||||
commitAt("c2", date, 10, 0, 0),
|
||||
}
|
||||
opts := defaultRetimeOptions(4)
|
||||
opts := defaultRetimeOptions(5)
|
||||
opts.StartDate = day(2026, 11, 1)
|
||||
opts.PerDay = 1
|
||||
opts.DayGap = 3
|
||||
opts.EndDate = day(2026, 11, 4)
|
||||
|
||||
plan := planRetime(commits, opts)
|
||||
if got := plan[1].NewTime.In(cst).Format("2006-01-02"); got != "2026-11-04" {
|
||||
t.Fatalf("second commit on %s, want 2026-11-04 (gap 3 days)", got)
|
||||
want := []string{"2026-11-01", "2026-11-03"}
|
||||
for i, w := range want {
|
||||
if got := plan[i].NewTime.In(cst).Format("2006-01-02"); got != w {
|
||||
t.Errorf("commit %d on %s, want %s", i, got, w)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestPlanRetimeRedatePacksSeveralPerDay(t *testing.T) {
|
||||
func TestPlanRetimeInRangeSingleDayWithoutEndDate(t *testing.T) {
|
||||
date := day(2026, 10, 1)
|
||||
var commits []gitCommit
|
||||
for i := 0; i < 4; i++ {
|
||||
commits = append(commits, commitAt("c", date, 9, i, 0))
|
||||
commits := []gitCommit{
|
||||
commitAt("c1", date, 9, 0, 0),
|
||||
commitAt("c2", date, 10, 0, 0),
|
||||
}
|
||||
opts := defaultRetimeOptions(5)
|
||||
opts.StartDate = day(2026, 11, 1)
|
||||
opts.PerDay = 2
|
||||
opts.DayGap = 1
|
||||
opts := defaultRetimeOptions(6)
|
||||
opts.StartDate = day(2026, 11, 7)
|
||||
|
||||
plan := planRetime(commits, opts)
|
||||
firstDay := plan[0].NewTime.In(cst).Format("2006-01-02")
|
||||
secondOfFirstDay := plan[1].NewTime.In(cst).Format("2006-01-02")
|
||||
thirdDay := plan[2].NewTime.In(cst).Format("2006-01-02")
|
||||
if firstDay != "2026-11-01" || secondOfFirstDay != "2026-11-01" {
|
||||
t.Fatalf("first two commits should share 2026-11-01, got %s and %s", firstDay, secondOfFirstDay)
|
||||
}
|
||||
if thirdDay != "2026-11-02" {
|
||||
t.Fatalf("third commit on %s, want 2026-11-02", thirdDay)
|
||||
}
|
||||
// Within a day the times stay ordered.
|
||||
if !plan[1].NewTime.After(plan[0].NewTime) {
|
||||
t.Fatalf("same-day commits are not ordered: %v, %v", plan[0].NewTime, plan[1].NewTime)
|
||||
for i, r := range plan {
|
||||
if got := r.NewTime.In(cst).Format("2006-01-02"); got != "2026-11-07" {
|
||||
t.Errorf("commit %d on %s, want the single start day", i, got)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user