Boost logo

Boost :

Subject: Re: [boost] [git] Effect of "git checkout develop" on submodule?
From: Cox, Michael (mhcox_at_[hidden])
Date: 2013-12-02 15:51:11


On Mon, Dec 2, 2013 at 11:09 AM, Daniel James <daniel_at_[hidden]>wrote:

> On 2 December 2013 16:58, Beman Dawes <bdawes_at_[hidden]> wrote:
> > On Mon, Dec 2, 2013 at 11:31 AM, Daniel James <daniel_at_[hidden]
> >wrote:
> >
> >> On 2 December 2013 16:15, Beman Dawes <bdawes_at_[hidden]> wrote:
> >> > If I do this:
> >> >
> >> > git clone --recursive git_at_[hidden]:boostorg/boost.git modular-boost
> >> > cd modular-boost/libs/math
> >> > git checkout develop
> >> >
> >> > What commit of math develop branch should be checked out?
> >>
> >> Won't it fail because there isn't a local develop branch?
> >>
> >
> > No, works fine. For example,
>
> Oh, I just tried it and git now creates a local branch if you try to
> checkout a remote branch with no local copy. I don't think it used to
> do that.
>

That's standard behavior when you checkout from a detached HEAD created by
the "git clone --recursive...". All the submodules of a supermodule will
point to a detached HEAD, the particular submodule reference (commit id)
that was commited in the supermodule at the time the supermodule was
committed. When you commit a submodule in a supermodule, all that's
committed in the supermodule is a *reference* to the commit id. The branch
you were own at commit is not stored, since that commit id can exist on
multiple branches (the "feature" branch, the develop branch, and eventually
the master branch).

> > D:\modular-boost\libs\math>cd ../system
> >
> > D:\modular-boost\libs\system>git checkout develop
> > Previous HEAD position was 067ff61... Merge from trunk.
> > Switched to branch 'develop'
>
> You are checking out a local branch here, you need to merge or pull
> the remote branch. You can tell when it's checking out a remote branch
> because it says something like, "Branch develop set up to track remote
> branch develop from origin."

You don't need to do any pulling or merging, assuming you've recently done
a "git clone --recursive..." or "git submodule --recursive update". When
you do a checkout with a branch name that doesn't exist locally, but exists
in one of your remotes (usually "origin"), you create a local branch with
the same name as the remote branch and that local branch "tracks" the
remote branch, i.e. when you do a push or pull, changes flow to from that
remote branch. This local branch starts out identical in content (changes
in HEAD and history) as the remote branch, which again, if the "git clone
--recursive..." or "git submodule update --recursive" was done recently,
should be the same as what's in github.com/boostorg.

You might want to do the following (at least I do, since I get nervous
working with a detached HEAD because I really don't know what branch that
change may go to):

git checkout develop # Create a local branch develop tracking
                  # origin/develop.
git checkout -b mhcox/feature # Create a local, untracked feature
                           # branch to work on changes required in
                               # the supermodule (boost).
git submodule update --init # so your changes start with
                             # the latest changes in
                             # github.com/boostorg
git submodule foreach --recursive git checkout develop # Now every
                      # submodule repository is on the develop branch
                      # (not necessarily the same as the submodule
                      # reference, if someone forgot to commit the new
                      # references to submodule commits in the
                      # supermodule).
# Now go into the library submodules you plan on making changes for
# the feature and checkout a feature branch.
cd libs/foo
git checkout -b mhcox/feature
cd libs/bar
git checkout -b mhcox/feature
# etc.

# Make your edits/commits in the affected libs.

# If this is a large change over an extended period, it may require
# pulls and rebases from develop to get changes from
# github.com/boostorg (assumes a remote named upstream has been
# configured to point to github.com/boostorg).

cd boost # In supermodule, boost.
git pull upstream develop # Update develop branch with any changes in
                           # github.com/boostorg.
# The command below updates all develop branches in the submodules to
# the latest upstream changes.
git submodule foreach --recursive git pull upstream develop:develop

# For each lib you changed for this feature, *rebase* the new changes
# from github.com/boostorg
cd libs/foo
git rebase develop # This brings in other peoples changes and
                    # recommits your changes on top of them (may
                    # require resolving conflicts).
# ... and other libs ...
cd ../bar
git rebase develop # See foo.

# Once you're happy with your changes (builds, passes tests, etc.),
# repeat the steps from "In supermodule, boost." down. Now merge your
# changes into develop from mhcox/feature in each submodule, starting #
from the leaves of the hierarchy of repositories.
# NOTE: You may want to do an interactive rebase (rebase -i) so that
# you can clean up the history or your feature branch to just the
# essential commits for the feature implementation, i.e. get rid of
# all your missteps and experimental rabbit holes so it looks like
# never make mistakes ;-).
cd libs/foo
git checkout develop
git merge mhcox/feature # Should merge cleanly into develop, since
                         # you've just rebased. If you didn't cleanup
                         # up your history with an interactive rebase,
                         # you may want to add the --squash option,
                         # which will combine all your commits on
                         # on mhcox/feature to one commit on develop.
cd ../bar # See foo.
cd boost
git status # Should show only new commits in the libs you've changed,
            # no uncommited changes or untracked files.
git add . # Adds to your index any changes you've made in the
            # supermodule, boost, as well as submodule references
            # to the current commits in your submodules.
git commit # Creates a commit in the supermodule that contains any
            # changes you've made in it plus the submodule references,
            # ready for pushing to the remote repository.
# Push the changes in the submodules to the remote.
git submodule foreach --recursive git push origin develop
# Push the changes in the supermodule to the remote.
git push origin develop.
# Now go to your github account and generate pull requests to get
# changes to github.com/boostorg.

Sorry, I got a little carried away with my exposition :-). But at least
now you have my $.02 on the matter of git workflow.

Michael

P.S. Just to be clear on the upstream and origin remotes, the upstream
remote could possibly point to the libs lead developer's github account
repositories instead of github.com/boostorg. The lead developer would be
responsible for merging/managing the flow of changes from contributors into
his/her repositories and create subsequent pull requests to the release
manager's github repositories (probably github.com/boostorg). The origin
should point to the user's github account/organization repositories for
backup, "early-access" needs to feature branches like mhcox/feature above,
and where pull requests are generated.

> _______________________________________________
> Unsubscribe & other changes:
> http://lists.boost.org/mailman/listinfo.cgi/boost
>


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk