unk*_*own 204 git version-control repository git-commit
我将所有内容转换为Git供我个人使用,我发现存储库中已有一些旧版本的文件.如何根据文件的"修改日期"以正确的顺序将其提交到历史记录,以便我有一个准确的文件历史记录?
我被告知这样的事情会起作用:
git filter-branch --env-filter="GIT_AUTHOR_DATE=... --index-filter "git commit path/to/file --date " --tag-name-filter cat -- --all
Run Code Online (Sandbox Code Playgroud)
Chr*_*sen 185
你给出的建议是有缺陷的.无条件地在一个设置中设置GIT_AUTHOR_DATE --env-filter会重写每次提交的日期.此外,在内部使用git commit也很不寻常--index-filter.
你在这里处理多个独立的问题.
每个提交都有两个日期:作者日期和提交者日期.您可以通过环境变量GIT_AUTHOR_DATE和GIT_COMMITTER_DATE为写入新提交的任何命令提供值来覆盖每个值.请参阅git-commit(1)或以下内容中的"日期格式":
Git internal format = <unix timestamp> <time zone offset>, e.g. 1112926393 +0200
RFC 2822 = e.g. Thu, 07 Apr 2005 22:13:13 +0200
ISO 8601 = e.g. 2005-04-07T22:13:13
Run Code Online (Sandbox Code Playgroud)
在正常使用期间写入新提交的唯一命令是git commit.它还有一个--date选项,可让您直接指定作者日期.您的预期用法还包括git filter-branch --env-filter使用上面提到的环境变量(这些是"env"的一部分,之后选项被命名;请参阅git-filter-branch(1)中的"Options"和底层的"plumbing"命令git-commit -tree(1).
如果您的存储库非常简单(即您只有一个分支,没有标记),那么您可以使用git rebase来完成工作.
在以下命令中,使用提交的对象名称(SHA-1哈希)而不是"A".运行git commit时,不要忘记使用"日期覆盖"方法之一.
---A---B---C---o---o---o master
git checkout master
git checkout A~0
git add path/to/file
git commit --date='whenever'
git tag ,new-commit -m'delete me later'
git checkout -
git rebase --onto ,new-commit A
git tag -d ,new-commit
---A---N (was ",new-commit", but we delete the tag)
\
B'---C'---o---o---o master
Run Code Online (Sandbox Code Playgroud)
如果要更新A以包含新文件(而不是创建添加它的新提交),则使用git commit --amend而不是git commit.结果如下所示:
---A'---B'---C'---o---o---o master
Run Code Online (Sandbox Code Playgroud)
只要您可以将提交命名为新提交的父级,上述操作就会起作用.如果您确实希望通过新的根提交(无父母)添加新文件,那么您需要一些不同的东西:
B---C---o---o---o master
git checkout master
git checkout --orphan new-root
git rm -rf .
git add path/to/file
GIT_AUTHOR_DATE='whenever' git commit
git checkout -
git rebase --root --onto new-root
git branch -d new-root
N (was new-root, but we deleted it)
\
B'---C'---o---o---o master
Run Code Online (Sandbox Code Playgroud)
git checkout --orphan是相对较新的(Git 1.7.2),但还有其他方法可以做同样的事情,适用于旧版本的Git.
如果您的存储库更复杂(即它有多个ref(分支,标签等)),那么您可能需要使用git filter-branch.在使用git filter-branch之前,您应该制作整个存储库的备份副本.您的整个工作树(包括.git目录)的简单tar存档就足够了.git filter-branch确实可以创建备份引用,但通过删除.git目录并从备份中恢复它,通常可以更轻松地从不太正确的过滤中恢复.
注意:下面的示例使用lower-level命令git update-index --add而不是git add.您可以使用git add,但首先需要将文件从某个外部位置复制到预期路径(--index-filter在临时GIT_WORK_TREE中运行其命令为空).
如果您希望将新文件添加到每个现有提交中,则可以执行以下操作:
new_file=$(git hash-object -w path/to/file)
git filter-branch \
--index-filter \
'git update-index --add --cacheinfo 100644 '"$new_file"' path/to/file' \
--tag-name-filter cat \
-- --all
git reset --hard
Run Code Online (Sandbox Code Playgroud)
我真的没有理由改变现有提交的日期--env-filter 'GIT_AUTHOR_DATE=…'.如果你确实使用它,你就可以使它成为条件,这样它就会重写每次提交的日期.
如果您希望新文件仅在某些现有提交("A")之后出现在提交中,则可以执行以下操作:
file_path=path/to/file
before_commit=$(git rev-parse --verify A)
file_blob=$(git hash-object -w "$file_path")
git filter-branch \
--index-filter '
if x=$(git rev-list -1 "$GIT_COMMIT" --not '"$before_commit"') &&
test -n "$x"; then
git update-index --add --cacheinfo 100644 '"$file_blob $file_path"'
fi
' \
--tag-name-filter cat \
-- --all
git reset --hard
Run Code Online (Sandbox Code Playgroud)
如果您希望通过要插入历史记录中间的新提交添加文件,则需要在使用git filter-branch之前生成新提交并添加--parent-filter到git filter-branch:
file_path=path/to/file
before_commit=$(git rev-parse --verify A)
git checkout master
git checkout "$before_commit"
git add "$file_path"
git commit --date='whenever'
new_commit=$(git rev-parse --verify HEAD)
file_blob=$(git rev-parse --verify HEAD:"$file_path")
git checkout -
git filter-branch \
--parent-filter "sed -e s/$before_commit/$new_commit/g" \
--index-filter '
if x=$(git rev-list -1 "$GIT_COMMIT" --not '"$new_commit"') &&
test -n "$x"; then
git update-index --add --cacheinfo 100644 '"$file_blob $file_path"'
fi
' \
--tag-name-filter cat \
-- --all
git reset --hard
Run Code Online (Sandbox Code Playgroud)
你也可以安排到一个新的根首先添加的文件提交:创建新的根通过从"赵氏孤儿"的方法提交git的变基节(捕获它new_commit),使用无条件的--index-filter,和--parent-filter喜欢"sed -e \"s/^$/-p $new_commit/\"".
mip*_*adi 111
您可以照常创建提交,但在提交时,请设置环境变量GIT_AUTHOR_DATE并设置GIT_COMMITTER_DATE相应的日期时间.
当然,这将使得提交位于分支的最前端(即,在当前HEAD提交之前).如果你想在回购中再推回它,你必须有点花哨.假设你有这样的历史:
o--o--o--o--o
Run Code Online (Sandbox Code Playgroud)
并且您希望新的提交(标记为"X")显示为第二个:
o--X--o--o--o--o
Run Code Online (Sandbox Code Playgroud)
最简单的方法是从第一次提交分支,添加新的提交,然后在新的提交之上重新设置所有其他提交.像这样:
$ git checkout -b new_commit $desired_parent_of_new_commit
$ git add new_file
$ GIT_AUTHOR_DATE='your date' GIT_COMMITTER_DATE='your date' git commit -m 'new (old) files'
$ git checkout master
$ git rebase new_commit
$ git branch -d new_commit
Run Code Online (Sandbox Code Playgroud)
Hyd*_* B. 91
我知道这个问题已经很老了,但这才是真正适合我的:
git commit --date="10 day ago" -m "Your commit message"
Run Code Online (Sandbox Code Playgroud)
ski*_*age 33
在我的情况下,随着时间的推移,我已经保存了一堆myfile的版本,如myfile_bak,myfile_old,myfile_2010,backups/myfile等.我想使用修改日期将myfile的历史记录放在git中.所以将最旧的重命名为myfile, git add myfile然后git commit --date=(modification date from ls -l) myfile将下一个最旧的重命名为myfile,使用--date重命名另一个git,重复...
要稍微自动化,可以使用shell-foo来获取文件的修改时间.我开始使用ls -l和cut,但stat(1)更直接
git commit --date="`stat -c %y myfile`" myfile
mx0*_*mx0 25
要进行看起来像过去完成的提交,您必须同时设置GIT_AUTHOR_DATE和GIT_COMMITTER_DATE:
GIT_AUTHOR_DATE=$(date -d'...') GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE" git commit -m '...'
Run Code Online (Sandbox Code Playgroud)
wheredate -d'...'可以是确切日期 like2019-01-01 12:00:00或 relative like 5 months ago 24 days ago。
要在 git log 中查看两个日期,请使用:
git log --pretty=fuller
Run Code Online (Sandbox Code Playgroud)
这也适用于合并提交:
GIT_AUTHOR_DATE=$(date -d'...') GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE" git merge <branchname> --no-ff
Run Code Online (Sandbox Code Playgroud)
小智 21
这是一个古老的问题,但我最近偶然发现了它。
git commit --date='2021-01-01 12:12:00' -m "message"工作正常并在GitHub.
Vil*_*ira 18
下面是我使用的更改提交foo到N=1在过去的日子:
git add foo
git commit -m "Update foo"
git commit --amend --date="$(date -v-1d)"
Run Code Online (Sandbox Code Playgroud)
如果你想提交一个更老的日期,比如3天前,只需更改date参数:date -v-3d.
例如,当你忘记昨天提交某些东西时,这非常有用.
更新:--date也接受像--date "3 days ago"或甚至--date "yesterday".所以我们可以将它减少到一行命令:
git add foo ; git commit --date "yesterday" -m "Update"
Run Code Online (Sandbox Code Playgroud)
Mac*_*zyk 17
GIT_AUTHOR_DATE="2020-10-24T18:00:00 +0200" GIT_COMMITTER_DATE=$GIT_AUTHOR_DATE git commit
Run Code Online (Sandbox Code Playgroud)
注意时区字符串并为您的时区设置一个合适的字符串。即+0200、-0400
Jst*_*oRR 16
在我的例子中,使用--date选项时,我的git进程崩溃了.可能是我做了一件可怕的事.结果出现了一些index.lock文件.所以我手动删除了.git文件夹中的.lock文件并执行了,因为所有修改过的文件都要在传递的日期提交,这次就可以了.谢谢所有答案在这里.
git commit --date="`date --date='2 day ago'`" -am "update"
Run Code Online (Sandbox Code Playgroud)
okw*_*wap 11
git --date仅更改GIT_AUTHOR_DATE但许多 git 应用程序,例如 GitHub 显示GIT_COMMITTER_DATE。确保GIT_COMMITTER_DATE也改变。OS X 中的完整示例(将GIT_COMMITTER_DATE和更改GIT_AUTHOR_DATE为 4 小时前):
x=$(date -v -4H +%Y-%m-%dT%H:%M:%S%z); export GIT_COMMITTER_DATE=$x; git commit --amend --date $x
Run Code Online (Sandbox Code Playgroud)
因此,如果您想在过去的日期在 Git 上提交某些内容,您只需使用这些命令即可帮助您完成此操作。
git commit --amend --no-edit --date="Sat Jun 5 20:00:00 2021 -0600"
Run Code Online (Sandbox Code Playgroud)
git add .git commit -m "Your commit message"。git commit --amend --no-edit --date="Sat Jun 5 20:00:00 2021 -0600"提交后运行此命令以修改带有记录时间戳的最后一次提交。--no-edit 将使消息保持原样。确保您必须根据您的喜好更改日期和时间。这将创建对过去特定日期的提交,并且您不会丢失 GitHub 记录。