From: Junio C Hamano <hidden> Date: 2016-08-11 19:58:21
Junio C Hamano [off-list ref] writes:
... Rather,
"building your next commit incrementally in the index is the
workflow git is designed to support, but you are not required to
do that _incrementally_. Until you encounter a complex
situation such as resolving a large conflicting merge, doing
that incrementally does not buy you anything as long as you work
in a clean working tree.
Side note. I think the above "Until..." is an overstatement,
and maybe the readers of the tutorial can be taught a lot
earlier how the index can help them. Maybe the following
sequence can be added to an early part of the tutorial sequence?
$ edit hello.c
$ make test
$ git diff
$ git update-index hello.c; # ok, that is good so far.
$ edit hello.c; # hack more
$ make test; # oops, does not work
$ git diff; # ah, that overeager edit broken what was good
$ git checkout hello.c; # get the last good one back
From: Marco Costalba <hidden> Date: 2016-08-11 19:17:38
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 ;-)
Repeat the above sentence again. IT JUST MAKES SENSE.
Yes. And it makes sense for the user to be able to say "unless I tell
you differently, I want to always commit the working-tree state of
<files> with every commit".
If so, you should make it a special case.
I refuse to believe in the "people who know what the hell they are doing
should work more at it" philosophy.
The "git commit -a" behaviour as it is now is better than the
alternatives, exactly because it's more flexible. It _allows_ you to not
commit anything at all (and as already mentioned, there are cases where
that is exactly what you want).
If you want to have a "-a by default", then that you require _you_ to do
more work, and no, it's NOT an excuse to say "I'm a clueless newbie, and I
don't know how to set a config option, so I think it's the smart and
beautiful people who should suffer for my shortcomings".
You can even do it by doing an alias like
[alias]
ci = commit -a
and then you can revel in your CVS-induced mudpit all you want. Just
don't try to convince people who have gotten over that braindamage to live
in the same muck with you.
Problem solved. For all I care, we can make that alias a default one, so
people who just can't get their mind out of the gutter that is CVS can
continue with their evil ways.
Having the index exposed for even simple operations means that the user
has to initially learn three states instead of two. The worst thing
about the index is that it is a limbo state. The committed content is in
the history and can be viewed by gitk (and other tools that the user
will be introduced to later) and the working tree is exactly what the
user sees in their editor. Having a hidden state isn't very good from an
HCI point of view.
Index is accessible, just like committed contents. The fact that gitk, qgit,
git-gui doesn't display state of index is their limitation.
Actually git-gui shows the index, but not quite as well as diff
and friends would.
But based on this thread I had a major realization: git-gui is
totally wrong in how it displays files (and therefore gitool is
too!). I'm going to rewrite that part of git-gui's UI, hopefully
early next week.
Linus is right: To deny the index is to deny git itself. Trying to
hide part of the index in git-gui is just wrong and makes things
like merge conflict resolutions harder, not easier.
--
From: Andy Parkins <hidden> Date: 2016-08-11 19:28:29
On Thursday 2006 November 30 21:03, Linus Torvalds wrote:
Yeah, I think it would probably make sense. I also think it would make
sense to rename "update-index" entirely, or at least offer other names for
How about this:
git-update-index becomes plumbing only - never expect a user to run it.
Hence,
git-add becomes git-prepare and does
a) update-index --add
when the file being "prepared" is not tracked
b) update-index
when the file is already tracked
git-rm takes on "git-update-index --remove" (and --force-remove) with
appropriate switches.
git-mv does what it does - it's already pretty perfect
git-cp gets added; even though it's simply "cp a b; git-prepare b"
Obviously with all the details that I've left out filled in.
Andy
--
Dr Andy Parkins, M Eng (hons), MIEE
From: Michael K. Edwards <hidden> Date: 2016-08-11 19:33:46
On 11/30/06, Carl Worth [off-list ref] wrote:
So I'd vote for "resolve" along with something else for the
mark-as-edited case. Maybe "refresh"? That's the best I've thought of
so far. Anyone else have a better suggestion? It does clash with the
separate notion of "git update-index --refresh" which is a bit
annoying. Any other suggestions for this?
git mark
and git add becomes just a synonym for git mark.
Cheers,
From: Johannes Schindelin <hidden> Date: 2016-08-11 19:33:57
Hi,
On Thu, 30 Nov 2006, Carl Worth wrote:
It might even make sense to invent one more name for the case where
the user wants to inform git that a file has been edited and that git
should accept the new contents. It's the sort of "note that file is
edited" operation that could be recommended to the user with "add; fix
typo; commit" confusion.
I suggest "commit". How about this: after editing the file, you tell git
that you finished editing it by doing
git commit the-edited-file.txt
Hmmm?
Ciao,
Dscho
From: Carl Worth <hidden> Date: 2016-08-11 19:34:06
On Thu, 30 Nov 2006 19:47:16 +0100, Jakub Narebski wrote:
while in git "git add" means "I want to add this file" (in the state
it is now) and not "I want the system to 'know' about this file".
And "commit" mean "Please commit the current 'known' state of all
files (or/and the current state of files I mention here on the
comand line)".
Yes. There is a logical explanation for what git does, and it is
self-consistent.
It just means that the user is _forced_ to pass file state across the:
"working tree" -> git
boundary at two different times with two different commands for the
very first commit the user makes. And the user _must_ understand that
this is a two-step process, (even though, without the "typo" in my
example above it would be natural to conclude the transition occurred
only during "commit").
See? Git _is_ harder to learn, and a user really cannot learn it
without being careful about the index right from the very beginning.
-Carl
From: Carl Worth <hidden> Date: 2016-08-11 19:39:46
On Thu, 30 Nov 2006 09:13:52 -0800 (PST), Linus Torvalds wrote:
On Thu, 30 Nov 2006, Theodore Tso wrote:
quoted
But then why is the default for "git commit" to commit the index, if
the index is almost == HEAD? And why is git-update-index given such
prominence in the documentation?
The default is: commit everything that you ask for to be committed.
...
It has NOTHING to do with the index per se.
OK. I'll try to not mention the "index" any more in any postings
here.
And can we agree that any time git spits out a message directing the
user to use update-index that that's a (minor) user-interface wart?
"git commit" with no parameters simply DOES NOT DO ANYTHING YOU
HAVEN'T ALREADY ASKED YOU TO DO.
I think the response that would come from the people that are confused
is:
"But I told git I wanted to track this file when I said 'git
add' long ago. Why is it making me tell it again."
As you mentioned, all systems have _some_ mechanism for keeping track
of the files to be committed, (and git's is only unique in having a
name and providing more functionality for direct manipulation and lots
of extra information in the case of a merge conflict).
But I think most every system out there _except_ git default to a
state of committing every file it "knows" about as it exists in the
working tree, and then allowing the user to restrict that behavior to
some subset of the files.
Git allows the same subsetting, and has behavior that is very similar
to these other systems when the user provides a list of files.
Git also provides a unique mode in that users can "stage" file state
to be committed later in spite of subsequent different changes being
made to the same files in the working tree that won't be
committed. Some git users love this functionality. But mentioning it
to new users does scare them off to some extent, ("Why would I _want_
to do that?", "What if that happens accidentally?").
And I think one thing that happens is that the current defaults
naturally lead users to hear about this "scary" functionality, even if
the presenter, (whether a human or printed documentation), isn't
trying to go that direction:
Presenter: So use "git commit -a" here.
New user: Why -a?
Presenter: To tell git that you want to commit all files rather
than having to list them all on the command line.
New user: Why not just "git commit" for that then?
Presenter: Because that's something else.
New user: What's that?
Presenter: It lets you stage things---stuff you think is ready to
commit, but when you want to delay that commit until
after making other changes to the files that you don't
want to commit.
New user: What? Really? That's bizarre.
Presenter: It can be useful in some situations. But for now,
just use "commit -a" and it will do what you want.
And at this point the user either trusts me, accepts it, gives git a
try and falls in love, or the user gives up and uses something else.
I think the above accurately captures the essence of actual
conversations I've had with new new users. And I'd be glad to take
suggestions on how to improve what I say here. But it's that feeling
of "git is bizarre" that I'd like to reduce, and I'd like to improve
the success rate of the conversation, (though I think I've done pretty
well for people that trust me).
And note that the same kind of conversation happens when using git
directly with tutorials and man pages, but without a human
presenter. Only, there the conversation is much worse. First, it's
harder to pull off "just trust me and give it a try" in technical
documentation. Second, the documentation does not do a good job of
letting the user know when they're getting more technical information
than they need.
For example, there's "git status", (used by "git commit"), that
directs the user to "git update-index". Then there's the documentation
of git-commit that says "Updates the index file...and makes a commit
object."
And so far my best response to those problems is to short-cut them by
improving the defaults of git-commit, (the documentation should be
improved too, and I did submit a patch to get "update-index" out of
git-status output for example).
Anyway, I'm repeating myself on some of these details, but only
because some people still haven't seemed to grasp the real, new-user
confusion that arises here.
That's really what I'm trying to reduce with all the talk about
"commit all known files by default".
"git commit" with no parameters simply DOES NOT DO ANYTHING YOU
HAVEN'T ALREADY ASKED YOU TO DO.
Repeat the above sentence again. IT JUST MAKES SENSE.
Yes. And it makes sense for the user to be able to say "unless I tell
you differently, I want to always commit the working-tree state of
<files> with every commit".
-Carl
I like it. Sort of a "temporary commit" to check against.
I (very) occasionally do this for patches I get.
You can do
git-apply --index patch
and it will apply the patch and update the index for you. That's great for
committing the patch (because it means that it adds and removes your files
automatically for you), but most of the time when I get an email that I
want to apply, I just use "git-applymbox".
So where doing the "git apply --index" thing is great is when you see a
patch that has some obvious deficiency that makes you not want to commit
it directly, but add some fixup of your own.
That's when it's useful to use the index to your advantage - you can do
"git diff" (to see just the fixups you did on top of the patch), or you
can do "git diff HEAD" (to see the combined effect of both the patch _and_
your fixups).
That said, I have to admit that I usually (a) don't do this very often (ie
this is not part of my daily routine) and (b) I tend to do "git reset"
fairly soon afterwards (or alternatively, just "git commit -a") to get
back to the situation where the index will match the current HEAD 100%
again. So the "index doesn't match HEAD" situation is always just a
_temporary_ thing for me.
From: Sam Vilain <hidden> Date: 2016-08-11 19:42:21
Steven Grimm wrote:
Am I missing some magic index command that would support multi-level
backing out? Obviously StGIT is an option as well, but that seems like
overkill when all I want is to checkpoint my work. The above is why,
even though (I think) I know enough about the index to use it as you
describe, I often don't bother and just run "commit -a" during
development instead. When I merge, I usually fold all my checkpoint
commits together and merge the change as a logical unit.
From: Jakub Narebski <hidden> Date: 2016-08-11 19:46:29
Robert Shearman wrote:
Having the index exposed for even simple operations means that the user
has to initially learn three states instead of two. The worst thing
about the index is that it is a limbo state. The committed content is in
the history and can be viewed by gitk (and other tools that the user
will be introduced to later) and the working tree is exactly what the
user sees in their editor. Having a hidden state isn't very good from an
HCI point of view.
Index is accessible, just like committed contents. The fact that gitk, qgit,
git-gui doesn't display state of index is their limitation.
--
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git
From: Johannes Schindelin <hidden> Date: 2016-08-11 19:46:45
Hi,
On Wed, 29 Nov 2006, Linus Torvalds wrote:
So where doing the "git apply --index" thing is great is when you see a
patch that has some obvious deficiency that makes you not want to commit
it directly, but add some fixup of your own.
An obvious deficiency would also be the presence of hundreds of debug
quirks I had to introduce to find the bug which I finally fixed. But I do
not want to commit, because it is such a mess. So: into the index, ye
files.
Now I can clean up everything I introduced to find the bug. If the result
does not work as expected? "git diff"!
But now that I cleaned up the mess, I find that there is a more elegant
way to solve the problem. Into the index, ye files! Clicketyclick, if I
mess up, I always have the state in the index!
Ciao,
Dscho
From: Jakub Narebski <hidden> Date: 2016-08-11 19:49:09
Linus Torvalds wrote:
The _original_ "git add" was literally just this one-liner:
#!/bin/sh
git-update-index --add -- "$@"
which actually was better in this respect (it updated the content), but
that didn't do sub-directories, so this is arguable a bug introduced by
commit 37539fbd:
[PATCH] Improved "git add"
This fixes everybodys favourite complaint about "git add", namely that it
doesn't take directories.
which started using
git-ls-files --others -z -- "$@"
together with the exclude files to generate the list of files to add. At
that point, we lost files that already existed (since "--others" specifies
just files we don't know about).
So should we use then
git-ls-files --cached --others -z -- "$@"
in git-add?
I'm very much for having git-add, -rm, -mv and -resolved as porcelain
wrappers around git update-index, so there would be even less events
when you have to use this plumbish command directly.
--
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git
From: Carl Worth <hidden> Date: 2016-08-11 19:55:58
On Thu, 30 Nov 2006 13:41:37 -0800, "Michael K. Edwards" wrote:
git mark
I actually thought of that. But compared to "refresh" it sounds more
like something that suggests marking a file path rather than copying
contents, so our dark lord might not approve of the wrong ideas it
might allow to persist in brain-damaged heads.
It is nice and short, which is a bonus though.
-Carl
From: Jakub Narebski <hidden> Date: 2016-08-11 19:57:32
Dnia czwartek 30. listopada 2006 22:50, Carl Worth napisał:
On Thu, 30 Nov 2006 13:41:37 -0800, "Michael K. Edwards" wrote:
quoted
git mark
I actually thought of that. But compared to "refresh" it sounds more
like something that suggests marking a file path rather than copying
contents, so our dark lord might not approve of the wrong ideas it
might allow to persist in brain-damaged heads.
It is nice and short, which is a bonus though.
What about "git update"? "git add" would also work, I think.
--
Jakub Narebski
From: Robert Shearman <hidden> Date: 2016-08-11 19:57:43
Carl Worth wrote:
If the "create file; git add; edit file; git commit" confusion isn't
blisteringly obvious to the git maintainers then I think I have to
give up here.
And this isn't just CVS-induced brain damage. It's the user being
required to mentally juggle 3 states for the file, (the last
"committed" state, the current "working tree" state, and this
"something else" state). The sequence above, (which is very natural),
exposes this "something else" state that to a new user.
Exactly. We had a tutorial for the project I contribute to (admittedly
the initial users were all used to how CVS worked) and while a number of
people got the concept of the index and were fairly happy with it, it
did add to the confusion of the tutorial, so now it doesn't mention the
index at all.
The tutorial introduced it as a staging area for commits, but the
trouble is that once you work like this you have to remember that
"git-diff" won't show you what will be committed, so you have to use
"git-diff-index" as well. If you get them mixed up then you end up
committing the wrong thing.
Here's a selected list of the commands introduced in the tutorial,
without mentioning the index:
git diff
git commit -a
git commit <changed-files>
git reset HEAD^
git cherry-pick
Here would be the same entries, but introducing the index too:
git-update-index
git diff
git diff-index
git commit
git commit -a
git commit <changed-files>
git reset HEAD^
git reset --soft HEAD^
git cherry-pick
git cherry-pick -n
The tutorial then goes from having ~12 common commands to learn up to ~17.
If we imagine a new user as coming, not from cvs, but coming from
no revision control system, then it's less confusing to add one single
new state, (the "last committed" state), in addition to the "working
tree" state the user is familiar with.
Forcing the user to learn two instead of one is just plain harder,
(which is completely separate from git _allowing_ this extra state
once you learn it).
Having the index exposed for even simple operations means that the user
has to initially learn three states instead of two. The worst thing
about the index is that it is a limbo state. The committed content is in
the history and can be viewed by gitk (and other tools that the user
will be introduced to later) and the working tree is exactly what the
user sees in their editor. Having a hidden state isn't very good from an
HCI point of view.
Once you understand the concept of the index, it is very useful.
However, new users should be shielded from it if at all possible.
I'm not advocating making "git-commit" equal to "git-commit -a" as I've
been frustrated by command's semantics changing in git before. I can
understand long-time git users would automatically try to use
"git-commit" to just commit their index and get annoyed if it did
something unexpected. Therefore, I would advocate there being no default
behaviour for "git-commit" except for displaying a help message, and
making previous "git-commit" users now use "git-commit -i".
--
Rob Shearman
That said, I have to admit that I usually (a) don't do this very often (ie
this is not part of my daily routine) and (b) I tend to do "git reset"
fairly soon afterwards (or alternatively, just "git commit -a") to get back
to the situation where the index will match the current HEAD 100% again. So
the "index doesn't match HEAD" situation is always just a _temporary_ thing
for me.
A staging area is per definition meant to keep temporary things before they
are committed to their designated place so there's nothing odd about that.
Sure. It's just that some people seem to expect the index to be different
from HEAD, and are afraid of being "confused" by it.
The fear seems to be about "git diff" getting different results from "git
diff HEAD", and always having to _check_ the two.
So I wanted to make it clear that I never have that situation, because I
never leave the index "dirty". I agree that there is nothing odd about it,
but I think that people who don't actively use the index (or don't use git
at all, and just worry about it) see it as a kind of separate entity with
a life all its own.
I can see that if you think the index is likely to be out of kilter with
HEAD, you'd always worry about "ok, so maybe the diff I get from 'git
diff' isn't the _true_ diff, so now I have to do _both_ 'git diff' and
'git diff HEAD' to make sure I know what's up".
I just wanted to clarify that that is never the case for me, and I doubt
anybody else really does it either. For a very complicated merge, I could
possibly see somebody having a dirty index for a day or two and taking a
break with the index dirty, but
(a) I've certainly never seen that myself (and it would have to be
something very messy indeed - I remember multi-day merges with CVS,
but that was because CVS is so bad at merging, not because the merges
per se would have been all that messy)
(b) if you have a merge _that_ messy, I don't think you're likely to
forget about it, and rather than be confused about the difference
between 'git diff' and 'git diff HEAD', you'll be really really happy
that you have some way of seeing just the _remaining_ pieces, rather
than all the crud you already fixed up.
In other words, the fact that the index _normally_ matches the HEAD may be
obvious, but it's also important - it's important to allay fears from
non-index users about it being somehow scary and confusing. It's not.
But then why is the default for "git commit" to commit the index, if
the index is almost == HEAD? And why is git-update-index given such
prominence in the documentation?
The default is: commit everything that you ask for to be committed.
If you haven't marked anything to be committed (which you can do with "git
add" too, or with simply being in the middle of a merge, or by having done
something like "git pull -n" or similar that does everything _but_
commit), then git commit will say "nothing to do".
It has NOTHING to do with the index per se.
I still don't understand why people are so hung up about the index.
So ignore the index entirely, and follow along with me:
"git commit" with no parameters simply DOES NOT DO ANYTHING YOU
HAVEN'T ALREADY ASKED YOU TO DO.
It's that simple. It's that logical. Ignore the index. Ignore everything
else. Just read that simple, straightforward, and logical sentence on its
own. It all makes sense.
Then, the trivial follow-up is:
If you want to commit _all_ dirty files, use "git commit -a".
Otherwise, name the files or subdirectories you want to commit
explicitly.
Again: THIS JUST MAKES SENSE.
Asking for "-a" to be the default behaviour is BAD.
For example, in "git commit --amend", it's _important_ that "-a" not be
the default, because you may well want to just amend the commit _message_.
No files updated AT ALL. You may have other state that is still dirty
(because you didn't ask it to be committed last time), and they should NOT
be committed, because the simple rule is:
"git commit" with no parameters simply DOES NOT DO ANYTHING YOU
HAVEN'T ALREADY ASKED YOU TO DO.
Repeat the above sentence again. IT JUST MAKES SENSE.
So maybe the documentation shouldn't mention the "index" at all, because
it apparently scares and confuses people. But the fact is, the
documentation started out as _technical_ documentation, that explains the
_technical_ side of git. We don't have lots of "end-user" docs.
But the lack of such end-user documentation should not cause idiotic
threads like this, where people blame "the index".
Yeah, so the docs are too scary. But none of this has anything to do with
"the index". It's all logical on its own, and the default behaviour to not
commit anything you haven't asked to be committed is the right one.
Make "git commit" just say "You didn't say what you wanted to commit.
Maybe you meant 'git commit -a'" if there's nothing to commit. How hard
can that be? But don't change semantics now, and please DO NOT change them
to something _worse_ than what we have now (and automatically adding the
"-a" only in _certain_ circumstances is definitely much worse imnsho)
From: Carl Worth <hidden> Date: 2016-08-11 20:05:35
On Thu, 30 Nov 2006 10:38:25 -0800, Carl Worth wrote:
And it's that "why should that behavior be confusing"
disconnect that I'm trying to bridge here. Can you see why the above
confuses new users?
By the way, I think I've said all I can in this thread.
If the "create file; git add; edit file; git commit" confusion isn't
blisteringly obvious to the git maintainers then I think I have to
give up here.
And this isn't just CVS-induced brain damage. It's the user being
required to mentally juggle 3 states for the file, (the last
"committed" state, the current "working tree" state, and this
"something else" state). The sequence above, (which is very natural),
exposes this "something else" state that to a new user.
If we imagine a new user as coming, not from cvs, but coming from
no revision control system, then it's less confusing to add one single
new state, (the "last committed" state), in addition to the "working
tree" state the user is familiar with.
Forcing the user to learn two instead of one is just plain harder,
(which is completely separate from git _allowing_ this extra state
once you learn it).
So if git is determined to just be harder to learn this way, then I
don't know what more I can do to help here.
I love git, and I think everyone should use it. I would just like to
help make it a bit easier for people to do that.
-Carl
On Thu, Nov 30, 2006 at 07:58:09AM -0800, Linus Torvalds wrote:
So I wanted to make it clear that I never have that situation, because I
never leave the index "dirty". I agree that there is nothing odd about it,
but I think that people who don't actively use the index (or don't use git
at all, and just worry about it) see it as a kind of separate entity with
a life all its own.
Well, sure, because the documentation *talks* about it as a separate
entity all its own. Just look at the man page for git-diff as a great
example of this, or the ascii art diagram of the index. It is all
technically _correct_, but it is scary as all heck.
I can see that if you think the index is likely to be out of kilter with
HEAD, you'd always worry about "ok, so maybe the diff I get from 'git
diff' isn't the _true_ diff, so now I have to do _both_ 'git diff' and
'git diff HEAD' to make sure I know what's up".
I just wanted to clarify that that is never the case for me, and I doubt
anybody else really does it either.
But then why is the default for "git commit" to commit the index, if
the index is almost == HEAD? And why is git-update-index given such
prominence in the documentation?
In other words, the fact that the index _normally_ matches the HEAD may be
obvious, but it's also important - it's important to allay fears from
non-index users about it being somehow scary and confusing. It's not.
If everyone agrees with this, I think it would be easier to make
changes to the documentation and maybe some UI tweaks about what the
default might be.
One suggestion is that perhaps a mode where warns users when index !=
HEAD for certain critical commands might not be a bad thing. That
might give users that are just graduating beyond novice git usage, and
just starting to become aware of the index, reassurance because if
they *don't* see the warning message, they can rest assured that they
don't have to do both "git diff" and "git diff HEAD", for example.
See? Git _is_ harder to learn, and a user really cannot learn it
without being careful about the index right from the very beginning.
I'm not so sure about that. I came from CVS / SVN, although I've fiddled
quite a bit with other scm's as well. The two-step commit process of git
didn't terrify me at all, and I had used git at least a month before I
joined the mailing-list and found out that there's this thing called an
I still don't know exactly how to operate adds and commits from the
command line. I regularly get bitten by not supplying the -a and -i
options.
I'm coming from darcs, where you can select which each diff hunk
to put in a commit separately.
However, I almost never do that. I operate git like darcs, from the
emacs support mode. I almost never do -a commits anyway, because with
emacs (M-x git-status) it's more natural to make functionally distinct
commits, at the risk of introducing non-tested tree states in the
repository.
--
From: Nicolas Pitre <hidden> Date: 2016-08-11 20:10:48
On Thu, 30 Nov 2006, Linus Torvalds wrote:
What does it mean to "add" something to a project? It has _nothing_ to do
with "filenames". Yeah, the filename obviously exists, but it's not
something that exists on its own. You add the ONLY thing that git tracks.
You add CONTENT.
When you do "git add file.c" you aren't adding a filename to the list of
files that git knows about. Not even CLOSE. No. You are really adding
_content_ to the project you are tracking. You haven't bound it to a
commit yet, but it's there. It's there both conceptually, and very much in
a real technical sense too (you've literally added the git object that
that file describes to the object database - the "commit" and "tree"
objects to tie it all together is just waiting to be added, but they
really just expose it - the actual file object has already been created
when you do "git add".)
So yes, you very much ARE talking about CVS braindamage. The reason why
git add file.c
echo New line >> file.c
git commit
commits the _old_ content, is very much because git is ALL ABOUT THE
CONTENT. It has _never_ been about filenames. And it _shouldn't_ be about
filenames, because that would be BUGGY AND BROKEN.
Great. But let me repeat my last question:
Would it make sense for "git add" to do the same as "git update-index"
on already tracked files? Given the explanation above this would make
100% sense to me.
Even for newbies this might help them understand the power of the index
with only one command. "You _add_ your changes together before you may
commit." That's simple to understand even for newbies. And then
they'll start using the power of the index even without realizing it.
But right now, doing "git add" on an already tracked file simply does
nothing. This is even worse than erroring out.
From: Carl Worth <hidden> Date: 2016-08-11 20:12:41
On Thu, 30 Nov 2006 Linus Torvalds wrote:
On Thu, 30 Nov 2006, Nicolas Pitre wrote:
quoted
Would it make sense for "git add" to do the same as "git update-index"
on already tracked files? Given the explanation above this would make
100% sense to me.
Yeah, I think it would probably make sense. I also think it would make
sense to rename "update-index" entirely, or at least offer other names for
it (ie the "git resolved" suggestion).
On Thu, 30 Nov 2006 22:16:29 +0100, Jakub Narebski wrote:
I'm very much for having git-add, -rm, -mv and -resolved as porcelain
wrappers around git update-index, so there would be even less events
when you have to use this plumbish command directly.
I'm happy with the direction of having several commands that take the
place of update-index, each with its own name oriented toward what the
user wants to do.
Obviously, "add", "mv", and "rm" have obvious places where the user
wants to use them.
There's the merge case where "resolve" and "resolved" have both been
floated as possible names.
It might even make sense to invent one more name for the case where
the user wants to inform git that a file has been edited and that git
should accept the new contents. It's the sort of "note that file is
edited" operation that could be recommended to the user with "add; fix
typo; commit" confusion.
Sure, "add" could be used again, and "update-index" clearly _works_
but it's a rather ugly name, (and already has "plumbing" functionality
like --add and --remove that we don't want here).
If "resolved" is the name for the new command, then "edited" might
work, but I think these adjectives don't work well next to the more
active verbs that git normally accepts, (and yes, "mv" and "rm" are
verbs even if horribly mangled spellings).
So I'd vote for "resolve" along with something else for the
mark-as-edited case. Maybe "refresh"? That's the best I've thought of
so far. Anyone else have a better suggestion? It does clash with the
separate notion of "git update-index --refresh" which is a bit
annoying. Any other suggestions for this?
-Carl
From: Alan Chandler <hidden> Date: 2016-08-11 20:16:16
On Friday 01 December 2006 08:34, Andy Parkins wrote:
How about this:
...
Hence,
git-add becomes git-prepare and does
Why can't it stay as git-add
It means "add the current state of the content to the index"
It has the useful property that git-commit -a can be seen as a short cut for
add all the files in the working try and commit.
--
Alan Chandler
From: Nicolas Pitre <hidden> Date: 2016-08-11 20:20:43
On Thu, 30 Nov 2006, Carl Worth wrote:
It might even make sense to invent one more name for the case where
the user wants to inform git that a file has been edited and that git
should accept the new contents. It's the sort of "note that file is
edited" operation that could be recommended to the user with "add; fix
typo; commit" confusion.
Sure, "add" could be used again, and "update-index" clearly _works_
but it's a rather ugly name, (and already has "plumbing" functionality
like --add and --remove that we don't want here).
I disagree. "add" is beautiful. It is short, easy to remember, and
transcend pretty much what the index is all about. And just because
"add" and "edited" can be made into the same command is a pretty damn
good reason not to create a separate command.
You "add" changes to the changeset then you commit that changeset.
No need to care whether or not this is a new file, an edited file, etc.
From: Carl Worth <hidden> Date: 2016-08-11 20:23:32
On Thu, 30 Nov 2006 12:37:49 -0500 (EST), Nicolas Pitre wrote:
Might it be a good idea to have "git-add" do the same as
"git-update-index" on already tracked files? That could be easily
taught as "you must explicitly _add_ files to your next commit"
I think this is worth doing, but it doesn't solve the problem.
It would be nice if this worked, because then it would be natural to
teach users to "git add" their changes, and then when the obvious
complaint about that being annoying to type all the time, then respond
by teaching "git commit -a" as a shortcut. That would be very natural.
But this doesn't quite work. Here's a major "index is confusing"
scenario that I first hit on my first exposure to git, (it was so long
ago that I completely forgot about it when when Linus asked what the
big deal is about the index).
It's all about the fine details of what "git add" does that can be
_extremely_ surprising to new users. Here's a simple scenario:
$ git init-db
defaulting to local storage area
$ echo "hello wurld" > hello
$ git add hello
# Oops! Look at that typo.
$ echo "hello world" > hello
$ git commit -m "add hello"
Committing initial tree 0267c1bf2956b3df47851e0163f2ea86c002379d
$ git diff
diff --git a/hello b/hello
index b1df5e6..3b18e51 100644
--- a/hello
+++ b/hello
@@ -1 +1 @@
-hello wurld
+hello world
And here the new user reaction is "What?! I fixed that before I
made the commit! What kind of broken system is this."
The above example is not at all surprising to someone who understands
the index. And it's that "why should that behavior be confusing"
disconnect that I'm trying to bridge here. Can you see why the above
confuses new users?
In most other systems I've used, 'add' means "I want the system to
'know' about this file" while 'commit' means "Please commit the
current state of all files you 'know' about (or the ones I mention
here on the command line)".
The current semantics do nothing to avoid this "interaction bug" and
there is no way to explain it to the user without going through an
"explanation of the index" and the user is left to decide that the
index is just there to help make broken commits.
So, I'd love for "git add" to be a shorter way to type "update-index",
(I have been campaigning for eliminating hyphens after all), but
without different semantics _somewhere_ the default behavior still is
potentially very confusing. The "ignore the index" stance Linus has
been proposing recently just doesn't work here.
And all of this contributes to make git harder to learn than it should
be.
-Carl
PS. It was actually "hard" for me to create that example above. The
first time I ran through the commands I ended up with an empty diff at
the end. "Huh? I _know_ that git does surprising things here." That
was because I was using Junio's "commit -a" patch which did right
thing rather than demonstrating the old wrong behavior I was trying to
demonstrate.
From: Steven Grimm <hidden> Date: 2016-08-11 20:31:44
Junio C Hamano wrote:
Side note. I think the above "Until..." is an overstatement,
and maybe the readers of the tutorial can be taught a lot
earlier how the index can help them. Maybe the following
sequence can be added to an early part of the tutorial sequence?
$ edit hello.c
$ make test
$ git diff
$ git update-index hello.c; # ok, that is good so far.
$ edit hello.c; # hack more
$ make test; # oops, does not work
$ git diff; # ah, that overeager edit broken what was good
$ git checkout hello.c; # get the last good one back
That actually points out one of the things I think isn't so hot about
using update-index for checkpointing your work. Here's a longer
development session:
$ edit hello.c
$ make test
$ git update-index hello.c; # so far so good
$ edit hello.c
$ make test
$ git update-index hello.c; # looks good too
$ edit hello.c
$ make test
$ git update-index hello.c; # sure, seems okay
$ edit hello.c
$ make test; # oops! design flaw in the second edit uncovered!
$ ???; # how do I back out the last three edits but not the first?
If you know for certain that you will only ever want to back out the
most recent edit during your development, or back out all the way to
HEAD, then update-index is fine, but if (like me) you want to checkpoint
your work frequently so you can step back in a very fine-grained
fashion, then it's less than ideal to have only one checkpoint that
keeps getting overwritten.
For frequent checkpointing, as far as I can tell I pretty much need to
commit (to a development branch, of course) every time. I do that
because I never know beforehand whether I'll need to go back by more
than one step later on; 99% of the time I don't have to, of course, but
the remaining 1% is pretty painful if I can't.
Am I missing some magic index command that would support multi-level
backing out? Obviously StGIT is an option as well, but that seems like
overkill when all I want is to checkpoint my work. The above is why,
even though (I think) I know enough about the index to use it as you
describe, I often don't bother and just run "commit -a" during
development instead. When I merge, I usually fold all my checkpoint
commits together and merge the change as a logical unit.
But I'm still a relative n00b and would appreciate knowing if I'm just
missing some big obvious technique.
Would it make sense for "git add" to do the same as "git update-index"
on already tracked files? Given the explanation above this would make
100% sense to me.
Yeah, I think it would probably make sense. I also think it would make
sense to rename "update-index" entirely, or at least offer other names for
it (ie the "git resolved" suggestion).
In short - I agree that it's all just facets of the same thing: telling
git that some part of the working tree is now in a state ready to be
committed. Whether it's because we want to "add" content, or just mark it
as no longer having conflicts, or any other reason.
But right now, doing "git add" on an already tracked file simply does
nothing. This is even worse than erroring out.
Yeah, that's arguably a stupid thing to do ("you already added it, what do
you want me to do?") but the choice we use is probably the worst of the
three straightforward possibilities (ignore, update or error).
The _original_ "git add" was literally just this one-liner:
#!/bin/sh
git-update-index --add -- "$@"
which actually was better in this respect (it updated the content), but
that didn't do sub-directories, so this is arguable a bug introduced by
commit 37539fbd:
[PATCH] Improved "git add"
This fixes everybodys favourite complaint about "git add", namely that it
doesn't take directories.
which started using
git-ls-files --others -z -- "$@"
together with the exclude files to generate the list of files to add. At
that point, we lost files that already existed (since "--others" specifies
just files we don't know about).
From: Nicolas Pitre <hidden> Date: 2016-08-11 20:32:24
On Thu, 30 Nov 2006, Linus Torvalds wrote:
The default is: commit everything that you ask for to be committed.
If you haven't marked anything to be committed (which you can do with "git
add" too, or with simply being in the middle of a merge, or by having done
something like "git pull -n" or similar that does everything _but_
commit), then git commit will say "nothing to do".
Might it be a good idea to have "git-add" do the same as
"git-update-index" on already tracked files? That could be easily
taught as "you must explicitly _add_ files to your next commit" and
whether the file is already tracked or not wouldn't matter. This would
help newbies actually getting used the index without mentioning the
dreaded word "index" at all.
Right now git-add on an already tracked file does nothing, not even a
message to say it did nothing.
From: Johannes Schindelin <hidden> Date: 2016-08-11 20:33:26
Hi,
On Wed, 29 Nov 2006, Junio C Hamano wrote:
Junio C Hamano [off-list ref] writes:
quoted
... Rather,
"building your next commit incrementally in the index is the
workflow git is designed to support, but you are not required to
do that _incrementally_. Until you encounter a complex
situation such as resolving a large conflicting merge, doing
that incrementally does not buy you anything as long as you work
in a clean working tree.
Side note. I think the above "Until..." is an overstatement,
and maybe the readers of the tutorial can be taught a lot
earlier how the index can help them. Maybe the following
sequence can be added to an early part of the tutorial sequence?
$ edit hello.c
$ make test
$ git diff
$ git update-index hello.c; # ok, that is good so far.
$ edit hello.c; # hack more
$ make test; # oops, does not work
$ git diff; # ah, that overeager edit broken what was good
$ git checkout hello.c; # get the last good one back
I like it. Sort of a "temporary commit" to check against.
Ciao,
Dscho
From: Josef Weidendorfer <hidden> Date: 2016-08-11 20:37:57
On Thursday 30 November 2006 22:37, Carl Worth wrote:
So I'd vote for "resolve" along with something else for the
mark-as-edited case. Maybe "refresh"? That's the best I've thought of
so far. Anyone else have a better suggestion?
From: Andreas Ericsson <hidden> Date: 2016-08-11 20:39:31
Carl Worth wrote:
See? Git _is_ harder to learn, and a user really cannot learn it
without being careful about the index right from the very beginning.
I'm not so sure about that. I came from CVS / SVN, although I've fiddled
quite a bit with other scm's as well. The two-step commit process of git
didn't terrify me at all, and I had used git at least a month before I
joined the mailing-list and found out that there's this thing called an
"index". I knew about it before, since back then (June or July 2005)
there was only git-update-index to mark things to commit. I just didn't
worry about it but expected the scm to tell me if I was about to break
something horribly (which it often but not always did).
I think the main thing people are having difficulties with when it comes
to git is that it doesn't do things like other SCM's do it. Imo this is
a good thing, because it allows git to be more powerful than other
SCM's. Otoh it forces users migrating from
darcs/hg/monotone/perforce/whatever to git actually read the
documentation (and quite a lot of it), while hg -> bzr migrators use
pretty much the same commands for pretty much the same actions. This
makes users accustomed to not reading docs / trying things out before
attempting Real Work(tm), which breaks down horribly when user
expectations doesn't match reality. The simplest and usually most
effective solution is to meet the users half-way, and tell them early on
that this power comes at the cost of having to read the documentation
and do the tutorials.
--
Andreas Ericsson andreas.ericsson@op5.se
OP5 AB www.op5.se
If the "create file; git add; edit file; git commit" confusion isn't
blisteringly obvious to the git maintainers then I think I have to
give up here.
And this isn't just CVS-induced brain damage.
I'm sorry, but you are wrong.
It really _is_ CVS-induced brain damage, and I'm trying to teach you. You
can give up, but that's really "refuse to see the damage that systems like
RCS and CVS has done to the world"
The fundamental brain damage that CVS (and RCS, and SVN, and just about
anything else) has had is thinking that "filenames" (and sometimes this is
"fixed" to be "file ID's") are somehow special, and a totally separate
thing from "file contents".
Really. It's a BUG. It's a deficiency in CVS and friends. And it's a
deficiency that you have gotten so used to that you don't even see that
it's simply obviously NOT TRUE.
You _cannot_ have a filename without the contents of that filename. That
whole concept doesn't make sense, except in the twisted AND WRONG mental
model of "files have identities even without content".
The whole point of git is that it is about "project state" and the history
that binds those states together. People have kind of come to accept that,
and a lot of people realize what it means, but I don't think you've really
accepted what it means for something as simple as a "git add" command.
Again, totally ignore the index. Imagine that it doesn't exist. Imagine
that you never actually learnt about it, and that none of the
documentation ever mentions it, and just ask yourself:
"What does 'adding a file' really mean?"
I mean _really_. It cannot be about the "filename", because a filename
simply doesn't have any meaning alone. Remember what git is all about.
No, when you do a "git add", YOU DO NOT TALK ABOUT FILENAMES AT ALL.
NOT EVEN CLOSE!
No. Git is, and has always been, all about tracking project content. The
fact that CVS is crap, and thinks that "filenames" are special (and this
causes major problems when you do renames), and the fact that SVN is crap,
and things that "file identities" are special (and this causes major
problems when you split a file or when two files join) is very much about
THEIR F*CKING IDIOTIC FUNDAMENTAL BRAINDAMAGE!
So take five minutes to really think about that. Take an hour. Take a
week. Ponder it.
What does it mean to "add" something to a project? It has _nothing_ to do
with "filenames". Yeah, the filename obviously exists, but it's not
something that exists on its own. You add the ONLY thing that git tracks.
You add CONTENT.
When you do "git add file.c" you aren't adding a filename to the list of
files that git knows about. Not even CLOSE. No. You are really adding
_content_ to the project you are tracking. You haven't bound it to a
commit yet, but it's there. It's there both conceptually, and very much in
a real technical sense too (you've literally added the git object that
that file describes to the object database - the "commit" and "tree"
objects to tie it all together is just waiting to be added, but they
really just expose it - the actual file object has already been created
when you do "git add".)
So yes, you very much ARE talking about CVS braindamage. The reason why
git add file.c
echo New line >> file.c
git commit
commits the _old_ content, is very much because git is ALL ABOUT THE
CONTENT. It has _never_ been about filenames. And it _shouldn't_ be about
filenames, because that would be BUGGY AND BROKEN.
Sorry for shouting, but as long as you think "git add" adds a filename,
you're just not getting it. And I think it's really sad that you don't
even seem to understand that yes, this _is_ braindamage that has been
forced upon you by decades of mental rape done by bad source control
systems.
Please. File identities are _bad_ in the SVN kind of setting. The CVS kind
of "filename == file identity" is even _worse_, but it's still exactly the
same disease. It's the disease of thinking that metadata is somehow
"different" from real data, and that "files" have identities that are
somehow separate from the data they contain.
Face it, git is consistent, and if it acted the way you seem to expect it
to act, it would actually be a BUG. Exactly because you cannot and MUST
NOT think that "filename" is something that has meaning without "file
content" (or "file type" and "file permissions" - they all go together).
And notice? NONE OF THIS HAS ANYTHING AT ALL TO DO WITH 'INDEX'!! The
explanation above is not "this is how the index works". It's a much more
fundamnetal issue of getting the right mental model, where the only thing
that matters is contents.
So even without an index, "git add" should work the way it works, once you
can just let go of the broken model that is CVS.
Please. Join me, Luke. The power of the git side is stronger. I am your
father.
From: Nicolas Pitre <hidden> Date: 2016-08-11 20:45:15
On Thu, 30 Nov 2006, Johannes Schindelin wrote:
Hi,
On Thu, 30 Nov 2006, Carl Worth wrote:
quoted
It might even make sense to invent one more name for the case where
the user wants to inform git that a file has been edited and that git
should accept the new contents. It's the sort of "note that file is
edited" operation that could be recommended to the user with "add; fix
typo; commit" confusion.
I suggest "commit". How about this: after editing the file, you tell git
that you finished editing it by doing
git commit the-edited-file.txt
Hmmm?
From: Andreas Ericsson <hidden> Date: 2016-08-11 20:45:19
Linus Torvalds wrote:
That said, I have to admit that I usually (a) don't do this very often (ie
this is not part of my daily routine) and (b) I tend to do "git reset"
fairly soon afterwards (or alternatively, just "git commit -a") to get
back to the situation where the index will match the current HEAD 100%
again. So the "index doesn't match HEAD" situation is always just a
_temporary_ thing for me.
A staging area is per definition meant to keep temporary things before
they are committed to their designated place so there's nothing odd
about that.
--
Andreas Ericsson andreas.ericsson@op5.se
OP5 AB www.op5.se
From: Jakub Narebski <hidden> Date: 2016-08-11 20:45:56
Carl Worth wrote:
In most other systems I've used, 'add' means "I want the system to
'know' about this file" while 'commit' means "Please commit the
current state of all files you 'know' about (or the ones I mention
here on the command line)".
while in git "git add" means "I want to add this file" (in the state
it is now) and not "I want the system to 'know' about this file".
And "commit" mean "Please commit the current 'known' state of all
files (or/and the current state of files I mention here on the
comand line)".
Yes, this is different than what other SCM do...
--
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git