【问题标题】:Git change branch, but don't change files in workspaceGit更改分支,但不要更改工作区中的文件
【发布时间】:2012-07-13 11:41:16
【问题描述】:

这与我的另一个问题 (Switch to another branch without changing the workspace files) 类似,但在那里有效的解决方案现在不起作用。

我需要删除一些很久以前推送到远程主机的更改。所以我不想从 master 中删除提交,但我想更改文件,就像这些更改被还原一样。所以我这样做了:

  1. 在主人时,git branch limits
  2. git checkout limits
  3. git rebase --interactive <commit before the ones I wanted to remove>
  4. 在交互式控制台中,我删除了带有我想要还原的更改的提交

所以现在在limits 我有我想要的代码。我怎样才能“移动”它来掌握?使用来自limits 的代码,我想更改为master 分支,但不更改工作区中的任何文件,因此我可以将更改作为对master 的新更改提交。

【问题讨论】:

  • 这种情况不就是git revert的作用吗?
  • 是的,我不知道。学习新东西总是好的。尽管如此,我仍然希望回答我的问题:)
  • @CarlNorum git revert 是这里的正确答案,如果您发布该答案,我会赞成。此处的交互式变基会更改历史记录,没有必要这样做,而且我们都知道更改推送历史记录不是一个好主意。
  • 当我发表评论时,我正在使用我的 iPad;我很高兴将代表让给那些有时间和精力写出更好答案的人。

标签: git branch git-branch


【解决方案1】:

移动分支指针

如果您实际上想要做的是在复杂的变基或合并到一个单独的分支之后将您的分支指针移动到 master,您可以通过多种方式做到这一点。例如,要强制移动某个临时分支以使其成为您的新主分支,您可以执行以下操作之一:

# Use git porcelain to move the branch over top of one that already
# exists.
git branch -M limits master

# Explicitly move the branch pointer to wherever the head for limits
# is pointing.
git reset --hard refs/heads/limits

您还可以通过多种方式执行此各种管道命令,但这并不意味着要详尽无遗。这应该足以让您指出正确的方向。

恢复提交

正如其他帖子和 cmets 正确指出的那样,如果您只想撤消 master 的目标提交,那么您可以使用 git-revert(1)。请注意,这会在您的历史记录中留下原始提交和还原;这通常是你想要的。

另外,请注意 git-revert 可能会导致您必须手动解决的冲突或不需要的更改,特别是如果您要恢复的提交不是小的原子更改。将 git-revert 视为一个反向补丁(从根本上讲,它是在后台),您可以看到可能出现潜在冲突的地方。

您的里程肯定会有所不同。

【讨论】:

  • 我知道 stash,但它是用于未提交的更改。我没有任何未提交的。
  • 他想基本把master扔掉,把内容换成limits。不仅仅是应用更改。
  • @Shahbaz 最初的问题并不清楚。提出的问题仍然是关于将重新定位的分支移动到 master 上,所以我将留下我的答案,但我认为 git-revertunderlying 目标的正确解决方案。
【解决方案2】:

您提出的问题的答案是:

$ git checkout master             # switch to master branch

$ git reset --hard limits         # hard-reset it to the limits commit
$ git reset --soft master@{1}     # move the reference back to where it was, but
                                  #  don't modify the working tree or index

这将使您的工作树和索引与您签出 limits 时完全一样,但您将位于其原始位置的 master 分支上。


但是,执行此类操作的正确方法是 git revert 您尝试撤消的每个更改。

【讨论】:

    【解决方案3】:

    除了使用交互式变基之外,您还可以还原每个您不想要的提交。当您使用git revert <object-name-of-commit> 时,git 将引入一个新的提交,以撤销您命名的那个引入的更改。因此,假设您要删除的提交是 abc123def456,您可以这样做:

    git checkout master
    git revert abc123
    git revert def456
    

    但是,如果找到这些提交需要大量工作,并且您对 limits 的提示感到满意,您可以在 master 上创建一个新提交,其中包含树的状态.首先,确保git status 是干净的,因为您将使用git reset --hard,这将清除未提交的更改:

    git checkout master
    git reset --hard limits
    git reset --soft HEAD@{1}
    git commit -m "Reverting unwanted commits"
    

    那个菜谱是这个问题的一个变体:

    【讨论】:

    • 谢谢。 HEAD@{1} 是什么意思?
    • git 使用称为“reflog”的东西跟踪每个 ref 所在位置的历史记录 - foo@{n} 大致意思是“ref foo 的位置,因为它是 n 之前的变化” .如果您想查看HEAD 的引用日志,只需执行git reflog,您就会明白这一点。请注意,对特定 refs 位置的跟踪与 refs 指向的提交图表示的历史完全正交。
    • 仅作记录:IIRC,剧烈的HEAD 运动也将原始状态保存在ORIG_HEAD 参考中,因此它可能也可以代替HEAD@{1}
    【解决方案4】:

    这要求revert :-)

    我会回到 master 和 git-revert 每个你想取消应用的提交。 这会为每个提交创建一个“未应用”提交 - 因此历史不会更改,但您会获得所需的效果。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-10-24
      • 2011-04-22
      • 1970-01-01
      • 2020-08-20
      • 1970-01-01
      • 2018-05-14
      • 2018-06-07
      相关资源
      最近更新 更多