合并后的 Git 壁球历史
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14043961/
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
Git squash history after merge
提问by E-rich
I merged an upstream of a large project with my local git repo. Prior to the merge I had a small amount of history that was easy to read through, but after the merge a massive amount of history is now in my repo. I have no need for all the history commits from the upstream repo.
我将一个大型项目的上游与我的本地 git 存储库合并。在合并之前,我有少量易于阅读的历史记录,但是在合并之后,大量历史记录现在在我的仓库中。我不需要上游 repo 的所有历史提交。
There have been other commits made after this upstream merge that I would like to keep. How do I squash all that history that was merged from the upstream into one commit while keeping the commits made after the upstream merge?
在这次上游合并之后,我还想保留其他提交。我如何压缩从上游合并到一个提交的所有历史记录,同时保留上游合并后的提交?
采纳答案by E-rich
The solution I ended up using was to manually recreate the history. I did this mainly because I didn't want to spend too much time looking for an elegant solution and there wasn't that much history (around 30 commits I'd have to manually merge).
我最终使用的解决方案是手动重新创建历史记录。我这样做主要是因为我不想花太多时间寻找一个优雅的解决方案,而且没有太多的历史记录(我必须手动合并大约 30 个提交)。
So, I created a branch before I merged the huge upstream:
所以,我在合并巨大的上游之前创建了一个分支:
git checkout -b remove-history-fix <commit ID before merge>
Then re-merged the upstream using the --squash
option.
然后使用该--squash
选项重新合并上游。
git merge --squash <upstream tag>
Then manually cherry-picked the commits after the merge from the old branch (the one with the huge amount of upstream history).
然后从旧分支(具有大量上游历史记录的分支)合并后手动挑选提交。
git cherry-pick <commit ID>
After all those commits were merged into my remove-history-fixbranch, I removed the branch with the upstream history.
在所有这些提交合并到我的remove-history-fix分支后,我删除了带有上游历史记录的分支。
git branch -D <upstream-history-branch>
回答by ams
I was able to squash several commits after multiple merges from the master branch using the strategy found here: https://stackoverflow.com/a/17141512/1388104
在使用此处找到的策略从主分支进行多次合并后,我能够压缩多次提交:https: //stackoverflow.com/a/17141512/1388104
git checkout my-branch # The branch you want to squash
git branch -m my-branch-old # Change the name to something old
git checkout master # Checkout the master branch
git checkout -b my-branch # Create a new branch
git merge --squash my-branch-old # Get all the changes from your old branch
git commit # Create one new commit
You will have to force an update if you need to push your squashed branch to a remote repository that you have previously pushed to, e.g. git push origin my-branch -f
如果您需要将压扁的分支推送到之前推送到的远程存储库,则必须强制更新,例如 git push origin my-branch -f
回答by John O'M.
A couple of options for you:
几个选项供您选择:
Limit Logging
限制记录
Not exactly what you asked for, but possibly a good alternative, and a lot easier. This allows you to use git like normal, but hides all the stuff you don't want to see (assuming the issue is the history cluttering up your log and not the raw storage space. I think squashing the merge in your branch won't prevent git from including all the commits from upstream if you fetched the upstream for the merge action in the first place.).
不完全是您所要求的,但可能是一个不错的选择,而且要容易得多。这允许您像往常一样使用 git,但隐藏了您不想看到的所有内容(假设问题是历史记录混乱了您的日志而不是原始存储空间。我认为在您的分支中压缩合并不会如果您首先为合并操作获取上游,请防止 git 包含来自上游的所有提交。)。
In this case, you would do a normal merge, but when logging you would add --first-parent
to the command.
在这种情况下,您将执行正常合并,但在记录时将添加--first-parent
到命令中。
For example, without the option I might have (assume "sample more" 1 to 3 was actually a lot more commits)
例如,如果没有我可能有的选项(假设“更多采样”1 到 3 实际上是更多的提交)
$ git log --oneline
0e151bf Merge remote-tracking branch 'origin/master' into nosquash
f578cbb sample more 3
7bc88cf sample more 2
682b412 sample more 1
fc6e1b3 Merge remote-tracking branch 'origin/master'
29ed293 More stuff
9577f30 my local change
018cb03 Another commit
a5166b1 Initial
But, if I add --first-parent
it cleans up to this:
但是,如果我添加--first-parent
它会清理这个:
$ git log --oneline --first-parent
0e151bf Merge remote-tracking branch 'origin/master'
fc6e1b3 Merge remote-tracking branch 'origin/master'
9577f30 my local change
018cb03 Another commit
a5166b1 Initial
Notice all of the commits from the master after I branched ("my local change" being my divergent commit) are gone. Only commits I made show up, including when I merged. If I had used better commit messages during the merge, I might even know what the batch of changes were.
请注意,在我分支之后,来自 master 的所有提交(“我的本地更改”是我的发散提交)都消失了。只显示我所做的提交,包括我合并时的提交。如果我在合并期间使用了更好的提交消息,我什至可能知道这批更改是什么。
Replace History
替换历史记录
This is for what you asked.
这是你问的。
Taking inspiration from https://git-scm.com/book/en/v2/Git-Tools-Replace
从https://git-scm.com/book/en/v2/Git-Tools-Replace 获取灵感
What we'll do here is squash the remote's history, replace their history with our squashed version from our perspective, and merge the squashed version.
我们在这里要做的是压缩遥控器的历史,从我们的角度用压缩版本替换它们的历史,然后合并压缩版本。
In my example repository, the revisions that upstream added which I hadn't merged yet were 682b412 "sample more 1" to origin/master (f578cbb "sample more 3") (although not that long for this example, pretend there are 50 commits or whatever in between).
在我的示例存储库中,上游添加的但我尚未合并的修订版是 682b412 "sample more 1" to origin/master (f578cbb "sample more 3")(虽然对于这个例子来说不是那么长,假设有 50 个提交或介于两者之间)。
The first thing I want is a local branch of the remote side:
我想要的第一件事是远程端的本地分支:
git checkout -b squashing origin/master
Next, I want to quickly squash it
接下来,我想快速压扁它
git reset --soft 682b412~
git commit -m "Squashed upstream"
Note the tilde ~
character. That causes our branch to be at the parent of the first commit in the range we want to squash, and because we specified --soft
, our index is still at the last commit in the range we want to squash. The commit line results in a single commit that consists of what was our first through last, inclusive.
注意波浪号~
字符。这导致我们的分支位于我们想要压缩的范围内第一个提交的父级,并且因为我们指定了--soft
,我们的索引仍然在我们想要压缩的范围内的最后一个提交。提交行导致单个提交,其中包含我们的第一个到最后一个,包括在内。
At this point, the origin/master and squashing branches have identical tree contents but different histories.
此时,origin/master 和 squashing 分支具有相同的树内容但不同的历史记录。
Now, we tell git that when it sees references to the original commit of origin/master, to use our squashed commit instead. Using git log
I can see the new "Squashed upstream" commit is 1f0bc14, so we do:
现在,我们告诉 git,当它看到对 origin/master 的原始提交的引用时,改用我们的压缩提交。使用git log
我可以看到新的“Squashed upstream”提交是 1f0bc14,所以我们这样做:
git replace f578cbb 1f0bc14
From here on, your git will use the "squashed upstream" commit.
从这里开始,您的 git 将使用“压缩的上游”提交。
Back on our original branch (if it was "master")
回到我们原来的分支(如果它是“master”)
git checkout master
git merge f578cbb
This appears to merge the origin master (f578cbb), actually gets 1f0bc14's contents, but logs it as having a parent SHA1 of f578cbb
这似乎合并了原始主 (f578cbb),实际上获取了 1f0bc14 的内容,但将其记录为具有 f578cbb 的父 SHA1
We no longer need the squashing branch, so you can get rid of it.
我们不再需要挤压分支,所以你可以摆脱它。
Now, let's say upstream added more features. In this simple example, on upstream's repo, a log might show this:
现在,假设上游添加了更多功能。在这个简单的例子中,在上游的 repo 上,日志可能会显示:
84f5044 new feature
f578cbb sample more 3
7bc88cf sample more 2
682b412 sample more 1
29ed293 More stuff
018cb03 Another commit
a5166b1 Initia
After we fetch upstream though, if we look at its log from our repo, we see this instead:
在我们获取上游之后,如果我们从我们的 repo 中查看它的日志,我们会看到这个:
84f5044 new feature
f578cbb squashed upstream
29ed293 More stuff
018cb03 Another commit
a5166b1 Initial
Note how it appears to have squashed history to us as well, and more importantly, the squashed upstream SHA1 is showing the one used in upstream's history (for them it is really the "sample more 3" commit).
请注意它对我们来说似乎也压缩了历史,更重要的是,压缩的上游 SHA1 显示了上游历史中使用的那个(对他们来说,它实际上是“样本更多 3”提交)。
So, merging continues to work like normal
因此,合并继续正常工作
git merge origin/master
But we don't have such a cluttered log:
但是我们没有这么杂乱的日志:
4a9b5b7 Merge remote-tracking branch 'origin/master' for new feature
46843b5 Merge remote-tracking branch 'origin/master'
84f5044 new feature
f578cbb squashed upstream
fc6e1b3 Merge remote-tracking branch 'origin/master'
29ed293 More stuff
9577f30 my local change
018cb03 Another commit
a5166b1 Initial
If the "new feature" commit in upstream was similarly a large number of commits, we could repeat this process to squash that down as well.
如果上游的“新功能”提交同样是大量提交,我们也可以重复此过程以将其压缩。
回答by Femaref
There is no way to do it, as you won't be able to push back or merge again with that remote repository or any other of that same project. When squashing, you are changing history, resulting in different sha1-hashes between your repository and the remote one.
没有办法做到这一点,因为您将无法再次推回或与该远程存储库或任何其他同一项目合并。压缩时,您正在更改历史记录,从而导致您的存储库和远程存储库之间的 sha1 哈希值不同。
You'll have to live with the large history.
你将不得不忍受庞大的历史。