threads / discuss / 30155

Linear history *and* share a branch?

Subject: Linear history *and* share a branch?

## tl;dr

7 messages between Apr 5, 2012 and Apr 10, 2012.

replies: 6people: 5as markdown or json

Hilco Wijbenga· Apr 5, 2012, 20:48 UTC · lore
Hi all,

We have been using Git for about a year now in a very small team. So far, everyone has worked on their own local branches and been doing "git rebase master" to make sure their local branches stay in synch. This way we have a nice linear history in master.

Recently, it has become useful to share one of these local branches between two devs. Of course, when one of the devs does his usual "git rebase master", he screws up the other dev's environment. Our solution has been to keep rebasing the shared branch but to actually work on a local branch that is rebased on the shared branch. By judiciously using "git reset" and "git pull" on the shared branch the two devs can keep the shared branch in synch and then use "git rebase shared-branch" on their local branch to keep it in synch to. While this works, there is probably a better/simpler solution.

Should we simply do "git merge master" instead of "git rebase master"? And then do something at the end when we are about to merge the shared branch back into master to guarantee linear history? Your thoughts and ideas would be greatly appreciated.

Cheers, Hilco

Ævar Arnfjörð Bjarmason· Apr 5, 2012, 20:56 UTC · re: Hilco Wijbenga · lore

Re: Linear history *and* share a branch?

On Thu, Apr 5, 2012 at 22:48, Hilco Wijbenga <hilco.wijbenga@gmail.com> wrote:
> Should we simply do "git merge master" instead of "git rebase master"?
> And then do something at the end when we are about to merge the shared
> branch back into master to guarantee linear history? Your thoughts and
> ideas would be greatly appreciated.

Yes, that's the most sensible workflow to have. You create a topic branch, push/pull it back and forth, do merge commits and never rebase it, then when you decide if it's finished you can either merge it into the mainline (with non-linear history), or have someone rebase it and push it to the mainline.

I use the latter workflow extensively in my work e.g. when peer programming. We'll both have the same branch set up as a tracking branch, make a bunch of WIP commits with crappy commit messages for a day or so, then at the end of the day interactively rebase the branch, and push it with linear history to the mainline.

Ævar Arnfjörð Bjarmason· Apr 6, 2012, 10:04 UTC · re: Ævar Arnfjörð Bjarmason · lore

Re: Linear history *and* share a branch?

On Thu, Apr 5, 2012 at 22:56, Ævar Arnfjörð Bjarmason <avarab@gmail.com> wrote:
Show 17 quoted lines
> On Thu, Apr 5, 2012 at 22:48, Hilco Wijbenga <hilco.wijbenga@gmail.com> wrote:
>> Should we simply do "git merge master" instead of "git rebase master"?
>> And then do something at the end when we are about to merge the shared
>> branch back into master to guarantee linear history? Your thoughts and
>> ideas would be greatly appreciated.
>
> Yes, that's the most sensible workflow to have. You create a topic
> branch, push/pull it back and forth, do merge commits and never rebase
> it, then when you decide if it's finished you can either merge it into
> the mainline (with non-linear history), or have someone rebase it and
> push it to the mainline.
>
> I use the latter workflow extensively in my work e.g. when peer
> programming. We'll both have the same branch set up as a tracking
> branch, make a bunch of WIP commits with crappy commit messages for a
> day or so, then at the end of the day interactively rebase the branch,
> and push it with linear history to the mainline.

To elaborate, this is how to do the workflow I'm talking about, with a git set to push.default=tracking.

The person setting up the topic branch does this, "origin" is our shared upstream server. This creates a new topic and pushes it:

    git checkout -b team-whatever/some-topic
    git push origin -u team-whatever/some-topic
Everyone else does this:
    git fetch origin
    git checkout -t team-whatever/some-topic

Then everyone hacks, and does a "git pull --no-rebase && git push" to push work. When you're pair programming and switching between computers this'll often be:

    git commit -a -m"wip"
    git push
Followed by, on the other box:
    git pull --no-rebase

Then when the topic is ready and you want to push it to the mainline someone does:

    git fetch origin
    git rebase -i origin/master
