Git development
 help / color / mirror / Atom feed
* Re: multi-project repos (was Re: Cleaning up git user-interface warts)
From: Johannes Schindelin @ 2006-11-17  2:16 UTC (permalink / raw)
  To: Petr Baudis; +Cc: Linus Torvalds, Han-Wen Nienhuys, Junio C Hamano, git
In-Reply-To: <20061117015238.GD7201@pasky.or.cz>

Hi,

On Fri, 17 Nov 2006, Petr Baudis wrote:

> On Fri, Nov 17, 2006 at 02:22:35AM CET, Johannes Schindelin wrote:
> > On Thu, 16 Nov 2006, Linus Torvalds wrote:
> > > For example, if you used one of the old-fashioned commit walkers, maybe we 
> > > got the initial commit, but we may not have gotten the whole _chain_. See?
> > 
> > Huh? I am quite certain that FETCH_HEAD is not updated in that case. If it 
> > is, that's a bug.
> 
> It may be updated and then things may break _afterwards_. git-prune will
> happily blow anything referenced by FETCH_HEAD, it's not considered by
> the fsck-objects reachability analysis.

This actually underlines my point: FETCH_HEAD is no _real_ branch, not 
even a temporary one. If it was, git-prune would not lose the related 
objects.

Ciao,
Dscho

^ permalink raw reply

* Re: [ANNOUNCE] Cogito-0.18.2
From: Petr Baudis @ 2006-11-17  1:58 UTC (permalink / raw)
  To: Martin Langhoff; +Cc: git
In-Reply-To: <46a038f90611161744q6c535218n5b815ef1fc5228b6@mail.gmail.com>

On Fri, Nov 17, 2006 at 02:44:47AM CET, Martin Langhoff wrote:
> On 11/17/06, Petr Baudis <pasky@suse.cz> wrote:
> 
> >* cg-log does not follow history across renames anymore; it never really
> >  actually worked and was instead causing problems and random error
> >  messages. There needs to be git-core support for this funcionality,
> >  hacking it with a perl filter is bad design, so I'm not going to fix
> >  the filter (but I'd take patches if someone else did ;).
> 
> I was looking at the follow renames Perl script last week (hey, I was
> bored!) and while I could tell it didn't work, I did get the feeling
> that it wasn't an impossible task, at least for the 'explicit paths'
> case.

Yes. It's fixable, but IIRC the current script is fairly broken; I'd
have to look at it again to remember why, but I think I wrote it to a
comment inside there somewhere.

It would be cool if someone would fix it, of course.

> For the 'whole tree' and subpath cases it _is_ tricky, and would
> be faster to solve within git, but not impossible.
> 
> And even then, I am tempted to think that git log could provide some
> better hints than it does today when walking the whole tree or
> subpaths, so that cg-log or gitk can ask [if relevant] for selective
> rename info.
> 
> I am curious as to why you see it as bad design...

Exactly because this information is really something core Git should
provide, and I'm feeling bad for not pushing this kind of functionality
to core Git and instead going at lengths implementing it in Cogito.

The conceptually proper solution I'd imagine is

	http://news.gmane.org/find-root.php?message_id=<20060515203700.GB4497@c165.ib.student.liu.se>

(I didn't look at the actual code though), currently in limbo and
waiting for someone to fight for it. :-)

OTOH doing it in a filter simulates greatly how powerful the Git's
pipeline architecture is, and has certain undeniable cool factor
associated. ;-)

-- 
				Petr "Pasky" Baudis
Stuff: http://pasky.or.cz/
#!/bin/perl -sp0777i<X+d*lMLa^*lN%0]dsXx++lMlN/dsM0<j]dsj
$/=unpack('H*',$_);$_=`echo 16dio\U$k"SK$/SM$n\EsN0p[lN*1

^ permalink raw reply

* Re: multi-project repos (was Re: Cleaning up git user-interface warts)
From: Petr Baudis @ 2006-11-17  1:52 UTC (permalink / raw)
  To: Johannes Schindelin; +Cc: Linus Torvalds, Han-Wen Nienhuys, Junio C Hamano, git
In-Reply-To: <Pine.LNX.4.63.0611170216190.13772@wbgn013.biozentrum.uni-wuerzburg.de>

On Fri, Nov 17, 2006 at 02:22:35AM CET, Johannes Schindelin wrote:
> On Thu, 16 Nov 2006, Linus Torvalds wrote:
> > For example, if you used one of the old-fashioned commit walkers, maybe we 
> > got the initial commit, but we may not have gotten the whole _chain_. See?
> 
> Huh? I am quite certain that FETCH_HEAD is not updated in that case. If it 
> is, that's a bug.

It may be updated and then things may break _afterwards_. git-prune will
happily blow anything referenced by FETCH_HEAD, it's not considered by
the fsck-objects reachability analysis.

-- 
				Petr "Pasky" Baudis
Stuff: http://pasky.or.cz/
#!/bin/perl -sp0777i<X+d*lMLa^*lN%0]dsXx++lMlN/dsM0<j]dsj
$/=unpack('H*',$_);$_=`echo 16dio\U$k"SK$/SM$n\EsN0p[lN*1

^ permalink raw reply

* Re: Cleaning up git user-interface warts
From: Junio C Hamano @ 2006-11-17  1:49 UTC (permalink / raw)
  To: Petr Baudis; +Cc: Carl Worth, git, Andy Whitcroft, Nicolas Pitre
In-Reply-To: <20061116222008.GA7201@pasky.or.cz>

Petr Baudis <pasky@suse.cz> writes:

You already said this kind of details are subjective so I'd omit
the usual "I would think" and answer them without worrying about
a big style flamewar.  People, please be civil ;-).

> What about [ instead of test?

[ ] is not more readable.

> 	if foo; then
>
> instead of
>
> 	if foo
> 	then

Having "then" on the beginning of line is much more readable.

> Am I the only one who hates
>
> case "$log_given" in
> tt*)
>         die "Only one of -c/-C/-F can be used." ;;
> *tm*|*mt*)
>         die "Option -m cannot be combined with -c/-C/-F." ;;
> esac

This is much more readable without "case".  "abandon the old
rule that told us to avoid if when case would do" applies.
Although it is about multiple possibility switch (so a case can
be made that "case" is appropriate here), we should reduce the
use of "case" to cases like the outermost big "case" you find in
git-merge-one-file-script.

> It would be really great if Git would have something alike the Cogito's
> optparse infrastructure. I'm not sure if you can implement it in Bourne
> sh with reasonable performance, though...

getopt(1) is fine, unless somebody screams that it is not
available on his platform.

^ permalink raw reply

* Re: [ANNOUNCE] Cogito-0.18.2
From: Martin Langhoff @ 2006-11-17  1:44 UTC (permalink / raw)
  To: Petr Baudis; +Cc: git
In-Reply-To: <20061117004930.GC7201@pasky.or.cz>

On 11/17/06, Petr Baudis <pasky@suse.cz> wrote:

> * cg-log does not follow history across renames anymore; it never really
>   actually worked and was instead causing problems and random error
>   messages. There needs to be git-core support for this funcionality,
>   hacking it with a perl filter is bad design, so I'm not going to fix
>   the filter (but I'd take patches if someone else did ;).

I was looking at the follow renames Perl script last week (hey, I was
bored!) and while I could tell it didn't work, I did get the feeling
that it wasn't an impossible task, at least for the 'explicit paths'
case. For the 'whole tree' and subpath cases it _is_ tricky, and would
be faster to solve within git, but not impossible.

And even then, I am tempted to think that git log could provide some
better hints than it does today when walking the whole tree or
subpaths, so that cg-log or gitk can ask [if relevant] for selective
rename info.

I am curious as to why you see it as bad design...

cheers,



^ permalink raw reply

* Re: Cleaning up git user-interface warts
From: Michael K. Edwards @ 2006-11-17  1:34 UTC (permalink / raw)
  To: git
In-Reply-To: <455CFCBD.8040901@xs4all.nl>

I think there's a fundamental assumption built into the design of git
that most programmers accustomed to a corporate environment don't
understand.  Namely, that each programmer owns his or her entire
"repository", and can do whatever he or she darn well pleases with it
at any time.  Go ahead and create hundreds of transient branches as
part of a scripted "merge complexity metric" calculation.  Try three
different refactoring strategies on different branches, abandon two of
them, and prune them months later.  And generally use the power of the
SCM to juggle a lot of things at once, because there's no sysadmin
gatekeeper stopping you, and the thing is designed and coded scalably
so it doesn't grind to a halt as soon as everyone has dozens of
private branches.

Even if you do find a way to push git in a direction that it doesn't
scale, it's no one's problem but your own -- people who pull from you
are pulling the _content_ on the branches they care about, not the
structure of your repository.

On 11/16/06, Han-Wen Nienhuys <hanwen@xs4all.nl> wrote:
> I agree that discussions on naming may cloud the issue, but "learning
> the workflow" implies that people should adapt to the limitations of
> their tools.  That's only a viable stance when the tools are finished
> and completely perfect.
>
> Until that time, it would be good goal to remove all idiosyncrasies,
> all gratuitious asymetries and needless limitations in the commands of
> git, eg.

One person's gratuitous asymmetry is another's minimalism.  (If the
symmetric thing doesn't make any sense or can't be implemented
scalably, leave it out.)  It is more important that git continue to
work than that it appear symmetric without reference to its function.

>  - clone but not a put-clone,

What possible use would that be?  git is not rsync.

>  - pull = merge + fetch, but no command for merge + throw

pull = fetch + merge.  It is (almost?) always followed by a judgment
call based on the merge results.  merge + throw doesn't make any sense
in terms of the job at hand, which is facilitating human judgments
about whether to accept someone else's work into one's working tree.

>  - clone for getting all branches of a repo, but no command for
>    updating all branches of a repo.

clone is shorthand for the steps involved in setting up a new
repository with content similar to an existing one.  There isn't any
merge involved, and no scope for human judgment, so it's simplest to
clone the whole state of the remote repository (including tags and
branches) and let the user blow away any branches he doesn't need.
But once the clone is done, all of those branches are _truly_ _local_
-- they don't retain any reference to the remote branches, and you can
commit to all of them.  The only entry placed in .git/remotes is the
"origin" of the new clone, which is the "master" of the remote
repository.  That's for the user's convenience, and is about the only
thing in the new clone that _isn't_ a copy of something in the remote
tree.

So the "update all" process wouldn't look anything like a clone, it
would be a fetch and replay of each remote branch onto the
corresponding local branch.  You and Carl seem to want "git clone" not
only to copy the heads of the remote branches but to populate
.git/remotes with trackers for all of those branches, and then to
start each "git update" by polling all of the remote repositories to
see if branches have been created or deleted, then pull every branch
in sight.  What do you do when "upstream" creates a branch with the
same name as a local branch you have created?  How do you deal with
branch points that don't exist in your repository because you touched
one of the "tracker" branches between pulls?

In short, if you want a local, read-only tracker for a whole remote
repository instead of a branch that's actually published to you (and
maintained accordingly), you might consider s/git/rsync/.

Cheers,

^ permalink raw reply

* Re: [DRAFT] Branching and merging with git
From: Junio C Hamano @ 2006-11-17  1:31 UTC (permalink / raw)
  To: linux; +Cc: git
In-Reply-To: <20061117011319.6738.qmail@science.horizon.com>

linux@horizon.com writes:

> If anyone has any advice on how and why one would invoke git-merge
> directly (the one why I know is to do a >2-way merge), that would
> be appreciated.

I use "git pull . topicA topicB" for a tetrapus, so that is not
a reason for me, but when a topicA's older parts are worthy to
be in 'next' while later parts are not yet, I often do (on 'next'):


	git merge "Merge early part of branch 'topicA'" HEAD topicA~3

Also I used to do

	git merge fast HEAD someTopicIknowIsAFastForward

because it felt faster than "git pull . someTopicIknowisAFastForward"
but I do not do that these days and I would not recommend it to anybody.

>>> 2) Revert changes to a small number of files.
>>>
>>> 	git checkout [<revision>] [--] <paths>
>>>    will copy the version of the <paths> from the index to the working
>>>    directory.  If a <revision> is given, the index for those paths will
>>>    be updated from the given revision before copying from the index to
>>>    the working tree.
>>>
>>>    Unlike the version with no <paths> specified, this does NOT update
>>>    HEAD, even if <paths> is ".".
>> 
>> It's great that you talk correctly about the latest feature-fix
>> that is queued for maint but not yet pushed out.
>
> Um... there's a fix in there?  I thought that's how it always worked.

I do not think naming a directory (say, ".") to mean "revert
everything underneath this directory" worked until the patch I
sent out post 1.4.4 release.

> I also need to mention that if you want to pull a remote tag,
> you need to prefix it with "tags/".

Yes, recent -mm announce message says "git pull ... tag v2.x-mmY".
"tag v2.x-mmy" is a shorthand for "refs/tags/v2.x-mmY:refs/tags/v2.x-mmY"


^ permalink raw reply

* Re: Cleaning up git user-interface warts
From: Carl Worth @ 2006-11-17  1:25 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: hanwen, git
In-Reply-To: <7vmz6r2amf.fsf@assigned-by-dhcp.cox.net>

[-- Attachment #1: Type: text/plain, Size: 1788 bytes --]

On Thu, 16 Nov 2006 16:13:44 -0800, Junio C Hamano wrote:
> This one I can understand, but how would you propose to "update
> all branches", in other words what's your design for mapping
> remote branch names to local branch namespaces?

What I want here is a command "git update" that fetches and
fast-forwards the all branches which are designated as "tracking" a
branch in some known remote repository. And git-clone would setup all
branches appropriately so that they would be updated by git-update.

Additionally, it would be nice if git-update would also create new
tracking branches for all remotes repositories that had been
designated as being tracked, (and git-clone would do this as well).

There should also be a mechanism to easily create new tracking support
for specific branches or all branches of a repository, (could be "git
fetch URL branch" or "git fetch --all URL", for example).

With this kind of setup, I would use "git update" regularly, and only
ever merge locally. And by definition merging with any local tracking
branch would have just as much information available as "pull URL
branch" so the message would be the same.

I've been using git for 10-11 months, so I think I understand the
models fairly well, and I'd be really happy with a setup like that. I
also have talked with a fair number of (non-git-using) users who think
git is confusing, but I think would find the above scenario just fine.

In this scenario, git pull would still work just fine, but it would
also be much easy to teach a workflow that didn't use pull at all, so
if there's any git-pull confusion that's an actual problem, it could
be avoided.

Junio, what do you think of a setup something like that? I really
don't want to create a command other than "git" to implement it.

-Carl

[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply

* Re: multi-project repos (was Re: Cleaning up git user-interface warts)
From: Johannes Schindelin @ 2006-11-17  1:22 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Han-Wen Nienhuys, Junio C Hamano, git
In-Reply-To: <Pine.LNX.4.64.0611161642320.3349@woody.osdl.org>

Hi,

On Thu, 16 Nov 2006, Linus Torvalds wrote:

> On Fri, 17 Nov 2006, Johannes Schindelin wrote:
> 
> > Besides, it is not really a temporary branch. If it was, the pull would 
> > _not_ download all these objects again, would it?
> 
> Well, exactly because they are temporary, we can't actually trust the 
> objects they point to.

Nonono.

We made _sure_ that FETCH_HEAD is only written once _all_ the objects were 
received. So, actually, we _can_, and we _should_ trust the objects they 
point to!

Or did I miss something?

> For example, if you used one of the old-fashioned commit walkers, maybe we 
> got the initial commit, but we may not have gotten the whole _chain_. See?

Huh? I am quite certain that FETCH_HEAD is not updated in that case. If it 
is, that's a bug.

Ciao,

^ permalink raw reply

* Re: [DRAFT] Branching and merging with git
From: linux @ 2006-11-17  1:13 UTC (permalink / raw)
  To: junkio, linux; +Cc: git
In-Reply-To: <7vslgj2bug.fsf@assigned-by-dhcp.cox.net>

> I find it very balanced to point out the quirks people
> would find difficult and explain why things are so by including
> historical notes in appropriate places when needed.

I'm trying; I've been following git since day 1, so occasionally an
obsolete fact gets stuck in my head.

If anyone has any advice on how and why one would invoke git-merge
directly (the one why I know is to do a >2-way merge), that would
be appreciated.

> I have finished only the first half because it's not my git day
> today, but so far...

Well, thank you for your time!

>> * Naming revisions
>>...
>> Second, you can refer to a head or tag name.  Git looks in the
>> following places, in order, for a head:
>> 	1) .git
>> 	2) .git/refs
>> 	3) .git/refs/heads
>> 	4) .git/refs/tags
> 
> You might want to check this with the array in sha1_name.c::get_sha1_basic().
> I think tags comes earlier than heads.

Quite right.  It's

        static const char *fmt[] = {
                "%.*s",
                "refs/%.*s",
                "refs/tags/%.*s",
                "refs/heads/%.*s",
                "refs/remotes/%.*s",
                "refs/remotes/%.*s/HEAD",
                NULL
        };

>> 2) Revert changes to a small number of files.
>>
>> 	git checkout [<revision>] [--] <paths>
>>    will copy the version of the <paths> from the index to the working
>>    directory.  If a <revision> is given, the index for those paths will
>>    be updated from the given revision before copying from the index to
>>    the working tree.
>>
>>    Unlike the version with no <paths> specified, this does NOT update
>>    HEAD, even if <paths> is ".".
> 
> It's great that you talk correctly about the latest feature-fix
> that is queued for maint but not yet pushed out.

Um... there's a fix in there?  I thought that's how it always worked.

> "If there's a side branch which does NOT touch the paths..." I think.

Ah, yes, I added include/scsi to the example to illustrate how
mutiple paths worked and didn't update the later paragraph.

>> * Alternate branch naming
>>
>> The original git scheme mixes tracking branches with all the other heads.
>> This requires that you remember which branches are tracking branches and
>> which aren't.  Hopefully, you remember what all your branches are for,
>> but if you track a lot of remote repositories, you might not remember
>> what every remote branch is for and what you called it locally.
> 
> I think you wanted to mention .git/refs/remotes hierarchy and
> separate-remote here, but haven't elaborated yet...

Yes, sorry.  I meant to research that and update this (I've never used
it before), but I forgot.

>> * Remote tags
>>
>> TODO: Figure out how remote tags work, under what circumstances
>> they are fetched, and what git does if there are conflicts.
> 
> refs/tags namespace is not policed at all by git and is treated
> as a global namespace, controlled mostly by social convention
> that your "upstream" (or central distribution point) supplies
> tags for people who use it to synchronize to share.  Also, since
> there is no guarantee that tags point at commits (v2.6.11-tree
> tag is a pointer to a tree object, for example), there is no
> farst-forward check performed for them.
> 
> The rule we use to autofollow tags currently is:
> 
> When you use shorthand fetch (or pull), we find tags that do not
> exist locally, and if the object they point at are already found
> in the repository then we fetch them automatically.  So for
> example, if you are only tracking my 'maint' and not 'master'
> nor 'next', and if you have tags up to v1.4.3.2, your "git fetch
> origin" would update your copy of 'maint' and bring the commits
> reachable from the tip of my 'maint'.  After that it notices
> that v1.4.3.3, v1.4.3.4, v1.4.3.5 tags are in my repository but
> missing from yours. It also notices that now you have
> v1.4.3.3^{}, v1.4.3.4^{} and v1.4.3.5^{} in your repository, so
> it issues another round of "git fetch" internally to fetch these
> three tags.  At the same time it would also notice that I have
> v1.4.4 tag that you do not have, but v1.4.4^0 commit is not
> something you would get by fetching 'maint', so it would not
> fetch it automatically.

Ah, okay.  Actually, v2.6.11-tree is a tag object
(5dc01c595e6c6ec9ccda4f6f69c131c0dd945f8c) which points
to a tree object (c39ae07f393806ccf406ef966e9a15afc43cc36a).

I was wondering if git only shared refs/tags that pointed to
heavyweight tag objects and not lightweight tags.

That appears to be the case:

mkdir a b
cd a
git-init-db
echo "Hello, world" > hello
git add hello
git commit -m "Initial commit"
git tag light
git tag -a -m "Test tag" heavy
cd ../b
git-init-db
echo "URL: ../a" > .git/remotes/a
echo "Pull: master:origin" >> .git/remotes/a
git fetch a

But!  It only fetches tags if you specify a destination branch name.
I hadn't noticed that before, but "git-fetch <url> foo" and
"git-fetch <url> foo:foo" do different things on the receiver.
Didn't they used to be synonyms?
(I think it's a net gain in flexibility.)

Oh!  Also, the git-pull man page says that multiple branch names are
allowed, even though the SYNOPSIS line says no.

I also need to mention that if you want to pull a remote tag,
you need to prefix it with "tags/".  For some reason, the search

^ permalink raw reply

* Re: [DRAFT] Branching and merging with git
From: Junio C Hamano @ 2006-11-17  1:09 UTC (permalink / raw)
  To: linux; +Cc: git
In-Reply-To: <20061116221701.4499.qmail@science.horizon.com>

linux@horizon.com writes:

> One outstanding problem with git's man pages is that often the most detail
> is in the command page that was written first, not the user-friendly
> one that you should use.

This is a very important point to remember not for users but for
us in git community.  Thanks for writing it down.

> * Git's representation of history
>...
> And then there are commits which have multiple parents.  Two is most
> common, but git allows many more.  (There's a limit of sixteen in the
> source code, and the most anyone's ever used in real life is 12, and
> that was generally regarded as overdoing it.  Google on "doedecapus"
> for discussion of it.)

Dodecapus would find a few, no hits on doedecapus ;-).

> * Deleting branches
>
> "git branch -d <head>" is safe.  It deletes the given <head>, but first
> it checks that the commit is reachable some other way.  That is, you
> merged the branch in somewhere, or you never did any edits on that branch.

It is not "somewhere" but "in the current branch", so in a sense
it is a bit stricter than that.  While on 'master' "branch -d
topic" would not remove the topic branch head if it is not fully
merged to my 'master' so that is a reasonable safety measure,
but when I am on 'next' it will happily remove it.  It is
recoverable because it is reachable from 'next', though.

> * Remote tags
>
> TODO: Figure out how remote tags work, under what circumstances
> they are fetched, and what git does if there are conflicts.

One bug in my previous response is that I said we do this only
when the command was invoked with shorthand remote name.  Not
so.  We do this only when we use tracking branches.

The reason is because 'git pull $url $branch' (typical Linus's
use) and 'git pull' (defaulting to 'origin' and using the
tracking branch mapping stored in .git/remotes/origin prepared
by git-clone) are sign of very different workflows.  The former
tends to be a one-shot event while the latter is most often
synchronizing with either an upstream or a common distribution
point (i.e. shared central repostiory).  When you are fetching
from somebody in a one-shot manner, most likely as a part of
'pull', you do not want to get the tag the other person has made
to mark his private work in progress.  But in the latter case,
the other end is where everybody who works in the same area
fetches from, and sharing the tags found there among the
developers by default is desirable, and more importantly there
is no risk of accidentally getting private tags, since the other
end is a public distribution point and by definition should not
have private tags that would clutter your refs/tags hierarchy.

> * Exchanging work with other repositories, part II: git-push
>...
> You have to merge the changes locally, and re-try the push when you've
> got a new head that includes the most recently pushed work as an ancestor.
>
> This is exactly like "cvs commit" not working if your recent checkout
> wasn't the (current) tip of the branch, but git can upload more than
> one commit.
>
> The simplest way to resolve the conflict is to merge the remote head with
> your local head.  This is easiest if you have different local branches
> for fetching the remote repository and for pushing to it.
>
> That is, you have one head that just tracks the master repository's
> main branch, and another that you add your work to, and push from.
> This makes merging simpler when there are conflicts.

Here you _might_ want to mention an alternative workflow that
uses rebase, which seems to be the way Wine folks run their
project.  Talking about all the different possibilities tends to
cloud things and may not add value to the document, so I am just
mentioning it as a possibility but I do not know if talking
about rebase is useful in the context of this document.

> * Merging (finally!)
>
> I went through everything else first because the most common merge case
> is local changes with remote changes.  Not that you can't merge two
> branches of your own, but you don't need to do that nearly as often.
>
> The primitive that does the merging is called (guess what?) git-merge.
> And you can use that if you want.  If you want to create a so-called
> octopus merge, with more than two parents, you have to.

This is not true; "git pull . topicA topicB topicC" works as
expected.  But we probably would not want to even talk about
Octopus in a document like this.  It is a curosity, and
sometimes tends to make histories even less cluttered, but
otherwise it does not add much value.

> However, it's usually easier to use the git-pull wrapper.  This merges
> the changes from some other branch into the current HEAD and generates
> a commit message automatically.
>
> git-merge lets you specify the commit message (rather than generating it
> automatically) and use a non-HEAD destination branch, but those options
> are usually more annoying than useful.

I haven't tried for a long time, but I do not think non-HEAD
destination even works at all.  It might be better not to even
mention git-merge at this point of the document.

> * How merging operates
>...
> If all three of a given file in O, A, B are different, then the three
> versions are pulled into the index file, called "stage 1", "stage 2",
> and "stage 3", and a merge strategy driver is called to resolve the mess.
> Git then uses the classic line-based three-way merge, looking for isolated
> changes and applying the same rules as for files when two of the source
> files are the same in some range.

You might also want to mention that recursive first 3-way merges
the renames.  If O->A renames a path while O->B keeps it, the
resulting stages are written under the new name.

> * When merging goes wrong
>...
> and the result of "git diff" is
>
> diff --cc hello.c
> index 4b7f550,948a5f8..0000000
> --- a/hello.c
> +++ b/hello.c
> @@@ -3,5 -3,6 +3,10 @@@
>   int
>   main(void)
>   {
> ++<<<<<<< HEAD/hello.c
>  +      printf("Goodbye, cruel world!");
> ++=======
> +       printf("Hello, world!\n");
> +       return 0;
> ++>>>>>>> edadc53fc7a8aef2a672a4fa9d09aa16f4e14706/hello.c
>   }
>
> Notice how this is not a standard diff!  It has two columns of diff
> symbols, and shows the difference from each of the ancestors to the
> current hello.c contents.  I can also use "git diff -1" to compare
> against the common ancestor, or "-2" or "-3" to compare against each of
> the merged copies individually.

Another tool to help the user decide how the mess should be
sorted out is "git log --merge -- $path".  It gives the logs of
commits that touched the path while the two branches were forked.

> * Cherry picking
>...
> You van get the list of commits on a branch with git-log or git-rev-list,

s/van/can/

> * Rebasing
>...
> Git-rebase can also help you divide up work.  Suppose you've mixed up
> development of two features in the current HEAD, a branch called "dev".

Ancestry graph before and after this procedure would help the
reader a lot here.

>...
> This will find all patches that are in dev and not in dev1,
> apply them on top of master, and call the result dev2.

> * Experimenting with merging
>...
> $ git status
> Hey, look, lots of interesting stuff.  Particularly, see
> # Changed but not updated:
> #   (use git-update-index to mark for commit)
> #
> #       unmerged: Makefile
> #       modified: Makefile
> #       unmerged: builtin.h
> #       modified: builtin.h
> #       unmerged: git.c
> #       modified: git.c
>
> The "unmerged" (a.k.a. "staged") files are ones that need manual resolution.
>
> (I notice that update-index.c isn't listed, despite being mentioned
> as a conflict in the message.  Can someone explain that?)

They were conflicts during the virtual ancestor computation by
recursive (the merge between 'a' and 'b' commits in your earlier
example).  When a virtual ancestor is created, it can textually
have conflicted merge, but that is recorded along with conflict
markers without manual resolving for obvious reasons.  If two
branches that use the virtual ancestor modifies the conflicted
region the same way (because they needed to resolve that
conflict in their branch), the final 3-way merge that uses the
virtual ancestor as the merge-base will replace that conflicted
region with their changes.  This "even conflict markers can be
eliminated by a merge resolution" behaviour is what inspired
git-rerere, by the way.

If you are using this particular commit as an example, you might
also want to tell your readers about:

	git show -M 3f69d405

(-M is there to make the output more readable, because this
merge involved a few renames).

^ permalink raw reply

* Re: multi-project repos (was Re: Cleaning up git user-interface warts)
From: Carl Worth @ 2006-11-17  1:08 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Johannes Schindelin, Han-Wen Nienhuys, Junio C Hamano, git
In-Reply-To: <Pine.LNX.4.64.0611161642320.3349@woody.osdl.org>

[-- Attachment #1: Type: text/plain, Size: 2517 bytes --]

On Thu, 16 Nov 2006 16:49:29 -0800 (PST), Linus Torvalds wrote:
> So in many ways, HEAD, FETCH_HEAD, MERGE_HEAD and ORIG_HEAD are more
> fundamental than any long-term branch has ever been, and maybe they should
> be taught first as such.

Older in git's history as it developed is not a good match for more
fundamental in the concepts that git makes available today.

> > > Again, why didn't you use FETCH_HEAD?
> >
> > Because I am a Jar-HEAD?
>
> Well, we clearly should document them better. Anybody?

I for one am totally unsatisfied with this approach.

Here's an operations I'd like to be able to do:

	Given a (URL, branch) pair I'd like I'd like to be able to
	investigate that code, (say with the fancy new "read-only
	branch" concept we've been talking about).

What are my options for this operation? What might a new user's
reaction to them be?

a) git fetch URL branch
   git checkout FETCH_HEAD

   This is really ugly. A name like "FETCH_HEAD" is something a user
   should really never have to type. It's hideously hard to type and
   has no natural discoverability. Yuck, yuck, yuck.

b) vi .git/remotes/something
   git fetch something
   git checkout branch

   Also yuck. I hope it's obvious that having to edit a configuration
   for this simple operation is a non-starter.

c) git fetch URL branch:local-branch
   git checkout local-branch

   We're getting close to the desired functionality now, but the UI
   makes users cringe? "What's that : for?" Why do I need another
   name?" etc. Linus, you yourself said this is a form that users
   should generally avoid.

d) git fetch URL branch:branch
   git checkout branch

   One step closer. But there's still that goofy extra ':' and a
   doubled name in the first command. "Why is that there? Git sure is
   weird...".

What I think this operation should look like is:

	git fetch URL branch
	git checkout branch

And the fetch should just complain if there's a name clash. Or better,
the fetch should tuck the fetched branch into its own URL-specific
namespace and then the checkout command can kindly prompt if there is
any ambiguity:

	Which "branch" do you want?
		local/branch
		remote-url/branch

or whatever.

See? That's what reasonable UI should look like.

