feat: git retime 支持重排提交日期,新增 install.sh
- 新增 --start-date:按原顺序从指定日期起重排提交日期,默认每天一个 - 新增 --per-day 控制每天提交数、--day-gap 控制日期间隔;两者需配合 --start-date 使用,否则报错提示 - 不给 --start-date 时保持原行为(保留原日期,只改时分秒) - 预览在重排模式下显示完整的新日期时间,并说明日期规则 - install.sh:补 shebang 与可执行权限,构建后安装到 /usr/local/bin - 文档:README.git.md 增加「重排日期」小节与选项表
This commit is contained in:
@@ -32,6 +32,13 @@ type retimeOptions struct {
|
||||
// spacing found on the remote branch. A zero (or out-of-range) entry falls
|
||||
// back to a random gap.
|
||||
Gaps []time.Duration
|
||||
|
||||
// StartDate, when set, re-dates the commits instead of keeping their
|
||||
// original days: the selected commits are laid out in order starting at
|
||||
// StartDate, stepping DayGap days per day and PerDay commits per day.
|
||||
StartDate time.Time
|
||||
DayGap int // days between consecutive commit days, at least 1
|
||||
PerDay int // commits placed on one day, 0 means "unlimited" (one day only)
|
||||
}
|
||||
|
||||
// defaultRetimeOptions matches the command's documented behaviour: commits land
|
||||
@@ -59,33 +66,60 @@ func planRetime(commits []gitCommit, opts retimeOptions) []retime {
|
||||
window := opts.WindowEnd - opts.WindowStart
|
||||
out := make([]retime, 0, len(commits))
|
||||
|
||||
// When a start date is given, days are assigned rather than inherited.
|
||||
redate := !opts.StartDate.IsZero()
|
||||
if redate && opts.DayGap < 1 {
|
||||
opts.DayGap = 1
|
||||
}
|
||||
|
||||
// Group by calendar day, preserving order.
|
||||
var dayCommits []gitCommit
|
||||
currentDay := time.Time{}
|
||||
var day time.Time
|
||||
flush := func() {
|
||||
if len(dayCommits) == 0 {
|
||||
return
|
||||
}
|
||||
out = append(out, planDay(dayCommits, opts, window)...)
|
||||
out = append(out, planDay(day, dayCommits, opts, window)...)
|
||||
dayCommits = nil
|
||||
}
|
||||
|
||||
for _, c := range commits {
|
||||
day := c.Date()
|
||||
if !currentDay.IsZero() && !day.Equal(currentDay) {
|
||||
if redate {
|
||||
// Start a new day whenever the current one is full.
|
||||
if len(dayCommits) == 0 {
|
||||
if !day.IsZero() {
|
||||
day = day.AddDate(0, 0, opts.DayGap)
|
||||
} else {
|
||||
day = midnightOf(opts.StartDate)
|
||||
}
|
||||
}
|
||||
if opts.PerDay > 0 && len(dayCommits) >= opts.PerDay {
|
||||
flush()
|
||||
day = day.AddDate(0, 0, opts.DayGap)
|
||||
}
|
||||
dayCommits = append(dayCommits, c)
|
||||
continue
|
||||
}
|
||||
|
||||
original := c.Date()
|
||||
if !day.IsZero() && !original.Equal(day) {
|
||||
flush()
|
||||
}
|
||||
currentDay = day
|
||||
day = original
|
||||
dayCommits = append(dayCommits, c)
|
||||
}
|
||||
flush()
|
||||
return out
|
||||
}
|
||||
|
||||
// midnightOf returns the start of the calendar day of t, in t's location.
|
||||
func midnightOf(t time.Time) time.Time {
|
||||
return time.Date(t.Year(), t.Month(), t.Day(), 0, 0, 0, 0, t.Location())
|
||||
}
|
||||
|
||||
// planDay spreads one day's commits across the window.
|
||||
func planDay(commits []gitCommit, opts retimeOptions, window time.Duration) []retime {
|
||||
func planDay(day time.Time, commits []gitCommit, opts retimeOptions, window time.Duration) []retime {
|
||||
out := make([]retime, 0, len(commits))
|
||||
day := commits[0].Date()
|
||||
|
||||
offsets, squeezed := spreadWithin(day, len(commits), opts, window)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user