and rewords/squashes/fixes up the various commits, followed by:
    # Now fixed up, push to the mainline
    git push origin team-whatever/some-topic:master
    # Nuke the now-redundant topic branch
    git push origin --delete team-whatever/some-topic
Junio C Hamano· Apr 5, 2012, 21:06 UTC · re: Hilco Wijbenga · lore

Re: Linear history *and* share a branch?

Hilco Wijbenga <hilco.wijbenga@gmail.com> writes:
Show 18 quoted lines
> Hi all,
>
> We have been using Git for about a year now in a very small team. So
> far, everyone has worked on their own local branches and been doing
> "git rebase master" to make sure their local branches stay in synch.
> This way we have a nice linear history in master.
>
> Recently, it has become useful to share one of these local branches
> between two devs. Of course, when one of the devs does his usual "git
> rebase master", he screws up the other dev's environment. Our solution
> has been to keep rebasing the shared branch but to actually work on a
> local branch that is rebased on the shared branch. By judiciously
> using "git reset" and "git pull" on the shared branch the two devs can
> keep the shared branch in synch and then use "git rebase
> shared-branch" on their local branch to keep it in synch to. While
> this works, there is probably a better/simpler solution.
>
> Should we simply do "git merge master" instead of "git rebase master"?
That certainly is a sensible thing to do.

But if your people are used to rebasing their own 'master' on top of shared 'master', I would imagine that it wouldn't be hard at all for these two people that work on a topic branch to do the same for their 'topic' branch, no? Just like rebasing their 'master' on shared 'master', they would rebase their own 'topic' on shared 'topic'.

Hilco Wijbenga· Apr 5, 2012, 21:57 UTC · re: Junio C Hamano · lore

Re: Linear history *and* share a branch?

On 5 April 2012 14:06, Junio C Hamano <gitster@pobox.com> wrote:
Show 27 quoted lines
> Hilco Wijbenga <hilco.wijbenga@gmail.com> writes:
>> Hi all,
>>
>> We have been using Git for about a year now in a very small team. So
>> far, everyone has worked on their own local branches and been doing
>> "git rebase master" to make sure their local branches stay in synch.
>> This way we have a nice linear history in master.
>>
>> Recently, it has become useful to share one of these local branches
>> between two devs. Of course, when one of the devs does his usual "git
>> rebase master", he screws up the other dev's environment. Our solution
>> has been to keep rebasing the shared branch but to actually work on a
>> local branch that is rebased on the shared branch. By judiciously
>> using "git reset" and "git pull" on the shared branch the two devs can
>> keep the shared branch in synch and then use "git rebase
>> shared-branch" on their local branch to keep it in synch to. While
>> this works, there is probably a better/simpler solution.
>>
>> Should we simply do "git merge master" instead of "git rebase master"?
>
> That certainly is a sensible thing to do.
>
> But if your people are used to rebasing their own 'master' on top of
> shared 'master', I would imagine that it wouldn't be hard at all for these
> two people that work on a topic branch to do the same for their 'topic'
> branch, no?  Just like rebasing their 'master' on shared 'master', they
> would rebase their own 'topic' on shared 'topic'.

I'm not sure I'm following you here. I agree with what you say but I'm not clear on exactly how it applies to what I asked. :-/

Rebasing the 'local-topic' on 'shared-topic' branch is certainly possible but that would not help with linear history with regards to 'master', right? And rebasing 'shared-topic' on 'master' (to get its updates) would "break" one of the dev's environments. Unless you mean they should both do that separately? I suppose that's possible. I'm not clear on the consequences.

It seems that (as Aevar said) we should simply ignore linear history while 'shared-topic' exists and only rebase on master when integrating it back into master. But I get the impression that you might have a slightly different approach in mind?

Michael Witten· Apr 6, 2012, 02:32 UTC · re: Hilco Wijbenga · lore

Re: Linear history *and* share a branch?

On Thu, 5 Apr 2012 13:48:23 -0700, Hilco Wijbenga wrote:
Show 14 quoted lines
> We have been using Git for about a year now in a very small team. So
> far, everyone has worked on their own local branches and been doing
> "git rebase master" to make sure their local branches stay in synch.
> This way we have a nice linear history in master.
>
> Recently, it has become useful to share one of these local branches
> between two devs. Of course, when one of the devs does his usual "git
> rebase master", he screws up the other dev's environment. Our solution
> has been to keep rebasing the shared branch but to actually work on a
> local branch that is rebased on the shared branch. By judiciously
> using "git reset" and "git pull" on the shared branch the two devs can
> keep the shared branch in synch and then use "git rebase
> shared-branch" on their local branch to keep it in synch to. While
> this works, there is probably a better/simpler solution.

I think you can keep doing what you're doing, but simplify the management. I try to express this more precisely below.

Take all this with a grain of salt; it's kind of off the top of my head, untested, and probably wrong (all the more so, because it has been a while since I had to think about these commands or workflows). Sorry if this is no different than what you're already doing.

For a branch head `X' and a branch head `Y', let:
  X > Y
mean that X should be periodically rebased on Y.

Your team could have the following repository (that is, there is a branch head `shared' and a branch head `master', and `shared' should be periodically rebased on `master'):

  origin:
    shared > master

Developer `A' has a repository with a remote-tracking branch `origin/shared', and a topic branch `local':

  A:
    local > origin/shared
Similarly for Developer `B':
  B:
    local > origin/shared

The concerns are separated as follows (I'm being a little more explicit with the commands than what is probably necessary):

  origin:
    git rebase master shared
  A and B:
    git checkout local
    # do some work with `local'
    # ...
    git pull --rebase origin +shared:remotes/origin/shared
    git push origin local:shared # If this fails, do the pull again.

In actuality, the `origin' maintenance can be done by Developer `A' or `B', too; from one of their repositories:

    git fetch origin +master:remotes/origin/master \
                     +shared:remotes/origin/shared
    git checkout -b shared origin/shared
    git rebase origin/master shared
    git push origin +shared:shared
    git checkout local
    git branch -D shared

With a suitably set up configuration, you could probably automate a lot of the command line arguments. For instance, if the `A' and `B' repos have configurations that look something like the following:

  [remote "origin"]
    fetch = +refs/heads/*:refs/remotes/origin/*
    ...
  [push]
    default = upstream
  [branch "local"]
    remote = origin
    merge  = shared
    rebase = true
then the usual `A' and `B' workflow could simply be:
  git checkout local
  # do some work with `local'
  # ...
  git pull
  git push # If this fails, do the pull again.

and as for rebasing `shared' in `origin', at least the fetch would just become just `git fetch'.

... I think...

Sincerely, Michael Witten

Neal Kreitzinger· Apr 10, 2012, 23:54 UTC · re: Hilco Wijbenga · lore

Re: Linear history *and* share a branch?

On 4/5/2012 3:48 PM, Hilco Wijbenga wrote:
Show 22 quoted lines
> Hi all,
>
> We have been using Git for about a year now in a very small team. So
> far, everyone has worked on their own local branches and been doing
> "git rebase master" to make sure their local branches stay in synch.
> This way we have a nice linear history in master.
>
> Recently, it has become useful to share one of these local branches
> between two devs. Of course, when one of the devs does his usual
> "git rebase master", he screws up the other dev's environment. Our
> solution has been to keep rebasing the shared branch but to actually
> work on a local branch that is rebased on the shared branch. By
> judiciously using "git reset" and "git pull" on the shared branch the
> two devs can keep the shared branch in synch and then use "git
> rebase shared-branch" on their local branch to keep it in synch to.
> While this works, there is probably a better/simpler solution.
>
> Should we simply do "git merge master" instead of "git rebase
> master"? And then do something at the end when we are about to merge
> the shared branch back into master to guarantee linear history? Your
> thoughts and ideas would be greatly appreciated.
>

I haven't tried this, but at the point when your topic branch is ready for master and the only thing left to do is make the history linear before publishing it you could: rebuild the branch using cherry pick. You could cherry pick only the merge-commits over and that would drop all the merge history. You would end up with linear history. Then you could further cleanup that linear history with rebase -i before you publish it.

I haven't tried cherry picking a merge commit so I'm assuming it only brings over the commit content and not the merge history.

v/r, neal

← back to recent threads