Git:批量更改提交日期

3

当我需要改变多个提交的提交日期时,我使用交互式变基并逐个更改它们。

我该如何在单个命令中更改它们所有提交的提交日期?换句话说,我需要将特定命令应用于在交互式变基中列出的所有提交。

谢谢


日期应该如何更改?全部设置为相同的时间,还是全部推迟一小时等? - Unapiedra
5个回答

5

Filter-Repo

git filter-branch 已经被弃用。请使用 git filter-repo 来代替。您需要安装它。

这里有一篇很棒的文章,介绍了如何使用 git-filter-repo 修改提交日期。 git-filter-repo 文档 很好地解释了 --commit-callback 的概念。

一个非常简单的例子

让我们将所有提交日期的时区重置为零。

# Save this as ../change_time.py
def handle(commit):
    "Reset the timezone of all commits."
    date_str = commit.author_date.decode('utf-8')
    [seconds, timezone] = date_str.split()
    new_date = f"{seconds} +0000"
    commit.author_date = new_date.encode('utf-8')

handle(commit)


# You need to be in a freshly-cleaned repo. Or use --force.
git clone <...> your_repo
cd your_repo
# First just a dry run.
git filter-repo --dry-run --commit-callback "$(cat ../change_time.py)"
# And now do it for real
git filter-repo --commit-callback "$(cat ../change_time.py)"

https://www.git-scm.com/docs/git-filter-branch#_warning 是“git filter-branch已弃用”注释的参考。 - phils

2

git rebase 支持 --exec 选项, 可以完美实现此功能。

-x <cmd>

--exec <cmd>

在每个创建提交的行后附加 "exec <cmd>",以便在最终历史记录中执行。<cmd> 将被解释为一个或多个 shell 命令。任何失败的命令都将中断 rebase,并返回退出代码 1。


0

git-filter-branch已经被弃用,请使用git filter-repo - Unapiedra
以下是官方filter-branch文档的内容:"请使用其他历史过滤工具,如git filter-repo。" (2) 运行“git filter-branch”(Git 2.25.2)时,您会收到类似的警告和建议,建议使用git filter-repo。 - Unapiedra

0
这是我为当前日期所做的方式:
git rebase main --exec 'git commit --amend --date="now" --no-edit --allow-empty'

-1

Filter-Repo

在其他答案中,建议将代码保存到文件.py中,并使用以下命令运行它:git filter-repo --commit-callback "$(cat ../<your file name>.py)"但是在我的情况下,它忽略了所有空格,这在Python中会破坏语法。对我来说,直接将其粘贴到命令中可以解决问题。我正在使用Windows,在PowerShell上进行测试,对这些事情是初学者。

更高级的示例

根据包含给定字符串的提交设置新日期。但是请注意,除非您有非常好的理由,否则不应更改日期!

if(b'[structural-programming]' in commit.message):
    base_date = datetime(2021,1,1,0,0,0)
    print(commit.message,' new date: ',base_date)
    commit.committer_date = f'{int(datetime.timestamp(base_date))} +0100'.encode('utf-8')
    commit.author_date = f'{int(datetime.timestamp(base_date))} +0100'.encode('utf-8')
elif(b'[intro-into-programming]' in commit.message):
    base_date = datetime(2021,1,2,0,0,0)
    print(commit.message,' new date: ',base_date)
    commit.committer_date = f'{int(datetime.timestamp(base_date))} +0100'.encode('utf-8')
    commit.author_date = f'{int(datetime.timestamp(base_date))} +0100'.encode('utf-8')
else:
    base_date = datetime(2021,1,3,0,0,0)
    print(commit.message,' new date: ',base_date)
    commit.committer_date = f'{int(datetime.timestamp(base_date))} +0100'.encode('utf-8')
    commit.author_date = f'{int(datetime.timestamp(base_date))} +0100'.encode('utf-8')

并且它如何在控制台中使用:

git filter-repo --commit-callback "                            
 [seconds, timezone] = commit.committer_date.decode('utf-8').split()
 
 if(b'[structural-programming]' in commit.message):
     base_date = datetime(2021,1,1,0,0,0)
     print(commit.message,' new date: ',base_date)
     commit.committer_date = f'{int(datetime.timestamp(base_date))} +0100'.encode('utf-8')
     commit.author_date = f'{int(datetime.timestamp(base_date))} +0100'.encode('utf-8')
 elif(b'[intro-into-programming]' in commit.message):
     base_date = datetime(2021,1,2,0,0,0)
     print(commit.message,' new date: ',base_date)
     commit.committer_date = f'{int(datetime.timestamp(base_date))} +0100'.encode('utf-8')
     commit.author_date = f'{int(datetime.timestamp(base_date))} +0100'.encode('utf-8')
 else:
     base_date = datetime(2021,1,3,0,0,0)
     print(commit.message,' new date: ',base_date)
     commit.committer_date = f'{int(datetime.timestamp(base_date))} +0100'.encode('utf-8')
     commit.author_date = f'{int(datetime.timestamp(base_date))} +0100'.encode('utf-8')
 "

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接