如何在过去进行 Git 提交?

发布于 2024-09-27 05:34:51 字数 278 浏览 4 评论 0原文

我正在将所有内容转换为 Git 供我个人使用,并且我发现存储库中已经存在一些旧版本的文件。如何根据文件的“修改日期”以正确的顺序将其提交到历史记录,以便我拥有文件的准确历史记录?

有人告诉我这样的事情会起作用:

git filter-branch --env-filter="GIT_AUTHOR_DATE=... --index-filter "git commit path/to/file --date " --tag-name-filter cat -- --all  

I'm converting everything over to Git for my own personal use and I found some old versions of a file already in the repository. How do I commit it to the history in the correct order according the file's "date modified" so I have an accurate history of the file?

I was told something like this would work:

git filter-branch --env-filter="GIT_AUTHOR_DATE=... --index-filter "git commit path/to/file --date " --tag-name-filter cat -- --all  

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(16

浮云落日 2024-10-04 05:34:51

这对我有用:

git commit --date "10 day ago" -m "Your commit message" 

This is what worked for me:

git commit --date "10 day ago" -m "Your commit message" 
爺獨霸怡葒院 2024-10-04 05:34:51

你得到的建议是有缺陷的。在 --env-filter 中无条件设置 GIT_AUTHOR_DATE 将重写每次提交的日期。另外,在 --index-filter 中使用 git commit 是不寻常的。

您在这里正在处理多个独立的问题。

指定“现在”以外的日期

每个提交都有两个日期:作者日期和提交者日期。您可以通过环境变量 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

在正常使用期间写入新提交的唯一命令是git commit。它还具有一个 --date 选项,可让您直接指定作者日期。您预期的用法包括 git filter-branch --env-filter 还使用上面提到的环境变量(这些是“env”的一部分,选项以该选项命名;请参阅 git-filter-branch(1) 中的“选项” 和底层“管道”命令 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

如果您想更新 A 以包含新文件(而不是在添加文件的地方创建新提交),请使用 git commit --amend 代替 git commit 。结果将如下所示:

---A'---B'---C'---o---o---o   master

只要您可以命名应该是新提交的父级的提交,上面的代码就可以工作。如果您确实希望通过新的根提交(无父级)添加新文件,那么您需要一些不同的东西:

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

git checkout --orphan 相对较新(Git 1.7.2),但是还有其他方法可以完成同样的事情,这些方法可以在旧版本的 Git 上运行。

将文件插入到多引用历史记录中

如果您的存储库比较复杂(即它有多个引用(分支、标签等)),那么您可能需要使用 git 过滤分支在使用git filter-branch之前,您应该制作整个存储库的备份副本。整个工作树的简单tar存档(包括.git 目录)就足够了。 git filter-branch 确实会备份引用,但通常更容易从不完全正确的过滤中恢复,只需删除 .git 目录并从您的备份。

注意:下面的示例使用较低级别的命令 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

我真的没有看到任何理由使用 --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

如果您希望通过要插入到您的文件中间的新提交来添加文件历史记录,那么您需要在使用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

您还可以安排文件首先添加到新的根提交中:通过 git rebase 部分中的“orphan”方法创建新的根提交(在 new_commit 中捕获它)),使用无条件 --index-filter--parent-filter"sed -e \"s/^ $/-p $new_commit/\"".

The advice you were given is flawed. Unconditionally setting GIT_AUTHOR_DATE in an --env-filter would rewrite the date of every commit. Also, it would be unusual to use git commit inside --index-filter.

You are dealing with multiple, independent problems here.

Specifying Dates Other Than “now”

Each commit has two dates: the author date and the committer date. You can override each by supplying values through the environment variables GIT_AUTHOR_DATE and GIT_COMMITTER_DATE for any command that writes a new commit. See “Date Formats” in git-commit(1) or the below:

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

The only command that writes a new commit during normal use is git commit. It also has a --date option that lets you directly specify the author date. Your anticipated usage includes git filter-branch --env-filter also uses the environment variables mentioned above (these are part of the “env” after which the option is named; see “Options” in git-filter-branch(1) and the underlying “plumbing” command git-commit-tree(1).

Inserting a File Into a Single ref History

If your repository is very simple (i.e. you only have a single branch, no tags), then you can probably use git rebase to do the work.

In the following commands, use the object name (SHA-1 hash) of the commit instead of “A”.
Do not forget to use one of the “date override” methods when you run 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

If you wanted to update A to include the new file (instead of creating a new commit where it was added), then use git commit --amend instead of git commit. The result would look like this:

---A'---B'---C'---o---o---o   master

The above works as long as you can name the commit that should be the parent of your new commit. If you actually want your new file to be added via a new root commit (no parents), then you need something a bit different:

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

git checkout --orphan is relatively new (Git 1.7.2), but there are other ways of doing the same thing that work on older versions of Git.

Inserting a File Into a Multi-ref History

If your repository is more complex (i.e. it has more than one ref (branches, tags, etc.)), then you will probably need to use git filter-branch. Before using git filter-branch, you should make a backup copy of your entire repository. A simple tar archive of your entire working tree (including the .git directory) is sufficient. git filter-branch does make backup refs, but it is often easier to recover from a not-quite-right filtering by just deleting your .git directory and restoring it from your backup.

Note: The examples below use the lower-level command git update-index --add instead of git add. You could use git add, but you would first need to copy the file from some external location to the expected path (--index-filter runs its command in a temporary GIT_WORK_TREE that is empty).

If you want your new file to be added to every existing commit, then you can do this:

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

I do not really see any reason to change the dates of the existing commits with --env-filter 'GIT_AUTHOR_DATE=…'. If you did use it, you would have make it conditional so that it would rewrite the date for every commit.

If you want your new file to appear only in the commits after some existing commit (“A”), then you can do this:

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

If you want the file to be added via a new commit that is to be inserted into the middle of your history, then you will need to generate the new commit prior to using git filter-branch and add --parent-filter to 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

You could also arrange for the file to be first added in a new root commit: create your new root commit via the “orphan” method from the git rebase section (capture it in new_commit), use the unconditional --index-filter, and a --parent-filter like "sed -e \"s/^$/-p $new_commit/\"".

爱你不解释 2024-10-04 05:34:51

您可以照常创建提交,但在提交时,请将环境变量 GIT_AUTHOR_DATEGIT_COMMITTER_DATE 设置为适当的日期时间。

当然,这将使提交发生在分支的顶端(即当前 HEAD 提交之前)。如果你想在仓库中将其向后推得更远,你必须变得有点花哨。假设您有这样的历史记录:

o--o--o--o--o

并且您希望新提交(标记为“X”)出现在第二

o--X--o--o--o--o

最简单的方法是从第一个提交分支,添加新提交,然后变基所有其他提交均位于新提交之上。就像这样:

$ 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

You can create the commit as usual, but when you commit, set the environment variables GIT_AUTHOR_DATE and GIT_COMMITTER_DATE to the appropriate datetimes.

Of course, this will make the commit at the tip of your branch (i.e., in front of the current HEAD commit). If you want to push it back farther in the repo, you have to get a bit fancy. Let's say you have this history:

o--o--o--o--o

And you want your new commit (marked as "X") to appear second:

o--X--o--o--o--o

The easiest way would be to branch from the first commit, add your new commit, then rebase all other commits on top of the new one. Like so:

$ 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
旧情别恋 2024-10-04 05:34:51

这是一个老问题,但我最近偶然发现了它。

git commit --date='year-month-day hour:minutes:seconds' -m "message"

所以它看起来像这样:
git commit --date='2021-01-01 12:12:00' -m "message" 工作正常,并在 GitHubGitLab< /代码>。

This is an old question but I recently stumbled upon it.

git commit --date='year-month-day hour:minutes:seconds' -m "message"

So it would look something like this:
git commit --date='2021-01-01 12:12:00' -m "message" worked properly and verified it on GitHub and GitLab.

濫情▎り 2024-10-04 05:34:51

要使提交看起来像是过去完成的,您必须设置 GIT_AUTHOR_DATEGIT_COMMITTER_DATE

GIT_AUTHOR_DATE=$(date -d'...') GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE" git commit -m '...'

其中 date -d'...' 可以是精确日期,如 2019-01-01 12:00:00 或相对日期,如 5 个月前 24 天前

要查看 git log 中的两个日期,请使用:

git log --pretty=fuller

这也适用于合并提交:

GIT_AUTHOR_DATE=$(date -d'...') GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE" git merge <branchname> --no-ff

To make a commit that looks like it was done in the past you have to set both GIT_AUTHOR_DATE and GIT_COMMITTER_DATE:

GIT_AUTHOR_DATE=$(date -d'...') GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE" git commit -m '...'

where date -d'...' can be exact date like 2019-01-01 12:00:00 or relative like 5 months ago 24 days ago.

To see both dates in git log use:

git log --pretty=fuller

This also works for merge commits:

GIT_AUTHOR_DATE=$(date -d'...') GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE" git merge <branchname> --no-ff
荒岛晴空 2024-10-04 05:34:51

以下是我用来将 foo 上的更改提交到过去 N=1 天的内容:

git add foo
git commit -m "Update foo"
git commit --amend --date="$(date -v-1d)"

如果您想提交到更早的日期,例如 3 天前,只需更改date参数:date -v-3d

例如,当您昨天忘记提交某件事时,这非常有用。

更新--date还接受诸如--date "3天前"或什至--date "yesterday"<之类的表达式/代码>。所以我们可以将其简化为一行命令:

git add foo ; git commit --date "yesterday" -m "Update"

The following is what I use to commit changes on foo to N=1 days in the past:

git add foo
git commit -m "Update foo"
git commit --amend --date="$(date -v-1d)"

If you want to commit to a even older date, say 3 days back, just change the date argument: date -v-3d.

That's really useful when you forget to commit something yesterday, for instance.

UPDATE: --date also accepts expressions like --date "3 days ago" or even --date "yesterday". So we can reduce it to one line command:

git add foo ; git commit --date "yesterday" -m "Update"
最舍不得你 2024-10-04 05:34:51

就我而言,随着时间的推移,我保存了许多版本的 myfile 作为 myfile_bak、myfile_old、myfile_2010、backups/myfile 等。我想使用它们的修改日期将 myfile 的历史记录放入 git 中。因此,将最旧的文件重命名为 myfile,git add myfile,然后 git commit --date=(ls -l 的修改日期) myfile,将下一个最旧的文件重命名为 myfile,另一个 git使用 --date 提交,重复...

要自动化此操作,您可以使用 shell-foo 来获取文件的修改时间。我从 ls -lcut 开始,但 stat(1) 更直接

git commit --date="`stat -c %y myfile`" myfile

In my case over time I had saved a bunch of versions of myfile as myfile_bak, myfile_old, myfile_2010, backups/myfile etc. I wanted to put myfile's history in git using their modification dates. So rename the oldest to myfile, git add myfile, then git commit --date=(modification date from ls -l) myfile, rename next oldest to myfile, another git commit with --date, repeat...

To automate this somewhat, you can use shell-foo to get the modification time of the file. I started with ls -l and cut, but stat(1) is more direct

git commit --date="`stat -c %y myfile`" myfile

但可醉心 2024-10-04 05:34:51

您正在寻找的简单答案:

GIT_AUTHOR_DATE="2020-10-24T18:00:00 +0200" GIT_COMMITTER_DATE=$GIT_AUTHOR_DATE git commit

注意时区字符串并为您的时区设置合适的字符串。即+0200、-0400

The simple answer you are looking for:

GIT_AUTHOR_DATE="2020-10-24T18:00:00 +0200" GIT_COMMITTER_DATE=$GIT_AUTHOR_DATE git commit

Mind the timezone string and set a proper one for your timezone. i.e. +0200, -0400

今天小雨转甜 2024-10-04 05:34:51

就我而言,在使用 --date 选项时,我的 git 进程崩溃了。也许我做了一些可怕的事情。结果出现了一些index.lock文件。因此,我手动从 .git 文件夹中删除了 .lock 文件并执行,以便所有修改的文件在过去的日期内提交,并且这次有效。感谢这里的所有答案。

git commit --date="`date --date='2 day ago'`" -am "update"

In my case, while using the --date option, my git process crashed. May be I did something terrible. And as a result some index.lock file appeared. So I manually deleted the .lock files from .git folder and executed, for all modified files to be commited in passed dates and it worked this time. Thanx for all the answers here.

git commit --date="`date --date='2 day ago'`" -am "update"
合约呢 2024-10-04 05:34:51
  1. git --date 仅更改 GIT_AUTHOR_DATE,但许多 git 应用程序(例如 GitHub)显示 GIT_COMMITTER_DATE。请确保也更改 GIT_COMMITTER_DATE
  2. git 不知道默认 UNIX 日期输出中的时区。确保将日期时间格式设置为兼容格式,例如 ISO8601。

OS X 中的完整示例(将 GIT_COMMITTER_DATEGIT_AUTHOR_DATE 更改为 4 小时前):

x=$(date -v -4H +%Y-%m-%dT%H:%M:%S%z); export GIT_COMMITTER_DATE=$x; git commit --amend --date $x
  1. git --date changes only GIT_AUTHOR_DATE but many git apps, e.g., GitHub shows GIT_COMMITTER_DATE. Make sure to change GIT_COMMITTER_DATE too.
  2. git does not aware time zone in default UNIX date output. Make sure to format the datetime format in a compatible format such as ISO8601.

Complete example in OS X (Change both GIT_COMMITTER_DATE and GIT_AUTHOR_DATE to 4 hours ago):

x=$(date -v -4H +%Y-%m-%dT%H:%M:%S%z); export GIT_COMMITTER_DATE=$x; git commit --amend --date $x
淡淡の花香 2024-10-04 05:34:51

或者只是使用 fake-git-history 为特定数据范围生成它。

Or just use a fake-git-history to generate it for a specific data range.

北城半夏 2024-10-04 05:34:51

因此,如果您想在过去的日期在 Git 上提交某些内容,您只需使用这些命令即可帮助您完成此操作。

git commit --amend --no-edit --date="Sat Jun 5 20:00:00 2021 -0600"
  1. 要在过去的日期进行提交,您只需运行 git add 将更改添加到本地存储库中。
  2. 使用 git commit -m "Your commit message" 提交更改。
  3. 在提交后运行此 git commit --amend --no-edit --date="Sat Jun 5 20:00:00 2021 -0600" 命令,以修改带有时间戳的最后一次提交。 --no-edit 将使消息保持原样。
  4. 通过运行 git Push 将更改推送到 GitHub 或您使用的任何平台。

确保您必须根据您的喜好更改日期和时间。这将创建对过去特定日期的提交,并且您不会丢失 GitHub 记录。

So if you want to commit something on Git in the past date, you simply use these commands that help you to do so.

git commit --amend --no-edit --date="Sat Jun 5 20:00:00 2021 -0600"
  1. To make a commit in the past date, you just want to add your changes in the local repository by running git add .
  2. Commit changes using git commit -m "Your commit message".
  3. Run this git commit --amend --no-edit --date="Sat Jun 5 20:00:00 2021 -0600" command after a commit to amend the last commit with the timestamp noted. The --no-edit will leave the message as-is.
  4. Push changes to GitHub or whichever platform you use by running git push.

Make sure you have to change the date and time according to your preference. This will create a commit to the particular date in the past and you do not lose your GitHub streak.

孤者何惧 2024-10-04 05:34:51

前期步骤。

  • 将所有数据从远程拉取到本地存储库。

  • 我们正在使用 --amend 和 --date 开关。

确切的命令如下:

$ git commit --amend --date="YYYY-MM-DD HH:MM:SS"

Pre-Step.

  • Pull all data from the remote to the local repository.

  • we are using the --amend and --date switches.

The exact command is as follows:

$ git commit --amend --date="YYYY-MM-DD HH:MM:SS"

恰似旧人归 2024-10-04 05:34:51

您始终可以更改计算机上的日期,进行提交,然后更改回日期并推送。

You can always change a date on your computer, make a commit, then change the date back and push.

深海里的那抹蓝 2024-10-04 05:34:51
git commit --date='year-month-day hour:minutes:seconds' -m "message"

git push 
git commit --date='year-month-day hour:minutes:seconds' -m "message"

git push 
も星光 2024-10-04 05:34:51

我发现最适合我的是这个。

git add .

git commit --date "1 day ago" -m "commit"

What I've found works best for me is this.

git add .

git commit --date "1 day ago" -m "commit"
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文