GIT:如何将文件添加到第一次提交(并在此过程中重写历史记录)?

min*_*der 17 git

我想将一个文件添加到git存储库,就像它从一开始就存在一样.我只找到了解释如何从整个历史记录中删除文件,而不是如何添加文件.

我试过,git filter-branch --tree-filter 'git add LICENSE.txt'但我得到错误,无法找到该文件.

tor*_*rek 21

git filter-branch 可以做到这一点,但可能比需要的重量更重.

你的历史有多大和分支?如果它很小又简短,最简单的方法是立即添加新文件,然后使用git rebase -i --root将新提交移动到第二个位置并将其压缩到根提交中.

例如,假设你有:

$ git log --oneline --graph --decorate --all
* e8719c9 (HEAD, master) umlaut
* b615ade finish
* e743479 initial
Run Code Online (Sandbox Code Playgroud)

(您的SHA-1值当然会有所不同)并且您希望将LICENSE.txt(已在工作目录中)添加到树中作为根提交的一部分.你现在可以这样做:

$ git add LICENSE.txt && git commit -m 'add LICENSE, for fixup into root'
[master 924ccd9] add LICENSE, for fixup into root
 1 file changed, 1 insertion(+)
 create mode 100644 LICENSE.txt
Run Code Online (Sandbox Code Playgroud)

然后运行git rebase -i --root.抓住最后一行(pick ... add LICENSE, ...)并将其移动到第二行,更改pickfixup,并将rebase-commands文件写出并退出编辑器:

".git/rebase-merge/git-rebase-todo" 22L, 705C written
[detached HEAD 7273593] initial
 2 files changed, 4 insertions(+)
 create mode 100644 LICENSE.txt
 create mode 100644 x.txt
Successfully rebased and updated refs/heads/master.
Run Code Online (Sandbox Code Playgroud)

(新的,完全重写的)历史现在看起来更像是这样的:

git log --oneline --graph --decorate --all
* bb71dde (HEAD, master) umlaut
* 7785112 finish
* 7273593 initial
Run Code Online (Sandbox Code Playgroud)

并且LICENSE.txt在所有提交中.


如果您确实有一个更复杂(多分支)的历史记录并想要使用git filter-branch它来更新它,那么--tree-filter您需要的不是:

'git add LICENSE.txt'
Run Code Online (Sandbox Code Playgroud)

反而:

'cp /somewhere/outside/the/repo/LICENSE.txt LICENSE.txt'
Run Code Online (Sandbox Code Playgroud)

每次都将新文件复制到树中.(更快的方法是使用,--index-filter但这更复杂.)


fil*_*pos 8

--index-filter 提供简单快速的解决方案:

git filter-branch --index-filter "cp /abs/path/to/LICENSE.txt . && git add LICENSE.txt"
Run Code Online (Sandbox Code Playgroud)

这是一个针对其他提议方法的非常简单的基准.

第一列(large)显示Git项目存储库副本中每个过滤器的一次运行的时间(以秒为单位)(45885提交,结账约30M).该rebase方法不适用,因为即使使用该-c选项,它也不会自动处理合并.

第二列(medium)显示了具有线性历史和相当大的树的中型存储库副本中每个方法的三次运行的中值时间(2430次提交,结账约为80M).

第三列(small)显示了小型存储库副本中每个方法的三次运行的中位数时间(554次提交,结账约为100K).

              large medium  small
index-filter   1064     38     10
tree-filter    4319     81     15
rebase            -    116     28
Run Code Online (Sandbox Code Playgroud)

另请注意,它在rebase功能上与filter-branch变体不同,因为它更新了提交者日期.

  • @walterlv要重写所有分支,只需在命令中附加` - --all`即可. (2认同)