How do I fast foward branches without switching to them?

时光总嘲笑我的痴心妄想 提交于 2019-12-11 01:28:38

问题


I currently am on my master branch, and my stage is dirty. I don't want to commit and I already have too many stashes to stash my changes (or am I too lazy ?).

I would like to move fast foward some branches without switching to them (remember, my stage is dirty).

How could I fastfoward optim to mobile ? or optim to master (my current branch) ?

image: http://i.stack.imgur.com/WUPeq.png


回答1:


Note: a branch name is merely a pointer to a (single) commit. The thing we tend to think of as "the branch"—the whole chain of commits—is found by working from each commit backwards to its parent(s). The parents are recorded only in the commits themselves, not in any branch names. It may help to think of branch names as sticky-notes that are pasted on to some particular commit. I can't draw that in text so I draw it below as an arrow (<--) instead.

Translating your image to text, rotating it, making an assumption or two, and truncating a bit to fit nicely in this answer, you're showing:

                                        o...
                                       /
--o--M--o--o--o--o--o--o--o--o--o--o--o    <-- mobile
    /
---o                                       <-- optim, origin/optim

(Here "newer" stuff is towards the right, instead of above, and the text of the various commit messages is omitted.)

A "fast forward" occurs when:1

  • you are "on a branch", i.e., HEAD is a symbolic reference to a branch name
  • you ask git to merge with another commit (by name or SHA1 ID; usually by branch-name)
  • and, the "merge with" commit is "straight ahead" of where the branch is now, i.e., it's possible to simply slide the branch name along some set of "descendent" links to get there. (More precisely, the HEAD commit is an ancestor of the "to-be-merged" commit.)

Since optim points to a commit whose single descendent is the merge commit M, and that commit has one descendent for each little o to the right, git can slide the branch name optim forward along that chain of commits.

Hence:

$ git checkout optim; git merge mobile

would slide the label up-and-right to M, then further right to where mobile points, giving:

                                        o...
                                       /
--o--M--o--o--o--o--o--o--o--o--o--o--o    <-- mobile, optim
    /
---o                                       <-- origin/optim

If you want to do that "manually", without doing anything else and without even being "on" that branch, you can just tell git "please re-point the branch name optim to target the same commit as the name mobile:

$ git branch -f optim mobile

The -f (or --force) flag says to go ahead and change an existing label's target-commit, rather than erroring out.

This command does not check that the operation is a fast-forward. (Of course plain git merge only checks for that to decide whether to do a fast-forward merge, or a "real" merge. However, you can ask git merge to do --ff-only, i.e., error out if the operation is not a fast-forward.)


1Fetch and push also apply the same kind of "fast forward" notion, so this is "when" but not "only when".




回答2:


Use git push . mobile:optim (yes, that's a dot) to fast-forward optim to mobile.



来源:https://stackoverflow.com/questions/19712998/how-do-i-fast-foward-branches-without-switching-to-them

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