threads / patch / 43215

patchRe: [PATCH] Explicitly add the default "git pull" behaviour to .git/config on clone

Subject: Re: [PATCH] Explicitly add the default "git pull" behaviour to .git/config on clone

## tl;dr

15 messages between Dec 6, 2006 and Dec 8, 2006. Diffs are folded; open one to read it.

replies: 14people: 7as markdown or json

Andy Parkins· Dec 6, 2006, 12:07 UTC · lore

[PATCH] Explicitly add the default "git pull" behaviour to .git/config on clone

Without any specification in the .git/config file, git-pull will execute "git-pull origin"; which in turn defaults to pull from the first "pull" definition for the remote, "origin".

This is a difficult set of defaults to track for a new user, and it's difficult to see what tells git to do this (especially when it is actually hard-coded behaviour). To ameliorate this slightly, this patch explicitly specifies the default behaviour during a clone using the "branch" section of the config.

For example, a clone of a typical repository would create a .git/config
containing:
  [remote "origin"]
  url = proto://host/repo.git
  fetch = refs/heads/master:refs/remotes/origin/master
  [branch "master"]
  remote = origin
  merge = refs/heads/master

The [branch "master"] section is such that there is no change to the functionality of git-pull, but that functionality is now explicitly documented.

Signed-off-by: Andy Parkins <andyparkins@gmail.com>
---
This is really to help newbies.  By explicitly documenting the default
behaviour, it makes it clearer what is going on.  It also means no routing
through documentation to find out what config option needs changing.

It's possible that we would want to remove the default behaviour entirely if there is no "branch" definition in the config. That would prevent accidents by users who don't know what pull does fully yet.

 git-clone.sh |    4 +++-
 1 files changed, 3 insertions(+), 1 deletions(-)
Show changes to git-clone.sh +3 −1
diff --git a/git-clone.sh b/git-clone.sh
index 826fdda..992cb7c 100755
--- a/git-clone.sh
+++ b/git-clone.sh
@@ -413,7 +413,9 @@ then
 			rm -f "refs/remotes/$origin/HEAD"
 			git-symbolic-ref "refs/remotes/$origin/HEAD" \
 				"refs/remotes/$origin/$head_points_at"
-		esac
+		esac &&
+		git-repo-config branch."$head_points_at".remote "$origin" &&
+		git-repo-config branch."$head_points_at".merge "refs/heads/$head_points_at"
 	esac
 
 	case "$no_checkout" in
-- 
1.4.4.1.g3ece-dirty
Johannes Schindelin· Dec 6, 2006, 12:20 UTC · re: Andy Parkins · lore
Hi,
On Wed, 6 Dec 2006, Andy Parkins wrote:
> This is really to help newbies.  By explicitly documenting the default 
> behaviour, it makes it clearer what is going on.  It also means no 
> routing through documentation to find out what config option needs 
> changing.
Melikes.
Ciao,
Jakub Narebski· Dec 6, 2006, 12:27 UTC · re: Andy Parkins · lore
Andy Parkins wrote:
Show 22 quoted lines
> Without any specification in the .git/config file, git-pull will execute
> "git-pull origin"; which in turn defaults to pull from the first "pull"
> definition for the remote, "origin".
> 
> This is a difficult set of defaults to track for a new user, and it's
> difficult to see what tells git to do this (especially when it is
> actually hard-coded behaviour).  To ameliorate this slightly, this patch
> explicitly specifies the default behaviour during a clone using the
> "branch" section of the config.
> 
> For example, a clone of a typical repository would create a .git/config
> containing:
>   [remote "origin"]
>   url = proto://host/repo.git
>   fetch = refs/heads/master:refs/remotes/origin/master
>   [branch "master"]
>   remote = origin
>   merge = refs/heads/master
> 
> The [branch "master"] section is such that there is no change to the
> functionality of git-pull, but that functionality is now explicitly
> documented.

This doesn't help newbies if they do "git pull" on branch other than "master". Git would fetch (a) from default remote "origin" (which can be unexpected a bit) (b) into current branch (which can be very unexpected for newbie) (c) the first branch in remote (which can be very unexpected).

The part (c) could be ameliorated (especially when globbing/regexp matching would get into 'master') with "Merge:" line in remotes file and equivalent remote.<name>.merge which would specify explicitely the branch to be merged, instead of using first branch.

Show 5 quoted lines
> Signed-off-by: Andy Parkins <andyparkins@gmail.com>
> ---
> This is really to help newbies.  By explicitly documenting the default
> behaviour, it makes it clearer what is going on.  It also means no routing
> through documentation to find out what config option needs changing.
Very nice.
 
> It's possible that we would want to remove the default behaviour entirely
> if there is no "branch" definition in the config.  That would prevent
> accidents by users who don't know what pull does fully yet.

Perhaps protected by config option and/or pull option... or perhaps not. Refuse pulling into current branch if it doesn.t have branch.<name>.remote matching current remote and doesn't have branch.<name>.merge entry, unless of course refspec is provided.

-- 
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git
Andy Parkins· Dec 6, 2006, 12:55 UTC · re: Jakub Narebski · lore
On Wednesday 2006 December 06 12:27, Jakub Narebski wrote:
Show 5 quoted lines
> This doesn't help newbies if they do "git pull" on branch other than
> "master". Git would fetch (a) from default remote "origin" (which can
> be unexpected a bit) (b) into current branch (which can be very
> unexpected for newbie) (c) the first branch in remote (which can be
> very unexpected).

That's why I was suggesting to remove the default behaviour when there is no branch defined. In that case git-pull would just exit with an appropriate message.

> Perhaps protected by config option and/or pull option... or perhaps not.
> Refuse pulling into current branch if it doesn.t have branch.<name>.remote
> matching current remote and doesn't have branch.<name>.merge entry, unless
> of course refspec is provided.
That's exactly what I meant; although your description is better.
Andy
-- 
Dr Andy Parkins, M Eng (hons), MIEE
Peter Baumann· Dec 6, 2006, 12:36 UTC · re: Andy Parkins · lore
On 2006-12-06, Andy Parkins <andyparkins@gmail.com> wrote:
Show 29 quoted lines
> Without any specification in the .git/config file, git-pull will execute
> "git-pull origin"; which in turn defaults to pull from the first "pull"
> definition for the remote, "origin".
>
> This is a difficult set of defaults to track for a new user, and it's
> difficult to see what tells git to do this (especially when it is
> actually hard-coded behaviour).  To ameliorate this slightly, this patch
> explicitly specifies the default behaviour during a clone using the
> "branch" section of the config.
>
> For example, a clone of a typical repository would create a .git/config
> containing:
>   [remote "origin"]
>   url = proto://host/repo.git
>   fetch = refs/heads/master:refs/remotes/origin/master
>   [branch "master"]
>   remote = origin
>   merge = refs/heads/master
>
> The [branch "master"] section is such that there is no change to the
> functionality of git-pull, but that functionality is now explicitly
> documented.
>
> Signed-off-by: Andy Parkins <andyparkins@gmail.com>
> ---
> This is really to help newbies.  By explicitly documenting the default
> behaviour, it makes it clearer what is going on.  It also means no routing
> through documentation to find out what config option needs changing.
>

I second that. It took me a while to understand why the first entry in remotes/origin merged with the current branch. I thought it was a bug because sometimes it did the right thing and once in a while nothing went wrong.

Obviously, it have switched the branch. I even tried to made this "buggy" behaviour reproducable to write a bugreport, but after several days the light goes on and I just felt a little bit stupid :-)

> It's possible that we would want to remove the default behaviour entirely
> if there is no "branch" definition in the config.  That would prevent
> accidents by users who don't know what pull does fully yet.
>

I'm not absolutly sure about this, but with --use-separate-remote this makes sense, because you can easly teach someone new to git that the changes from the remote branches are under refs/remotes/<branches> and (s)he could merge it with git-pull . refs/remotes/$branch

No more clueless users why git pull on master branch updated the working tree and git pull an other branch does nothing.

-Peter
Show 18 quoted lines
>  git-clone.sh |    4 +++-
>  1 files changed, 3 insertions(+), 1 deletions(-)
>
> diff --git a/git-clone.sh b/git-clone.sh
> index 826fdda..992cb7c 100755
> --- a/git-clone.sh
> +++ b/git-clone.sh
> @@ -413,7 +413,9 @@ then
>  			rm -f "refs/remotes/$origin/HEAD"
>  			git-symbolic-ref "refs/remotes/$origin/HEAD" \
>  				"refs/remotes/$origin/$head_points_at"
> -		esac
> +		esac &&
> +		git-repo-config branch."$head_points_at".remote "$origin" &&
> +		git-repo-config branch."$head_points_at".merge "refs/heads/$head_points_at"
>  	esac
>  
>  	case "$no_checkout" in
Josef Weidendorfer· Dec 6, 2006, 17:00 UTC · re: Andy Parkins · lore
On Wednesday 06 December 2006 13:07, Andy Parkins wrote:
> The [branch "master"] section is such that there is no change to the
> functionality of git-pull, but that functionality is now explicitly
> documented.

Nice. However, changing "git-clone" for this is an adhoc solution and looks wrong.

Branching off a local development branch for a tracking branch is the job of git-branch. So first, git-branch should be called from git-clone to do this setup.

And git-branch should be told to change the configuration of default behavior of git-pull, whenever it sees that you are branching off from a branch tracking a remote one. I even would go so far to setup a default "git-pull" action even for branching off from local branches, by setting "branch.<newbranch>.remote = ." to merge from local "upstream".

Similar, "git-checkout -b <newbranch>" should call "git-branch" for branch creation, too.

Jakub Narebski· Dec 6, 2006, 17:15 UTC · re: Josef Weidendorfer · lore
Josef Weidendorfer wrote:
> I even would go so far to setup
> a default "git-pull" action even for branching off from local branches,
> by setting "branch.<newbranch>.remote = ." to merge from local "upstream".

I wouldn't go that far, as it would forbit perfectly good "git fetch" from anywhere in the sources meaning "git fetch origin".

-- 
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git
Johannes Schindelin· Dec 6, 2006, 23:23 UTC · re: Josef Weidendorfer · lore
Hi,
On Wed, 6 Dec 2006, Josef Weidendorfer wrote:
Show 7 quoted lines
> On Wednesday 06 December 2006 13:07, Andy Parkins wrote:
> > The [branch "master"] section is such that there is no change to the
> > functionality of git-pull, but that functionality is now explicitly
> > documented.
> 
> Nice. However, changing "git-clone" for this is an adhoc solution and 
> looks wrong.

Not to me. There is _no_ other place to put this, if you want to help people graps the concept of branch.*.merge.

Ciao, Dscho

Josef Weidendorfer· Dec 7, 2006, 02:49 UTC · re: Johannes Schindelin · lore
On Thursday 07 December 2006 00:23, Johannes Schindelin wrote:
Show 14 quoted lines
> Hi,
> 
> On Wed, 6 Dec 2006, Josef Weidendorfer wrote:
> 
> > On Wednesday 06 December 2006 13:07, Andy Parkins wrote:
> > > The [branch "master"] section is such that there is no change to the
> > > functionality of git-pull, but that functionality is now explicitly
> > > documented.
> > 
> > Nice. However, changing "git-clone" for this is an adhoc solution and 
> > looks wrong.
> 
> Not to me. There is _no_ other place to put this, if you want to help 
> people graps the concept of branch.*.merge.

As far as I understand, git-clone defaults to kind of a mirror operation while changing remotes ref names slightly as tracking branches, and afterwards, it sets up a local branch for development, which is branched off from the branch which tracks remote's master.

IMHO there only should be one place/command which is creating new branches, and which is called by other porcelain commands [*1*]. This way, if we add some further action to "branching off" (like adding a default merge branch), we will not miss any place where a new branch will be created, thus keeping everything consistent.

Why should we not setup branch.*.merge when a create a new development branch from a tracking branch via "git branch", or "git checkout -b" ?

Josef

[*1*] I recently made up my mind about this. I suggested a patch (see "[PATCH/RFC] Convenient support of remote branches in git-checkout" in the mail archive), which also set up "branch.*.merge" in a similar way as this patch is doing. And I got - rightly - the same response

Junio C Hamano· Dec 7, 2006, 03:44 UTC · re: Josef Weidendorfer · lore
Josef Weidendorfer <Josef.Weidendorfer@gmx.de> writes:
> IMHO there only should be one place/command which is creating new branches,
> and which is called by other porcelain commands [*1*].

Giving an option to git branch to set something like this up would be nice. I would agree the division of labor you propose is a good way to keep the scripts maintainable.

It however is a different matter if we would want to set up the merge default always in the way you propose for a new branch at the policy level.

It also is a different matter if "git branch" has enough information to figure out which upstream "origin" needs to be fetched from, given an origin SHA-1 expression to create a new branch from, at the technical level

It entirely is possible to use the same remotes/origin/ hierarchy to track two physically different URLs (thus two different "origin"s) on a mobile machine that has different connectivity to the outside world depending on where you are ("that mirror is closer from here" and "I need to go over the firewall while I am here"). Because they track the logically same repository, it does not make sense to use different hierarchies under remotes/ for this purpose.

In such a setup, "git branch new origin/for-public" would not be able to tell which "origin" to fetch from, so it may not even be feasible to do what you propose without an explicit help from the command line option. At least, however, the call to "git branch" you would add as a part of this proposal to "git clone" would know which URL, because at that point it would not even know about the alternate connectivity yet.

> Why should we not setup branch.*.merge when a create a new development
> branch from a tracking branch via "git branch", or "git checkout -b"?

So while I am definitely in favor of the technical side of your proposal to have "git checkout -b" use "git branch", instead of doing it by hand, I think it would be an easier sell to separate the policy from the discussion at least in the beginning.

I say this not because I disagree with your question: "Why should we not?" I do not have a ready-answer to that rhetorical question yet. But that is different from saying "it does not make sense to do this setup because of such and such concrete reasons", so I haven't formed an opinion on this policy matter yet.

Josef Weidendorfer· Dec 7, 2006, 14:52 UTC · re: Junio C Hamano · lore
On Thursday 07 December 2006 04:44, Junio C Hamano wrote:
Show 17 quoted lines
> Josef Weidendorfer <Josef.Weidendorfer@gmx.de> writes:
> 
> > IMHO there only should be one place/command which is creating new branches,
> > and which is called by other porcelain commands [*1*].
> 
> Giving an option to git branch to set something like this up
> would be nice.  I would agree the division of labor you propose
> is a good way to keep the scripts maintainable.
> 
> It however is a different matter if we would want to set up the
> merge default always in the way you propose for a new branch at
> the policy level.
> 
> It also is a different matter if "git branch" has enough
> information to figure out which upstream "origin" needs to be
> fetched from, given an origin SHA-1 expression to create a new
> branch from, at the technical level
We could setup the branch.*.remote option for every tracking branch
git-clone is fetching (and git-fetch with the wildcard refspec).
And git-branch sets branch.*.remote/merge for the new branch
whenever it sees that a remote is set for the branch we are
branching off.
 
Show 11 quoted lines
> It entirely is possible to use the same remotes/origin/
> hierarchy to track two physically different URLs (thus two
> different "origin"s) on a mobile machine that has different
> connectivity to the outside world depending on where you are
> ("that mirror is closer from here" and "I need to go over the
> firewall while I am here").  Because they track the logically
> same repository, it does not make sense to use different
> hierarchies under remotes/ for this purpose.
> 
> In such a setup, "git branch new origin/for-public" would not be
> able to tell which "origin" to fetch from

I see. But I hope with my suggestion above, this can be looked up then in the branch."remotes/origin/for-public".remote option.

Johannes Schindelin· Dec 7, 2006, 14:13 UTC · re: Josef Weidendorfer · lore
Hi,
On Thu, 7 Dec 2006, Josef Weidendorfer wrote:
Show 20 quoted lines
> On Thursday 07 December 2006 00:23, Johannes Schindelin wrote:
> > Hi,
> > 
> > On Wed, 6 Dec 2006, Josef Weidendorfer wrote:
> > 
> > > On Wednesday 06 December 2006 13:07, Andy Parkins wrote:
> > > > The [branch "master"] section is such that there is no change to the
> > > > functionality of git-pull, but that functionality is now explicitly
> > > > documented.
> > > 
> > > Nice. However, changing "git-clone" for this is an adhoc solution and 
> > > looks wrong.
> > 
> > Not to me. There is _no_ other place to put this, if you want to help 
> > people graps the concept of branch.*.merge.
> 
> As far as I understand, git-clone defaults to kind of a mirror operation
> while changing remotes ref names slightly as tracking branches, and
> afterwards, it sets up a local branch for development, which is
> branched off from the branch which tracks remote's master.

Yes. And I should back off from my strong language: I think this git-clone the most obvious program to set branch.master.merge. It should make life easier for new Git users.

Ciao,
Josef Weidendorfer· Dec 7, 2006, 14:44 UTC · re: Johannes Schindelin · lore
On Thursday 07 December 2006 15:13, Johannes Schindelin wrote:
Show 14 quoted lines
> > > > Nice. However, changing "git-clone" for this is an adhoc solution and 
> > > > looks wrong.
> > > 
> > > Not to me. There is _no_ other place to put this, if you want to help 
> > > people graps the concept of branch.*.merge.
> > 
> > As far as I understand, git-clone defaults to kind of a mirror operation
> > while changing remotes ref names slightly as tracking branches, and
> > afterwards, it sets up a local branch for development, which is
> > branched off from the branch which tracks remote's master.
> 
> Yes. And I should back off from my strong language: I think this git-clone 
> the most obvious program to set branch.master.merge. It should make life 
> easier for new Git users.

Oh, no problem ;-) I myself used quite strong words. And I fully agree that it makes life easier for users. And it is way easier to do it in git-clone because (1) in git-clone we _know_ that we branch of a tracking branch; in git-branch, we first have to check if we want the configuration set. (2) git-branch is more difficult to change because it's written in C :-)

However, as discussed in another thread, branch.*.merge currently has quite a strange semantic [*1*], and without changing, users have no way to grasp this configuration option.

And that branch renaming feature cooking in pu really has to move branch attributes too, when we even officially set them now in git-clone.

Josef

[*1*] Currently, in branch.*.merge you have to specify the remote branch name of a refspec which updates a local tracking branch in the fetch phase of git pull.

Jakub Narebski· Dec 8, 2006, 10:36 UTC · re: Josef Weidendorfer · lore
Josef Weidendorfer wrote:
> However, as discussed in another thread, branch.*.merge currently has quite
> a strange semantic [*1*], and without changing, users have no way to grasp this
> configuration option.
[...]
> [*1*] Currently, in branch.*.merge you have to specify the remote branch name
> of a refspec which updates a local tracking branch in the fetch phase of git pull.
> I.e. the option value has nothing todo with the merge action itself!

That's (I think) because branch.<name>.merge can be for pull used _without_ tracking branch. So it is not that easy to change semantics, I agree bit strange for newbie git users, who know git from the begining with --use-separate-remote and tracking branches.

Perhaps we should extend it so it can take beginning part of refspec (as now), full refspec, or ':' and local branch.

-- 
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git
Aneesh Kumar K.V· Dec 7, 2006, 06:49 UTC · re: Andy Parkins · lore
Andy Parkins wrote:
Show 33 quoted lines
> Without any specification in the .git/config file, git-pull will execute
> "git-pull origin"; which in turn defaults to pull from the first "pull"
> definition for the remote, "origin".
> 
> This is a difficult set of defaults to track for a new user, and it's
> difficult to see what tells git to do this (especially when it is
> actually hard-coded behaviour).  To ameliorate this slightly, this patch
> explicitly specifies the default behaviour during a clone using the
> "branch" section of the config.
> 
> For example, a clone of a typical repository would create a .git/config
> containing:
>   [remote "origin"]
>   url = proto://host/repo.git
>   fetch = refs/heads/master:refs/remotes/origin/master
>   [branch "master"]
>   remote = origin
>   merge = refs/heads/master
> 
> The [branch "master"] section is such that there is no change to the
> functionality of git-pull, but that functionality is now explicitly
> documented.
> 
> Signed-off-by: Andy Parkins <andyparkins@gmail.com>
> ---
> This is really to help newbies.  By explicitly documenting the default
> behaviour, it makes it clearer what is going on.  It also means no routing
> through documentation to find out what config option needs changing.
> 
> It's possible that we would want to remove the default behaviour entirely
> if there is no "branch" definition in the config.  That would prevent
> accidents by users who don't know what pull does fully yet.
> 
I liked this. This avoid lot of confusion and the "magic" master  update.
-aneesh

← back to recent threads