git 如何隐藏我之前的提交?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/26884364/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to stash my previous commit?
提问by Developer87
I've got the following situation on my git log
:
我有以下情况git log
:
commit 111 <-- need to push it to the repository
commit 222 <-- need to stash this one
...
As you can see, I need to push only last (without previous) commit to repository.
如您所见,我只需要将最后(没有先前)提交推送到存储库。
How can I do it? git revert --soft commit_hash
will help me?
我该怎么做?git revert --soft commit_hash
会帮助我吗?
回答by rmorrin
If you've not pushed either commit to your remote repository, you could use interactive rebasing to 'reorder' your commits and stash the (new) most recent commit's changes only.
如果您尚未将任一提交推送到远程存储库,则可以使用交互式变基来“重新排序”您的提交并仅存储(新的)最近提交的更改。
Assuming you have the tip of your current branch (commit 111 in your example) checked out, execute the following:
假设您已检出当前分支的提示(在您的示例中为 commit 111),请执行以下操作:
git rebase -i HEAD~2
This will open your default editor, listing most recent 2 commits and provide you with some instructions. Be very cautious as to what you do here, as you are going to effectively 'rewrite' the history of your repository, and can potentially lose work if you aren't careful (make a backup of the whole repository first if necessary). I've estimated commit hashes/titles below for example
这将打开您的默认编辑器,列出最近的 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
Reorder the two commits (they are listed oldest => newest) like this:
像这样重新排序两个提交(它们被列为最旧 => 最新):
pick 111 commit to be pushed to remote
pick 222 commit to be stashed
Save and exit, at which point git will do some processing to rewrite the two commits you have changed. Assuming no issues, you should have reversed the order of your two changesets. This can be confirmed with git log --pretty=oneline -5
which will output newest-first.
保存并退出,此时 git 将进行一些处理以重写您更改的两个提交。假设没有问题,您应该颠倒两个变更集的顺序。这可以通过git log --pretty=oneline -5
哪个将输出最新的来确认。
At this point, you can simply do a soft-reset on the most recent commit, and stash your working changes:
此时,您可以简单地对最近的提交进行软重置,并隐藏您的工作更改:
git reset --soft HEAD~1
git stash
It's important to mention that this option is only really viable if you have not previously pushed any of these changes to your remote, otherwise it can cause issues for everyone using the repository.
值得一提的是,此选项仅在您之前未将任何这些更改推送到远程时才真正可行,否则它可能会给使用存储库的每个人带来问题。
回答by twasbrillig
If it were me, I would avoid any risky revision editing and do the following instead:
如果是我,我会避免任何冒险的修订编辑,而是执行以下操作:
Create a new branch on the SHA where 222 was committed, basically as a bookmark.
Switch back to the main branch. In it, revert commit 222.
Push all the commits that have been made, which will push commit 111 only, because 222 was reverted.
Work on the branch from step #1 if needed. Merge from the trunk to it as needed to keep it up to date. I wouldn't bother with stash.
在提交 222 的 SHA 上创建一个新分支,基本上作为书签。
切换回主分支。在其中,还原提交 222。
推送所有已进行的提交,这将仅推送提交 111,因为 222 已还原。
如果需要,在第 1 步的分支上工作。根据需要从主干合并到它以使其保持最新状态。我不会为藏匿而烦恼。
When it's time for the changes in commit 222 to go in, that branch can be merged to trunk.
当提交 222 中的更改进入时,该分支可以合并到主干。
回答by Chris C.
An alternative solution uses the stash:
另一种解决方案使用 stash:
Before:
前:
~/dev/gitpro $git stash list
~/dev/gitpro $git log --oneline -3
* 7049dd5 (HEAD -> master) c111
* 3f1fa3d c222
* 0a0f6c4 c333
- git reset head~1<--- head shifted one back to c222; working still contains c111 changes
- git stash push -m "commit 111"<--- staging/working (containing c111 changes) stashed; staging/working rolled back to revised head (containing c222 changes)
- git reset head~1<--- head shifted one back to c333; working still contains c222 changes
- git stash push -m "commit 222"<--- staging/working (containing c222 changes) stashed; staging/working rolled back to revised head (containing c333 changes)
- git stash pop stash@{1}<--- oldest stash entry with c111 changes removed & applied to staging/working
- git commit -am "commit 111"<-- new commit with c111's changes becomes new head
- git reset head~1<--- head 移回 c222; 工作仍然包含 c111 更改
- git stash push -m "commit 111"<--- 暂存/工作(包含 c111 更改)藏匿;暂存/工作回滚到修订后的头部(包含 c222 更改)
- git reset head~1<--- head 移回 c333; 工作仍然包含 c222 更改
- git stash push -m "commit 222"<--- 暂存/工作(包含 c222 更改)藏匿;暂存/工作回滚到修订后的头部(包含 c333 更改)
- git stash pop stash@{1}<--- 删除了 c111 更改并应用于暂存/工作的最旧的存储条目
- git commit -am "commit 111"<-- 带有 c111 更改的新提交成为新的头
noteyou cannot run 'git stash pop' without specifying the stash@{1} entry. The stash is a LIFO stack -- not FIFO -- so that would incorrectly pop the stash@{0} entry with c222's changes (instead of stash@{1} with c111's changes).
请注意,您不能在不指定 stash@{1} 条目的情况下运行 'git stash pop'。stash 是一个 LIFO 堆栈——不是 FIFO——所以它会错误地弹出带有 c222 更改的 stash@{0} 条目(而不是带有 c111 更改的 stash@{1})。
noteif there are conflicting chunks between commits 111 and 222, then you'll be forced to resolve them when attempting to pop. (This would be the case if you went with an alternative rebase solution as well.)
请注意,如果提交 111 和 222 之间存在冲突块,那么您将在尝试弹出时被迫解决它们。(如果您也使用替代的 rebase 解决方案,就会出现这种情况。)
After:
后:
~/dev/gitpro $git stash list
stash@{0}: On master: c222
~/dev/gitpro $git log -2 --oneline
* edbd9e8 (HEAD -> master) c111
* 0a0f6c4 c333
回答by ukod
It's works for me;
它对我有用;
- Checkout on commit that is a origin of current branch.
- Create new branch from this commit.
- Checkout to new branch.
- Merge branch with code for stash in new branch.
- Make soft reset in new branch.
- Stash your target code.
- Remove new branch.
- 在提交时签出是当前分支的来源。
- 从此提交创建新分支。
- 结帐到新分支。
- 将分支与存储在新分支中的代码合并。
- 在新分支中进行软重置。
- 隐藏你的目标代码。
- 删除新分支。
I recommend use something like a SourceTree for this.
我建议为此使用类似 SourceTree 的东西。