threads / discuss / 4239

Current Issues #3

Subject: Current Issues #3

## tl;dr

8 messages between May 22, 2006 and May 23, 2006.

replies: 7people: 8as markdown or json

Junio C Hamano· May 22, 2006, 08:44 UTC · lore
[Third installment of the "Issues" series, but I've been half
 awake for the past week or so, and I suspect I have missed some
 topics that deserve further discussion.]
* Per branch configuration
  The [section "foo"] configuration syntax update by Linus, and
  git-parse-remote update to use remote.stuff.{url,push,pull} by
  Johannes are now both in the "master".  The stage is set to
  discuss what to actually do with per-branch configuration.
  We will use the [branch "foo"] section for configuration about
  local branch named "foo".  I do not think there is any
  disagreement about this.
  The ideas floated so far (I am forgetting many of them
  perhaps):
    1. "upstream" refers to the remote section to use when
       running "git-{fetch,pull,push}" while on that branch.
	[branch "master"]
		upstream = "origin"
	[remote "origin"]
        	url = "git://git.kernel.org/.../git.git"
		fetch = refs/heads/master:refs/remotes/origin/master
    2. "url/fetch/push" directly specifies what would usually be
       taken from a remote section by "git-{fetch,pull,push}"
       while on that branch.
	[branch "foo"]
        	url = "company.com.xz:myrepo"
		fetch = refs/heads/master:refs/remotes/origin/master
		push = refs/heads/master:refs/heads/origin
* reflog
  I still haven't merged this series to "next" -- I do not have
  much against what the code does, but I am unconvinced if it is
  useful.  Also objections raised on the list that this can be
  replaced by making sure that a repository that has hundreds of
  tags usable certainly have a point.
Linus Torvalds· May 22, 2006, 10:18 UTC · re: Junio C Hamano · lore

Re: Current Issues #3

On Mon, 22 May 2006, Junio C Hamano wrote:
Show 33 quoted lines
> 
> * Per branch configuration
> 
>   The [section "foo"] configuration syntax update by Linus, and
>   git-parse-remote update to use remote.stuff.{url,push,pull} by
>   Johannes are now both in the "master".  The stage is set to
>   discuss what to actually do with per-branch configuration.
> 
>   We will use the [branch "foo"] section for configuration about
>   local branch named "foo".  I do not think there is any
>   disagreement about this.
> 
>   The ideas floated so far (I am forgetting many of them
>   perhaps):
> 
>     1. "upstream" refers to the remote section to use when
>        running "git-{fetch,pull,push}" while on that branch.
> 
> 	[branch "master"]
> 		upstream = "origin"
> 
> 	[remote "origin"]
>         	url = "git://git.kernel.org/.../git.git"
> 		fetch = refs/heads/master:refs/remotes/origin/master
> 
>     2. "url/fetch/push" directly specifies what would usually be
>        taken from a remote section by "git-{fetch,pull,push}"
>        while on that branch.
> 
> 	[branch "foo"]
>         	url = "company.com.xz:myrepo"
> 		fetch = refs/heads/master:refs/remotes/origin/master
> 		push = refs/heads/master:refs/heads/origin
I'd _much_ prefer (1) over (2).

However, I wonder if we couldn't do even better. How about forgetting about the "branch" vs "remote" thing, and instead splitting it into _three_: "branch", "repository" and "remote branch".

Something like
	[repo "origin"]
		url = "git://git.kernel.org/.../git.git"
	[repo "gitk"]
		url = "git://git.kernel.org/.../gitk.git"

to describe two remote repositories (and NOTE! No branch descriptions within those. We're just describing the actual repository, so we might have things like "readonly" to indicate that we can't push to them, but if we do things like that, they would be "repo-wide" things that we describe for that repository),

Then, we can describe remote branches within those repositories:
	[remote "origin/master"]
		repo = origin
		branch = master
	[remote "origin/next"]
		repo = origin
		branch = next
	[remote "origin/pu"]
		repo = origin
		branch = pu
	[remote "gitk/master"]
		repo = gitk
		branch = master

now, here we're describing two things: the name of the remote is what we will then use for the ".git/remotes/<name>" thing to remember the last value, and we're describing where to get that data (which repo, and which branch).

NOTE! In the example above, I made the name of the remote always match the <repo>/<branch> format, but that would be just a convention. You could do

	[remote "linus"]
		repo = kernel
		branch = master

to describe the "linus" remote as the master branch of the "kernel" repository.

Finally, local branches:
	[branch "master"]
		source = origin/master
	[branch "origin"]
		readonly
		source = origin/master
	[branch "next"]
		readonly
		source = origin/next
	[branch "pu"]
		readonly
		rebase
		source = origin/pu
	[branch "gitk"]
		readonly
		source = gitk/master

This marks the things that just _track_ somebody elses branch as being readonly (so "master" and "origin" are really different: they're both branches, but one of them just tracks remotes/origin/master, while the other one can be committed to), and "pu" has been marked as not only being read-only, it also re-bases to its source.

I dunno. Does this sound too verbose and abstract?

Normally, you'd not have a lot of these. For example, for somebody who follows the kernel, you'd literally just have

	[branch "master"]
		source = linus
	[remote "linus"]
		repo = kernel
		branch = master
	[repo "kernel"]
		url = git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6

and you'd be done. The above would describe both the local "master" branch and the "remotes/linus" head, and give the relationship between them.

The git repo is actually much more complex, especially if you want to track all of the different branches Junio has, and if you want to also track the branches Paul has to gitk.

But with the above, you can fairly naturally do:
 - "git pull" 
	No arguments. fetch the remote described by the current branch, 
	and merge into current branch (we might decide to fetch all the 
	remotes associated with that repo, just because once we do this, 
	we might as well, but that's not that important to the end 
	result).
 - "git pull <repo>"
	fetch all remotes that use <repo>. IFF the current branch is 
	matched to one of those remotes, merge the changes into the 
	current branch. But if you happened to be on another unrelated 
	branch, nothing happens aside from the fetch.
 - "git pull <remote>"
	fetch just the named remote. IFF that remote is also the remote 
	for the current branch, do merge it into current. Again, we 
	_might_ decide to just do the whole repo.
 - "git pull <repo> <branchname>"
	fetch the named branch from the named repository and merge it into 
	current (no ifs, buts or maybes - now we've basically overridden 
	the default relationships, so now the <repo> is just a pure 
	shorthand for the location of the repository)
 - "git pull <repo> <src>:<dst>"
	same as now. fetch <repo> <src> into <dst>, and merge it into the 
	current branch (again, we've overridden any default relationships).
but maybe this is overdesigned. Comments?
			Linus
Sean· May 22, 2006, 11:19 UTC · re: Linus Torvalds · lore

Re: Current Issues #3

On Mon, 22 May 2006 03:18:02 -0700 (PDT) Linus Torvalds <torvalds@osdl.org> wrote:

> [...]
> 
> but maybe this is overdesigned. Comments?

It all looks good, especially your description of the git pull variations which seem more natural than what exists now.

The only minor comment i'd make is that we shouldn't mix so many different names for the same thing. In your example you have "remote" (singular) sections with branch sections that contain "source" keys which map to those remote sections, both corresponding to "refs/remotes" (plural).

There doesn't seem to be any need to stick with "source" as a key, so :
[remote "origin/master"]
	repo = origin
	branch = master
[branch "master"]
	remote = "origin/master"
Sean
Jakub Narebski· May 23, 2006, 21:58 UTC · re: Linus Torvalds · lore

Re: Current Issues #3

Linus Torvalds wrote:
[...]
Show 11 quoted lines
> But with the above, you can fairly naturally do:
> 
>  - "git pull" 
> 
>       No arguments. fetch the remote described by the current branch, 
>       and merge into current branch (we might decide to fetch all the 
>       remotes associated with that repo, just because once we do this, 
>       we might as well, but that's not that important to the end 
>       result).
> 
>  - "git pull <repo>"
     (i.e. re-clone)
Show 17 quoted lines
>       fetch all remotes that use <repo>. IFF the current branch is 
>       matched to one of those remotes, merge the changes into the 
>       current branch. But if you happened to be on another unrelated 
>       branch, nothing happens aside from the fetch.
> 
>  - "git pull <remote>"
> 
>       fetch just the named remote. IFF that remote is also the remote 
>       for the current branch, do merge it into current. Again, we 
>       _might_ decide to just do the whole repo.
> 
>  - "git pull <repo> <branchname>"
> 
>       fetch the named branch from the named repository and merge it into 
>       current (no ifs, buts or maybes - now we've basically overridden 
>       the default relationships, so now the <repo> is just a pure 
>       shorthand for the location of the repository)

Fetch into curret branch, or specified by branch configuration, then current if unspecified?

Show 6 quoted lines
>  - "git pull <repo> <src>:<dst>"
> 
>       same as now. fetch <repo> <src> into <dst>, and merge it into the 
>       current branch (again, we've overridden any default relationships).
> 
> but maybe this is overdesigned. Comments?

It all means that within <repo> annd <remote> names should be unique (to know if we use "git pull <repo>" or "git pull <remote>").

Perhaps it would be nice to have
 - "git pull <repo> *:<dst>"
 - "git pull <repo> <src>:*"
 - "git pull <repo> *:*"
and
 - "git pull <repo> <src>:<dst>:<to-merge>"

as easier to remember options. Of course what is the remote branch related to <dst>, and what is local branch related to <src> would be in branch/remotes/repos configuration.

BTW. what about --use-separate-remotes option support?
-- 
Jakub Narebski
Warsaw, Poland
Martin Waitz· May 22, 2006, 10:20 UTC · re: Junio C Hamano · lore

Re: Current Issues #3

hoi :)
On Mon, May 22, 2006 at 01:44:15AM -0700, Junio C Hamano wrote:
Show 5 quoted lines
>     1. "upstream" refers to the remote section to use when
>        running "git-{fetch,pull,push}" while on that branch.
> 
> 	[branch "master"]
> 		upstream = "origin"
what do you do for [branch "next"] here?

Does it make sense to regard all refs/remotes/*/<branchname> as upstream and merge these into the current branch when pulling?

Perhaps a pull could even merge all newly fetched remote heads into the corresponding branch, but for that we'd need to be able to merge without using the working dir.

-- 
Martin Waitz
Daniel Barkalow· May 22, 2006, 21:54 UTC · re: Junio C Hamano · lore

Re: Current Issues #3

On Mon, 22 May 2006, Junio C Hamano wrote:
Show 7 quoted lines
> * reflog
> 
>   I still haven't merged this series to "next" -- I do not have
>   much against what the code does, but I am unconvinced if it is
>   useful.  Also objections raised on the list that this can be
>   replaced by making sure that a repository that has hundreds of
>   tags usable certainly have a point.

I think it would make gitweb's summary view clearer, and Linus seemed interested in being able to look up what happened in the fast forward which was the first of several merges in a day.

It could be replaced by a repository with hundreds of machine-readable tags with code to parse dates into queries for suitable tags. But I don't think there's an advantage to using the tag mechanism here, because you never want to look the history up by exactly which history it is (the thing that a tag ref is good for); you'll be looking for whatever reflog item is the newest not after a specified time, where the specified time is almost never a time that a reflog item was created.

	-Daniel
*This .sig left intentionally blank*
Carl Worth· May 22, 2006, 22:02 UTC · re: Daniel Barkalow · lore

Re: Current Issues #3

On Mon, 22 May 2006 17:54:28 -0400 (EDT), Daniel Barkalow wrote:
> On Mon, 22 May 2006, Junio C Hamano wrote:
> 
> > * reflog

Am I the only one that read that as re-flog rather than ref-log the first time?

-Carl
Shawn Pearce· May 22, 2006, 23:12 UTC · re: Daniel Barkalow · lore

Re: Current Issues #3

Daniel Barkalow <barkalow@iabervon.org> wrote:
Show 21 quoted lines
> On Mon, 22 May 2006, Junio C Hamano wrote:
> 
> > * reflog
> > 
> >   I still haven't merged this series to "next" -- I do not have
> >   much against what the code does, but I am unconvinced if it is
> >   useful.  Also objections raised on the list that this can be
> >   replaced by making sure that a repository that has hundreds of
> >   tags usable certainly have a point.
> 
> I think it would make gitweb's summary view clearer, and Linus seemed 
> interested in being able to look up what happened in the fast forward 
> which was the first of several merges in a day.
> 
> It could be replaced by a repository with hundreds of machine-readable 
> tags with code to parse dates into queries for suitable tags. But I don't 
> think there's an advantage to using the tag mechanism here, because you 
> never want to look the history up by exactly which history it is (the 
> thing that a tag ref is good for); you'll be looking for whatever reflog 
> item is the newest not after a specified time, where the specified time is 
> almost never a time that a reflog item was created.

The thing is this might also be easily represented as a structure of tags; for example:

	refs/logs/heads/<ref>/<year>/<month>/<day> <hour>:<min>:<sec>:<seq>

where the tag is a tag of the commit which was valid in that ref at that time. Searching for an entry "around a particular time" isn't that much more difficult than parsing a file, you just have to walk backwards through the sorted directory listings then read the tag object which matches; that tag object will point at the tree/commit/tag which is was in that ref..

What's ugly about this is simply the disk storage: a ref file is an expensive thing (relatively speaking) on most UNIX file systems due to the inode overhead. If this was stored in a more compact format (such as a GIT tree) then this would cost very little.

So the alternative that I have been mentaly kicking around for the past two days is storing the GIT_DIR/refs directory within a standard GIT tree. This of course would need to be an option that gets enabled by the user as currently most tools expect the refs directory to actually be a directory, not a tree. The advantage here is that unlike proposed reflog it is a compact ref representation which could be used by other features, such as tagging a GIT commit with the unique name of the same change from another SCM. Or tagging your repository on every automated build, which runs once every 5 minutes.

-- 
Shawn.

← back to recent threads