4

Not sure what to Google for regarding this issue. The above should be my X question. My Y question is

How do you deal with a parent branch that is frequently rebased?

Let's say I have the following branches:

STACK-123 [origin/master: ahead 3]
STACK-456 [STACK-123: ahead 7]
STACK-789 [STACK-456: ahead 4]

Note that they also have this dependency chain

origin/master <- STACK-123 <- STACK-456 <- STACK-789

Essentially I want to treat all of them as a set of patches. But if any of them get rebased, the downstream branches still retain the old versions of the commits.

So let's say we have this list of commits:

STACK-123 (a, b, c, d) atop origin/master
STACK-456 (e, f, g) and implicitly (a, b, c, d) atop origin/master

If STACK-123 is rebased, we get:

STACK-123 (a', b', c', d') atop origin/master
STACK-456 (a, b, c, d, e, f, g) atop origin/master

Notice how STACK-456 keeps the old commits?

What workflow is there that just links the branch to a set of commits and doesn't encounter this problem after rebasing?

Short of manually repairing each branch.

(Also, well aware of the dangers of rebasing already-published commits, so please forego repeating. None of these branches are published/mainlined.)

Mark Canlas
  • 9,385
  • 5
  • 41
  • 63
  • Unless your collaborators have agreed to frequent rebasing, don't do this with a git branch, just keep a set of patches. If they *have* agreed, you may want to fuss with your fetch refspecs. If you want to keep patches inside the repo (on branches of their own) you could have independent root commits for them. That might be a bit weird but workable. I've never tried to do that. Also, consider [guilt](http://stackoverflow.com/questions/5016862/whats-the-git-approach-to-publish-a-patch-queue). – torek Jul 19 '13 at 22:55
  • This question is a bit like asking "I know my car requires diesel fuel, but how can I make it run well on gasoline?" – Cogwheel Jul 19 '13 at 22:56
  • @Cogwheel I disagree. It's not unreasonable to view features as sets of patches that may be dependent on other unreleased features. It would be nice to avoid the headache that merges seem to cause git novices short of saying "well they should learn how to merge properly". Keeping commit history straightforward via rebasing is worthwhile. – Mark Canlas Jul 19 '13 at 23:13
  • By 'headaches', are you referring to conflicts requiring manual resolution? Frequent rebasing will cause the same or more conflicts compared to a standard "immutable history" workflow with the added disadvantage that the original parent of the rebased commits is not recorded so it is impossible to distinguish errors caused by mis-merging as opposed to errors in original code. – CB Bailey Jul 19 '13 at 23:29
  • @CharlesBailey I don't understand what you are saying. An error in the code will either be in the parent or the feature branch. What ambiguity is there? – Mark Canlas Jul 19 '13 at 23:37
  • When you rebase a commit or sequence of commits you are left with a sequence of commits each of which only has one parent. Because the original parent of a rebased commit is not recorded it is not possible to distinguish the original change from the additional changes required by changing its parent. This is different from a merge commit where both parents are recorded allowing the merge to be recreated after the fact and the conflict resolution part of the change to be examined. – CB Bailey Jul 20 '13 at 00:00
  • What importance is there to know what part of the parent causes a change in the patch's implementation? If I have a feature patch that works in the 1.9 series of some parent software, and then that software gets upgraded to 2.0 and my patch no longer works, do you really care that the patch originated in 1.9? The patch should be rewritten to work in 2.0. Its relation to 1.9 is moot. – Mark Canlas Jul 20 '13 at 00:11
  • Sorry, you didn't @ me, so I didn't see this reply. If the rebase happened successfully then you don't care but I was guessing that 'merge headaches' referred to manual conflict resolutions (something that you have neither confirmed nor denied) so I was pointing out ways in which rebase is less desirable if your developers are (in general) less comfortable with merge resolution. – CB Bailey Jul 22 '13 at 14:00

3 Answers3

1

You should only rebase local branches before pushing them out to the world. Having a shared repo which is regularly being rebased is simply the wrong way to use Git.

(Also, well aware of the dangers of rebasing already-published commits, so please forego repeating.)

But it's the correct answer.

Rebasing rewrites history. The set of commits on a rebased branch is effectively unrelated to the set of commits on your local branches that haven't seen the rebase. Rebasing is basically a shortcut for doing a bunch of related cherry-picks.

Merging & branching are the way you should be sharing code with git. Rebasing is meant to clean up your local work before exposing it to the world.

Cogwheel
  • 22,781
  • 4
  • 49
  • 67
0

One solution I've been thinking about... Which I currently hate... Is to encode which commits really belong to the topic branch by encoding that into the commit messages (something JIRA-style developers do anyway).

STACK-123 (a', b', c', d') atop origin/master
STACK-456 (a, b, c, d, e*, f*, g*) atop origin/master

If commits e f g had some sort of marker (a string to grep for) in their commits, you could use a utility script (outside of git) to filter them out.

a [self] STACK-123 ... relics before rebase, will be filtered
b [self] STACK-123 ...
c [self] STACK-123 ...
d [self] STACK-123 ...
f [self] STACK-456 ... contains the string 'STACK-456', will be kept
g [self] STACK-456 ...
h [self] STACK-456 ...
Mark Canlas
  • 9,385
  • 5
  • 41
  • 63
0

Use topgit

This answer will be scant on details since I just found this and I'm having some trouble getting it to work... But it seems to pretty much be the exact answer to this type of workflow. It encodes the originating branch in metadata files stored in git. It has its own update command that Does The Right Thing in terms of updating descendant branches.

https://github.com/greenrd/topgit

Mark Canlas
  • 9,385
  • 5
  • 41
  • 63