在本地删除文件并提交更改后如何合并存储?

时间:2019-06-05 22:07:09

标签: xcode git

当前在与另一位开发人员合作并将Git用作我们的源代码管理时,“ UserInterfaceState.xcuserstate”存在问题。我很早就意识到.gitignore并没有忽略该文件,因此我决定使用'git rm --cached'删除/取消跟踪。在执行命令之前,我将当前更改保存到:

  1. 保留我当前的更改
  2. 创建一个反映已删除UserInterfaceState.xcuserstate的快速提交

我创建了提交,反映了对'UserInterfaceState.xcuserstate'的删除,并进行了'git stash apply'。这是我收到的错误:

needs merge
unable to refresh index

我知道存储区仍然有UserInterfaceState.xcuserstate,但是我给人的印象是Git会将master分支的新提交状态与存储区合并,并迫使我解决merge conflict

我将如何合并存储以将我的以前的工作恢复到不再提交且不再跟踪UserInterfaceState.xcuserstate的新提交的master分支?

1 个答案:

答案 0 :(得分:3)

每当有不适用的存储区时,我建议将其存储为分支。

为此,首先请确保您没有未完成的工作。这意味着您现在应该执行您正在做的任何事情,或者将其隐藏起来-后者有点讽刺和怪异,但可以正常工作,只要您还记得要转换的隐藏项已被重新编号。现在,所有内容都是“干净的”,请按其ID(stash@{1}stash@{6}或其他必要的东西,选择麻烦的存储卡,如果是当前存储卡或仅存储卡,则选择默认存储卡)并使用该ID(或默认值)作为git stash branch命令的参数:

$ git stash branch newbranch stash@{3}

您现在处于一种状态,可以运行git status,然后可以运行git commitgit addgit commit,依此类推-您的stash@{3}隐藏已被重新加载到索引中(就像您已运行git stash apply --index一样),并已被重新加载到工作树中,就好像是通过同一命令一样。完成提交后,即可根据需要使用新分支。

(实际上,Git实际上是 did 运行命令:首先,Git运行git checkout的适当提交。然后Git在存储区中运行git stash apply --index,这恢复了保存索引和保存的工作树。然后,在成功应用之后,Git在保存的存储上运行了git stash drop。)

在这种情况下,在git stash branch name stash之后,您可能需要一个git addgit commit,这将节省您的所有工作,包括未删除,可能已修改的烦人的代码,也许不是UserInterfaceState.xcuserstate文件。但是,现在您可以git checkout正在工作的分支,应用并丢弃您创建的临时存储,并git cherry-pick -n对该新分支的提交从您的麻烦藏匿。如果该提交没有对讨厌的文件进行任何更改,并且讨厌的文件在此处不存在,那么Cherry-pick可能会进行得很顺利,并且您将一切就绪。

讨论

一旦您意识到(a)git stash对象只是一团提交,这一切就在一定意义上了; (b)提交始终记录其父提交; (c)分支只是由分支 name 指定的一系列提交,这些提交标识了将被视为分支一部分的 last 提交。

如果git stash做出一些小的承诺是正常的,那么您将:

...--o--o--*--o   <-- your-branch
            \
             i--w   <-- stash

,因此隐藏实际上就像任何分支一样,除了refs/stash不是以refs/heads/开头的事实(与refs/heads/your-branch比较,显然是以{{ 1}})。在这里,refs/heads/是您运行* 所执行的提交。您又添加了一个提交,即git stash右侧的一个提交。在运行*时,此处的iw提交将包含索引和工作树状态。

棘手的部分是git stash根本不像git stashi这样。相反,它使:

w

也就是说,保存的工作树状态似乎是合并提交,保存了合并索引提交...--o--o--*--o <-- your-branch |\ i-w <-- stash 和运行{{ 1}}(提交i)。它并不是真正的合并,因为它不是您通过运行git stash会得到的:隐藏代码只是在滥用合并提交格式,以使以后的隐藏代码更容易。

幸运的是,*知道如何取消滥用格式。它:

  • 检出提交git merge;
  • 创建一个新的分支名称以记住您现在所在的位置;和
  • 应用存储区,以使其索引和工作树组件分开(就像保存存储区时一样),以防万一。

现在您有了:

git stash branch

在索引中*(准备提交),在工作树中返回 o <-- your-branch / ...--o--o--* <-- new-branch (准备进行i编辑更新索引,然后{{ 1}}将出现在您的索引中,可以提交了。当然,提交w中包含讨厌的文件,因此将讨厌的文件保留在没有任何更改的位置,添加并提交其他所有内容,您将得到:

git add

其中w是您所拥有的工作树状态的常规普通提交,可以随时提供给*(可能与 o <-- your-branch / ...--o--o--*--W <-- new-branch 一起使用),也可以随意使用。 >

最终,您只需删除分支W(您可能想用其他名称调用),然后放弃提交git cherry-pick,最终将完全消失。