如何隐藏我以前的提交?


74

我的情况如下git log

commit 111  <-- need to push it to the repository

commit 222  <-- need to stash this one

...

如您所见,我只需要将最后(而不是先前)提交推送到存储库。

我该怎么做?git revert --soft commit_hash会帮助我吗?


您有什么理由要隐瞒上一次提交吗?您是否打算使用在提交222中所做的任何更改?
rmorrin 2014年

是的,我想在最近的将来使用提交222中的更改。但是要推送提交111而不是将其与提交222合并,我需要以某种方式隐藏提交222。–
Developer87

不幸的是,仍然没有答案考虑到提交的提交消息(可以很容易地将其转换为隐藏消息),我发现没有任何git stash功能可以轻松地实现该功能,这使我感到困惑。
Xerus

Answers:


80

如果您尚未将任何提交推送到远程存储库,则可以使用交互式变基对提交进行“重新排序”,并仅存储(新)最新提交的更改。

假设您已检出当前分支的尖端(在示例中为111),请执行以下操作:

git rebase -i HEAD~2

这将打开您的默认编辑器,列出最近的两次提交并为您提供一些说明。请谨慎对待此处的操作,因为这将有效地“重写”存储库的历史记录,如果不小心,可能会丢失工作(如果需要,请首先对整个存储库进行备份)。例如,我估计下面的提交哈希/标题

pick 222 commit to be stashed
pick 111 commit to be pushed to remote

# Rebase 111..222 onto 333
#
# Commands:
#  p, pick = use commit
#  r, reword = use commit, but edit the commit message
#  e, edit = use commit, but stop for amending
#  s, squash = use commit, but meld into previous commit
#  f, fixup = like "squash", but discard this commit's log message
#  x, exec = run command (the rest of the line) using shell
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#
# Note that empty commits are commented out

重新排序两个提交(它们被列为最旧=>最新),如下所示:

pick 111 commit to be pushed to remote
pick 222 commit to be stashed

保存并退出,这时git将进行一些处理以重写您已更改的两个提交。假设没有问题,您应该颠倒两个变更集的顺序。可以确认git log --oneline -5这将输出最新的。

在这一点上,您可以对最近的提交进行软重置,并保存您的工作更改:

git reset --soft HEAD~1
git stash

值得一提的是,只有当您之前没有将这些更改中的任何一项推送到远程设备时,此选项才真正可行,否则可能会对使用存储库的每个人造成问题。


10

如果是我,我将避免进行任何危险的修订编辑,而执行以下操作:

  1. 在提交了222的SHA上创建一个新分支,基本上将其作为书签。

  2. 切换回主分支。在其中,还原提交222。

  3. 推送所有已提交的提交,这将仅推送提交111,因为222已还原。

  4. 如果需要,请从步骤1开始在分支上工作。根据需要从主干合并到主干,以使其保持最新状态。我不会为隐藏而烦恼。

当需要提交222中的更改时,可以将该分支合并到中继。


1
你救我!我正要弄乱一切@twasbrilling
Math-O5

如果只有很短的时间,还有一种更简单的方法:保存提交的哈希,还原提交,完成工作,然后再次选择它。由于gits宽大处理,删除的悬空提交仍会保留一段时间(大约30天甚至90天)。
Xerus

3

另一种解决方案是使用隐藏项:

之前:

~/dev/gitpro $git stash list

~/dev/gitpro $git log --oneline -3

* 7049dd5 (HEAD -> master) c111
* 3f1fa3d c222
* 0a0f6c4 c333
  1. git reset head〜1 <---将头移回c222; 工作仍然包含c111更改
  2. git stash push -m“提交111” <-暂存/工作(包含c111更改);分期/工作回滚到修订的标头(包含c222更改)
  3. git reset head〜1 <---头移回c333; 工作仍然包含c222更改
  4. git stash push -m“ commit 222” <-暂存/工作(包含c222更改)分期/工作回滚到修订的标头(包含c333更改)
  5. git stash pop stash @ {1} <---已删除c111更改的最旧的stash条目,并应用于登台/工作
  6. git commit -am“ commit 111” <-具有c111的更改的新提交成为新的头部

注意如果不指定stash @ {1}条目,则无法运行“ git stash pop”。该存储是LIFO堆栈-而不是FIFO-因此会错误地弹出带有c222更改的stash @ {0}条目(而不是带有c111更改的stash @ {1})。

请注意,如果提交111和222之间存在冲突的块,那么在尝试弹出时将被迫解决它们。(如果您还选择了替代性的变基解决方案,就会是这种情况。)

后:

~/dev/gitpro $git stash list

stash@{0}: On master: c222

~/dev/gitpro $git log -2 --oneline

* edbd9e8 (HEAD -> master) c111
* 0a0f6c4 c333

1

对我有用

  1. 作为当前分支起源的提交检出。
  2. 从该提交创建新分支。
  3. 结帐到新分支。
  4. 将分支与代码合并以存储在新分支中。
  5. 在新分支中进行软重置。
  6. 隐藏您的目标代码。
  7. 删除新分支。

我建议为此使用诸如SourceTree之类的东西。


0

我解决了这个问题:

删除目标提交

git revert-策略解析222

将提交222保存到补丁文件

git diff HEAD〜2 HEAD〜1> 222.补丁

套用此补丁

补丁-p1 <222.patch

推藏起来

git stash

删除临时文件

rm -f 222.patch

我认为非常简单的策略

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.