Re: git bug? + question

11 messages, 8 authors, 2016-08-11 · open the first message on its own page

Re: git bug? + question

From: Junio C Hamano <hidden>
Date: 2016-08-11 20:38:15

Karl Hasselström [off-list ref] writes:
On 2006-11-02 18:40:30 -0800, Junio C Hamano wrote:
quoted
I still need to remember to process "master" first, so all things
considered, this is a regression in usability for my workflow.
Where does this constraint come from?
    With separate remotes, I'd need something like:

            for b in master maint next pu
            do
                    git checkout $b && git pull && make || break
            done

    And I also would need to have per-branch configuration to merge
    from ". remotes/origin/$b" without re-fetching while on a
    non-master branch $b, for the above to work.  I still need to
    remember to process "master" first, so all things considered,
    this is a regression in usability for my workflow.

Because I'll have to have the per-branch configuration that
would say something like this:

	[remote."gitster"]
		url = gitster.example.com:/home/junio/git.git/
        	fetch = heads/maint:remotes/gitster/maint
        	fetch = heads/master:remotes/gitster/master
        	fetch = heads/next:remotes/gitster/next
        	fetch = +heads/pu:remotes/gitster/pu

	[branch."master"]
        	remote = gitster
                merge = heads/master
	[branch."maint"]
        	remote = .
                merge = remotes/gitster/maint
	[branch."next"]
        	remote = .
                merge = remotes/gitster/next
	...

Side note: the above would not actually work because I am
missing an earlier patch by Santi to special case 'dot' as the
value of "branch.$name.remote", but I think you get the idea.

This requires that by the time we update maint, next and pu
branches with what is in the upstream, their corresponding
remotes/gitster/* branches are already up-to-date and do not
have to be re-fetched, and processing master first is what
guarantees it.

I do not mind treating "master" specially at all; my otherwise
idle repositories with working tree (read: ones on secondary
machines I use primarily to build git binary for that machine or
that platform, not to develop on) always have "master" checked
out; I start working in them while "master" is checked out, and
I'll be on "master" before I leave that machine.

If I keep using the traditional layout, where master is fetched
to origin and next, maint and pu are used to track the remote, I
do not have to do any of the above remote/branch configuration
in the .git/config file, and after one "git pull" while on
"master", I'd have all four branches up to date, ready to be
checked out and compiled.

But I suspect this "following multiple branches at the same
time, switch between them only to compile, test and install but
never develop on them" workflow is rather specific to top-level
maintainer's workflow and that is why I said defaulting to
separate-remote would be an inconvenience to a minority.

Re: git bug? + question

From: Martin Waitz <hidden>
Date: 2016-08-11 19:25:47

hoi :)

On Fri, Nov 03, 2006 at 12:51:32AM -0800, Junio C Hamano wrote:
    With separate remotes, I'd need something like:

            for b in master maint next pu
            do
                    git checkout $b && git pull && make || break
            done

    And I also would need to have per-branch configuration to merge
    from ". remotes/origin/$b" without re-fetching while on a
    non-master branch $b, for the above to work.  I still need to
    remember to process "master" first, so all things considered,
    this is a regression in usability for my workflow.
you could also run git-fetch first and then always default to
the local repository.  But that would of course make pull just
a shortcut for merge, without any fetch.

Would it be so bad for you to call fetch three times?
I think the most intuitive thing for pull would be to fetch into
remotes/<remotename>/* and then to merge
remotes/<remotename>/<currentbranch>.

-- 
Martin Waitz

Re: git bug? + question

From: Junio C Hamano <hidden>
Date: 2016-08-11 19:29:00

Josef Weidendorfer [off-list ref] writes:
On Friday 03 November 2006 10:46, Karl Hasselström wrote:
quoted
Hmm. How about changing the meaning of "remote" slightly? Like this:
That's not good, as it changes existing config meaning.
...
Other option: Introduce "fetchonly" line which ignores the original
fetch lines in the remote section.

       [remote."gitster"]
               url = gitster.example.com:/home/junio/git.git/
               fetch = heads/master:remotes/gitster/master
               fetch = heads/next:remotes/gitster/next
       [branch."master"]
               remote = gitster
               fetchonly = heads/master:remotes/gitster/master
               merge = remotes/gitster/master
That is a regression in that now I need to fetch twice (in the
above example, in reality four).

Re: git bug? + question

From: Josef Weidendorfer <hidden>
Date: 2016-08-11 19:31:47

On Friday 03 November 2006 18:13, Jakub Narebski wrote:
Josef Weidendorfer wrote:
quoted
Other option: Introduce "fetchonly" line which ignores the original
fetch lines in the remote section.
I like this.
That's implementing it:

=================================
--- a/git-parse-remote.sh
+++ b/git-parse-remote.sh
@@ -156,6 +156,18 @@ canon_refs_list_for_fetch () {

 # Returns list of src: (no store), or src:dst (store)
 get_remote_default_refs_for_fetch () {
+       # if there are any branch.${curr_branch}.fetchonly entries,
+       # only use them as default
+       curr_branch=$(git-symbolic-ref HEAD | \
+               sed -e 's|^refs/heads/||')
+       fetchonly_branches=$(git-repo-config \
+               --get-all "branch.${curr_branch}.fetchonly")
+       if test ! -z $fetchonly_branches
+       then
+               canon_refs_list_for_fetch -d "$1" $fetchonly_branches
+               return
+       fi
+
        data_source=$(get_data_source "$1")
        case "$data_source" in
        '' | config-partial | branches-partial)
=================================

The problem with this small patch is that with

       [remote."gitster"]
               url = gitster.example.com:/home/junio/git.git/
               fetch = heads/master:remotes/gitster/master
               fetch = heads/next:remotes/gitster/next
       [branch."master"]
               remote = gitster
               fetchonly = heads/master:remotes/gitster/master
               merge = remotes/gitster/master

and current branch "master", even "git fetch gitster" does not
fetch both branches, which is expected IMHO. We would need to
pass the info that an explicit repository was given down to
get_remote_default_refs_for_fetch().

Re: git bug? + question

From: Santi Béjar <hidden>
Date: 2016-08-11 19:47:18

On 11/3/06, Martin Waitz [off-list ref] wrote:
I think the most intuitive thing for pull would be to fetch into
remotes/<remotename>/* and then to merge
remotes/<remotename>/<currentbranch>.
Yes as the default branch to merge instead the first line, the problem
is that it changes the current behaviour. But I think the most
intuitive thing would be to record the branch it is based off at the
branch creation time. Something similar to my patch:

Oct 17 [PATCHv2] git-branch: Set branch properties
Message-ID: [off-list ref]

Note that it is for the "old" git-branch.sh.

Re: git bug? + question

From: Josef Weidendorfer <hidden>
Date: 2016-08-11 20:04:48

On Saturday 04 November 2006 13:03, Junio C Hamano wrote:
Josef Weidendorfer [off-list ref] writes:
quoted
On Friday 03 November 2006 10:46, Karl Hasselström wrote:
quoted
Hmm. How about changing the meaning of "remote" slightly? Like this:
That's not good, as it changes existing config meaning.
...
Other option: Introduce "fetchonly" line which ignores the original
fetch lines in the remote section.

       [remote."gitster"]
               url = gitster.example.com:/home/junio/git.git/
               fetch = heads/master:remotes/gitster/master
               fetch = heads/next:remotes/gitster/next
       [branch."master"]
               remote = gitster
               fetchonly = heads/master:remotes/gitster/master
               merge = remotes/gitster/master
That is a regression in that now I need to fetch twice (in the
above example, in reality four).
Hmm. You do not need to use it.
However, there are use cases for this.

For example, I am mostly interested in what's new on the
next and master branch in the git repository. There is no need for me
to always fetch pu or maint.

So I can use (I am behind a firewall):

[remote "origin"]
        url = http://www.kernel.org/pub/scm/git/git.git
        fetch = master:origin
        fetch = maint:maint
        fetch = next:next
        fetch = todo:todo
        fetch = +pu:pu

[branch "master"]
        remote = origin
        fetchonly = master:origin
	fetchonly = next:next
        merge = origin

and get master and next with a "git fetch" when on master, and
"git fetch origin" would fetch all branches.

Re: git bug? + question

From: Josef Weidendorfer <hidden>
Date: 2016-08-11 20:07:49

On Friday 03 November 2006 10:46, Karl Hasselström wrote:
Hmm. How about changing the meaning of "remote" slightly? Like this:
That's not good, as it changes existing config meaning.
But why not support fetch lines in [branch.*] sections?

Ie. instead of
      [remote."gitster"]
              url = gitster.example.com:/home/junio/git.git/
              fetch = heads/master:remotes/gitster/master
              fetch = heads/next:remotes/gitster/next
      [branch."master"]
              remote = gitster
              merge = remotes/gitster/master
      [branch."next"]
              remote = gitster
              merge = remotes/gitster/next
make your config look like

       [remote."gitster"]
               url = gitster.example.com:/home/junio/git.git/
       [branch."master"]
               remote = gitster
               fetch = heads/master:remotes/gitster/master
               merge = remotes/gitster/master
       [branch."next"]
               remote = gitster
               fetch = heads/next:remotes/gitster/next
               merge = remotes/gitster/next

A fetch line in [branch.*] means: Also fetch this refspec in
addition to the refspecs specified in the remote section.
Problem being that "git fetch gitster" does nothing anymore :-(

Other option: Introduce "fetchonly" line which ignores the original
fetch lines in the remote section.

       [remote."gitster"]
               url = gitster.example.com:/home/junio/git.git/
               fetch = heads/master:remotes/gitster/master
               fetch = heads/next:remotes/gitster/next
       [branch."master"]
               remote = gitster
               fetchonly = heads/master:remotes/gitster/master
               merge = remotes/gitster/master

Re: git bug? + question

From: Andy Parkins <hidden>
Date: 2016-08-11 20:12:46

On Friday 2006 November 03 08:51, Junio C Hamano wrote:
time, switch between them only to compile, test and install but
never develop on them" workflow is rather specific to top-level
maintainer's workflow and that is why I said defaulting to
separate-remote would be an inconvenience to a minority.
This is only a question of the default; why couldn't you (when it exists) use?

  git clone --dont-use-separate-remote URL

To get exactly what you always had if that's what you want?


Andy

-- 
Dr Andy Parkins, M Eng (hons), MIEE

Re: git bug? + question

From: Jakub Narebski <hidden>
Date: 2016-08-11 20:19:48

Josef Weidendorfer wrote:
Other option: Introduce "fetchonly" line which ignores the original
fetch lines in the remote section.
I like this.
-- 
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git

Re: git bug? + question

From: Karl Hasselström <hidden>
Date: 2016-08-11 20:35:01

On 2006-11-03 00:51:32 -0800, Junio C Hamano wrote:
Karl Hasselström [off-list ref] writes:
quoted
On 2006-11-02 18:40:30 -0800, Junio C Hamano wrote:
quoted
I still need to remember to process "master" first, so all
things considered, this is a regression in usability for my
workflow.
Where does this constraint come from?
Because I'll have to have the per-branch configuration that would
say something like this:

      [remote."gitster"]
              url = gitster.example.com:/home/junio/git.git/
              fetch = heads/maint:remotes/gitster/maint
              fetch = heads/master:remotes/gitster/master
              fetch = heads/next:remotes/gitster/next
              fetch = +heads/pu:remotes/gitster/pu

      [branch."master"]
              remote = gitster
              merge = heads/master
      [branch."maint"]
              remote = .
              merge = remotes/gitster/maint
      [branch."next"]
              remote = .
              merge = remotes/gitster/next
      ...

This requires that by the time we update maint, next and pu branches
with what is in the upstream, their corresponding remotes/gitster/*
branches are already up-to-date and do not have to be re-fetched,
and processing master first is what guarantees it.
Ahh, here is where our workflows differ: I would want to have "remote
= ." for all the branches, and use "git fetch" to update the remotes.
(I guess this is only natural; my workflow requires less state in the
head of the user, and so is easier for beginners, while yours is
slightly more efficient in terms of number of commands that have to be
given.)

Hmm. How about changing the meaning of "remote" slightly? Like this:

      [remote."gitster"]
              url = gitster.example.com:/home/junio/git.git/
              fetch = heads/master:remotes/gitster/master
              fetch = heads/next:remotes/gitster/next
      [branch."master"]
              remote = gitster
              merge = remotes/gitster/master
      [branch."next"]
              remote = gitster
              merge = remotes/gitster/next

This would mean: When the user says "git pull" in master, use the
remote gitster to fetch updates to remotes/gitster/master, then merge
remotes/gitster/master into master.

With this scheme, "git pull" would never fetch any other branches than
those about to be merged; to fetch more in one go, use "git fetch".

I realize this would break existing configs quite badly, so don't take
it too seriously.

-- 
Karl Hasselström, kha@treskal.com

Re: git bug? + question

From: Linus Torvalds <torvalds@osdl.org>
Date: 2016-08-11 20:45:30


On Fri, 3 Nov 2006, Junio C Hamano wrote:
	[remote."gitster"]
Btw, why the '.'? It doesn't even work with a dot, you have to have a 
space, which is also a lot more readable..

Also, may I suggest that we just extend the format with a robust default 
value thing?

It should be reasonably easy to have just the rule:

 - add a new "remote.<remote>.branch" thing that lists multiple simple 
   branches separated by whitespace.

 - a "simple branch" is just a "implicit refspec" for the relationship
   "heads/<name>:remotes/<remote>/<name>"

And then you should be able to write all of your cumbersome config options 
as a simple

	[remote "gitster"]
		url = gitster.example.com:/home/junio/git.git/
		branch = maint master next +pu

and you're all done. It would imply everything you said.

This would basically require that "git-parse-remote" be re-written as a 
native builtin, because quite frankly, it would be too damn painful any 
other way, but it really shouldn't be that nasty. In fact, I think we 
should have done that long ago, because the shell-code is just horrid for 
things like this.

For example, for builtin-push (which is currently the only thing that 
parses "remote" entries in C), you'd just need to do something like the 
appended..  It would generate the full refspecs from the "branch" config 
automatically.

		Linus

---
diff --git a/builtin-push.c b/builtin-push.c
index d23974e..805ffa8 100644
--- a/builtin-push.c
+++ b/builtin-push.c
@@ -123,15 +123,33 @@ static int get_remote_config(const char*
 {
 	if (!strncmp(key, "remote.", 7) &&
 	    !strncmp(key + 7, config_repo, config_repo_len)) {
-		if (!strcmp(key + 7 + config_repo_len, ".url")) {
+	    	const char *subkey = key + 7 + config_repo_len;
+		if (!strcmp(subkey, ".url")) {
 			if (config_current_uri < MAX_URI)
 				config_uri[config_current_uri++] = xstrdup(value);
 			else
 				error("more than %d URL's specified, ignoring the rest", MAX_URI);
 		}
-		else if (config_get_refspecs &&
-			 !strcmp(key + 7 + config_repo_len, ".push"))
-			add_refspec(xstrdup(value));
+		else if (config_get_refspecs) {
+			if (!strcmp(subkey, ".push"))
+				add_refspec(xstrdup(value));
+			else if (!strcmp(subkey, ".branch")) {
+				while (isspace(*value))
+					value++;
+				while (*value) {
+					const char *end = value;
+					while (!isspace(*end))
+						end++;
+					add_refspec(xsprintf("heads/%.*s:remotes/%.*s/%.*s",
+						end-value, value,
+						config_repo_len, config_repo,
+						end-value, value));
+					while (isspace(*end))
+						end++;
+					value = end;
+				}
+			}
+		}
 	}
 	return 0;
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help