简体   繁体   English

我如何在过去进行 Git 提交?

[英]How do I make a Git commit in the past?

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.我正在将所有内容转换为 Git 供我个人使用,我发现存储库中已经有一些旧版本的文件。 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  

The advice you were given is flawed.你得到的建议是有缺陷的。 Unconditionally setting GIT_AUTHOR_DATE in an --env-filter would rewrite the date of every commit.--env-filter无条件设置 GIT_AUTHOR_DATE 将重写每次提交的日期。 Also, it would be unusual to use git commit inside --index-filter .此外,在--index-filter使用git commit是不寻常的。

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.您可以通过环境变量 GIT_AUTHOR_DATE 和 GIT_COMMITTER_DATE 为写入新提交的任何命令提供值来覆盖每个。 See “Date Formats” in git-commit(1) or the below:请参阅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

The only command that writes a new commit during normal use is git commit .在正常使用期间写入新提交的唯一命令是git commit It also has a --date option that lets you directly specify the author date.它还有一个--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) .您预期的用法包括git filter-branch --env-filter还使用上面提到的环境变量(这些是“env”的一部分,选项在其后命名;请参阅git-filter-branch(1) 中的“选项”和底层的“管道”命令git-commit-tree(1)

Inserting a File Into a Single ref History将文件插入单个引用历史记录

If your repository is very simple (ie you only have a single branch, no tags), then you can probably use git rebase to do the work.如果您的存储库非常简单(即您只有一个分支,没有标签),那么您可能可以使用git rebase来完成这项工作。

In the following commands, use the object name (SHA-1 hash) of the commit instead of “A”.在以下命令中,使用提交的对象名称(SHA-1 哈希)而不是“A”。 Do not forget to use one of the “date override” methods when you run git commit .运行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 .如果您想更新 A 以包含新文件(而不是在添加新文件的位置创建新提交),请使用git commit --amend而不是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. git checkout --orphan相对较新(Git 1.7.2),但还有其他方法可以在旧版本的 Git 上做同样的事情

Inserting a File Into a Multi- ref History将文件插入多参考历史记录

If your repository is more complex (ie it has more than one ref (branches, tags, etc.)), then you will probably need to use git filter-branch .如果您的存储库更复杂(即它有多个引用(分支、标签等)),那么您可能需要使用git filter-branch Before using git filter-branch , you should make a backup copy of your entire repository.在使用git filter-branch之前,您应该制作整个存储库的备份副本。 A simple tar archive of your entire working tree (including the .git directory) is sufficient.整个工作树(包括 .git 目录)的简单tar存档就足够了。 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. git filter-branch确实会生成备份引用,但是通过删除.git目录并从备份中恢复它,通常更容易从不太正确的过滤中恢复。

Note: The examples below use the lower-level command git update-index --add instead of git add .注意:下面的示例使用较低级别的命令git update-index --add而不是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).您可以使用git add ,但您首先需要将文件从某个外部位置复制到预期路径( --index-filter在空的临时 GIT_WORK_TREE 中运行其命令)。

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=…' .我真的看不出有任何理由使用--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:如果你希望你的新文件只出现在一些现有提交(“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

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 :如果您希望通过将插入到历史记录中间的新提交来添加文件,那么您需要在使用git filter-branch之前生成新提交并将--parent-filter添加到git filter -分支

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

我知道这个问题已经很老了,但这实际上对我有用:

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

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.您可以照常创建提交,但在提交时,请将环境变量GIT_AUTHOR_DATEGIT_COMMITTER_DATE设置为适当的日期时间。

Of course, this will make the commit at the tip of your branch (ie, in front of the current HEAD commit).当然,这将使提交在您的分支的顶端(即,在当前 HEAD 提交之前)。 If you want to push it back farther in the repo, you have to get a bit fancy.如果你想在 repo 中把它推回更远的地方,你必须有点花哨。 Let's say you have this history:假设你有这样的历史:

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

And you want your new commit (marked as "X") to appear second :并且您希望您的新提交(标记为“X”)出现在第二个

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

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.在我的情况下,随着时间的推移,我已经将myfile的一堆版本保存为 myfile_bak、myfile_old、myfile_2010、backups/myfile 等。我想使用它们的修改日期将 myfile 的历史记录放在 git 中。 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...因此,将最旧的重命名为 myfile, git add myfile ,然后git commit --date=(modification date from ls -l) myfile ,将下一个最旧的重命名为 myfile,另一个 git commit 与 --date,重复...

To automate this somewhat, you can use shell-foo to get the modification time of the file.为了在某​​种程度上自动化,您可以使用 shell-foo 来获取文件的修改时间。 I started with ls -l and cut , but stat(1) is more direct我从ls -lcut开始,但 stat(1) 更直接

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

The following is what I use to commit changes on foo to N=1 days in the past:以下是我过去用于将foo上的更改提交到N=1天的内容:

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 .如果你想提交一个更早的日期,比如 3 天前,只需更改date参数: 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" .更新--date还接受诸如--date "3 days ago"甚至--date "yesterday" So we can reduce it to one line command:所以我们可以将其缩减为一行命令:

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

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_DATEGIT_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 .其中date -d'...'可以是确切日期,如2019-01-01 12:00:00或相对如5 months ago 24 days ago

To see both dates in git log use:要在 git log 中查看两个日期,请使用:

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

This is an old question but I recently stumbled upon it.这是一个古老的问题,但我最近偶然发现了它。

git commit --date='2021-01-01 12:12:00' -m "message" worked properly and verified it on GitHub . git commit --date='2021-01-01 12:12:00' -m "message"工作正常并在GitHub进行了验证。

In my case, while using the --date option, my git process crashed.就我而言,在使用 --date 选项时,我的 git 进程崩溃了。 May be I did something terrible.可能是我做了什么可怕的事情。 And as a result some index.lock file appeared.结果出现了一些 index.lock 文件。 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.所以我手动从 .git 文件夹中删除了 .lock 文件并执行,所有修改过的文件都在传递的日期提交,这次它起作用了。 Thanx for all the answers here.感谢这里的所有答案。

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

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

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

Pre-Step.预步。

  • Pull all data from the remote to the local repository.将所有数据从远程拉取到本地存储库。

  • we are using the --amend and --date switches.我们正在使用 --amend 和 --date 开关。

The exact command is as follows:确切的命令如下:

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

  1. git --date changes only GIT_AUTHOR_DATE but many git apps, eg, GitHub shows GIT_COMMITTER_DATE . git --date仅更改GIT_AUTHOR_DATE但许多 git 应用程序,例如,GitHub 显示GIT_COMMITTER_DATE Make sure to change GIT_COMMITTER_DATE too.确保也更改GIT_COMMITTER_DATE
  2. git does not aware time zone in default UNIX date output. git 不知道默认 UNIX 日期输出中的时区。 Make sure to format the datetime format in a compatible format such as ISO8601.确保以兼容格式(例如 ISO8601)格式化日期时间格式。

Complete example in OS X (Change both GIT_COMMITTER_DATE and GIT_AUTHOR_DATE to 4 hours ago): 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

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.注意时区 string 并为您的时区设置一个合适的时区。 ie +0200, -0400即+0200,-0400

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

git push 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 我如何压缩 git 中提交日期不是过去的提交? - How do I squash commits in git with a commit date that is not in the past? 我如何使用git使旧的提交成为当前的主提交? - How do I make an old commit the current master commit with git? 如何编辑包含数百次合并的 Git 提交并将冲突合并到过去? - How do I edit a Git commit that is hundreds of merges and merge conflicts into the past? 如何编辑过去的git提交以从提交日志中删除我的密码? - How do I edit past git commits to remove my password from the commit logs? 我如何让Jenkins在git commit上做任何事情? - How do I make Jenkins do anything on git commit? 我如何让Jenkins看到Git合并提交作为更改? - How do I make Jenkins see a Git merge commit as a change? 如何使我的 git 提交历史看起来不错? - How do I make my git commit history look nice? 我可以更改过去的git commit的描述吗? - can I change the description of the past git commit? 在 Visual Studio 中从过去的提交创建新的 git 分支时,如何处理数组越界异常? - How do I deal with the array out of bounds exception when creating a new git branch from a past commit in Visual Studio? 如何从父克隆的过去提交中获取git子模块的关联提交ID? - How can I get a git submodule's associated commit ID from a past commit in the parent clone?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM