git命令使得一个分支像另一个分支 [英] git command for making one branch like another

查看:125
本文介绍了git命令使得一个分支像另一个分支的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图让一个分支进行变更,并将其带回与其分离的上游相同。这些更改都是本地的,并且已经推送到github,所以 git reset 或者 git rebase 都是真正可行的,因为他们改变了历史,这对于一个已经被推送的分支来说是一件坏事。



我也试过 git merge 有不同的策略,但它们都不会撤消本地更改,即如果我添加了文件,合并可能会使其他文件重新排列,但我仍然会保留上游文件所没有的文件。 / p>

我可以在上游创建一个新的分支,但我真的很喜欢一个合并,根据修订历史记录应用所有更改以创建分支与上游再次相同,这样我就可以安全地推动这一变化而不会破坏历史。有没有这样一个命令或一系列命令?

解决方案

您可以将上游分支合并到 dev 分支,使用自定义合并驱动程序keepTheirs

请参阅 git merge -s theirs 需要 - 但我知道它不存在

在你的情况下,只需要一个 .gitattributes ,并且一个 keepTheirs 脚本如:

  mv -f $ 3 $ 2 
exit 0






git merge - strategy = theirs 模拟#1



显示为合并,上游为第一个父级。



Jefromi 提及(在评论中)合并 - 我们的,合并您的工作在上游(或从上游开始的临时分支上),然后将分支快速转发到该合并的结果:

  git checkout -b tmp origin / upstream 
git merge -s我们的下游#忽略下游的所有更改
git checkout downstream
git merge tmp#fast-forward to tmp HEAD
git branch -D tmp#删除tmp




这有利于记录上游祖先作为第一个父母,因此合并意味着吸收这个过时的主题分支,而不是销毁此主题分支并将其替换为上游。

b

(编辑2011):

这个工作流程已经在博客文章


为什么我要再次购买?



只要我的回购与公开版无关,这一切都很好,但是现在我希望能够与其他团队成员和外部贡献者合作在WIP上,我希望确保我的公共分支机构可靠地让其他人分支并从中撤出,也就是说,不再需要重新分配和重置我已经推送到远程备份的事物,因为它现在在GitHub上并且是公开的。



因此,我应该如何继续下去。

99%的时间我的副本将进入上游主人,所以我想工作我的主人并推入上游最的时间。

但是每过一段时间,我在 wip 中的内容都会被上游的内容取消,我将放弃某些内容我的 wip

此时我想让我的主人与上游同步,但不会破坏我的任何提交点公开推动主人。即我想要一个与上游合并,最终与变更集,使我的副本与上游相同

这就是 git merge --strategy = theirs 应该这样做。







git merge - -strategy = theirs 模拟#2



显示为合并,以我们的第一个父项为



(由 jcwenger 提议)

  git checkout -b tmp上游
git merge -s我们thebranch#忽略下游的所有更改
git checkout downstream
git合并--squash tmp#从tmp应用更改,但不作为合并。
git rev-parse upstream> .git / MERGE_HEAD #record上游第二个合并头
git commit -m将上游分支重定位#进行提交。
git分支-D tmp#删除tmp






< h2> git merge --strategy = theirs 模拟#3

博客文章提及

  git merge -s我们的ref-to-be-merged 
git diff --binary ref-to-be-merged | git apply -R --index
git commit -F .git / COMMIT_EDITMSG --amend




有时您确实希望这样做,而不是因为您的历史记录中存在垃圾,但可能是因为您希望在公共存储库中更改开发基准,避免







git merge - 战略=他们的模拟#4



(相同的博文)


或者,如果您想保持本地上游分支可快速转发,潜在的折中方案是在理解sid / unstable时,上游分支可以不时重置/重新分配(基于最终不受上游项目方面控制的事件)。

这不是什么大不了的事情,并且与这个假设一起工作意味着保持本地上游分支仅处于它的状态很容易需要fa



  git branch -m上游不稳定上游不稳定保存
git分支上游不稳定上游远程/主
git合并-s我们的上游 - 不稳定
git diff --binary ref-to-merged | git apply -R --index --exclude =debian / *
git commit -F .git / COMMIT_EDITMSG --amend






git merge --strategy = theirs 模拟#5



(由 Barak A. Pearlmutter 提议) :

  git checkout MINE 
git merge --no-commit -s我们的HERS
git rm - rf。
git checkout HERS - 。
git checkout MINE - debian#或其他适当的
git gui#edit commit message&点击提交按钮






git merge --strategy = theirs 模拟#6



(由相同的 Michael Gebetsroither ):


Michael Gebetsroither插话说道,声称我是作弊;),并给出了另一个解决方案,使用低级管道命令:

(如果git不可能的话, )



 <$ c只有命令,所有在git中的diff / patch / apply都不是真正的解决方案。 $ c>#获取另一个分支的内容
git read-tree -u --reset< ID>
#选择性地合并子目录
#例如从另一个分支中取代上游源
git合并-s我们的--no-commit other_upstream
git读取树--reset -u other_upstream#或使用--prefix = foo /
git checkout HEAD - debian /
git checkout HEAD - .gitignore
git commit -m'取代上游来源'-a


I'm trying to take a branch with changes and bring it back to be identical to the upstream it diverged from. The changes are both local and have been pushed to github, so neither git reset or git rebase are really viable, since they change history, which is a bad thing with a branch that's already been pushed.

I've also tried git merge with various strategies but none of them undo the local changes, i.e. if I'd added a file, a merge might bring other files back in line, but I'll still have that file that the upstream doesn't have.

I could just create a new branch off the upstream, but i'd really like a merge that in terms of revision history applies all the changes to take my branch and make it identical to the upstream again, so that I can safely push that change without clobbering history. Is there such a command or series of commands?

解决方案

You could merge your upstream branch to your dev branch, with a custom merge driver "keepTheirs":
See ""git merge -s theirs" needed — but I know it doesn't exist".
In your case, only one .gitattributes would be required, and a keepTheirs script like:

mv -f $3 $2
exit 0


git merge --strategy=theirs Simulation #1

Shows as a merge, with upstream as the first parent.

Jefromi mentions (in the comments) the merge -s ours, by merging your work on the upstream (or on a temp branch starting from upstream), and then fast-forwarding your branch to the result of that merge:

git checkout -b tmp origin/upstream
git merge -s ours downstream         # ignoring all changes from downstream
git checkout downstream
git merge tmp                        # fast-forward to tmp HEAD
git branch -D tmp                    # deleting tmp

This has the benefit of recording the upstream ancestor as the first parent, so that the merge means "absorb this out-of-date topic branch" rather than "destroy this topic branch and replace it with upstream".

(Edit 2011):

This workflow has been reported in this blog post by the OP:

Why do I want this again?

As long as my repo had nothing to do with the public version, this was all fine, but since now I'd want the ability to collorate on WIP with other team members and outside contributors, I want to make sure that my public branches are reliable for others to branch off and pull from, i.e. no more rebase and reset on things I've pushed to the remote backup, since it's now on GitHub and public.

So that leaves me with how I should proceed.
99% of the time my copy will go into the upstream master, so I want to work my master and push into upstream most of the time.
But every once in a while, what I have in wip will get invalidated by what goes into upstream and I will abandon some part of my wip.
At that point I want to bring my master back in sync with upstream, but not destroy any commit points on my publicly pushed master. I.e. i want a merge with upstream that ends up with the changeset that make my copy identical to upstream.
And that's what git merge --strategy=theirs should do.


git merge --strategy=theirs Simulation #2

Shows as a merge, with ours as the first parent.

(proposed by jcwenger)

git checkout -b tmp upstream
git merge -s ours thebranch         # ignoring all changes from downstream
git checkout downstream
git merge --squash tmp               # apply changes from tmp but not as merge.
git rev-parse upstream > .git/MERGE_HEAD #record upstream 2nd merge head
git commit -m "rebaselined thebranch from upstream" # make the commit.
git branch -D tmp                    # deleting tmp


git merge --strategy=theirs Simulation #3

This blog post mentions:

git merge -s ours ref-to-be-merged
git diff --binary ref-to-be-merged | git apply -R --index
git commit -F .git/COMMIT_EDITMSG --amend

sometimes you do want to do this, and not because you have "crap" in your history, but perhaps because you want to change the baseline for development in a public repository where rebasing should be avoided.


git merge --strategy=theirs Simulation #4

(same blog post)

Alternatively, if you want to keep the local upstream branches fast-forwardable, a potential compromise is to work with the understanding that for sid/unstable, the upstream branch can from time to time be reset/rebased (based on events that are ultimately out of your control on the upstream project's side).
This isn't a big deal and working with that assumption means that it's easy to keep the local upstream branch in a state where it only takes fast-forward updates.

git branch -m upstream-unstable upstream-unstable-save
git branch upstream-unstable upstream-remote/master
git merge -s ours upstream-unstable
git diff --binary ref-to-be-merged | git apply -R --index --exclude="debian/*"
git commit -F .git/COMMIT_EDITMSG --amend


git merge --strategy=theirs Simulation #5

(proposed by Barak A. Pearlmutter):

git checkout MINE
git merge --no-commit -s ours HERS
git rm -rf .
git checkout HERS -- .
git checkout MINE -- debian # or whatever, as appropriate
git gui # edit commit message & click commit button


git merge --strategy=theirs Simulation #6

(proposed by the same Michael Gebetsroither):

Michael Gebetsroither chimed in, claiming I was "cheating" ;) and gave another solution with lower-level plumbing commands:

(it wouldn't be git if it wouldn't be possible with git only commands, everything in git with diff/patch/apply isn't a real solution ;).

# get the contents of another branch
git read-tree -u --reset <ID>
# selectivly merge subdirectories
# e.g superseed upstream source with that from another branch
git merge -s ours --no-commit other_upstream
git read-tree --reset -u other_upstream     # or use --prefix=foo/
git checkout HEAD -- debian/
git checkout HEAD -- .gitignore
git commit -m 'superseed upstream source' -a

这篇关于git命令使得一个分支像另一个分支的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