Please feel free to keep using vestiges like FETCH_HEAD as much as you
like, but please don't recommend documenting them better as a solution
for UI warts in git. (If you would only look at these warts closer,
you'd see they have some lovely locks of hair on them.)

-Carl

[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply

* Re: Cleaning up git user-interface warts
From: Han-Wen Nienhuys @ 2006-11-17  0:52 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Junio C Hamano, git
In-Reply-To: <Pine.LNX.4.64.0611161623170.3349@woody.osdl.org>

Linus Torvalds escreveu:
> The fact that we can do "git clone" on the _receiving_ side is an 
> assymmetry, but it's not gratutous: when receiving we don't need any extra 
> permissions or setup to create a new archive. In contrast, when sending, 
> you do have to have that "get permission to create new archive" phase.
> 
>>  - pull = merge + fetch, but no command for merge + throw
> 
> Again, this is not gratuitous, and the reason is very similar: when you 
> pull, you're pulling into something that _you_ control and _you_ have 

>But "push" and "pull" _fundamentally_ aren't symmetric operations, and you 
>simply cannot possibly make them symmetric. 

Point taken;  thank you. 

In that case, we're full circle with the command naming issues. Push
and pull are fundamentally asymmetric operations, but then a
consistent UI would dictate that they wouldn't be named symmetrically,
as they are now.


-- 

^ permalink raw reply

* Re: multi-project repos (was Re: Cleaning up git user-interface warts)
From: Linus Torvalds @ 2006-11-17  0:49 UTC (permalink / raw)
  To: Johannes Schindelin; +Cc: Han-Wen Nienhuys, Junio C Hamano, git
In-Reply-To: <Pine.LNX.4.63.0611170013590.13772@wbgn013.biozentrum.uni-wuerzburg.de>



On Fri, 17 Nov 2006, Johannes Schindelin wrote:
> > Why? We _do_ have the temporary branch. It's called FETCH_HEAD.
> 
> It is a terrible UI, because it was not that obvious to me. And I consider 
> myself not a git newbie.

Heh. The "temporary branches" are actually the _original_ branches as far 
as git is concerned. The long-term branches only came later.

So in many ways, HEAD, FETCH_HEAD, MERGE_HEAD and ORIG_HEAD are more 
fundamental than any long-term branch has ever been, and maybe they should 
be taught first as such.

So you're newbie enough that you've only seen those new-fangled "real" 
branches.

When I was young, we had to walk to school up-hill in three feet of snow 
every day. And we _liked_ our FETCH_HEAD's.

> Besides, it is not really a temporary branch. If it was, the pull would 
> _not_ download all these objects again, would it?

Well, exactly because they are temporary, we can't actually trust the 
objects they point to. They have no "real" long-term life, so no, I'm 
afraid that we always will have to re-fetch the objects, because fetching 
them is the only way to know that we still have them. 

That said, we could certainly _make_ them be honored by things like "git 
prune" and friends. But yes, they really _are_ temporary branches right 
now, and part of the meaning of that "temporary" is exactly the fact that 
git fetch will not trust that you still have the objects. 

For example, if you used one of the old-fashioned commit walkers, maybe we 
got the initial commit, but we may not have gotten the whole _chain_. See?

Temporary branch indeed.

> > Again, why didn't you use FETCH_HEAD?
> 
> Because I am a Jar-HEAD?

Well, we clearly should document them better. Anybody?


^ permalink raw reply

* [ANNOUNCE] Cogito-0.18.2
From: Petr Baudis @ 2006-11-17  0:49 UTC (permalink / raw)
  To: git; +Cc: linux-kernel

  Hello,

  I've released cogito-0.18.2, bringing a couple of bugfixes and a trivial new
feature to cogito-0.18.1. Still nothing too groundshattering.

* cg-log does not follow history across renames anymore; it never really
  actually worked and was instead causing problems and random error
  messages. There needs to be git-core support for this funcionality,
  hacking it with a perl filter is bad design, so I'm not going to fix
  the filter (but I'd take patches if someone else did ;).

* Fix cg-init not letting you edit the initial commit message by default
* Fix cg-clone -l which would not setup alternates properly in some cases
* Fix cg-merge not picking the right base when following volatile branches
* Fix cg-log -d sometimes showing "% @" in diff output
* Some other minor fixes

* New cg-object-id -b to print the current branch name

* Documentation improvements (better documented ignoring mechanism,
  ~/.gitconfig mentioned, GIT_COMMITTER_* bogus information fixed, ...)
* Some testsuite fixes

  Happy hacking,

-- 
				Petr "Pasky" Baudis
Stuff: http://pasky.or.cz/
Of the 3 great composers Mozart tells us what it's like to be human,
Beethoven tells us what it's like to be Beethoven and Bach tells us

^ permalink raw reply

* Re: Cleaning up git user-interface warts
From: Linus Torvalds @ 2006-11-17  0:39 UTC (permalink / raw)
  To: Han-Wen Nienhuys; +Cc: Junio C Hamano, git
In-Reply-To: <455CFCBD.8040901@xs4all.nl>



On Fri, 17 Nov 2006, Han-Wen Nienhuys wrote:
> 
> Until that time, it would be good goal to remove all idiosyncrasies,
> all gratuitious asymetries and needless limitations in the commands of
> git, eg.

Well, a lot of the assymmetries aren't actually gratuitous at all.

>  - clone but not a put-clone,

As mentioned, in order to "put-clone", you generally have to "create" 
first, so the "put-clone" really makes no sense.

The _true_ reverse is really your

 - "git init-db" on both sides

 - "git pull" (your workflow ;) on receiving

 - "git push" on sending.

The fact that we can do "git clone" on the _receiving_ side is an 
assymmetry, but it's not gratutous: when receiving we don't need any extra 
permissions or setup to create a new archive. In contrast, when sending, 
you do have to have that "get permission to create new archive" phase.

>  - pull = merge + fetch, but no command for merge + throw

Again, this is not gratuitous, and the reason is very similar: when you 
pull, you're pulling into something that _you_ control and _you_ have 
access to, namely your working directory. In order to merge you have to 
have the ability to fix up conflicts (whether automatically or manually), 
and this is something that you _fundamentally_ can only do when you own 
the repo space.

Again, when you do "push", the reason you can't merge is not a "gratuitous 
assymmetry", but a _fundamental_ assymmetry: by definition, you're pushing 
to a _remote_ thing, and as such you can't merge, because you can't fix up 
any merge problems.

See?

In many ways, if you want _symmetry_, you need to make sure that the 
_cases_ are symmetrical. If you have ssh shell access, you can often do 
that, and the "reverse" of a "git pull" is actually just another "git 
pull" from the other side:

	ssh other-side "cd repo ; git pull back"

Now they really _are_ symmetrical: "git pull" is really in many ways ITS 
OWN reverse operation. 

But "push" and "pull" _fundamentally_ aren't symmetric operations, and you 
simply cannot possibly make them symmetric. Any system that tries would be 
absolutely horrible to use, exactly because it would be either:

 - making local/remote operations totally equivalent

   This sounds like a "good" thing, but from a real user perspective it's 
   actually horribly horribly bad. Knowing the difference between local 
   and remote is what allows a lot of performance optimizations, and a lot 
   of security. Your local repo is _yours_, and nobody can take that away 
   from you, and that's a really fundamental reason for why the symmetry 
   cannot exist, and why local/remote operations MUST NOT be something 
   that you can mix without thinking about them,

 - limit local operations in a way to make them effectively unusable and 
   unscriptable.

   You'd basically have to do everything even _locally_ through some 
   server interface, and you'd not be allowed to ever touch your local 
   checked-out repository directly. Again: local repositories really _are_ 
   special, because you can touch the checked out copy. If you try to 
   suppress that, you're screwed.

>  - clone for getting all branches of a repo, but no command for
>    updating all branches of a repo.  

As in sending? Sure there is: use "git push --all". It will push out every 
branch (and tag) you have. Add "--force" if you want to make sure that it 
also pushed out branches even if the result isn't a strict superset (of 
course, the receiving end may actually end up refusing to take it, there's 
a option for the receiver to say "I will refuse any update that isn't a 
strict superset of what I had").

If you mean as in "receiving new branches", then yeah, you do have to 
script it, with some fairly trivial "git ls-remote" to make sure you get 
the new remotes.


^ permalink raw reply

* Re: Cleaning up git user-interface warts
From: Carl Worth @ 2006-11-17  0:37 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: hanwen, git
In-Reply-To: <7vmz6r2amf.fsf@assigned-by-dhcp.cox.net>

[-- Attachment #1: Type: text/plain, Size: 760 bytes --]

On Thu, 16 Nov 2006 16:13:44 -0800, Junio C Hamano wrote:
> >  - clone for getting all branches of a repo, but no command for
> >    updating all branches of a repo.

I want this one as well.

> This one I can understand, but how would you propose to "update
> all branches", in other words what's your design for mapping
> remote branch names to local branch namespaces?

As long as its consistent with "clone" I'll be happy, (I think as part
of a separate topic we need to fix the mappings in clone, see
--use-separate-remotes as default and related).

The current case is really annoying where I have to throw use clone
into a new repository just to get everything, rather than just being
able to fetch everything into the repository I already have.

-Carl

[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply

* Re: Cleaning up git user-interface warts
From: Petr Baudis @ 2006-11-17  0:35 UTC (permalink / raw)
  To: Han-Wen Nienhuys; +Cc: Junio C Hamano, git
In-Reply-To: <455D0209.7070608@xs4all.nl>

On Fri, Nov 17, 2006 at 01:27:53AM CET, Han-Wen Nienhuys wrote:
> put clone would be the putative inverse of clone, ie. make a clone of
> a local repository on a remote server.

So effectively to tell git push not to unpack on the remote side, and to
push all branches and relevant tags.

..snip..
> It's more logical for clone to either
> 
>  * leave all names unchanged
> 
>  * put all remote branches into a subdirectory.  This would also make
>    it easier to track branches from multiple servers.
> 
>    At present,  I have in my build-daemon the following branches,
> 
> 	cvs-head-repo.or.cz-lilypond.git
> 	hanwen-repo.or.cz-lilypond.git
> 	hwn-jcn-repo.or.cz-lilypond.git
> 	lilypond_1_0-repo.or.cz-lilypond.git
> 	lilypond_1_2-repo.or.cz-lilypond.git
> 	lilypond_1_4-repo.or.cz-lilypond.git
> 	lilypond_1_6-repo.or.cz-lilypond.git
> 	lilypond_1_8-repo.or.cz-lilypond.git
> 	lilypond_2_0-repo.or.cz-lilypond.git
> 	lilypond_2_2-repo.or.cz-lilypond.git
> 	lilypond_2_3_2b-repo.or.cz-lilypond.git
> 	lilypond_2_3_5b-repo.or.cz-lilypond.git
> 	lilypond_2_4-repo.or.cz-lilypond.git
> 	lilypond_2_6-repo.or.cz-lilypond.git
> 	lilypond_2_8-repo.or.cz-lilypond.git
> 	master-git.sv.gnu.org-lilypond.git
> 	master-hanwen
> 	master-repo.or.cz-lilypond.git
> 	origin-repo.or.cz-lilypond.git
> 	stable
> 	stable-2.10
> 	stable--2.10-git.sv.gnu.org-lilypond.git
> 
>   It would solve lots of problems for me if cloning and fetching would
>   put branches into a subdirectory, ie.
> 
>     git clone git://repo.or.cz/lilypond.git
> 
>   leads to branches
> 
>     repo.or.cz/lilypond_2_8
>     repo.or.cz/lilypond_2_6
>     repo.or.cz/lilypond_2_4
>     repo.or.cz/master
>      (etc..)

That's basically exactly what git clone --use-separate-remote should do.
Now only if it would become the default... :-)

-- 
				Petr "Pasky" Baudis
Stuff: http://pasky.or.cz/
#!/bin/perl -sp0777i<X+d*lMLa^*lN%0]dsXx++lMlN/dsM0<j]dsj
$/=unpack('H*',$_);$_=`echo 16dio\U$k"SK$/SM$n\EsN0p[lN*1

^ permalink raw reply

* Re: multi-project repos
From: Johannes Schindelin @ 2006-11-17  0:29 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <7vmz6r3tat.fsf@assigned-by-dhcp.cox.net>

Hi,

On Thu, 16 Nov 2006, Junio C Hamano wrote:

> I think the earlier write-up by Linus on magic HEADs would help 
> documenting FETCH_HEAD better.

I am not sure that documenting FETCH_HEAD better would help. As Han-Wen 
pointed out (and some colleagues of mine who would never subscribe to a 
mailing list), people do not read the manual, but rather try to wrap their 
heads around the inner workings from the interface. And FETCH_HEAD just 
does not meet _any_ expectation a sane (read: untainted) user might have.

While I'm at it: the problem I pointed out with -pull may annoy just me.

But there is another problem with "git fetch": a common work flow is 
tracking other peoples branches. And since git makes it so easy to 
have multiple branches, chances are that you track more than one 
branch per remote repository.

Now, an old gripe of mine was the lack of "git fetch --all". I wrote a 
script for that (Linus would be proud of me!), which just does "git 
ls-remote" and constructs a command line for "git fetch" from that.

But even if you agree with the common story that you should specify the 
branches you want to track: it is hard!

If I were new to git, after reading some tutorials I would _expect_ "git 
fetch" to be the tool to track branches. (I posted a patch to at least be 
able to store the current "git fetch" command line under a nick IIRC). But 
it does not.

(Of course, after reading several documentation, as a new user I would 
eventually find that I should edit .git/remotes/<nick>, or even 
edit/-repo-config the remotes information in the config, but I would fully 
expect a new user to give up before reaching that stage.)

But maybe I got it all wrong and this is not the common expectation...

Ciao,
Dscho

^ permalink raw reply

* Re: Cleaning up git user-interface warts
From: Han-Wen Nienhuys @ 2006-11-17  0:27 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <7vmz6r2amf.fsf@assigned-by-dhcp.cox.net>

Junio C Hamano escreveu:
> Han-Wen Nienhuys <hanwen@xs4all.nl> writes:
> 
>>  - clone but not a put-clone,
> 
> What's put-clone?  Care to explain?

put clone would be the putative inverse of clone, ie. make a clone of
a local repository on a remote server.

>>  - pull = merge + fetch, but no command for merge + throw
> 
> What's merge+throw?  Care to explain?

throw is the hypothetical opposite of fetch. I agree that this is
academical, because it's logical to only allow fast-forwards for
sending revisions.

>>  - clone for getting all branches of a repo, but no command for
>>    updating all branches of a repo.  
> 
> This one I can understand, but how would you propose to "update
> all branches", in other words what's your design for mapping
> remote branch names to local branch namespaces?
> 
> It would be nice if the design does not straightjacket different
> repository layouts different people seem to like, but I think it
> would be Ok to limit ourselves only to support the straight
> one-to-one mapping and support only separate-remote layout.

I think the whole clone design is a bit broken, in that the "master"
branch gets renamed or copied to "origin", but all of the other
branches remain unchanged in their names.

It's more logical for clone to either

 * leave all names unchanged

 * put all remote branches into a subdirectory.  This would also make
   it easier to track branches from multiple servers.

   At present,  I have in my build-daemon the following branches,

	cvs-head-repo.or.cz-lilypond.git
	hanwen-repo.or.cz-lilypond.git
	hwn-jcn-repo.or.cz-lilypond.git
	lilypond_1_0-repo.or.cz-lilypond.git
	lilypond_1_2-repo.or.cz-lilypond.git
	lilypond_1_4-repo.or.cz-lilypond.git
	lilypond_1_6-repo.or.cz-lilypond.git
	lilypond_1_8-repo.or.cz-lilypond.git
	lilypond_2_0-repo.or.cz-lilypond.git
	lilypond_2_2-repo.or.cz-lilypond.git
	lilypond_2_3_2b-repo.or.cz-lilypond.git
	lilypond_2_3_5b-repo.or.cz-lilypond.git
	lilypond_2_4-repo.or.cz-lilypond.git
	lilypond_2_6-repo.or.cz-lilypond.git
	lilypond_2_8-repo.or.cz-lilypond.git
	master-git.sv.gnu.org-lilypond.git
	master-hanwen
	master-repo.or.cz-lilypond.git
	origin-repo.or.cz-lilypond.git
	stable
	stable-2.10
	stable--2.10-git.sv.gnu.org-lilypond.git

  It would solve lots of problems for me if cloning and fetching would
  put branches into a subdirectory, ie.

    git clone git://repo.or.cz/lilypond.git

  leads to branches

    repo.or.cz/lilypond_2_8
    repo.or.cz/lilypond_2_6
    repo.or.cz/lilypond_2_4
    repo.or.cz/master
     (etc..)

	
-- 

^ permalink raw reply

* Re: Cleaning up git user-interface warts
From: Junio C Hamano @ 2006-11-17  0:13 UTC (permalink / raw)
  To: hanwen; +Cc: git
In-Reply-To: <455CFCBD.8040901@xs4all.nl>

Han-Wen Nienhuys <hanwen@xs4all.nl> writes:

>  - clone but not a put-clone,

What's put-clone?  Care to explain?

>  - pull = merge + fetch, but no command for merge + throw

What's merge+throw?  Care to explain?

>  - clone for getting all branches of a repo, but no command for
>    updating all branches of a repo.  

This one I can understand, but how would you propose to "update
all branches", in other words what's your design for mapping
remote branch names to local branch namespaces?

It would be nice if the design does not straightjacket different
repository layouts different people seem to like, but I think it
would be Ok to limit ourselves only to support the straight
one-to-one mapping and support only separate-remote layout.

^ permalink raw reply

* Re: Cleaning up git user-interface warts
From: Han-Wen Nienhuys @ 2006-11-17  0:11 UTC (permalink / raw)
  To: Petr Baudis; +Cc: Carl Worth, git, Andy Whitcroft, Nicolas Pitre
In-Reply-To: <20061116051240.GV7201@pasky.or.cz>

Petr Baudis escreveu:
> (vi) Coding issues. This is probably very subjective, but a blocker for
> me. I have no issues about C here, but about the shell part of Git.
> Well, how to say it... It's just fundamentally incompatible with me. I

(on a tangent)

I concur, but probably in a different way.

some 10 years ago I vowed never to write perl code again, and some 5
years ago, I made the same pledge for shell scripts, because I spent
inordinate amounts of time debugging them.

When I see the GIT shell scripts, my hands start to itch to make a
nice object oriented Python wrapper for it.

-- 

^ permalink raw reply

* Re: Cleaning up git user-interface warts
From: Han-Wen Nienhuys @ 2006-11-17  0:05 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano, git
In-Reply-To: <Pine.LNX.4.64.0611161508530.3349@woody.osdl.org>



Linus Torvalds escreveu:
> My real point was/is that usually it's really not the "naming details" 
> that people _really_ have problems with. The real problems tend to be in 
> learning a new workflow.

I agree that discussions on naming may cloud the issue, but "learning
the workflow" implies that people should adapt to the limitations of
their tools.  That's only a viable stance when the tools are finished
and completely perfect.

Until that time, it would be good goal to remove all idiosyncrasies,
all gratuitious asymetries and needless limitations in the commands of
git, eg.

 - clone but not a put-clone,

 - pull = merge + fetch, but no command for merge + throw

 - clone for getting all branches of a repo, but no command for
   updating all branches of a repo.  

Of course, when all warts are fixed, backward compatibility will force
us to choose some new names. At that point, a discussion on naming is
in place.


-- 
 Han-Wen Nienhuys - hanwen@xs4all.nl - http://www.xs4all.nl/~hanwen

^ permalink raw reply

* Re: [DRAFT] Branching and merging with git
From: Junio C Hamano @ 2006-11-16 23:47 UTC (permalink / raw)
  To: linux; +Cc: git
In-Reply-To: <20061116221701.4499.qmail@science.horizon.com>

linux@horizon.com writes:

> I know it took me a while to get used to playing with branches, and I
> still get nervous when doing something creative.  So I've been trying
> to get more comfortable, and wrote the following to document what I've
> learned.
>
> It's a first draft - I just finished writing it, so there are probably
> some glaring errors - but I thought it might be of interest anyway.

This is a greatest write-up I've seen for the past several
months.  I find it very balanced to point out the quirks people
would find difficult and explain why things are so by including
historical notes in appropriate places when needed.  Definitely
Documentation/ material when copyediting is done.

I have finished only the first half because it's not my git day
today, but so far...

> * Naming revisions
>...
> Second, you can refer to a head or tag name.  Git looks in the
> following places, in order, for a head:
> 	1) .git
> 	2) .git/refs
> 	3) .git/refs/heads
> 	4) .git/refs/tags

You might want to check this with the array in sha1_name.c::get_sha1_basic().
I think tags comes earlier than heads.

> 2) Revert changes to a small number of files.
>
> 	git checkout [<revision>] [--] <paths>
>    will copy the version of the <paths> from the index to the working
>    directory.  If a <revision> is given, the index for those paths will
>    be updated from the given revision before copying from the index to
>    the working tree.
>
>    Unlike the version with no <paths> specified, this does NOT update
>    HEAD, even if <paths> is ".".

It's great that you talk correctly about the latest feature-fix
that is queued for maint but not yet pushed out.

> 2) By path name.  This is a feature which appears to be unique to git.
>    If you give git-rev-list (or git-log, or gitk, or qgit) a list of
>    pathname prefixes, it will list only commits which touch those
>    paths. So "git log drivers/scsi include/scsi" will list only
>    commits which alters a file whose name begins with drivers/scsi
>    or include/scsi.
>
>    (If there's any possible ambiguity between a path name and a commit
>    name, git-rev-list will refuse to proceed.  You can resolve it by
>    including "--" on the command line.  Everything before that is a
>    commit name; everything after is a path.)
>
>    This filter is in addition to the ancestry filter.  It's also rather
>    clever about omitting unnecessary detail.  In particular, if there's
>    a side branch which does touch drivers/scsi, then the entire branch,
>    and the merge at the end, will be removed from the log.

"If there's a side branch which does NOT touch the paths..." I think.

> * Alternate branch naming
>
> The original git scheme mixes tracking branches with all the other heads.
> This requires that you remember which branches are tracking branches and
> which aren't.  Hopefully, you remember what all your branches are for,
> but if you track a lot of remote repositories, you might not remember
> what every remote branch is for and what you called it locally.

I think you wanted to mention .git/refs/remotes hierarchy and
separate-remote here, but haven't elaborated yet...

> * Remote tags
>
> TODO: Figure out how remote tags work, under what circumstances
> they are fetched, and what git does if there are conflicts.

refs/tags namespace is not policed at all by git and is treated
as a global namespace, controlled mostly by social convention
that your "upstream" (or central distribution point) supplies
tags for people who use it to synchronize to share.  Also, since
there is no guarantee that tags point at commits (v2.6.11-tree
tag is a pointer to a tree object, for example), there is no
farst-forward check performed for them.

The rule we use to autofollow tags currently is:

When you use shorthand fetch (or pull), we find tags that do not
exist locally, and if the object they point at are already found
in the repository then we fetch them automatically.  So for
example, if you are only tracking my 'maint' and not 'master'
nor 'next', and if you have tags up to v1.4.3.2, your "git fetch
origin" would update your copy of 'maint' and bring the commits
reachable from the tip of my 'maint'.  After that it notices
that v1.4.3.3, v1.4.3.4, v1.4.3.5 tags are in my repository but
missing from yours. It also notices that now you have
v1.4.3.3^{}, v1.4.3.4^{} and v1.4.3.5^{} in your repository, so
it issues another round of "git fetch" internally to fetch these
three tags.  At the same time it would also notice that I have
v1.4.4 tag that you do not have, but v1.4.4^0 commit is not
something you would get by fetching 'maint', so it would not
fetch it automatically.

^ permalink raw reply

* Re: multi-project repos (was Re: Cleaning up git user-interface  warts)
From: Han-Wen Nienhuys @ 2006-11-16 23:40 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Junio C Hamano, git
In-Reply-To: <Pine.LNX.4.64.0611161436230.3349@woody.osdl.org>

Linus Torvalds escreveu:
> A lot of the complaints seem to not be about the interfaces, but about 
> people not _understanding_ and knowing what the interfaces do. If you were 

From the point of view of a user, there is not really a difference
between the two.  As a user, you form a mental model of how things
work by looking at the interface. If the interface is bad, the user
creates a faulty model in his head, and starts doing things that
are perfectly logical in the faulty model, but stupid and silly when
you consider the actual internals.

A nice book about this is "The Design of Everyday Things" by Donald
Norman.

-- 

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox