Re: Re: Re: [RFC v2] submodule: Respect requested branch on all clones

2014-01-14 Thread Heiko Voigt
Hi,

On Tue, Jan 14, 2014 at 11:24:45AM +0100, Heiko Voigt wrote:
 I will write another post about how I think we should/can proceed.

and here is my suggestion how we should proceed.

I think there have been many interesting ideas in this thread but IMO
some of them tried to achieve a little bit to much and were not clear
enough. I am a fan of: Keep it as simple as possible, but *no simpler*.
I think some ideas where going in the make it to simple direction.

Take my idea for feature branch support from here[1]. After thinking more
thoroughly it still too many corner cases. E.g. it is way to easy to
accidentally merge the feature branch configuration into the stable branch. But
we want to support the user properly so we need to catch stuff like that.

Submodules are separate projects. There is a boundary between
superproject and submodule and IMO its there for a good reason. E.g.
take the typical shared code use-case. If A and B are using C
then both want to make sure a change from A does not break B's
expectations and vice versa. Thats were you usually write unit tests in
C for: Ensure that the expectations are met. The more users of the code
the higher the quality and thus the boundary for bad code should be.

I would like to step back a bit and get back to the original problem at hand:
Francescos original use case of an attached head for direct commits on a stable
branch in a submodule. How about we finish discussing the exact solution of
that first. AFAIK that is already solved with the following:

 * Trevor's first patch[2] to create a branch on initial clone of a submodule
 * A possibly a configuration variable for --remote so it can be
   set as the default update method
 * Combined with submodule.name.update=merge/rebase

That should be all (and IIRC Francesco agreed) needed for that use-case.

Lets not implement more than currently is needed. We can revisit the ideas once
some other real use-case manifests. Also we (Jens and I) would first like to
proceed with the recursive checkout / fetch (for which the plan is clear) as
the next complicated step.

Once that is done and people gain some experience with it we can still extend
further.

What do you think?

Cheers Heiko

[1] http://article.gmane.org/gmane.comp.version-control.git/240178/
[2] http://article.gmane.org/gmane.comp.version-control.git/239921
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: Re: Re: [RFC v2] submodule: Respect requested branch on all clones

2014-01-14 Thread Heiko Voigt
On Tue, Jan 14, 2014 at 01:42:09PM -0800, W. Trevor King wrote:
 On Tue, Jan 14, 2014 at 09:58:30PM +0100, Heiko Voigt wrote:
  A typical workflow where a feature in a project needs some extension or
  change in a submodule goes like this:
  
  1. The developer does his changes locally implementing everything
 needed. To commit he creates a local branch in the submodule and in
 the superproject (most of the times from the current HEAD that is
 checked out).
  
  2. For convenience I usually commit the resulting commit sha1 of the
 submodule in the commit that needs the change. That way when I switch
 to a different branch and back I can simply say: git submodule update
 and get the correct code everywhere.
 
 This checkout functionality is exactly what my
 submodule.name.localBranch is designed to automate [1].  I think
 that should be different from integrating local and external changes,
 which is what 'git submodule update' is about.  For example, after you
 run 'git submodule update' here, you'll have your original commit
 checked out, but you'll be on a detached HEAD instead of your original
 branch.  If you want to further develop the submodule feature branch,
 you currently have to cd into the submodule and check the branch out
 by hand.

Yes and thats exactly what my idea was about but after further thinking
am afraid that this is the wrong place. I am not sure but afraid as I
wrote in the other post that it would be way to dangerous to accidentally
merge these changes in. We would need something to prevent this
configuration from ever entering a stable branch.

Another solution (and completely different approach) would be to have
something that is outside of the tree and actually attached to a
branchname. E.g. at the gitmerge last year I though it would be nice to
have a place for a description for a branch inside git. In a short
discussion we were envisioning a special ref like the notes trees but
allowing to attach and describe branches. That place could also be where
we could store such a configuration. Once the branchname ceases to exist
so would the configuration.

I know this is a completely different piece of work so I am not sure
whether we want to pursue it at the moment. But at the moment I think
this would actually be the correct solution.

  How about the use-case I sketched above? Is that what you are searching
  for? In that use-case we have to update to the new master after a
  submodule change was merged. That could be achieved by
  
  git submodule update --remote submodule
  
  with the wanted stable branch configured. But in practise something
  along the lines of
  
  (cd submodule  git checkout origin/stable)
  
  is usually used and simple enough.
 
 The “gitlinked commits must be in the subproject's master” rule
 protects you from blowing stuff away here.  You could use rebase- or
 merge-style integration as well, assuming the maintainer didn't have
 dirty local work in their submodule.

No we can't. Developers are not allowed to merge in some submodules.
The most central ones have maintainers and only they are allowed to
merge into the stable branch. So we need to track exact commits on the
stable branch, no local merge (except the fast-forward case of course)
allowed. Thats why the developer does an exact checkout here.

  We have a tool in our git gui configuration that does
  
  git submodule foreach 'git fetch  git checkout origin/master'
 
 I agree that with 'submodule update' seems superfluous.  With proper
 out-of-tree submodule configs specifying remote URLs and upstream
 branches,
 
   git submodule foreach 'git fetch  git checkout @{upstream}'
 
 (or merge/rebase/…) should cover this case more generically and with
 less mental overhead.
 
  I hope that draws a clear picture of how we use submodules.
 
 It's certainly clearer, thanks :).  I'm not sure where checkout-mode
 is specifically important, though.  In your step-2, it doesn't restore
 your original branch.  In your “update the superproject's master”
 step, you aren't even using 'submodule update' :p.

Ah sorry I though that was clear. The others are using submodule update ;-)

I mean someone who gets stuff from a stable superproject branch by
either rebasing their development branch or updating their local copy of
a stable branch (e.g. master) by using

git checkout master
git pull --ff --ff-only
git submodule update --init --recursive

This also prevents the pure updaters from creating unnecessary merges.

Cheers Heiko

 [1]: http://article.gmane.org/gmane.comp.version-control.git/240336
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: Re: Re: [RFC v2] submodule: Respect requested branch on all clones

2014-01-06 Thread Heiko Voigt
On Sun, Jan 05, 2014 at 03:39:43PM -0800, W. Trevor King wrote:
 On Sun, Jan 05, 2014 at 11:57:33PM +0100, Heiko Voigt wrote:
  On Sun, Jan 05, 2014 at 01:24:58PM -0800, W. Trevor King wrote:
   If submodule.name.branch is set, it *always* creates a new local
   branch of that name pointing to the exact sha1.  If
   submodule.name.branch is not set, we still create a
   detached-HEAD checkout of the exact sha1.
  
  Thanks for this clarification. Since the usual usage with --remote
  is with a remote-tracking branch, I confused this here. I am not
  sure whether blindly creating a local branch from the recorded sha1
  is the right thing to do. In what situations would that be helpful?
 
 In any situation where your going to develop the submodule locally,
 you're going to want a branch to develop in.  Starting local-submodule
 developers off on a branch seems useful, even if we can only use
 submodule.name.branch to guess at their preferred local branch name.
 Sometimes (often?) the guess will be right.  However, A detached HEAD
 will never be right for local development, so being right sometimes is
 still an improvement ;).

Starting developers at a local submodule branch makes sense. But lets
think further. What happens after the initial update? Most times the
submodule will already be initialized and cloned. Then developers will
still get a detached HEAD even with your local branch feature.

If there are no changes on it should we advance the local branch
somehow on update? If it does not exist anymore should we recreate it?

  At $dayjob we usually use feature branches for our work. So if
  someone wants to work in a submodule you simply create a branch at
  the current sha1 which you then send out for review.
 
 I'm all for named feature branches for development, and in this case
 submodule.name.branch is likely to be the wrong choice.  However,
 it's still safer to develop in that branch and then rename the branch
 to match your feature than it would be to develop your fix with a
 detached HEAD.  If your developers have enough discipline to always
 checkout their feature branch before starting development, my patch
 won't affect them.  However, I know a number of folks who go into
 fight-or-flight mode when they have a detached HEAD :p.

I agree having an initial branch makes it less likely to loose committed
changes. Thats good. Also starting on some local branch name and then
renaming the branch sounds quite practical. Then we could recreate the
default local branch on update (like described above).

  The reason why one would set a branch option here is to share the
  superproject branch with colleagues. He can make sure they can
  always fetch and checkout the submodule even though the branch there
  is still under cleanup and thus will be rebased often. The commit
  referenced by sha1 would not be available to a developer fetching
  after a rebase.
 
 Yeah, floating gitlinks are something else.  I'd be happy to have that
 functionality (gitlinks pointing to references) should be built into
 gitlinks themselves, not added as an additional layer in the submodule
 script.  This gitlinked sha1 rebased out of existence scenario is
 the first I've heard where I think gitlinked references would be
 useful.

Yeah I have been thinking about this for quite a while now, but have not
yet found the time to really think it through and come up with a good
solution that does not put you in danger of unprecise revisions. The
only solution I can think of is a similar approach as
submodule.name.branch gives us now but possibly enabled by some
option (i.e.: submodule.name.remote = true).
This way you always get the current tip of development but still see the
differences (which you can choose to commit) in git status.

   Thinking through this more, perhaps the logic should be:
   
   * If submodule.name.update (defaulting to checkout) is checkout,
 create a detached HEAD.
   * Otherwise, create a new branch submodule.name.branch
 (defaulting to master).
  
  Why not trigger the attached state with the submodule.name.branch
  configuration option? If there is a local branch available use that,
  if not the tracking branch (as it is currently). Then a developer
  can start working on the branch with:
  
  cd submodule; git checkout -t origin/branchname
  
  assuming that submodule update learns some more support for this.
 
 Isn't that already what 'git update --remote submodule' already
 does?

Does it? As far as I understood (not using the branch option yet) it
only does

git checkout origin/branchname

so there is no local branch created that tracks the remote branch (-t).
What I was thinking is that when submodule.name.branch is set a

git submodule update

will:

1. if no local branch with that name exists:

   checkout the remote/branch

2. If a local branch with that name exists:

   checkout the local branch and possibly advance it according to its
   setting.

Thinking further: