Re: Sanity Check: scrum teams, shared 'story branches', rebasing shared branches
On Sat, 9 Jun 2012 16:51:28 -0700, Christofer Jennings wrote:
Show 15 quoted lines
> I've been using Git and GitHub for ~6 months. Working on a SCM plan
> for a Scrum project with 50+ developers in ~8 dev. teams. Each team
> will be working on one or two stories simultaneously, so expect ~16
> 'story branches' (and master) at any given time. We've got GitHub
> Enterprise and are working out how to manage story development on
> shared branches that get merged to master only after going through
> acceptance & peer review. We hope stories will only be 3 - 5 days to
> complete, but may take 2 weeks. We're promoting frequent pushes to
> story branches.
>
> After a number of experiments and doing online research, we're
> thinking to use rebase to keep the story branches up-to-date with
> master while the story branches are in development. This seems to be
> the best approach because it will allow us to use bisect to isolate
> issues, and it will give us the most linear history graph.
You can use bisect to isolate issues regardless of merges. Also, linear histories are not always better histories; for one, merge commits can usefully encode the way that something was actually developed.
Show 11 quoted lines
> So, here's my question: Can we use "rebase -s recursive -Xtheirs" as
> shown below?
>
> In this experiment, we're on 'story' branch 's1'. It's behind master
> because another story has been merged to master. We need to rebase
> to master and then rebase to origin/s1 to be up-to-date. So we...
>
> git fetch -v
> git rebase origin/master
> ... resolve stuff ...
> git rebase -s recursive -Xtheirs origin/s1
Let's expand that a bit for the sake of discussion:
git fetch -v
git branch -f s1_0 # Additional line
git rebase origin/master
... resolve stuff ...
git branch -f s1_1 # Additional line
git rebase -s recursive -Xtheirs origin/s1
So:
* The first rebase applies all the commits in `origin/master..s1_0'
on top of the commit to which `origin/master' points; the branch
heads `s1' and `s1_1' are then set to point to the youngest of
the resulting commits. * The second rebase applies all the commits in `origin/s1..s1_1'
on top of the commit to which `origin/s1' points; the branch
heads `s1' and `s1_2' are then set to point to the youngest of
the resulting commits.In that second rebase, the range:
origin/s1..s1_1
is equivalent to:
^origin/s1 s1_1
which is equivalent to:
^origin/s1 origin/master s1_1
because `origin/master' is reachable from `s1_1'. This in turn is equivalent to:
origin/s1..origin/master origin/s1..s1_1
In other words, the second rebase applies all the commits in `origin/s1..origin/master' (namely, possibly the commits from the other story) ON TOP of the commit pointed to by `origin/s1', which is probably not what you want; the code might be correct, but the history is probably not.
To see for yourself, try this small example:
$ git init origin; cd origin
$ echo 0 > a; git add a; git commit -m Initial
$ git branch s1
$ echo 1 > a; git commit -am 'Other Story'
$ cd ..; git clone origin local
$ cd origin; git checkout s1
$ echo 0 > b; git add b; git commit -m 'Shared s1 update'
$ cd ../local
$ git checkout -b s1 origin/s1
$ echo 0 > c; git add c; git commit -m 'Local s1 work'
$ git fetch
$ git rebase origin/master
$ git rebase origin/s1
First, rewinding head to replay your work on top of it...
Applying: Other Story
Applying: Local s1 work
$ git log --format=%s --graph
* Local s1 work
* Other Story
* Shared s1 update
* Initial
> The "-s recursive -Xtheirs" part seems to result in all the right code
> at the end. We only had to "git add && git rebase --continue" for
> deleted files.
Two points:
* I think it's dangerous to ignore any conflicts, let alone when mixing
code from multiple upstreams. * Be certain that you don't want -Xours. IIRC, during a rebase, the commits
that have already been placed in the new history (which includes the
upstream) are considered `ours' during a rebase.Basically, you need to define more strictly what "upstream" means in your project, and you need to be less afraid of merging, a fundamental process around which git was designed.
Sincerely, Michael Witten