【问题标题】:Git: best way to remove all changes from a given file for one branchGit:从一个分支的给定文件中删除所有更改的最佳方法
【发布时间】:2012-04-02 20:40:41
【问题描述】:

我的分支有点杂乱,大约有 20 个提交,我正在准备合并回 master。我已经将它从 master 中重新定位,并且仔细观察,我意识到有些文件正在以与该分支完全无关的方式进行修改,并且还没有准备好提交。对这些文件的更改并不局限于特定的提交。

所以基本上,如果可能的话,我不希望将这些文件包含在此分支中。有什么好的方法可以解决这个问题吗?我的后备位置#1 显然只是复制每个文件的最新副本然后提交。但是历史仍然会包含这些变化,Git 之神会对我皱眉头。

后退位置 #2 也是这样做的,然后将整个分支历史压缩到一个提交。

对这些有什么改进吗?

【问题讨论】:

    标签: git git-rebase git-merge git-branch


    【解决方案1】:

    作为 Windows 用户,我遇到了几个问题:

    1. 对 --tree-filter 命令使用双引号。
    2. 文件路径使用正斜杠。
    3. 不要以正斜杠开头文件路径。

    这是我的命令最终的样子:

    git filter-branch -f --tree-filter "git checkout a59f75 -- source/_posts/blog1.md source/_posts/blog2.md" master..tmp
    

    【讨论】:

      【解决方案2】:

      说你的历史是

      $ git lola
      * 6473d7f(大师)更新
      | * 9bcfa7e (HEAD, topic) Munge a, b, and c
      | * 99af942 芒格 b 和 c
      | * 8383e2c 芒格 a 和 b
      |/
      * d1363f4 基线

      注意:lola 是一个非标准但有用的别名。

      提交修改了三个不同的文件。

      $ git log --decorate=short --pretty=oneline --name-status 主题
      9bcfa7e946a92c226ad50ce430a9e4ae55b32490(头,主题)
      嘛
      甲乙
      麦克
      99af942dbb922effcad8a72e96bec9ee9afcc437 芒格 b 和 c
      甲乙
      麦克
      8383e2c8d6092550fec13d3c888c037b3a68af15 芒格 a 和 b
      嘛
      甲乙
      d1363f4fba67d94999b269b51bdb50a8a68ba27a 基线
      一个
      乙
      一个c

      对文件b 的更改是您想要保留的,并且您想要放弃对ac 的所有更改。一种方法是使用git filter-branch

      $ git checkout -b tmp 主题
      切换到新分支 'tmp'
      
      $ git 合并基础主题大师
      d1363f4fba67d94999b269b51bdb50a8a68ba27a
      
      $ git filter-branch --tree-filter 'git checkout d1363f -- a c' master..tmp
      重写 8383e2c8d6092550fec13d3c888c037b3a68af15 (1/3)
      重写 99af942dbb922effcad8a72e96bec9ee9afcc437 (2/3)
      重写 9bcfa7e946a92c226ad50ce430a9e4ae55b32490 (3/3)
      Ref 'refs/heads/tmp' 被重写
      

      上面的树过滤器检查命名范围内的提交并将文件ac恢复到“合并基础”的内容,即topic从@987654331分支的提交@。

      现在tmp 拥有topicb 的所有更改,但没有任何其他文件的更改。

      $ git log --decorate --pretty=oneline --name-status tmp
      9ee7e2bd2f380cc338b0264686bcd6f071eb1087 (HEAD, tmp) 芒格 a、b 和 c
      甲乙
      226c22f150af1ddc1f9adc19f97fc4f220851ada Munge b 和 c
      甲乙
      45e706f7b22c37ee2025ee0d04c651135e7b31cd 芒格 a 和 b
      甲乙
      d1363f4fba67d94999b269b51bdb50a8a68ba27a 基线
      一个
      乙
      一个c

      作为一项安全措施,git filter-branch 存储您原始参考的备份。当您对更改感到满意并想要删除备份 tmp 时,运行

      $ git update-ref -d refs/original/refs/heads/tmp

      【讨论】:

      • +1 很好的答案。使用 filter-branch 是一个非常棒的工具。
      • 这里有很多很棒的东西我还在消化。 'log --name-status ' 很酷。
      • 呃。我遵循了这个出色答案的所有步骤,一切都顺利进行,直到过滤器分支结束。 “警告:参考 'refs/heads/tmp' 未更改”。检查历史记录,文件修改仍然存在,并且提交 id 都没有改变(据我所知),即使 git 报告“重写”它们。嗯。
      • 啊。奇怪的是,“git checkout”的参数被视为区分大小写(即使我在 Windows 上)。现在已经奏效了。运行“git log”命令现在有两种奇怪的方式:它仍然将文件列为已修改(即使在 diff 中没有对其进行更改),并且保留旧的提交 ID(但现在显示为黄色)。可怕的命令!
      • 错误,下一个问题:如何从该备份中恢复,我在 refs/original/heads/...中看到
      【解决方案3】:

      要结帐到特定版本,您可以执行以下操作 git checkout <sha1> <file> 其中sha1 是您希望文件所在版本的唯一 sha1 哈希。

      【讨论】:

        猜你喜欢
        • 2023-03-22
        • 1970-01-01
        • 1970-01-01
        • 2015-05-15
        • 2012-10-21
        • 2018-06-21
        • 2020-01-07
        • 2015-04-04
        • 2021-05-28
        相关资源
        最近更新 更多