* Re: [RFC] Submodules in GIT
From: sf @ 2006-12-01 23:34 UTC (permalink / raw)
To: Martin Waitz; +Cc: git
In-Reply-To: <20061201184801.GG18810@admingilde.org>
Martin Waitz wrote:
> On Fri, Dec 01, 2006 at 06:33:12PM +0100, Stephan Feder wrote:
>> We are in agreement about two fundamental parts of the implementation
>> and their meaning:
>>
>> 1. A submodule is stored as a commit id in a tree object.
>>
>> 2. Every object that is reachable from the submodule's commit are
>> reachable from the supermodule's repository.
>
> Correct.
Good. For me that is the main point. As I said before the user interface
is not so important because it can be changed anytime, but to change the
object database later is close to impossible.
...
> Let's see if I understand you correctly:
>
> You don't want to create an additional .git directory for the submodule
> and just handle everything with one toplevel .git repository for the
> whole project.
Yes.
> Without the .git directory, you of course do not have refs/heads inside
> the submodule.
Correct..
> So this is a different user-interface approach to submodules when
> compared to my approach. But the basis is the same and both could
> inter-operate.
Big YES.
> Now your submodule is no longer seen as an independent git repository
> and I think this would cause problems when you want to push/pull between
> the submodule and its upstream repository.
You can always pick a single commit or several commits out of a larger
repository and have a complete git repository.
And I already explained how to push and pull even from within superprojects.
> No technical problems, but UI-problems because now your submodule is
> handled completly different to a "normal" repository.
Yes and no. You can always have branches that are only concerned with
submodules' code, say, in refs/heads/submodules/<submodule>/.
"submodules" here is simply an example and has not deeper meaning. You
could call it foo or whatever you like. Or you could use
refs/heads/<submodule>/ if it suits you.
But if you mean the submodule as seen from the supermodule, then there
is a difference. Naturally, because the concept of submodules is new to git.
>>> Yes, but if it would have been integrated as a submodule it obviously
>>> would have been committed to the xdiff submodule inside the git
>>> repository.
>> No. The xdiff submodule would only exist as part of the git repository.
>
> But you could still call the "xdiff" part of the git repository a
> submodule. And then changes to the xdiff directory result in a new
> submodule commit, even when there is no direct reference to it.
> So you'd still "commit to the xdiff submodule".
Let's make certain that we understand each other. I see a clear
distinction between the submodule code in a supermodule branch (commits
in the supermodule's tree and nothing else) and submodule branches which
are independent of the superproject. Supermodule branches and submodule
branches do not interact, only if I want them to.
>
>> You could, f.e., access the xdiff commit in git HEAD as HEAD:xdiff//
>> (again my proposed syntax). HEAD:xdiff//~2:xemit.c would give you the
>> grandparent of xemit.c in the xdiff submodule.
>
> git-cat-file commit HEAD:xdiff already works out of the box (even
> cat-file tree to get the submodule tree). But up to now revision
> parsing follows the file name only once.
>
> What about just separating things with "/"?
>
> commit HEAD
> tree HEAD/
> blob HEAD/Makefile
> commit HEAD/xdiff
> tree HEAD/xdiff/
> blob HEAD/xdiff~2/xemit.c
>
> this may add some confusion when used with hierarchical branches, but
> it's still unique:
>
> refs/heads/master/xdiff/xemit.c
>
> Just use as many path components until a matching reference is found,
> then start peeling.
> Or just use / between super and submodule:
>
> refs/heads/master:xdiff/xemit.c
>
> I think this is easier to read then
>
> refs/heads/master:xdiff//:xemit.c
The double slashes is the only way I can think of that clearly indicates
that I do not mean the contents named by the path, but the commit that
you find there. Once you have named a commit in that way, you can
continue to apply other revision naming suffixes, paths, and so on.
Let's try. What does git cat-file -p
master:dir/sub//^^^:sub/dir/sub//^:dir/file mean?
Explanation: Take branch master and go to path dir/sub. There you will
find a commit. Take its grand-grandparent and go to path sub/dir/sub
(the first sub is a subproject as well but we do not care). There you
will, again, find a commit. Take its parent and go to path dir/file
which happens to be a blob the contents of which you want to cat.
In reality you will never see these kinds of complex paths. Have you
ever seen something like git cat-file -p
bd2c39f58f915af532b488c5bda753314f0db603~12^{commit}^2^5~8^2~308:README ?
>> If you mean the submodule repository created by init-module I
>> understand. But why create this "helper repository at all"?
>
> Because it helps "normal" git operations ;-)
Let's see. I still have to try.
Regards
^ permalink raw reply
* Re: [RFC] Submodules in GIT
From: Josef Weidendorfer @ 2006-12-01 23:36 UTC (permalink / raw)
To: Linus Torvalds; +Cc: sf, git, Martin Waitz
In-Reply-To: <Pine.LNX.4.64.0612011505190.3695@woody.osdl.org>
On Saturday 02 December 2006 00:09, Linus Torvalds wrote:
>
> On Fri, 1 Dec 2006, sf wrote:
> > Linus Torvalds wrote:
> > ...
> > > In contrast, a submodule that we don't fetch is an all-or-nothing
> > > situation: we simply don't have the data at all, and it's really a matter
> > > of simply not recursing into that submodule at all - much more like not
> > > checking out a particular part of the tree.
> >
> > If you do not want to fetch all of the supermodule then do not fetch the
> > supermodule.
>
> So why do you want to limit it? There's absolutely no cost to saying "I
> want to see all the common shared infrastructure, but I'm actually only
> interested in this one submodule that I work with".
So you are for a global submodule namespace in supermodule repositories,
do I understand correctly?
Otherwise, how would you specify the submodules at clone time given the
ability that submodule roots can have relative path changed arbitrarily
between commits?
^ permalink raw reply
* Re: [PATCH 0/2] Making "git commit" to mean "git commit -a".
From: Alan Chandler @ 2006-12-01 23:36 UTC (permalink / raw)
To: git
In-Reply-To: <456FEED4.7030400@op5.se>
On Friday 01 December 2006 08:59, Andreas Ericsson wrote:
> Nicolas Pitre wrote:
>
> > 2) By using "git commit -a" directly
> >
> > This is a quick way to automatically "add" all modified files to
>
> .. "add" all tracked and modified files to ...
add all tracked and modified content
>
...
>
> me likes
me too
--
Alan Chandler
^ permalink raw reply
* Re: Resolving conflicts
From: Alan Chandler @ 2006-12-01 23:47 UTC (permalink / raw)
To: git
In-Reply-To: <456FE642.6020102@saville.com>
On Friday 01 December 2006 08:22, Wink Saville wrote:
> Ubuntu is debian based and I use Synaptic GUI, a front end to apt-get. My
> earlier problem was I couldn't find which package "merge" was in. But now I
> just figured it out by going to debian.org and using "Search the contents
> of packages" for "merge". Turns out "merge" is in devel/rcs which of course
> the whole world knows, unless your a neophyte like me:)
I'm actually using Debian Unstable and basically use the git-core package. Its
at version 1.4.4.1 - so right up to date, and of course resolves all
dependencies automatically.
Doesn't Ubuntu have git-core in its repository?
--
Alan Chandler
^ permalink raw reply
* Re: [RFC] Submodules in GIT
From: sf @ 2006-12-01 23:49 UTC (permalink / raw)
To: Linus Torvalds; +Cc: sf, git, Martin Waitz
In-Reply-To: <Pine.LNX.4.64.0612011505190.3695@woody.osdl.org>
Linus Torvalds wrote:
>
> On Fri, 1 Dec 2006, sf wrote:
>> Linus Torvalds wrote:
>> ...
>>> In contrast, a submodule that we don't fetch is an all-or-nothing
>>> situation: we simply don't have the data at all, and it's really a matter
>>> of simply not recursing into that submodule at all - much more like not
>>> checking out a particular part of the tree.
>> If you do not want to fetch all of the supermodule then do not fetch the
>> supermodule.
>
> So why do you want to limit it? There's absolutely no cost to saying "I
> want to see all the common shared infrastructure, but I'm actually only
> interested in this one submodule that I work with".
If you need a common infrastructure to be able to work with the
submodule, then the submodule is not independent of of the supermodule.
I see a contradiction in your requirements.
> Also, anybody who works on just the build infrastructure simply may not
> care about all the submodules. The submodules may add up to hundreds of
> gigs of stuff. Not everybody wants them. But you may still want to get the
> common build infrastructure.
See above.
> In other words, your "all or nothing" approach is
> (a) not friendly
> and
> (b) has no real advantages anyway, since modules have to be independent
> enough that you _can_ split them off for other reasons anyway.
>
> So forcing that "you have to take everything" mentality onyl has
> negatives, and no positives. Why do it?
(There have been lots of use cases for shallow clones but for a long
time git did not support them).
If you can extend this partial fetch feature to the non-subproject case
I would agree with your reasoning. What makes the subprojects so special
in this regard. Do I have to turn a plain tree into a subproject to be
able to ignore it? Once you can restrict fetches to parts of the
contents you get the ability to restrict fetches to the "common
infrastructure" and selected submodules for free.
Regards
Stephan
^ permalink raw reply
* Re: [RFC] Submodules in GIT
From: Linus Torvalds @ 2006-12-02 0:12 UTC (permalink / raw)
To: Josef Weidendorfer; +Cc: sf, git, Martin Waitz
In-Reply-To: <200612020036.08826.Josef.Weidendorfer@gmx.de>
On Sat, 2 Dec 2006, Josef Weidendorfer wrote:
>
> So you are for a global submodule namespace in supermodule repositories,
> do I understand correctly?
>
> Otherwise, how would you specify the submodules at clone time given the
> ability that submodule roots can have relative path changed arbitrarily
> between commits?
The only _true_ namespace would be the SHA1 of the commit (and maybe allow
a pointer to a tag too, but the namespace ends up being the same).
How to _find_ a repository that contains that SHA1 must be left to higher
levels. After all, repositories move around, and the place you found them
originally is not a stable name.
So within the supermodule, on a "git object" level, a submodule should
just be named by the SHA1 that was it's HEAD when it was committed within
the supermodule. So in the "tree object", you'd see something like the
following when you go "git ls-tree HEAD" on the superproject:
...
100644 blob 08602f522183dc43787616f37cba9b8af4e3dade xdiff-interface.c
100644 blob 1346908bea31319aabeabdfd955e2ea9aab37456 xdiff-interface.h
040000 tree 959dd5d97e665998eb26c764d3a889ae7903d9c2 xdiff
050000 link 0215ffb08ce99e2bb59eca114a99499a4d06e704 xyzzy
where that 050000 is the new magic type (I picked one out of my *ss: it's
not a valid type for a file mode, so it's a godo choice, but it could be
anythign that cannot conflict with a real file), which just specifies the
"link" part. The SHA1 is the SHA1 of the commit, and the "xyzzy" is
obviously just the name within the directory of the submodule.
That's all that is actually required for a lot of git commands that
already expect all objects to be available (ie "git checkout", "git diff"
etc).
It only gets interesting for commands that fetch new objects, ie do a
"pull/fetch" op, and you'd need to know where/how to fetch new objects for
the xyzzy subproject, so that's a "naming" issue. You have a few choices:
- get all the objects directly from the subproject as if it was one big
project.
I actually think this sucks. Why? Because it puts an insane load on the
server side, which basically needs to traverse the object list of the
_sum_ of all projects. An initial clone (or a really big pull, which
comes to the same thing) would be absolutely horrendous
So I'd strongly argue against that approach, for scalability reasons. So
instead, you should really try to do pulls etc one git repo at a time:
- take the "list of subprojects" from the supermodule, and pull them all
one by one.
This again makes subprojects "less seamless", and makes each subproject
more of a separate thing, with the project list gotten from the
superproject and parsed separately. But it means you have none of the
scalability problems, since you never see things as one huge project
with millions of files and even more objects.
The second approach also means that you can see the "supermodule" support
in git as less of a "plumbing" thing, and it's largely just a thin veneer
around the core plumbing that really doesn't understand about multiple
repositories at all (apart from the single "link" extension in the tree
object), and it's really just scripting to get the subprojects to "look"
like one thing, when they really are pretty much independent.
^ permalink raw reply
* Re: [RFC] Submodules in GIT
From: Josef Weidendorfer @ 2006-12-02 0:14 UTC (permalink / raw)
To: Linus Torvalds; +Cc: sf, git, Martin Waitz
In-Reply-To: <Pine.LNX.4.64.0612011510290.3695@woody.osdl.org>
On Saturday 02 December 2006 00:30, Linus Torvalds wrote:
> On Fri, 1 Dec 2006, Josef Weidendorfer wrote:
> >
> > What about my other argument for a submodule namespace:
> > You want to be able to move the relative root path of a submodule
> > inside of your supermodule, but yet want to have a unique name
> > for the submodule:
> > - to be able to just clone a submodule without having to know
> > the current position in HEAD
>
> Umm? I don't get the issue. A submodule is a git repo in its own right,
> and you clone it exactly like you'd clone any other repo. It _does_ have a
> HEAD. It has it's own branches. It has everything.
I just thought about the case when you want to clone a submodule directly
out of the supermodule repository, at a given realive path. And that can
be changing.
Of course, every project which happens to be submodule of some supermodule,
also can have its own repository, as it is fully independent. And then,
you of course can clone from without any knowledge of its relative position
in the supermodule.
> In the trivial case where the submodule doesn't even _have_ any external
> existence at all (ie it's always maintained as _just_ a submodule, it
> would probably tend to have just one branch, and a clone would get
> whatever that branch is), but that's just a degenerate special case of the
> much richer "this submodule actually has a life of its own" case.
Yes.
> > - more practically, e.g. to be able to name a submodule
> > independent from any current commit you are on in the supermodule,
> > e.g. to be able to store some meta information about a submodule:
>
> The current commit within the supermodule would be _totally_ invisible to
> the submodule.
Of course.
Yet, you need some name to store meta information of submodules
into some config file of the supermodule, like whether you want to have
it checked out (see below).
In that case, such a name for a submodule does not have to be global in
the supermodule project...
> > - "Should git allow to commit rewind actions of this submodule
> > in the supermodule?" (which, AFAICS, exactly has the same
> > problems as publishing a rewound branch: you will get into
> > merge hell when you want to pull upstream changes into the
> > supermodule)
>
> The only thing that a submodule must NOT be allowed to do on its own is
> pruning (and it's distant cousin "git repack -d"). You must always prune
> >from the supermodule, because the submodule cannot really know on its own
> what references point into it.
Yes. I just gave an example of a policy some project may want for submodule
handling.
> > - "Should this submodule be checked out?"
>
> This, I think, requires too much configuration to say separately for every
> possible submodule, so I would suggest that the way to make that decision
> is:
>
> - "git clone" by default will fetch and check out all submodules (and
> obviously they have to be described some way outside of the object
> database, just so that you don't have to parse the _whole_ history of
> the _whole_ supermodule just to find all possible submodules. So the
> supermodule _will_ need some "list of submodules and where to get them"
> in a config file or other).
Exactly. And in this list, you have to specify names.
The thing I wanted to discuss is whether such names would need to be globally
unique in the project containing submodles, or not.
If yes, it IMHO makes a lot of sense to introduce "submodule objects" which contain
these submodule names, and which are used as pointers to submodule commits in
supermodule trees.
^ permalink raw reply
* Re: [PATCH] make 'git add' a first class user friendly interface to the index
From: Alan Chandler @ 2006-12-02 0:18 UTC (permalink / raw)
To: git
In-Reply-To: <7vpsb36yem.fsf@assigned-by-dhcp.cox.net>
On Friday 01 December 2006 22:31, Junio C Hamano wrote:
> Nicolas Pitre <nico@cam.org> writes:
...
>
> > +Contrary to other SCMs, with GIT you have to explicitly "add" all the
> > +changed file content you want to commit together to form a changeset
> > +with the 'add' command before using the 'commit' command.
>
> ... "before a new commit is made"; it is not an offence to leave
> local changes outside the index. Staging such changes to all
> files is done using the "-a" flag and that is done "before a new
> commit is made", but not "before using the 'commit' command" --
> it is done at the same time.
How about
Contrary to other SCM's, with GIT you have to explicitly "add" the content
that you want to commit before it is made; it is not an offence to leave
changes outside the index if you want to leave them to a later commit.
However if you do want all changes from your working tree to be added to the
commit before it is made use the "-a" flag with the commit command and the
content will be added just before the commit is made.
--
Alan Chandler
^ permalink raw reply
* Re: [RFC] Submodules in GIT
From: Linus Torvalds @ 2006-12-02 0:33 UTC (permalink / raw)
To: Josef Weidendorfer; +Cc: sf, git, Martin Waitz
In-Reply-To: <200612020114.42858.Josef.Weidendorfer@gmx.de>
On Sat, 2 Dec 2006, Josef Weidendorfer wrote:
> >
> > The current commit within the supermodule would be _totally_ invisible to
> > the submodule.
>
> Of course.
>
> Yet, you need some name to store meta information of submodules
> into some config file of the supermodule, like whether you want to have
> it checked out (see below).
Yes, you do need to have a list of submodules somewhere, and you'd need to
maintain that separately. One of the results of having the submodules be
independent from the supermodule is that it's not all "automatically
integrated", and thus the supermodule does end up having to have things
like that maintained separately.
And yes, if you screw that up, you wouldn't be able to fetch submodules
properly etc, even if you see the supermodule, and yes, this sounds more
like the CVS "Entries" kind of file that is more "tacked on" than really
deeply integrated. But I think the separation is _more_ than worth the
fact that you can see things being separate.
In fact, I'm very much arguing for keeping things as separate as possible,
while just integrating to the smallest possible degree (just _barely_
enough that you can do things like "git clone" and it will fetch multiple
repositories and put them all in the right places, and "git diff" and
friends will do reasonably sane things).
Keep it simple, stupid.
> > - "git clone" by default will fetch and check out all submodules (and
> > obviously they have to be described some way outside of the object
> > database, just so that you don't have to parse the _whole_ history of
> > the _whole_ supermodule just to find all possible submodules. So the
> > supermodule _will_ need some "list of submodules and where to get them"
> > in a config file or other).
>
> Exactly. And in this list, you have to specify names.
Yes.
> The thing I wanted to discuss is whether such names would need to be globally
> unique in the project containing submodles, or not.
My preference would be for it to be "local", just because (as I
mentioned), with mirroring etc, it might well be that you want to fetch
things from the _closest_ repository. That's really not a global decision,
it's a local one.
> If yes, it IMHO makes a lot of sense to introduce "submodule objects" which contain
> these submodule names, and which are used as pointers to submodule commits in
> supermodule trees.
You could do it that way, and then it would be global. It would work, and
in many ways it would probably be "simpler" on a supermodule level.
The advantage of a global namespace is that you can much more easily
update it - "git fetch" will just fetch the new file(s) that describe the
subprojects very naturally if they are all global. Putting them in a local
.git/config file has it's advantages (see above), but it also makes it
very hard to version them, and to update the list - it would have to
become manual.
There are possibly combinations of the two approaches: have a "global
namespace" that describes the canonical place to get the subprojects, but
have some way to add local "translation" of the canonical names into
locally preferred versions (eg you could just have a way to say "this is
the local mirror for that global canonical place")
Maybe that would work?
^ permalink raw reply
* Re: [PATCH] make 'git add' a first class user friendly interface to the index
From: Nicolas Pitre @ 2006-12-02 2:01 UTC (permalink / raw)
To: Alan Chandler; +Cc: git
In-Reply-To: <200612020018.32672.alan@chandlerfamily.org.uk>
On Sat, 2 Dec 2006, Alan Chandler wrote:
> On Friday 01 December 2006 22:31, Junio C Hamano wrote:
> > Nicolas Pitre <nico@cam.org> writes:
> ...
> >
> > > +Contrary to other SCMs, with GIT you have to explicitly "add" all the
> > > +changed file content you want to commit together to form a changeset
> > > +with the 'add' command before using the 'commit' command.
> >
> > ... "before a new commit is made"; it is not an offence to leave
> > local changes outside the index. Staging such changes to all
> > files is done using the "-a" flag and that is done "before a new
> > commit is made", but not "before using the 'commit' command" --
> > it is done at the same time.
Bleamphfff... Nah. There is certainly another way to formulate that.
> How about
>
> Contrary to other SCM's, with GIT you have to explicitly "add" the content
> that you want to commit before it is made; it is not an offence to leave
Before what is made?
> changes outside the index if you want to leave them to a later commit.
> However if you do want all changes from your working tree to be added to the
> commit before it is made use the "-a" flag with the commit command and the
> content will be added just before the commit is made.
Nah. Too many concepts in the same paragraph.
^ permalink raw reply
* Re: Resolving conflicts
From: Wink Saville @ 2006-12-02 3:04 UTC (permalink / raw)
To: Alan Chandler; +Cc: git
In-Reply-To: <200612012347.55294.alan@chandlerfamily.org.uk>
Alan Chandler wrote:
> On Friday 01 December 2006 08:22, Wink Saville wrote:
>
>> Ubuntu is debian based and I use Synaptic GUI, a front end to apt-get. My
>> earlier problem was I couldn't find which package "merge" was in. But now I
>> just figured it out by going to debian.org and using "Search the contents
>> of packages" for "merge". Turns out "merge" is in devel/rcs which of course
>> the whole world knows, unless your a neophyte like me:)
>
> I'm actually using Debian Unstable and basically use the git-core package. Its
> at version 1.4.4.1 - so right up to date, and of course resolves all
> dependencies automatically.
>
> Doesn't Ubuntu have git-core in its repository?
>
It was an older version, so I started at the source.
W
^ permalink raw reply
* Re: [PATCH] make 'git add' a first class user friendly interface to the index
From: Nicolas Pitre @ 2006-12-02 3:05 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <7vpsb36yem.fsf@assigned-by-dhcp.cox.net>
On Fri, 1 Dec 2006, Junio C Hamano wrote:
> Nicolas Pitre <nico@cam.org> writes:
>
> > I personally think this is going to make the GIT experience lot more
> > enjoyable for everybody. This brings the power of the index up front
> > using a proper mental model without talking about the index at all. See
> > for example how all the technical discussion has been evacuated from the
> > git-add man page.
>
> I like the direction this is taking us.
>
> The documentation update is in the same spirit with the sample
> rewrite of 'git diff' manpage. We might want to tweak the
> wording to make this round of documentation updates consistent.
>
> My preferences:
>
> - You used the word "changeset"; I am not sure that is a good
> wording.
Why not? It is a well defined word in the SCM context, and I really
think what is built in the index before a commit is a changeset.
But actually I'd prefer "set of changes" even better as it is more
independent of any definition "changeset" might have.
> The recent explanation I saw on the list and liked
> were "you _stage_ your changes to prepare for the next
> commit (footnote: the staging area is called 'the index')".
> My impression was that both extremes (Linus and Carl) are
> also Ok with this wording.
Well... dunno.
> - We keep the word "index", and not reword it to "stage" in the
> names of commands and options. "to stage" is very good verb
> to explain the _concept_, but there is no need to use
> inconsistent wording Porcelain-ish and plumbing use to
> describe the entity used for staging.
First I don't know if "to stage" is such a good verb. According to
http://dictionary.reference.com/search?q=stage I think "stage" has just
too many definitions already, and none of which really make me think of
GIT's index.
> (1) New people need to learn the new concept anyway, and they
> are intelligent enough to learn what that new concept has
> been called for a long time in git-land at the same time.
>
> "The index" is the receiver of new contents to be staged;
> conversely, "to stage" is the act of registering contents
> to the index.
In technical docs maybe. But I don't see the need for this wording in
the tutorial, not even in the "add" man page.
The best way not to confuse people and making the thing look
not too complicated is to avoid making too many explanations especially
when they're not necessary to operate the thing. In my
opinion the above quote fails that test.
There are two level of languages we must be aware of. First there is
language to explain how to use the thing. Next there is language to
explain how the thing works. And _most_ people just want to know how to
use the thing at first. They don't care how it works under the hood
until they have more confidence in their own ability to use the thing
first. So it is really important not to mix both levels of language.
In my opinion git-add man page and the tutorial should be about how to
use the thing, not about how the thing works. the git-update-index is
where to talk about how the thing works.
And even on the technical level, the quote above is wrong. Because if
we talk about the actual index, it doesn't contain new content only.
The index really contains everything, including current unmodified
content. So on a technical level (on the "how it works" level) we
really "update" the index to reflect a different state, and in that
context the git-update-index could not have a better name. It really
says what it does.
It's just that GIT users are simply not interested to know about it. Of
course all subscribers of this mailing list are, but not users. What
users want to know is how to use the tool and the best way IMHO is to
simply create a mental model where "all changes always have to be added
together explicitly before they are committed with git-add." All the
rest are shortcuts and variants derived from that fundamental user
model.
And eventually the more intripid users will discover that what they were
doing without knowing initially was "updating the index".
What we really want is for users to make use of the index. This is our
goal. This is how GIT is superior.
But we don't need to force users to know about how it all works. Not
before they are confortable with using GIT first.
> (2) Majority of git old timers do not follow git mailing list
> discussion closely. They already know the concept of
> "registering thing in the index". We on the list are
> just about to agree to give a good short name, "to
> stage", for that action they have known about, in order
> for us to make it easier to explain to new people. That
> should not affect the terminology the old timers are
> accustomed to and and trained their fingers with
> ("update-index", "diff --cached", "apply --index").
I don't see the point. Old timers are already familiar with GIT and
with how it works so they don't really need the tutorial nor the basic
command's man pages. They won't be affected at all by any change of
"how to use" model and terminology since they obviously don't have to
learn how to use GIT.
> (3) I hope nobody proposes to rename "update-index" to
> "update-stage" nor "diff-index" to "diff-stage"; that
> would break countless number of existing third party
> scripts old timers rely on and even new people would find
> on the web and tempted to try out, so plumbing level
> commands and options have to keep using the word 'index'.
Absolutely not! Doing that would be an horrible mistake. First because
of the reasons you mention above, and because IMHO "stage" isn't it at
all. The "how it works" model is perfectly sane and it is really about
"updating the index". Always was, always should.
> The option to 'git diff --cached' may need a new synonym
> to make things consistent, but the new synonym should be
> --index, not --staged.
It should be --index, and it should also be --commit in my opinion. The
first for the "how it works" model, and the second for the "how to use"
model. Because what _users_ want is a diff of what is going to be
committed if they type "git commit". Therefore I think --commit is
really the best it could be. Let's avoid proxy meanings like "stage" or
whatever and get to the point. It is --index for obvious reasons, and
it is --commit for another but as obvious reason.
> (4) New people will not stay newbies forever. Using a
> consistent word for the entity used for staging for the
> next commit across Porcelain and plumbing is important.
I disagree. Porcelain is about usage. Plumbing is about programming.
It is perfectly normal that they have different concepts and words.
> > maybe add a -f/--force argument to allow for adding ignored files
> > instead of going through git-update-index.
>
> Yup.
>
> > maybe add --new-only and --known-only arguments if there is a real need
> > to discriminate between new vs updated files. I would not suggest
> > against it though, because if someone really has such fancy and uncommon
Sorry, "I would suggest against" is what I meant.
^ permalink raw reply
* Re: Resolving conflicts
From: Linus Torvalds @ 2006-12-02 4:30 UTC (permalink / raw)
To: Junio C Hamano, Johannes Schindelin; +Cc: git
In-Reply-To: <456FDF24.1070001@saville.com>
[ Tangentially related.. ]
On Thu, 30 Nov 2006, Wink Saville wrote:
>
> Earlier had a problem with git wanting merge but didn't have it and
> couldn't figure out which package it was in Ubuntu:( So I symlinked merge
> to kdiff3 which worked at the time:
Btw, what's the status of the xdl_merge() thing in "pu"?
It would be lovely if this could be one less thing we ever need to worry
about, just because we just do it ourselves. But quite frankly, I've never
looked at the RCS merge logic, so while I peeked at the xdl_merge patch
itself, I have absolutely zero way of judging it.
But the patch in "pu" to make merge-recursive use it looks pretty, and
removes more lines than it adds, and the xdl_merge() code itself _looked_
sane even if I can't judge the algorithm, so...
Anyway, here's one vote for trying to move this thing into "next" (first
asking whether all of Dscho's fixup patches got merged too?).
I realize that git-cvsserver (and my toy merge-file.c that isn't used by
anything real) also use the external merge program, so we can't remove the
dependency entirely (both in git.spec.in and documentation) without fixing
those too, but at least we would _practically_ be able to ignore it for
all normal users. And cvsserver would probably be quite fixable too..
^ permalink raw reply
* Re: [PATCH] make 'git add' a first class user friendly interface to the index
From: Carl Worth @ 2006-12-02 6:54 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Nicolas Pitre, git
In-Reply-To: <7vpsb36yem.fsf@assigned-by-dhcp.cox.net>
[-- Attachment #1: Type: text/plain, Size: 10046 bytes --]
On Fri, 01 Dec 2006 14:31:45 -0800, Junio C Hamano wrote:
> "registering thing in the index". We on the list are
> just about to agree to give a good short name, "to
> stage", for that action they have known about, in order
> for us to make it easier to explain to new people. That
> should not affect the terminology the old timers are
> accustomed to and and trained their fingers with
> ("update-index", "diff --cached", "apply --index").
You can adopt a new, short name, and use it in both documentation
_and_ commands without breaking any habits. Just leave the
implementation of the old commands alone. You can even remove things
from the documentation, (or squirrel chunks away to "deprecated"
sections), if you're leaving things only for old-timers.
I've been _trying_ to make git easier to learn, and when there are two
commands, (update-index and "diff --cached"), that use different
terminology for the same concept, that's a road bump to learning.
Yes, _we_ all know that it's talking about the same thing. And we are
all an existence proof that people _can_ learn git as it is without
any changes. But I contend that more people could learn git more
easily if we worked to smooth things out like this.
But almost none of what I proposed should really make things harder on
experienced users. If we make the terminology of the command-set
consistent with the way we explain things in the tutorials and
documentation, then we're being that much nicer. I came up with
"stage" and "--staged" because over and over again I saw Linus and
other say things like "the index is easy to understand if you think of
it as a staging area."
Someone didn't like the use of "stage" as a verb. I'd be happy with
something else that's a nice, short verb that has a consistent
adjective to match. Currently, we have an unshort, non-verb
"update-index", a mismatched adjective "--cached" and a misplaced noun
"--index".
The proposal in the current thread of using "add" is an improvement on
the shortness side, and I am _delighted_ to see documentation
appearing that is focused on what the user wants to achieve and what
the user should expect to happen. So, Junio, please go ahead with
Nico's stuff here. It is an improvement over the current
situation. (And thanks, Nico, for fighting against having technical
details getting added to user-oriented documentation).
But I do still think it's a mistake to muddle the concepts of "adding"
a file and "staging edited content" for a file. In index terms, the
distinction is between adding a new path (and contents, of course) to
the index vs. just updating the contents for an existing path.
But it's not the index distinction that's interesting. It's that users
think of those operations differently. An "add" operation takes a
files out of the "untracked file" state as reported by git
status. That's a very different thing conceptually than updating the
contents of a file that is already being tracked by git. And if the
user thinks of an operation as being different, the command should
reflect that. There is a sense in which the user is always right here,
(since if the tool doesn't do what the user wants, the user just goes
somewhere else).
> The option to 'git diff --cached' may need a new synonym
> to make things consistent, but the new synonym should be
> --index, not --staged.
I like consistency, so I agree that "diff --index" is an improvement
over "diff --cached", (and of course you can leave "diff --cached"
around forever).
The "--staged" thing only came up as I looked for a replacement for
"update-index" as a verb. We can just use "add" to, but it is a bit
awkward for the reasons I explained above.
> > maybe add a -f/--force argument to allow for adding ignored files
> > instead of going through git-update-index.
>
> Yup.
Yes, very nice.
> > maybe add --new-only and --known-only arguments if there is a real need
> > to discriminate between new vs updated files. I would not suggest
> > against it though, because if someone really has such fancy and uncommon
> > requirements he might just use git-update-index directly at that point.
Please don't add --new-only and --known-only options to git add. The
fewer the options, the easier the command is for humans to learn.
The only place I can imagine --new-only or --known-only being useful
would be in a scripting situation, not manually typed on the command
line. And as you say, update-index already exists for that.
Please keep user-oriented commands focused on things that _users_
actually want to do.
> > +Contrary to other SCMs, with GIT you have to explicitly "add" all the
> > +changed file content you want to commit together to form a changeset
> > +with the 'add' command before using the 'commit' command.
I think we can explain the git model in positive terms that stand on
its own. People will learn the differences and appreciate how git is
better. So I'd just drop "Contrary to other SCMs". It's a really weak
form of pride to compare ourselves to other systems. We can do much
better by having the hubris to pretend no other systems exists.
> > +This is not only for adding new files.
I think this sentence shows the failing of the "add" naming. We having
to explicitly say here. Oh, and when we say "add" we don't mean what
you think of as "add", we mean something else. If we mean something
else, why don't we just call it something else?
> I think there is another twist more deserving of mention than -i twist.
> If you jump the index using --only, what is committed with that
> commit becomes part of what is staged for the commit after that,
> and in order to prevent data loss, we disallow this sequence:
[...]
> So if we allowed the above sequence to succeed, we would commit
> the result of the second edit, and after the commit, the index
> would have the result of the second edit. We would lose the
> state the user wanted to keep in the index while this commit
> jumped the index, and that is why we disallow it.
Wow, this index stuff sure takes a lot of explaining. Why are users
better off having to grasp all of that stuff before they can
successfully add; edit; #oops, add again; and commit their files?
> I wonder if this sequence should do the same as "git rm -f foo":
>
> $ /bin/rm foo
> $ git add foo
Argh. Please no. Update-index already exists. Let's not push all of
its semantics onto "add". Let's use "add" for when the user _actually_
wants to _add_ a file. Please? please?
> That's one of the reasons I suggested 'checkin' instead of
> 'resolve', 'resolved', etc. You check-in the removal of the
> content from that path to the staging area, to go as a part of
> the next commit.
I think having "checkin" as a non-synonym for "commit" would be a big
mistake for new users. Different systems out there use those terms
interchangeably. Since git has something unique in its "index" or
"staging area" we're much better off sticking to unique terms for
describing it.
> "use git-add to mark for commit, or use commit -a"?
>
> I think the one source of confusion is "update-index" sounds as
> if it is a command to "update the index" and as if you can leave
> out "with what?" part to complete the order to the command.
Yes. Jesse Keating, for example, read the "use update-index"
suggestion from git-commit and was very confused why he didn't succeed
when he thought he was following instructions with:
git update-index
git commit
Maybe the above could be:
Use "git add <files...>" then "git commit",
or "git commit -a" to add and commit all tracked files.
But why are we even directing to "git add" here instead of just:
What would you like to commit?
Use "git commit <files..>" to commit some files
or "git commit -a" to commit all files.
This doesn't teach the two-part, staged commit to the user at this
point, but that's perhaps OK.
Except it does still leave open the user confusion of:
git add file1
git commit
"cool, that works"
edit file1
git add file2
git commit
"hmm, why didn't file1 get commited that time?!"
And the only answer we can give to the poor user is:
Oh, "git add", (and "git commit" for that matter) don't do
what you think they do. Go read the documentation and try
again.
At least, with this latest round of updates, the "git add"
documentation will actually explain this stuff, (and not just say
"this is a wrapper for update-index"). But there are still a lot of
users that will say "I have to add the file over and over again?
That's bizarre." They won't be saying, "Oh, the git designers were so
brilliant to implement a system based entirely on file contents and
never treating filenames as an interesting entity separate from
content. Thank you so much!"
So, git still isn't "usable" by just picking up the commands and
running with them, learning more as they go along. Some potential
users get lost here. And that's too bad, because nothing in git's
model, (or even in functionality already existing in the command set),
is missing compared to what the user wants. They just didn't find it
by default.
Git _will_ be more learnable from the documentation, but it will still
leave a lot of users thinking it makes some simple things harder than
they should be. So other potential users get lost here. And that's too
bad too, because if they would stick with it a little, they could
learn things later on where git would make complex things simple,
(like conflict resolution).
If add really were uniquely about _adding_ files to be tracked,
(rather than just a short synonym for update-index), and if we tweaked
the default behavior of git-commit, we could fix these things. And
all the model and power of git would still exist and be ready to be
learned by anyone that wants it, (rather than only by those who manage
to get past snags like these).
-Carl
PS. Is there a twelve-steps program for people who can't let a thread
die? I really want to stop, and I keep telling myself I can stop
anytime I want.
[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply
* Re: [PATCH 0/2] Making "git commit" to mean "git commit -a".
From: Marco Costalba @ 2006-12-02 7:48 UTC (permalink / raw)
To: Jakub Narebski; +Cc: git
In-Reply-To: <eknj33$q2r$1@sea.gmane.org>
>
> Index is accessible, just like committed contents. The fact that gitk, qgit,
> git-gui doesn't display state of index is their limitation.
> --
Actually qgit let's you see state index for each file when committing
with qgit commit dialog.
Indeed you can also choose to update only the index state of a file
without committing, ie without create a new tree object.
Internally, the index state of each file is known and tracked. No
other interface is provided, as example a diff, just because I found
it confusing and of little concrete help.
Of course if knowning the index state became important to perform some
concrete and quite common operation I could add whatever GUI would
suite.
Suggestions are welcomed ;-)
^ permalink raw reply
* Re: [PATCH] make 'git add' a first class user friendly interface to the index
From: Junio C Hamano @ 2006-12-02 7:54 UTC (permalink / raw)
To: Carl Worth; +Cc: Nicolas Pitre, git
In-Reply-To: <87veku3i0j.wl%cworth@cworth.org>
Carl Worth <cworth@cworth.org> writes:
>> > +Contrary to other SCMs, with GIT you have to explicitly "add" all the
>> > +changed file content you want to commit together to form a changeset
>> > +with the 'add' command before using the 'commit' command.
>
> I think we can explain the git model in positive terms that stand on
> its own. People will learn the differences and appreciate how git is
> better. So I'd just drop "Contrary to other SCMs".
I already committed Nico's on 'master', because all he said in
his response made sense, but this comment made me rewind it. I
agree that we do not have to start with a "we are harder to
learn, we are different from what you know, you have been
warned." I'll queue it for 'next'.
> Wow, this index stuff sure takes a lot of explaining. Why are users
> better off having to grasp all of that stuff before they can
> successfully add; edit; #oops, add again; and commit their files?
Jumping the index is not about that sequence. It is about being
interrupted while doing something else, and committing a smaller
trivial change first that is independent from what you have been
doing. Beginners do not have to do that "interrupted work"
sequence.
>> I wonder if this sequence should do the same as "git rm -f foo":
>>
>> $ /bin/rm foo
>> $ git add foo
>
> Argh. Please no. Update-index already exists. Let's not push all of
> its semantics onto "add". Let's use "add" for when the user _actually_
> wants to _add_ a file. Please? please?
I do agree "adding the deletion" is a funny terminology. But
this is a illustration that this part of proposed update to the
tutorial could be further improved:
+But for instance it is best to only remember 'git add' + 'git commit'
+and/or 'git commit -a'.
+
+No special command is required when removing a file; just remove it,
+then tell `commit` about the file as usual.
We say "you should add modified state again if you edit it again
after you added it" in a section before these sentences, and
encourage users to consistently say 'git add'. Since we supply
"git rm" and "git mv" to make it convenient to remove/rename
files and index entries at the same time, I think it would be
better to say "Use add/rm/mv", not "don't worry about rm".
By the way, aren't people disturbed that "git rm" does not
default to "-f" -- I rarely use the command myself but that
makes it feel even more awkward that "git rm foo" does not
remove the file "foo".
> PS. Is there a twelve-steps program for people who can't let a thread
> die? I really want to stop, and I keep telling myself I can stop
> anytime I want.
Well, I think at least we are converging.
^ permalink raw reply
* Re: Resolving conflicts
From: Junio C Hamano @ 2006-12-02 7:55 UTC (permalink / raw)
To: Linus Torvalds; +Cc: git, Johannes Schindelin
In-Reply-To: <Pine.LNX.4.64.0612012018490.3476@woody.osdl.org>
Linus Torvalds <torvalds@osdl.org> writes:
> [ Tangentially related.. ]
>
> On Thu, 30 Nov 2006, Wink Saville wrote:
>>
>> Earlier had a problem with git wanting merge but didn't have it and
>> couldn't figure out which package it was in Ubuntu:( So I symlinked merge
>> to kdiff3 which worked at the time:
>
> Btw, what's the status of the xdl_merge() thing in "pu"?
I am *BEHIND*. There are too many distractions these days
(read: day job) and I haven't touched git in any significant
ways for the last several days.
I haven't looked at the code any further than minimally checking
its external interface to be able to interface it with
merge-recursive and no more. Namely:
- I haven't read the algorithm to judge its correctness;
- I haven't looked for leaks;
- I haven't used the resulting merge-recursive in any real
merge; some of our tests do rely on a correctly working
merge-recursive, so it is not like the algorithm is always
emitting "boo ha ha" and returning no conflicts ;-).
- I haven't benched it to see how much performance is gained
by bypassing an extra fork+exec.
Among the four patches Johannes sent out to the list and Davide,
one was already in his original patch I have in 'pu', another
makes the same return value change I did myself when interfacing
the code with merge-recursive. I have queued the remaining two
in 'pu', so there should be nothing missing.
One of them is marked as "fix off by one error" but it was about
more than off by one (the code walks two arrays using one index
for each, but the original code incorrectly used the same index
to access both arrays at one point, which was also fixed). I
did mind the lack of explanation and wanted to reword the log
message, but as I said, I haven't read the algorithm to
understand what the code is doing enough, so I cannot write
anything useful there yet X-<, which is one of the reasons why
it is still queued in 'pu'.
^ permalink raw reply
* Re: [PATCH] Make git-commit cleverer - have it figure out whether it needs -a automatically
From: Junio C Hamano @ 2006-12-02 8:09 UTC (permalink / raw)
To: Andy Parkins; +Cc: git
In-Reply-To: <200612011106.42272.andyparkins@gmail.com>
Andy Parkins <andyparkins@gmail.com> writes:
> Raimund Bauer offered this suggestion (paraphrased):
>
> "Maybe we could do git-commit -a _only_ if the index matches HEAD, and
> otherwise keep current behavior? So people who don't care about the
> index won't get tripped up, and when you do have a dirty index, you get
> told about it?"
>
> Johannes Schindelin pointed out that this isn't the right thing to do for
> an --amend, so that is checked for. Additionally, it's probably not the
> right thing to do if any files are specified with "--only" or
> "--include", so they turn this behaviour off as well.
>
> Nguyen Thai Ngoc Duy asked that git-commit let you know it's done this
> by adding an extra comment to the commit message.
>
> Signed-off-by: Andy Parkins <andyparkins@gmail.com>
Aside from the "working tree not matching index" safety valve I
asked for, there is a more important case that "when the index
matches HEAD" is not a safe enough check for this 'cleverness'.
It's related to this code in git-commit:
if [ "$?" != "0" -a ! -f "$GIT_DIR/MERGE_HEAD" -a -z "$amend" ]
then
rm -f "$GIT_DIR/COMMIT_EDITMSG" "$GIT_DIR/SQUASH_MSG"
run_status
exit 1
fi
This allows you to make a new commit with an identical tree as
the current HEAD, when making a merge.
We originally did not allow a commit that has identical tree
with its first parent. It was pointed out as a bug in the real
world setting, where two bugs are independently fixed by two
people, textually and also logically differently, and the merge
results in a conflict. In such a case, after examining the text
(git diff --cc) and motivation (git log --merge) of the changes
that conflicted from both ends, if you decide that you prefer
your own fix over the fix made by the other party, your edit of
the conflicted file would end up to be identical to what you had
originally in the HEAD.
In such a situation, it makes sense to record the fact that the
two development paths came to the same conclusion as a merge.
It would also simplify later merges from the other side, and the
merges the other side attempts by pulling from you.
So after you fix the conflicts, you would mark the conflicted
file with Nico's shiny new "git add". The index _still_ matches
HEAD. The 'cleverer' "git commit" would not notice this
situation and commits unrelated changes that the user does not
have any intention to commit in the working tree by mistake.
So that is _another_ exception you must handle.
But I think the problem with this 'cleverer' commit runs
deeper.
Notice that you needed to say "The main idea is this cleverness,
but foo pointed out this special case, and bar pointed out
another, and we fixed all of these known ones and now this is
good, let's apply it." in your proposed commit log message? You
should smell fishiness in that kind of reasoning.
It's not that you cannot be sure that these suggestions covered
all cases; you should not have to cover everything under the sun
in your initial revision. New exceptions can certainly be added
incrementally to address breakages. However, having to have
exception from the beginning is a sign that the general rule you
started from is a broken rule. To realize that yourself, Think
about how you would describe the behaviour to a new user.
The currently proposed rewording of "git add" and "git commit"
manual pages would define "git commit" to behave in two primary
modes:
1. With paths, "git commit <paths>" means "forget for a moment
the changes I staged to be committed, and make a commit that
includes only these paths (i.e. the new commit and the
current HEAD are different at exactly these paths and
nowhere else, and the new commit has contents from the
working tree for these paths)".
2. Without paths, "git commit" means "make a commit out of
everything I have told you to commit (aka 'staged') so far".
The primary ways to tell git to stage contents are "git
add/rm/mv". But as a short-hand, you can say "git commit
-a" to ask the command to place all the changes in the
working tree in the changeset to be committed before making
the new commit.
How would your version be described?
1. (ditto)
2. (ditto). However, there are number of exceptions you should
be aware of:
2-a. The above general rule only applies if you have already
told git to stage something for the next commit.
2-b. However, even if you had told git to stage new contents,
if the new contents happen to be the same as HEAD, then
the command grabs every change in the working tree and
makes a commit out of it.
2-c. Contrary to the above exception, even if you staged the
same contents as in HEAD, if you are in the middle of the
merge, it does not include the working tree changes in the
new commit. This is because....
2-d. Another exception is that if you are amending an existing
commit, ... This is because....
With careful reading, the users may understand it after they
read the above description, but would that understanding really
be committed to memory? Are you confident that you will
remember your own reasoning for the exceptions and be prepared
to defend this change (and perhaps follow-up additions to the
list of exceptions), if 6 months down the road when an old timer
from the kernel circle says "I updated to recent git, and its
'commit' behaves funnily in the way I did not expect. Why does
it do that"?
I really think the users would be much better off with
consistent behaviour that is easy and simple to describe than a
complex magic that does the right thing 99.9% of the time,
because you either understand the complex magic or constantly in
fear of the tool that can work against you 0.01% of the time.
^ permalink raw reply
* Re: [RFC] git-add update with all-0 object
From: Jakub Narebski @ 2006-12-02 8:26 UTC (permalink / raw)
To: git
In-Reply-To: <Pine.LNX.4.64.0612010223010.20138@iabervon.org>
Daniel Barkalow wrote:
> Of course, we'd still have to disabuse people of the notion that the index
> can store the information "there's nothing at this path yet, but I'm
> interested in it", because that's a piece of information people often know
> before a file is ready, and think git would be able to remember in a
> staging area.
Well, that was what about the first message in this thread about. Marking
a file "interesting" (so 'git commit -a' would pick it up) using all-0
for object hash... which of course requires review and if necessary
modification of all core tools which touch the index.
--
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git
^ permalink raw reply
* Re: [PATCH] make 'git add' a first class user friendly interface to the index
From: Alan Chandler @ 2006-12-02 8:28 UTC (permalink / raw)
To: git; +Cc: Carl Worth, Junio C Hamano, Nicolas Pitre
In-Reply-To: <87veku3i0j.wl%cworth@cworth.org>
On Saturday 02 December 2006 06:54, Carl Worth wrote:
...
> The proposal in the current thread of using "add" is an improvement on
> the shortness side, and I am _delighted_ to see documentation
> appearing that is focused on what the user wants to achieve and what
> the user should expect to happen. So, Junio, please go ahead with
> Nico's stuff here. It is an improvement over the current
> situation. (And thanks, Nico, for fighting against having technical
> details getting added to user-oriented documentation).
>
> But I do still think it's a mistake to muddle the concepts of "adding"
> a file and "staging edited content" for a file. In index terms, the
> distinction is between adding a new path (and contents, of course) to
> the index vs. just updating the contents for an existing path.
>
> But it's not the index distinction that's interesting. It's that users
> think of those operations differently. An "add" operation takes a
> files out of the "untracked file" state as reported by git
> status. That's a very different thing conceptually than updating the
> contents of a file that is already being tracked by git. And if the
> user thinks of an operation as being different, the command should
> reflect that. There is a sense in which the user is always right here,
> (since if the tool doesn't do what the user wants, the user just goes
> somewhere else).
>
...
>
> Except it does still leave open the user confusion of:
>
> git add file1
> git commit
> "cool, that works"
>
> edit file1
> git add file2
> git commit
> "hmm, why didn't file1 get commited that time?!"
>
> And the only answer we can give to the poor user is:
>
> Oh, "git add", (and "git commit" for that matter) don't do
> what you think they do. Go read the documentation and try
> again.
>
...
> If add really were uniquely about _adding_ files to be tracked,
> (rather than just a short synonym for update-index), and if we tweaked
> the default behavior of git-commit, we could fix these things. And
> all the model and power of git would still exist and be ready to be
> learned by anyone that wants it, (rather than only by those who manage
> to get past snags like these).
There is a conceptual difference between thinking that git-add is about adding
a file and git-add adding the current state of a files content. If your
conceptual model is the first of these - then I can see why you see a problem
with git-add being used to say a files contents have changed.
However, if you regard the git-add command is "adding the current content of
the file to a staging area" , and you say this is an SCM which by definition
keeps the history of things once its been told about them I don't see why
there is a need for a different name for the operation the first time and for
the operation later.
Trying to put myself in the shoes of a newbie - if taught to use add in both
ways up front - is to ask why git isn't clever enough to notice that I have
changed the content of something it already knows about rather than having it
to manually add it again.
So I am with you that we need to effective teach
git add <filename> #add content of filename to the SCM
#edit <filename>
git commit -a #commit current state of all tracked content
first, and then move on to teach selective commiting
The benefit of one name rather than two is that its less to remember
--
Alan Chandler
^ permalink raw reply
* Re: [RFC] git-add update with all-0 object
From: Jakub Narebski @ 2006-12-02 8:35 UTC (permalink / raw)
To: git
In-Reply-To: <200612010937.08468.andyparkins@gmail.com>
Andy Parkins wrote:
> On Friday 2006 December 01 08:10, Daniel Barkalow wrote:
>
>> My position on this subject is that "index" is a good name, but that
>> description is a terrible description, and "index" is a word that needs a
>> good description in context. If we just said up front:
>
> If we need to explain what "index" means in the context of diff then it's not
> a good name :-)
But "staging area" or more descriptive "staging area for commits" is
a bit long. But we no longer name the "index" "dircache".
> An index /everywhere else/ is a lookup table. topic->page number;
> author->book title. record id->byte position. There is never any content in
> an index, indices just point at content.
Just like git index.
> I imagine that's how git's index got it's name. (I'm only guessing as I've
> not looked at what's actually inside git's "index"). Here's my guess:
>
> git update-index file1 hashes file1, stores it somewhere under that hash and
> writes the hash->filename connection to .git/index. That is why git's index
> is called an index. It's a hash->filename index.
This "somewhere" is object repository. And it is reverse: it is
filename->(stat + hash) index; from a file in the working area to the blob
(or tree) in the repository.
> Unfortunately, "index" in colloquial git actually means the combination
> of .git/index plus the hashed file itself. That's no longer an index, it's
> a "book". :-)
Yes, it is true that "index" in colloquial git means "index version"
(version pointed by the "index").
> It's made worse, I think, by the fact that git doesn't want to do any
> index-like things with the "index". Being content-oriented rather than
> name-oriented means that an entry like "file1->NOTHING" is impossible in git.
> This leads to the sort of "git-add means track this filename" confusion that
> turns up a lot with new users.
It is possible. By convention all-0 hash means 'no such object'. The very
first message in this thread tried to make use of it... but "git add" to
mark filename as interesting instead of "git add" to add _current_ contents
of the file goes a bit against git ideas.
> It's probably all too late to change the nomenclature, but I've always been of
> the opinion that names are important, they confer meaning. When we use a
> common word, with common meaning and deviate from that common meaning we are
> bound to create confusion. New users don't have any "git-way-of-thinking"
> knowledge when they begin, so when they hear "index" they can only fall back
> on their standard understanding of that word. We shouldn't be surprised then
> when new users don't get "the index".
Well, "dircache" was changed to "index". "<ent>" was axed in preference
to "<tree-ish>". I think using "staging area" name in git man pages would
be a good idea (as would be making --index to be alias to --cached).
--
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git
^ permalink raw reply
* Re: [RFC] git-add update with all-0 object
From: Jakub Narebski @ 2006-12-02 8:55 UTC (permalink / raw)
To: git
In-Reply-To: <7vhcwgcf39.fsf@assigned-by-dhcp.cox.net>
Junio C Hamano wrote:
> * 'git-diff' [--options] <commit> <commit> -- [<path>...]
>
> is to see the changes between two <commit>.
>
> Just in case if you are doing something exotic, it
> should be noted that all of the <commit> in the above
> descriptoin can be any <tree-ish>.
s/descriptoin/description/
It _might_ be worth mentioning that you can compare two arbitrary
files using
git diff [--options] <blob1 sha> <blob2 sha>
where <blob sha> can be entered as <tree-ish>:<filename>, usually
<commit>:<filename> (<filename> is HEAD:<filename>) to compare blob (file)
from a named tree/from a given commit, or as :<stage>:<filename> (or
just ::<filename> if file is not in merge conflict) to compare blob (file)
from an index.
If I understand correctly there is currently no way to compare files from a
working tree, not to mention files outside working tree
(including /dev/null) with that syntax.
--
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git
^ permalink raw reply
* Re: git and bzr
From: Jakub Narebski @ 2006-12-02 8:57 UTC (permalink / raw)
To: git
In-Reply-To: <456FFC10.7060703@op5.se>
Andreas Ericsson wrote:
> ---%<---%<---%<---
> SYNOPSIS
> --------
> 'git-diff' [ --diff-options ] <tree-ish>{0,2} [<path>...]
>
> DESCRIPTION
> -----------
> Show changes between two trees, a tree and the working tree, a
> tree and the index file, or the index file and the working tree.
> The combination of what is compared with what is determined by
> the number of trees given to the command.
>
> * When no <tree-ish> is given, the working tree and the index
> file are compared, using `git-diff-files`.
>
> * When one <tree-ish> is given, the working tree and the named
> tree are compared, using `git-diff-index`. The option
> `--index` can be given to compare the index file and
> the named tree.
> `--cached` is a deprecated alias for `--index`. It's use is
> discouraged.
>
> * When two <tree-ish>s are given, these two trees are compared
> using `git-diff-tree`.
> ---%<---%<---%<---
>
> This needs an update, I think. I'll look into it on sunday if no-one's
> beaten me to it.
You might want to use Junio proposal in
Message-ID: <7vhcwgcf39.fsf@assigned-by-dhcp.cox.net>
http://permalink.gmane.org/gmane.comp.version-control.git/32853
(and perhaps also my reply to it)
--
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git
^ permalink raw reply
* Re: [PATCH] make 'git add' a first class user friendly interface to the index
From: Carl Worth @ 2006-12-02 9:06 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Nicolas Pitre, git
In-Reply-To: <7vlklq20n5.fsf@assigned-by-dhcp.cox.net>
[-- Attachment #1: Type: text/plain, Size: 7638 bytes --]
On Fri, 01 Dec 2006 23:54:38 -0800, Junio C Hamano wrote:
> > Wow, this index stuff sure takes a lot of explaining. Why are users
> > better off having to grasp all of that stuff before they can
> > successfully add; edit; #oops, add again; and commit their files?
>
> Jumping the index is not about that sequence. It is about being
> interrupted while doing something else, and committing a smaller
> trivial change first that is independent from what you have been
> doing. Beginners do not have to do that "interrupted work"
> sequence.
I guess my point is, the only arguments I've heard against changing the
default behavior of "git commit" are:
1. It's always been the way it is
This is a legitimate concern, yes. It might justify a big bump to
git's version number, or a new configuration option that the
old-timers would set, or maybe the "default" I want could be a a new
configuration option that would be set by default for new clones.
Whatever. There's an inertia problem here, but that hasn't been the
strong push-back I've been getting.
2. Doing anything other than the way it is would "deny the index"
This argument has been made forcefully, and again and again.
But I don't think it stands at all. The current behavior of
"git-commit files..." denies the index just as much. Just look at
the documentation for git-commit. It starts out with a technical,
index-based description:
Updates the index file for given paths, or all modified files
if -a is specified, and makes a commit object.
Now, that description doesn't explicitly say from _what_ the commit
object is created, but a natural reading would be "from the updated
index". And historically, that is exactly what "git commit files..."
did. I'm sure this wording is fairly old.
However, today what "git commit files..." does today is very
different. It's a bit hard to track it down in the man page, but
eventually you end up with:
"Commit only the files specified on the command line."
What does that even mean in terms of the index? I don't even know
the precise details. And I don't think there's even a very clean way
to describe it. (The documentation already starts to get a bit messy
where it has to describe that certain index states will make "git
commit files..." balk completely).
So "git commit files..." already "denies the index" just as much as
my proposed default behavior for "git commit". Why? Because it's
_useful_, that's why. The old "git commit files..." behavior was
much more consistent in terms of index manipulation, but Junio got a
scalding email from Linus when he suggested reverting that behavior.
If you try to think about all the index manipulations of "git commit
files..." you'll actually get fairly confused. But has there been
some problem with people failing to be able to learn the index as a
result? Has anyone ever even run into this confusion? No. Because,
"git commit files..." does exactly what you actually _want_ to do,
and that operation is really easy to describe without any confusion:
"Commit only the files specified on the command line."
So, we can come up with just as short descriptions for the other
useful git commands:
commit -a Commit all files tracked by git
commit Commit all files as they exist in the index
Think about when the behavior of these commands is the same, and think
about when they are different. If they're different, think about what
situations make that difference _useful_, what does the user _want_ to
do? And finally, what did the user have to do to arrive at that
situation?
* The commands are the same when resolving a merge.
* The commands are different when explicitly staging a commit. This
difference is useful---a point which has also been made forcefully,
again and again. This situation arises when a user explicitly
executes a command to stage something into the index, (historically
with "update-index" and now proposed for "add").
* The commands are different after adding a new file to be tracked by
git for the first time. This difference is not useful. This
situation arises whenever a file is added and subsequently
edited. It's not necessarily the case that the user is _trying_ to
do any staged commit, (and most commonly the user is not).
The recent "git add" conversation conflates these last two use cases,
which is a bit problematic because one is useful to the user while the
other is not.
> We say "you should add modified state again if you edit it again
> after you added it" in a section before these sentences, and
> encourage users to consistently say 'git add'.
I think this is a mistake for documentation that will be encountered
early by new users, (as git-add is one of the first things a user must
use if starting with git from scratch as opposed to through a
clone). The problem is that all the talk of "git add + git commit"
easily leads to the impression that there's more work to do in git
than in any other system that anyone may have ever encountered.
Now, there isn't actually more work, and we can explain that later,
"you will most commonly not use the sequence explained above, but will
instead use 'git commit -a' which will perform both steps for you".
This is the kind of sentence in documentation which just screams that
there's a user-interface problem. Why do we explain how to do
something only to say a moment later that user's won't do that? The
reason is because we _have_ to explain git-add that way or else the
current semantics of git-add + git-commit can be very confusing.
Let's just eliminate that confusion, drop the stuff from the
docs. that make git seem like it's harder to use than anything else on
the planet, and save the discussion of the index for a section in the
documentation that deals with something the user is wanting to do that
actually _benefits_ from the index.
> By the way, aren't people disturbed that "git rm" does not
> default to "-f" -- I rarely use the command myself but that
> makes it feel even more awkward that "git rm foo" does not
> remove the file "foo".
Yes, it's usually a bug that it doesn't delete the file by
default. This one's my doing, but I was thinking of an actual
situation that I had been in, that of wanting to undo an "add". For
example:
git add file1
git add file2
# Oh, wait, I should commit these independently
git rm file2
git commit -m "add file1"
git add file2
git commit -m "add file2"
So one way to fix this would be to make "git rm" delete the file if it
is consistent in working-tree and HEAD and to leave it there
otherwise. The message could be something like:
Note: file <foo> has uncommitted changes, leaving it in
the working tree as an untracked file.
Then, -f could still be useful as a way to force file deletion even in
this case.
> Well, I think at least we are converging.
I'm glad you feel that way. I know I've been something of a pest
recently, (and yes, Linus, I do often get weary of pests that want to
throw out the fundamental strengths of a system like X).
Maybe think of it this way: I've been arguing on behalf of
brain-damaged users. Git's got the cure for them, but they're not
ready to sign up for that kind of brain surgery when they can see it
coming. If we can subdue them with a more gentle introduction, ("start
counting the everyday git commands backwards from 10 to 1"), then
we'll have their brains and can do everything we want to them.
And I really think the re-training can be painless---I don't think the
proposals I'm making will setup any nasty surprises down the road.
-Carl
[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply
* Re: [RFC] Submodules in GIT
From: Andy Parkins @ 2006-12-02 9:22 UTC (permalink / raw)
To: git
In-Reply-To: <Pine.LNX.4.64.0612011540010.3695@woody.osdl.org>
On Saturday 2006, December 02 00:12, Linus Torvalds wrote:
> 100644 blob 08602f522183dc43787616f37cba9b8af4e3dade xdiff-interface.c
> 100644 blob 1346908bea31319aabeabdfd955e2ea9aab37456 xdiff-interface.h
> 040000 tree 959dd5d97e665998eb26c764d3a889ae7903d9c2 xdiff
> 050000 link 0215ffb08ce99e2bb59eca114a99499a4d06e704 xyzzy
>
> where that 050000 is the new magic type (I picked one out of my *ss: it's
> not a valid type for a file mode, so it's a godo choice, but it could be
> anythign that cannot conflict with a real file), which just specifies the
> "link" part. The SHA1 is the SHA1 of the commit, and the "xyzzy" is
> obviously just the name within the directory of the submodule.
Can I argue that the hash in that object should actually be to a real object
in the supermodule repository rather than a link? Then THAT object would
contain the hash? So in your above example:
100644 blob 08602f522183dc43787616f37cba9b8af4e3dade xdiff-interface.c
100644 blob 1346908bea31319aabeabdfd955e2ea9aab37456 xdiff-interface.h
040000 tree 959dd5d97e665998eb26c764d3a889ae7903d9c2 xdiff
050000 link a7f26495b7b7e32bf949efbd91ee32267b792cba xyzzy
And then the local object a7f26495b7b7e32bf949efbd91ee32267b792cba would
contain your original hash 0215ffb08ce99e2bb59eca114a99499a4d06e704.
The reason I suggest this as without out it the "link" object is the only hash
in the tree that doesn't point to a valid object. The contents of objects is
entirely arbitrary so it's perfectly okay for that to contain a hash that
won't dereference to a real object in the supermodule.
The main advantage of this is (I think) that git-prune, git-fsck, and whatever
else relies on tree objects all being real, don't need to be modified at all.
It also gives you scope to later add fields to the "link" object if you
wanted.
Andy
--
Dr Andrew Parkins, M Eng (Hons), AMIEE
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox