How to achieve a private branch in git that “floats” when merging with upstream?

左心房为你撑大大i 提交于 2019-12-12 20:26:31

问题


I have a fork of another organization's repository. I'm at the the latest tag in the repo, which is not the head, and I've created a branch from that tag which will never be pushed upstream. That's why I consider the branch private.

I've made commits to my private branch and am using that code in my production environment. When a new tag is made to the upstream repository, I want to be able to pull their changes.

However, I'd like to always keep my commits in a neat stack on top of their last tag. I don't want to merge then, since my commits will end up living far back in the history and I want to see them right on top so I can work with them easily when I use certain tools on my repository.

So really, I want a "floating" branch, one that I can transplant to an arbitrary point when I bring the upstream changes to my repository.

[edits] I don't believe I can use rebase, however, since that's a history-rewriting operation. You see, I use my repository on two machines, my development and production. I make my commits on the development machine, push to github, then pull to production. All of this has nothing to do with the changes on the upstream repository that I originally forked from.

I'm not entirely clear on transplanting, cherry-picking or whatever other tool might be suited. Whichever tool it is though, I gather it shouldn't rewrite history. From my reading, I see that rewriting repo history is a no-no when pushing . So I'm not sure what commands I should be using that will transplant a branch without rewriting history.

If I were using mercurial, I might consider something like a version-controlled mq. I don't know the analogous solution for git, if there is one, or whether there is another, better-suited tool for git.

[edit]

After evaluating the responses I got here, I finally determined that cherry-picking was the right answer. In all cases, rebase removes history, and since this is a shared repository, removing history is unacceptable, at least according to every source I've read.

Cherry-picking, however, copies the commit to my working tree without removing it from its original location. So I can plant a copy of my changes on top of the latest tag and have them in a nice neat pile.

For the record, I also tried to do this with Mercurial, by using the hg-git extension which lets you use hg to clone a git repository. This had pluses and minuses. The biggest minus was that when I finished using it, it couldn't push. hg-git works happily until that point, then tells you that it doesn't push with hg 1.9. Bogus, to say the least. The other minus was that cloning and pulling a large set of changes is extremely slow. However, mq and TortoiseHg's merge conflict resolution tools are a vast improvement over git cherry-pick and Smartgit's merge conflict resolution. I wish hg-git could have worked.

I guess that in the end, "floating" wasn't such a good description for my change branch, since the result is to copy it rather than move it. Sorry for my perhaps poor description, I was still figuring out exactly what the options were. Thanks for the help.


回答1:


git fetch
git rebase --onto latesttag previoustag yourbranch

Conflicts have to be dealt with and entirely depend on what you are doing with files that may have changed from one tag to the next. In particular, if someone has eliminated some code that you change, you will have to address this and make sure that the code you changed can now be applied elsewhere. There is no silver bullet for this. Once you resolved your conflicts and everything works,

git add -A
git rebase --continue

Rinse repeat.

To add, if you are doing this to just be able to deploy, a "floating branch" may not be the best method for dealing with this. Consider these alternates:

  1. deploy scripts that manipulate the files to ensure the deploy works.
  2. smudge/clean scripts that modify files when populating the working directory. (https://git-scm.com/book/en/v2/Customizing-Git-Git-Attributes#_keyword_expansion)

Your floating branch seems like it is there only for the sake of your own environment and hence should not be part of the project.




回答2:


You describe the job of git rebase --onto here.

Scenario:

  • git fetch from the remote;
  • by security, make a new copy: git branch newbranch currentbranch;
  • say the old tag, which you are currently based on, is oldtag, and the new tag is newtag;
  • "transplant": git rebase --onto newtag oldtag newbranch;
  • resolve conflicts if need be;
  • git branch -D currentbranch;
  • git branch -m newbranch currentbranch.

However, as to rewriting history, you will -- of your branch, not of the origin repository, you don't have write access to it, do you?



来源:https://stackoverflow.com/questions/8660883/how-to-achieve-a-private-branch-in-git-that-floats-when-merging-with-upstream

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!