【问题标题】:How can I remove a file from a commit of a private branch?如何从私有分支的提交中删除文件?
【发布时间】:2014-02-17 05:10:16
【问题描述】:

我正在修改主分支,修改 10 个文件并添加 5 个新文件。
我意识到其中一个文件不应该被修改,我应该取消暂存它,因为原始版本是正确的。
我还决定继续在分公司工作。
我做了一个:git checkout -b newBranch
然后我对分支做了git addgit commit 的所有工作。
但我忘记了我必须取消暂存其中一个文件!
所以现在我能想到的唯一解决方案是将原始文件从主分支复制到我的分支,然后添加并提交以替换修改后的文件。
我认为这应该可行,但我认为稍后将我的私有分支的最后一次提交与我的主分支合并并交付与主分支相同的文件会很奇怪。
有没有更好的方法来处理这个烂摊子?

【问题讨论】:

    标签: git version-control git-branch git-merge git-commit


    【解决方案1】:

    只要你不分享这个分支,你就有几个解决方案。


    提交 --amend

    如果你刚刚提交了所有文件,你可以这样做

    #Restore the file
    git checkout HEAD -- my/file.txt
    
    #Fix your commit
    git add my/file.txt
    git commit --amend
    

    它会在你的文件被修复的情况下重做你的最后一次提交

    变基 -i

    还有另一种更复杂但更灵活的方法。即使您今天不使用它,它也可能会为您节省一些其他时间。

    你可以压缩你的提交。

    假设你有

    • 您在其中添加了所有文件的一次提交(我们称之为abc
    • 一次提交,您可以在其中检索您不想更改的文件的旧版本(我们称之为def

    你可以做git rebase -i HEAD^^。它将打开一个包含您最后两次提交的文本编辑器,例如

    pick abc first commit message
    pick def second commit message
    

    替换成

    pick abc first commit message
    fixup def second commit message
    

    然后保存退出,git会合并这两个提交


    Edit1:关于第二个解决方案的一些解释,以跟进评论

    git rebase -i HEAD^^ 表示“让我更改我的提交树,从HEAD^^ 开始”(而HEAD^^ 表示“the parent of the parent of my current commit”)

    然后它将打开一个文本编辑器,其中包含所有涉及的提交的列表,它会让您为每个提交选择一个操作。可能的操作列表显示在文件的底部。

    pick,默认操作,意思是“不要更改这个提交。squash 意思是“合并这个提交和前一个”。fixup 是“合并这个提交和前一个,然后重新使用提交消息”

    无论如何,如果您不确定自己在做什么,您可以在进行此类操作之前标记初始提交。示例:

    git tag safetyNet
    git rebase -i HEAD^^
    #damned, I screwed up
    git checkout safetyNet
    

    Edit2回答其他评论

    如果您已经将您的分支推送到远程,并且您是唯一使用它的人,那么这没什么大不了的。但是,您必须“强制”推动。这就是为什么

    假设您有以下提交:

    A -- B
         L  newBranch | commit with the file you didn't want to modify
    

    自从您推送以来,这就是您在本地和远程存储库中拥有的内容。

    修复后(使用解决方案 1 或 2),您将在本地存储库中拥有

    A -- B2
     \   L newBranch |fixed commit
      \
       \- B
          L commit with the file you didn't want to modify, not on any branch anymore
    

    如果您尝试git push origin newBranch,它将失败,因为您不能将fast forwardB 转换为B2

    所以你需要git push -f origin newBranch 告诉 git “我知道我在做什么;继续前进吧”。

    阅读http://git-scm.com/book/en/Git-Branching-Remote-Branches 可能有助于澄清这些概念

    【讨论】:

    • git rebase HEAD^^ 这在我的私人分支中变基?这是做什么的?我也不确定pick/fixup 是什么
    • “只要你不共享这个分支”如果你是这个意思,我已经把它推送到远程。但我是唯一一个在做这个的人。
    • 因为你是唯一使用它的人,所以你很安全。但是,请注意,之后您必须git push -f
    • git push -f?对于 2 中的哪种方法?我为什么需要那个?对不起,我对 git 不是很有经验,我仍在努力解决
    猜你喜欢
    • 2017-07-19
    • 2021-07-29
    • 2021-08-02
    • 2023-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-24
    • 2022-10-15
    相关资源
    最近更新 更多