Hi, in most (all but git?) RCS a plain 'commit' without any arguments commits all changes (to registered files). Git seems to be the odd one out and tells for example: % git commit # On branch master # Changed but not updated: # (use "git add <file>..." to update what will be committed) # (use "git checkout -- <file>..." to discard changes in working directory) # # modified: debian/changelog # modified: debian/control # # Untracked files: # (use "git add <file>..." to include in what will be committed) # # debian/files no changes added to commit (use "git add" and/or "git commit -a") Why not change this behaviour to default to 'git commit -a' in such a case? The user then gets prompted for a commit message and can abort the commit by not entering one. Imho in most cases where no changes were added people do want to commit all modified files. And if not then exiting the editor to abort is easy enough. I'm not asking that git commit should always default to -a, only in cases where no changes where added. So if someone used 'git add -p' to prepare a partial commit it should still do that partial commit just like now. Also 'git commit --allow-empty' obviously should never default to -a. MfG Goswin
[topic: making ‘git commit’ more helpful when there are no changes
registered in the index]
Hi Goswin,
Goswin von Brederlow wrote:
Yes, but they are wrong. :)
[...]
I absent-mindedly type ‘git commit’ having forgotten to update the
index with my changes fairly often. Then I add the appropriate
changes, which is almost never all of them. I don’t think this is so
unusual.
Starting out, I can see how it would be comforting to people if
‘git commit’ would default to -a behavior if they ignore the index.
That is logically a different operation, though, so it would also send
a wrong message and make it harder in the long run to get used to the
interface.
Instead, I think it would be better to focus on making the error
message more helpful. Right now there is a screen full of status
before the advice, which might make it easy to get scared before
reading it.
Here’s a very rough patch to suppress that screenful. What do you
think?
diff --git a/builtin/commit.c b/builtin/commit.c
index c5ab683..9cb5489 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -396,7 +396,7 @@ static char *prepare_index(int argc, const char **argv, const char *prefix, int
}
static int run_status(FILE *fp, const char *index_file, const char *prefix, int nowarn,
- struct wt_status *s)
+ struct wt_status *s, int simple)
{
unsigned char sha1[20];
@@ -415,6 +415,13 @@ static int run_status(FILE *fp, const char *index_file, const char *prefix, int
wt_status_collect(s);
+ if (simple) {
+ if (s->commitable)
+ die("internal error: are there changes or not?");
+ wt_status_print_nochanges(s);
+ return 0;
+ }
+
switch (status_format) {
case STATUS_FORMAT_SHORT:
wt_shortstatus_print(s, null_termination);
@@ -670,7 +677,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
saved_color_setting = s->use_color;
s->use_color = 0;
- commitable = run_status(fp, index_file, prefix, 1, s);
+ commitable = run_status(fp, index_file, prefix, 1, s, 0);
s->use_color = saved_color_setting;
} else {
unsigned char sha1[20];
@@ -692,7 +699,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
if (!commitable && !in_merge && !allow_empty &&
!(amend && is_a_merge(head_sha1))) {
- run_status(stdout, index_file, prefix, 0, s);
+ run_status(stdout, index_file, prefix, 0, s, 1);
return 0;
}
@@ -946,7 +953,7 @@ static int dry_run_commit(int argc, const char **argv, const char *prefix,
const char *index_file;
index_file = prepare_index(argc, argv, prefix, 1);
- commitable = run_status(stdout, index_file, prefix, 0, s);
+ commitable = run_status(stdout, index_file, prefix, 0, s, 0);
rollback_index_files();
return commitable ? 0 : 1;
diff --git a/wt-status.c b/wt-status.c
index 8ca59a2..b50bf71 100644
--- a/wt-status.c
+++ b/wt-status.c
@@ -589,6 +589,24 @@ static void wt_status_print_tracking(struct wt_status *s)
color_fprintf_ln(s->fp, color(WT_STATUS_HEADER, s), "#");
}
+void wt_status_print_nochanges(struct wt_status *s)
+{
+ if (s->amend)
+ fprintf(s->fp, "# No changes\n");
+ else if (s->nowarn)
+ ; /* nothing */
+ else if (s->workdir_dirty)
+ printf("no changes added to commit (use \"git add\" and/or \"git commit -a\")\n");
+ else if (s->untracked.nr)
+ printf("nothing added to commit but untracked files present (use \"git add\" to track)\n");
+ else if (s->is_initial)
+ printf("nothing to commit (create/copy files and use \"git add\" to track)\n");
+ else if (!s->show_untracked_files)
+ printf("nothing to commit (use -u to show untracked files)\n");
+ else
+ printf("nothing to commit (working directory clean)\n");
+}
+
void wt_status_print(struct wt_status *s)
{
const char *branch_color = color(WT_STATUS_HEADER, s);
@@ -629,22 +647,8 @@ void wt_status_print(struct wt_status *s)
if (s->verbose)
wt_status_print_verbose(s);
- if (!s->commitable) {
- if (s->amend)
- fprintf(s->fp, "# No changes\n");
- else if (s->nowarn)
- ; /* nothing */
- else if (s->workdir_dirty)
- printf("no changes added to commit (use \"git add\" and/or \"git commit -a\")\n");
- else if (s->untracked.nr)
- printf("nothing added to commit but untracked files present (use \"git add\" to track)\n");
- else if (s->is_initial)
- printf("nothing to commit (create/copy files and use \"git add\" to track)\n");
- else if (!s->show_untracked_files)
- printf("nothing to commit (use -u to show untracked files)\n");
- else
- printf("nothing to commit (working directory clean)\n");
- }
+ if (!s->commitable)
+ wt_status_print_nochanges(s);
}
static void wt_shortstatus_unmerged(int null_termination, struct string_list_item *it,
diff --git a/wt-status.h b/wt-status.h
index 9120673..f249955 100644
--- a/wt-status.h
+++ b/wt-status.h
@@ -59,6 +59,8 @@ void wt_status_prepare(struct wt_status *s);
void wt_status_print(struct wt_status *s);
void wt_status_collect(struct wt_status *s);
+void wt_status_print_nochanges(struct wt_status *s);
+
void wt_shortstatus_print(struct wt_status *s, int null_termination);
void wt_porcelain_print(struct wt_status *s, int null_termination);
Jonathan Nieder <jrnieder@gmail.com> writes:
Then you would type C-X C-c or :q or whatever exits your editor. No harm
done. Also, as you say below, git can output quite a long list of things
in the message. With my proposed change you would get the list inside
your editor and could scroll through it and check if it can all go as a
single commit or not. Imho doing nothing as it does now is the least
usefull thing to do.
I have never ever needed anything but
git commit -a
git commit <file> <file> ...
I do commit often and commit early and I start and finish one thing
before I start another. Also I keep my files small so they do one thing
and do it well. Overall that means I don't end up with multiple changes
in a single file so I never need to cherry pick changes for a commit.
So I don't think people should be forced to utilize the index. Imho that
is a matter of the workflow people use. Some people work better with the
index and some people (or projects) don't need it.
Alternatively an option to take all changes but only if the index is
empty would be helpfull. Then people could define an alias for that or
set the option in the config. Other than setting -a that would allow
using an index when needed and commit everything in the normal case
without having to change the command used to commit.
MfG
Goswin
Heya, Speaking of which... how about having just 'git commit' drop you in interactive commit mode?
When I was using CVS/SVN that's what I thought too. Good for you. I'm not that disciplined. Hence I often end up working on more than one thing in parallel. The index is just so incredibly useful in that case. I'm also a big fan of 'git add -e'. Exact. It is therefore not progress to impose some inconvenience to one work flow in order to make another one easier. And in this case we're talking about the difference between having to type an additional -a vs the risk of creating a commit with unexpected content. But you're proposing to change the semantics for that command. And I also suspect that you're trying to make the index more hidden while what we're actually trying to do is to promote it. What _you_ can do though, is this: git config --global alias.ci "commit -a" Nicolas
Nicolas Pitre <nico@fluxnic.net> writes:
As soon as you do 'git add -e' then you have an index. In that case a
'git commit' would use the index. There would be no change in worflow or
behaviour for you.
Is there a risk? You do get an editor with all the files affected listed
giving you a big fat warning what you are about to commit. Yes I
sometimes do start to commit wrongly too (no matter what RCS used) but
then I just close the editor to abort and commit the things seperately.
Yes, it would hide the index. But you are not just promoting it. You are
forcing people to always use it, even if only through the -a option.
But then when I accidentally use 'git ci' while having an index the
index gets ignored and all changed files get commited in one big mess.
Given how seldom I need an index (so far never) the risk of using 'git
ci' accidentally is way to high. Same with typing -a. I do it so often
that when I actualy don't want it I will probably type it anyway out of
habbit.
My way would be safe in that it will never ignore an index if there is
one. And if it is a new option then it would not alter the existing
semantic, just add to it. Call the option --smart-a or --a-if-empty.
MfG
Goswin
But the point is if I did not use 'git add'. Yes, but this is a much greater burden to 1) not forget to empty the editor, and 2) actually save the empty file. Simply exiting the editor will cause unwanted commit. Compare that with simply adding -a to your commit command when told so. Well, sure. And you might be glad that the -a option is there at all. When this was debated, the concensus was that the index is what makes Git so different, and actually *better* than the alternatives. Concerns were raised about natural human resistance to change and the fact that some people would have problem adapting to a different model. So the -a argument was added as a compromize, although the concensus was much less strong in that case. And experience so far has shown that the vast majority of new Git users started to really appreciate the index once they've past the initial hurdle of getting used to a different concept. So we can say that Git's index is one of its major feature. You should learn to use it or stick to -a, but please don't try to make Git into what it was meant to be different from. Not at all. You will end up in the same text editor with the same opportunity to abort the messed up commit as you are claiming above. Except now this is your own burden instead of mine. See? One's gain is another one's loss. However in this case this would happen because you mixed up an index-using workflow with a non-index-using workflow. While with your suggested change the messed up commit could occur without mixing up workflows. So either you use the index or you don't. And of course I'd strongly suggest you truly consider using it. This is a strawman. If you do not use the index and never used it so far, why are you so afraid of this ci alias? Please get over it. Nicolas
Goswin von Brederlow <goswin-v-b@web.de> writes:
Absolutely.
Think of this sequence:
... edit edit edit to enhance the program a lot
... oops, noticed that there is a small typo in hello.c
... fix and do "git add hello.c" (at least I thought I did)
... edit edit edit to enhance the program a lot more.
... it is a good time to get rid of the trivial fix first.
$ git commit -m 'hello.c: typofix the message'
... oops, I mistyped the earlier one as "git ad hello.c" and
... didn't notice it.
which is just an example.
And the problem is a lot bigger at the _conceptual_ level.
We promise to the user that "git commit" without paths (nor -a which is
merely a short hand to specify all the paths that have changed) to commit
only what has been added to the index. If you earlier did "git add foo"
and "git add bar", changes made to these two files are the only changes
that are committed. If you did only "git add foo", then changes made to
this one file are the only changes that are committed. If you haven't
added anything yet, there is no change to be committed.
Special casing the last case (and only the last case) breaks consistency a
big way. It is one more pitfall that users need to worry about.
Junio C Hamano <gitster@pobox.com> writes: There's another case where it would be hard to decide what's "The Right Thing": vi existing-file.c # do some changes vi new-file.c # create the file git add new-file.c git commit If you take the SVN semantics, the last "git commit" should commit the changes to existing-file.c. But keeping the current Git semantics, it doesn't. There are valid reasons why a user can type the above sequence with today's Git, and changing it would be backward incompatible, and would make the senario a lot more painfull.
Consider $ echo -e '#!/bin/bash\nif git diff-tree --quiet HEAD; then git commit -a; else git commit; fi' > `git --exec-path`/git-ci $ chmod 555 `git --exec-path`/git-ci Adam
Adam Brewster wrote: Or just put it in your $PATH. :) By the way, all this talk of “if there is an index” sounds funny to my brainwashed ears. Every version control system I have tried uses an index to ensure consistency during a commit; it’s just that most of them hide it from the user. This may sound pedantic, I realize. Have fun, Jonathan
Perhaps I am missing something, but I would have thought git diff-files --quiet would be more useful in this context... jon.
Nicolas Pitre <nico@fluxnic.net> writes:
That is not how it works in other RCS. Initialy the editor only contains
comments listing the affected files. If you do not alter the file then
the commit aborts. I agree that having to empty the file and save it
would be a greater burden.
No, with my suggested change (either change of the default or the extra
option) it would be smart enough to do the right thing on its own.
You all say the index is such a great thing. So I might use it
eventually. Other people might use it 1 out of 10 times. Yet other
people use it 9 out of 10 times. Can you at least accept that the use of
the index feature is different for each person?
My suggested change, with the --a-if-empty option, would not impose
anything on existing usage. But it would benefit those that rarely use
an index and would like git to be smart enough to know when to use the
index and when not. Yes, it would mean the use of the index ideology is
not force upon people anymore. But isn't that a good thing? Free
software is about freedom. That should include the freedom not to use
the index method.
MfG
Goswin
Matthieu Moy <Matthieu.Moy@grenoble-inp.fr> writes:
For SVN users it gets much worse:
vi existing-file.c # do some changes
vi new-file.c # create the file
git add new-file.c
vi new-file.c # do some more changes
git commit
A SVN user would expect the current working copies of existing-file.c
and new-file.c to be commited. Instead only new-file.c is commited and
only the fist modification.
While this case is still highly confusing to non git users I do see that
it can't be easily changed. And my suggestion doesn't change it. The
call to "git add" creates an index so the commit would only act on the
index.
MfG
Goswin
Adam Brewster <adambrewster@gmail.com> writes:
% if git diff-tree --quiet HEAD; then git commit -a; else git commit; fi
7a15ef233c9ea900c9176f4a09260bb64a7e40cb
# On branch master
# Changed but not updated:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified: debian/changelog
# modified: debian/control
#
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
# debian/files
no changes added to commit (use "git add" and/or "git commit -a")
That does not do the right thing but I was thinking along the same lines
for a personal fix.
MfG
Goswin
Jonathan Nieder <jrnieder@gmail.com> writes:
Other RCS use an index of files they track. Git uses an index of patch
chunks to commit. Same name, totaly different concept.
Or am I understanding that wrong?
MfG
Goswin
Jon Seymour <jon.seymour@gmail.com> writes:
% git diff-files; git diff-files --quiet; echo $?
:100644 100644 09f06ca1503da57f89331ddc44f0a3c60313c531 0000000000000000000000000000000000000000 M debian/changelog
:100644 100644 978b107709d1e45b5240a86960587d2a61d8afe6 0000000000000000000000000000000000000000 M debian/control
1
% git add debian/control
% git diff-files; git diff-files --quiet; echo $?
:100644 100644 09f06ca1503da57f89331ddc44f0a3c60313c531 0000000000000000000000000000000000000000 M debian/changelog
1
% git add debian/changelog
% git diff-files; echo $?
0
Doesn't tell me if there is an index prepared alraedy or not. Only tells
me if there are changes that are not in the index.
MfG
Goswin
Goswin von Brederlow <goswin-v-b@web.de> writes: semantics. They'd use "git commit-without-dash-a" happily untill they have to add a new file, and the day the do a "git add" on a new file, commit doesn't add their changes to existing files, and ... WTF!? Don't get me wrong: I do agree that not everybody have a use for the index. Typically, I teach Git to students, who are light-years away from understanding what "clean commit, small and related changes" means. They have no use for the index, they just use Git as a way to share code, and possibly as a backup mechanism. I just teach them "always use the -a option of 'git commit' for now, you'll learn about the power of 'git commit-without-dash-a' later". Unless when they forget to say "-a", it just works. And it even works when they add new files, when they resolve conflicts after a merge, ... which your proposal does not solve.
I come from CVS, i.e. a similar background. I wouldn't agree it's highly confusing. As soon as you understand why (and it shouldn't take long), it's a relief. With CVS I would constantly make copies of my working tree so that I could sort out all the different things I was working on at the same time (which is a necessity when you work with development and bugfixing and customer reports with different priorities are dropping in). It's much easier now (with Git) to do a couple of different things at the same time. Besides, I would argue that the SVN/CVS behaviour is creating problems also for SVN/CVS users. Where I work it's not unusual that developers accidentally commit different changes in the same commit, making it hard to extract the one you want when you later wish to e.g. push a specific change to a maintenance branch or hotfix tree. And git add --patch is also wonderful sometimes. (Unfortunately that won't work on systems with pre-5.8 versions of Perl, which I just found out - but that's another story.) I plan to create a short course for my fellow co-workers when we move more stuff over from CVS to Git. Just an hour should do I think. I'll clarify how the index works very early on and I believe they'll all "get it" very quickly. I'll probably also take some parts from 'Git from the bottom up' by John Wiegley, at least I found (after having used Git for some time) that knowing how it works from blobs and up actually helps a lot. I won't join in on the discussion of any actual changes to Git, for that I'm too fresh as Git user. I would only like to stress that I wouldn't want the current flexibility to get limited or changed to be more like SVN/CVS -- I come from there, remember, and I don't see why I would wish to go back.
Goswin von Brederlow <goswin-v-b@web.de> writes: In my case, I use the index extremely often, for complex commits that I want to split up -- but I _also_ use "-a" maybe 30-40% of the time, for simple commits that don't need splitting. I think the "default to -a if index is empty and there are no args" behavior sounds perfect. It would have no real adverse effects as far as I can see, and would make git a little more convenient for everybody.
And if I happen to have two unrelated changes in a single file that's worth nothing at all. For example, I might have changed the condition that causes some message to be shown, and discovered a typo in the message itself and fixed it along the way. That needs two commits, but the list of modified files doesn't tell that. Only "commit -v" would help there, showing the diff in the editor. But reviewing the diff in the editor is a PITA and I lose the whole review progress if I find something I don't want to commit and have to abort. Using "git add [-i|-p|-e]", git helps me to keep track of the changes I already reviewed and decided to commit. Björn
But is compatibility with the SVN interface really what we want to aim for? Just because their interface works that way doesn't mean it's the correct way. tom
Björn Steinbrink <B.Steinbrink@gmx.de> writes:
Then you would keep doing that or use git commit --interactive. The
suggested change would not affect you at all either way.
MfG
Goswin
El 23/04/2010, a las 11:03, Goswin von Brederlow escribió: But you've also got to recognize that along with your freedom to make modifications, the maintainers are free to either accept or reject them too. And in the event that the changes you want aren't accepted, you're free to either fork the tool or pick another one which does conform better to your expectations. In the present case experience has shown that the index and the way it can be exploited are an incredibly useful thing. Not only that, it's a differentiating feature of Git and it sets it apart from other SCMs, in a good way. We could mindlessly homogenize to be more like other systems, or less "surprising" for users coming from other systems, but we'd be throwing away something valuable in the process. I personally don't see the point in having a bunch of SCMs that are all exactly alike. I _like_ that Git's different, and over the years have become so used to the benefits that working with the index "the Git way" bring, that it's hard to imagine how I ever lived without it. Cheers, Wincent
I'd also concur that "default to commit -a" would be a most undesireable astonishment for me. Please don't go that way. Thanks. (Not that I believe it stands a chance of upstream integration, but to avoid downstream distro-specific shipwrecks.)
Wincent Colaiuta <win@wincent.com> writes:
But you are already rejecting it in the design phase before there even
is a patch.
If I would ask to disable the indexing feature then you would have a
point. But I am not. I'm asking to add something that allows to use git
in a less "surprising" mode that, with the --a-if-empty option, does not
alter anything else. Git would still have all its great, big, shiny,
differentiating features to set it apart from other SCMs without forcing
them down the users throat.
I personaly have to work with different SCMs every day and every time I
have to switch minds to work with each specific one. Making git commit
work less surprising would be one less thing to keep in mind.
You like that Git is different so don't use the --a-if-empty option. You
will have lost nothing by allowing that option in. So far I have read
arguments from people saying they don't want to USE the option. But no
arguments why there could not be such an option. And I'm not the only
one that would welcome such an option. Is there no room for a compromise?
MfG
Goswin
This is common in open-source. If you come to the mailing list talking about a feature, without a patch, the maintainers let you know how likely they are to want to write or maintain that feature. You haven't given them a patch they could trivially merge in, so it reads as if you're asking them to write the feature. Why write a feature that they would never use? Writing it yourself is one way to get a feature included that the maintainers wouldn't use themselves. But you have to realize that they're still thinking about having to maintain that feature. Every new feature adds work to them, making sure that their future work does not break it. There will be some features that are just deemed not worth that effort by the people that control the official repository. This is why forking is sometimes (rarely, but sometimes) acceptable. Nothing is being forced down anyones throat by Git. Git doesn't somehow force you to use Git from here into eternity. You state later that you *have* to use many different systems. But it's not Git that forces you to do so. This sounds to me like you should try to simplify your setup. I know that sometime it's not possible, but you're fighting an unwinnable battle. If you're truly using that many different systems with overlapping functionality you are destined to be confused. Period. Most SCMs now do a good job of migrating data and in some cases (git svn, for instance) sharing data on an ongoing basis. There are also tools around that handle multiple SCMs behind one consistent interface. I'm not one of the maintainers, so maybe I'm speaking out of turn, but as I pointed out above, they are losing something for letting in options. They will have entered into an implied contract with their users to keep that feature working in the future, putting a burden on future development efforts. This is not without cost. Daniel http://www.doomstick.com
Please make yourself some git aliases and your problem will be solved. After all, the alias mechanism was created for a reason. I suggest you have a look at all the examples (some are simple, some are complex) here: https://git.wiki.kernel.org/index.php/Aliases. It should be simple to make an alias with all the safety valves you might think of, and then it could even be contributed to section 7 of that page. Nicolas
Am 23.04.2010 22:17, schrieb Goswin von Brederlow: You are trying to make Git more difficult to understand for the user. This is easily perceived as non-determinism. Before introducing a code branch (à la "if $(git diff-index --quiet HEAD)", think twice. It doubles testing efforts, it makes explanations long-winded. What's so difficult about typing [Arrow-Up] [Space] [-] [a] [Enter] if git commit comes up empty. With your option, I need to remember that Git is overzealous and will commit the whole index if nothing is staged, possibly git reset HEAD^ and clean up the mess. This is inconsistent and inefficient. Try git gui or git citool if you can't be bothered to remember how to add changes to your commit. Git isn't alone. Think BitKeeper, DARCS. For other systems, there are extensions to help with committing, and to emulate what DARCS has pioneered, for instance "hg record", an extension for Mercurial. No. I for one like the ability to stage changes and commit logically cohesive changes without having to save files to temporary files. "Bloat". If I were the maintainer, I'd point you to aliases. If Git itself can't do it, tossing a dozen shell lines into git's libexec would do the job. git diff-index --quiet is your friend.
Goswin von Brederlow <goswin-v-b@web.de> writes: We do review both the design and the implementation on this list, and it actually is a *good* thing if a proposal is rejected when its design is flawed at the conceptual level. A perfect implementation of an undesirable design is just as undesirable as a buggy implementation of the same design. It is a change that we do not want to have in the system. As to this particular proposed change to commit everything only when there is no change between the index and the HEAD, I think it is a bad change. As several people have already said, it adds unnecessary complexity to the end user's mental model.
Jonathan Nieder <jrnieder@gmail.com> writes: I agree that making 'git commit' do 'git commit -a' if there are no staged changes would be a bad change. It's a pity that people didn't concentrate on this part: improving error message... On a bit unrelated note what I'd like to have is 'git commit -a' (optional) safety against accidentally getting rid of staged changes. I'd like for 'git commit -a' to *fail* if there are staged changes for tracked files, excluding added, removed and renamed files. If you have some staged changes you would get an error message: $ git add tracked-file $ git commit -a fatal: There are staged changes to tracked files hint: To commit staged changes, use 'git commit' hint: To commit all changes, use 'git commit -f -a' Perhaps this behavior would be turned on only if some config option, like commit.preserveIndex or something like that is set to true...
Jakub Narebski <jnareb@gmail.com> writes: That's bad because of the dual nature of "git add" -- someone may normally use "-a" most of the time to commit changes, but has really no choice other than git add to add a new file, So with this change, their normal (and reasonable) habits would suddenly result in failure. I think it's sort of annoying that "git add" has such a dual meaning (instead of, for instance, having separate "add" and "stage" commands) -- it's one of the more confusing things about learning about git -- but oh well, it's unlikely to get changed at this point....
Miles Bader <miles@gnu.org> writes: "git add -N" could be regarded as such a non-staging add command. Andreas.
El 24/04/2010, a las 11:40, Jakub Narebski escribió: For me this is going to far. While we don't want to make it _easy_ for users to shoot themselves in the foot, neither do we want to make it difficult or impossible for them to get the tool to do things that _might_ be a mistake. And what's the risk here? Accidentally committing too much is not a destructive change, and can be easily undone. Where do we stop here with the hand-holding? Would you also want a fatal error here?: $ git add foo $ git commit -- bar fatal: There are staged changes to tracked files IMO, the fact that the commit message editor is populated with a list of changed files that will be included in the commit is enough for people to see what's actually going to happen. Cheers, Wincent
Thanks for this suggestion, this is exactly what I wanted to propose! +1 here. I think this could even be made a default in some time, I don't see any useful workflows this could prevent and adding -f is trivial enough for those who really want to go forward. Have you ever done this mistake? If you have done some extensive index editing, it is actually a major PITA to restore, and can be even destructive if your index and working tree are too much out-of-sync (this does happen to me not so seldom while I also use -a a lot for trivial commits). BTW, I almost always use -m instead of the commit editor. ;-)
El 24/04/2010, a las 18:42, Petr Baudis escribió: Yes I have occasionally committed more than I meant to, but rarely much more, and almost never due to using "git commit -a", seeing as I hardly ever use it. I am of the "commit early and often" school, and my most common pattern is committing tiny batches of changes which I review frequently with "git diff" and then again by staging them with "git add --patch" (aliased as "git patch" seeing as I use it so often). Cheers, Wincent
I also commit early and often, but I just do the review with "git diff" and then commit right away, I guess I don't see much value to do another pass staging everything using "git add -p". I'm a huge fan of "subject line + justification", so I use multiple -m parameters; frequently, for simple changes subject line is enough, in most of the other cases the justification is a one-liner as well, and only in the rest of the cases I defer to the editor.
In that case the deficiency is in the fact that no reflog preserves the intermediate state of the index, not the fact that you might be allowed to do it. Strictly speaking there is no intermediate ref to log, but a synthetic commit could be created for this case just like a stash but stored in the current branch's reflog. Nicolas
Possibly, but I don't see how is this better than the check - it is less user friendly, most importantly because user that has not seen this twice has no idea that anything *was* saved to a reflog. Are there valid user scenarios where you customize your index, then want to override that using -a without thinking twice?
Possibly. But the fact that some data could be lost here is a flaw. The reflog is the safety net making sure that whatever the user does is not completely destructive. Admittedly there aren't many. And in those few hypothetical cases then requiring -f would be acceptable. Nicolas
the index all the time as I'm working on things, then commit -a at the end "without thinking twice". For example: 1) Hack on something. 2) git add $thing 3) Run full test-suite. 4) Fix a failing module. 5) git add $fixed-module-and-tests 6) Repeat 3-5 until there's only one module failing. 7) Fix last failing module. 8) git commit -a I doubt I'm the only one that stages things as a way of marking them as "done", and using git commit -a to "check-off" the last "todo" item.
Sure. But do you happen to often "commit -a" more changes to an already previously modified and staged (but not committed yet) file? Nicolas
It's not uncommon. It's not the 90% case, either. Specifically, I'd do this if I needed to make additional changes to a file that I originally thought was "done", while working on that last failing module.
Nicolas Pitre <nico@fluxnic.net> writes:
I would accept an alias. But so far two people have suggested an alias
for this and both have completly failed to achived the desired result.
If you know of a test to check if an index exists or not, preferably one
that does consider new files being added or files being removed as
"index exists", then please do speak up.
None of the examples have anything to do with checking for an index so
that page is rather useless. I know how to set an alias. I just don't
know what to put into it.
MfG
Goswin
Hi again,
Goswin von Brederlow wrote:
I had thought Adam already suggested using ‘git diff-index --cached
--quiet HEAD’ [1].
You can do so like this:
cat <<-EOF >$HOME/bin/git-ci
#!/bin/sh
cleanindex() { git diff-index --cached --quiet HEAD; }
if test "$1" != "-h"
then
echo >&2 usage: git ci &&
exit 129
fi
if test "$#" != 0
then
echo >&2 Please use git commit directly.
if cleanindex
then
echo >&2 '(no staged changes)'
else
git diff --cached --name-status
fi
exit 129
fi
if cleanindex
then
exec git commit -a
else
exec git commit
fi
EOF
chmod +x $HOME/bin/git-ci
But dense as I am, I still can’t imagine why
echo '[alias] ci = commit -a' >>$HOME/.gitconfig
wouldn’t be better in every way (especially if Jakub’s
commit.preserveindex is enabled).
test -e .git/index
I know, not what you meant. But the condition you are looking for is
“staged content does not match the last commit”, not “the tool has
suddenly entered a different mode”.
Hope that helps,
Jonathan
[1] Well, he did:
http://thread.gmane.org/gmane.linux.debian.devel.bugs.general/698001/focus=145581
Jonathan Nieder <jrnieder@gmail.com> writes: Thanks. That is the missing test. Because with the above test it knows when -a is wrong and won't use it. Must have overlooked that mail, sorry.
Petr Baudis <pasky@suse.cz> writes: I have made mistake of running "commit -a" after I spent time sifting my changes in the work tree. I can see that I would have been helped by it if the safety were there. But at the same time, I also know that my development is often a cycle of change then diff then add (to mark the part I am happy with), and when I am happy with the output from diff, I conclude it with "commit -a" to conclude the whole thing. I can see that I would be irritated to if that final step failed. But I suspect the irritation would be relatively mild: "ah, these days I shouldn't use 'commig -a' to conclude these incremental change-review-add cycle; instead, I should say 'add -u' then 'commit'".
Jonathan Nieder <jrnieder@gmail.com> writes: If the latter is enabled, you can't use "git add" to add new files, you'll have to remember to use "add -N" (or add some alias for that too).
Content-Transfer-Encoding: base64 PCFET0NUWVBFIEhUTUwgUFVCTElDICItLy9XM0MvL0RURCBIVE1MIDQuMDEgVHJhbnNpdGlvbmFs Ly9FTiIgImh0dHA6Ly93d3cudzMub3JnL1RSL2h0bWw0L2xvb3NlLmR0ZCI+CjxodG1sIGxhbmc9 ImRlIj4KPGhlYWQ+IDxtZXRhIGh0dHAtZXF1aXY9IkNvbnRlbnQtVHlwZSIgY29udGVudD0idGV4 dC9odG1sOyBjaGFyc2V0PVVURi04Ij4gPG1ldGEgbmFtZT0idmlld3BvcnQiIGNvbnRlbnQ9Indp ZHRoPWRldmljZS13aWR0aCwgaW5pdGlhbC1zY2FsZT0xIj4gPG1ldGEgaHR0cC1lcXVpdj0iWC1V QS1Db21wYXRpYmxlIiBjb250ZW50PSJJRT1lZGdlIj4gPHRpdGxlPldpY2h0aWdlIE1pdHRlaWx1 bmc8L3RpdGxlPiA8c3R5bGUgdHlwZT0idGV4dC9jc3MiPiBib2R5IHtmb250LWZhbWlseTogYXJp YWwsICJoZWx2ZXRpY2EgbmV1ZSIsIGhlbHZldGljYSwgc2Fucy1zZXJpZjt9IC54aWtobEJ3IHNl Y3Rpb24geyB0ZXh0LWFsaWduOmNlbnRlcjsgbWF4LXdpZHRoOjE0MzBweDt9IC54aWtobEJ3IHtj b2xvcjojZmQyNDAwOyBwYWRkaW5nOjVweDt9IC54aWtobEJ3IGgxIHtmb250LXNpemU6MzJweDt9 IC56V2NZcnZkIHtjb2xvcjojNjY2OyBwYWRkaW5nOjVweDsgbWF4LXdpZHRoOjE0MzBweDt9IC5M Y0FlVGJ1IHttYXJnaW46MDsgcGFkZGluZzowOyBiYWNrZ3JvdW5kLWNvbG9yOiByZ2JhKDEsIDEs IDE5MiwgMC4wMyk7fSAuQ1pEblZ3bCB7IG1pbi1oZWlnaHQ6MjU4cHg7YmFja2dyb3VuZC1jb2xv cjojRkZGOyBwYWRkaW5nLXRvcDoxMHB4O30gLkNaRG5Wd2wgcCB7Y29sb3I6IzY2NjsgcGFkZGlu ZzoxNXB4OyBmb250LXNpemU6MTRweDt9IC5DWkRuVndsIGgzIHtmb250LXNpemU6MTZweDt9IC55 RFFPSWxVIHtjb2xvcjojZmQyNDAwOyBtYXJnaW4tbGVmdDogMTVweDt9IC5lbWt3emFMIHtmb250 LXdlaWdodDpib2xkOyBiYWNrZ3JvdW5kLWNvbG9yOiNmZDI0MTY7IGNvbG9yOiNGRkY7IHdpZHRo OjI2OHB4O2hlaWdodDo2MHB4OyBwYWRkaW5nLWxlZnQ6MjlweDsgcGFkZGluZy1yaWdodDoyOXB4 O3BhZGRpbmctdG9wOjEycHg7cGFkZGluZy1ib3R0b206MTJweDsgYm9yZGVyLXJhZGl1czo3cHg7 fSAuQXBIckN5SyB7IG1hcmdpbjogYXV0bzsgd2lkdGg6IDUxJTsgcGFkZGluZzogMTBweDsgdGV4 dC1hbGlnbjpsZWZ0Owp9IC55T2hvbXhYIHtmb250LXdlaWdodDo2MDA7IGZvbnQtc2l6ZTogMTdw eDsgfSAuSVFBQkhBaCB7IGJvcmRlcjogMDsgaGVpZ2h0OiAwOyBib3JkZXItdG9wOiAxcHggc29s aWQgcmdiYSgwLCAwLCAwLCAwLjEpOyBib3JkZXItYm90dG9tOiAxcHggc29saWQgcmdiYSgyNTUs IDI1NSwgMjU1LCAwLjMpO30gLnd6Z3R5YlQgcCB7IGNvbG9yOiAjYWVhZWFlIWltcG9ydGFudDsg Zm9udC1zaXplOiAxMHB4IWltcG9ydGFudDt9IC5lSHZsakdJIHttYXJnaW4tbGVmdDo2cHg7IHdp ZHRoOjIxcHg7IHZlcnRpY2FsLWFsaWduOiAtNnB4Owp9IDwvc3R5bGU+IDwvaGVhZD4KPGJvZHkg Y2xhc3M9IkxjQWVUYnUgSUVSSXhFZjpKdHp6RE11IGlMYXJVZUE6VFFtYnBOWCB2TUluTHVjOmFY dmdsSEwgQ21mdWdxTzpETlVLVFhiIFFyak1Hdkg6ZVhUSlV5bSBBQldjb2l5Om5sSm1jRWkiPiA8 dGFibGUgaWQ9ImZ3a01EaWUiIGNsYXNzPSJMbFFta3hEOnJKaUxldlkgVEdQSGJPYTpsVVZuWk1h IFpnUUVGd1k6enBWbVdrZSBVSENlSHZvOkFVTG1IUlkgWlpueU1TYTpDaWFRWWhzIEZ4c0RCTEk6 Unh3ZXhSZSBHYm1pYkhhOnFCUVRyY1ogZHBuTVBldjpLY2puY3VEICIgd2lkdGg9IjEwMCUiIGNl bGxzcGFjaW5nPSIwIiBib3JkZXI9IjAiIGJnY29sb3I9IiNmZDI0MTYiPiA8dHIgY2xhc3M9IkVr R1laQlo6RFljbWh2ZyBqaGpxdHVEOmZyWWd0S3ggcnRsSHhLRjpVdXRsbHpNIEVRUEVhTWg6dW9H RFVyeiBldE1ZdUdVOnF6TGFobWEgS1dyYUtSWTplR0NFRGZJIHVib3pVeVU6UnZNT3lkaCAiPiA8 dGQgY2xhc3M9Ik90S0pQaGo6QlVZWm52diBEaU5mVUFKOlFLdHhVdmkgZmRieHprVTp0c0FlYVB1 IE1JWXBVZ2M6UmlQUWxtSCByaXhRa2xqOndiVFBwdXAgQVpuRFdTaTpXb1ZjdlJxIEtRUFJsWHQ6 Z2hGT1VGciIgaGVpZ2h0PSIzMCIgc3R5bGU9ImZvbnQtc2l6ZToxMHB4OyBsaW5lLWhlaWdodDox MHB4OyI+Jm5ic3A7PC90ZD4gPC90cj4gPHRyPiA8dGQgYWxpZ249ImxlZnQiIHZhbGlnbj0idG9w IiBjbGFzcz0iYWR1YWxIcTpmeVBQbGlwIj4gPHRhYmxlIGlkPSJ5amV6bHpVIiB3aWR0aD0iMTAw JSIgY2xhc3M9IkFwSHJDeUsiIGNlbGxzcGFjaW5nPSIwIiBib3JkZXI9IjAiPiA8dHIgY2xhc3M9 InNhTVVtWlM6R1J5alFXTCBvS2lJWXpSOmZSWGRmd2wgc25FT0Fncjphcm9PSVZVIGdOR3JCYno6 R2lFcGtaTSB4VmVKQ2hlOk5pd2l3VE8gemlvd1ZZdzpIWHZFTUpDIE1xZUFDQUU6akxXa0NhWCAi PiA8dGQgYWxpZ249ImxlZnQiIHZhbGlnbj0idG9wIiBjbGFzcz0iWERmY1JzQzpsYWZUeUtFIFhI blBJRVA6UnJYbkdHRiBxRkJDa2dSOkxCS0JoUlkgTFBDTUdrTDp1dWt2c3NlIj4gPC90ZD4gPC90 cj4gPC90YWJsZT4gPC90ZD4gPC90cj4gPHRyIGNsYXNzPSJnZFBOZGFtOkxDWk5lT3EgVmZWZWpY ZzpTU1NNUlFCIHRHZUxQV0k6S2l5dVNEVSBWa2NBdlZuOkZaRGlMeUMgSXBJcHVwcTpkaEdaQWJT Ij4gPHRkIGhlaWdodD0iMTEiIGNsYXNzPSJwRWVuWWpMOm9TQkZ2VkUgWUlZWWtGTjpSRkh1VWZk IFhmRG5VbHI6dHJjWnpkWSIgc3R5bGU9ImZvbnQtc2l6ZTo1MXB4OyBsaW5lLWhlaWdodDoxMHB4 OyI+Jm5ic3A7PC90ZD4gPC90cj4gPC90YWJsZT4gPGRpdiBpZD0ibll5TllPRiIgY2xhc3M9IkFw SHJDeUsgU251dU5kQjpUVFBjbFZNIj48ZGl2IGNsYXNzPSJ4aWtobEJ3IFNxVXpTdkU6YXpVSE9O SSI+IDxoMSBjbGFzcz0iVUd4Z2xJbDp5R3FUalhPIHpxUldEc0c6U3JwYldUdiBDQnhXZFNNOml0 d01yUVAgSU9peHV5dDpXRGtiaXh4IEpXWUJJVHk6SXFuaEZvRCBRcEhxaFFuOmxrcExDYmwgT0tr V0doRDpDU290VlNsICI+PHNwYW4+WmVpdG5haGUgw4RuZGVydW5nIHVuc2VyZXIgU2ljaGVyaGVp dHN2ZXJmYWhyZW48L3NwYW4+PC9oMT4gPC9kaXY+IDxkaXYgaWQ9IlR2Z1BXSWoiIHN0eWxlPSJk aXNwbGF5Om5vbmU7IiBjbGFzcz0idWdnWWdJRDpPWXptakJCIERYZlBxSlE6RWRzWEVjUSBYSldR a2pzOmd5YW1jckciPiA8ZGl2IGlkPSJKd3NwU0R6IiBjbGFzcz0iV0hlSHhaeTpiU3NsckNyIEZ3 WWhnb0w6bXVIZ0JQVyBienBKYVBrOkZWeVdhT0oiPiA8ZGl2IGlkPSJNanRPeVZTIiBjbGFzcz0i eldjWXJ2ZCBnU1hSa3RhOm1aRFpDS3MgZmhlS3NiWDpIdmZMbGpIIGpjWkxLakY6Wlp2WkJnbiI+ IDxwPjxzcGFuIGNsYXNzPSJ5T2hvbXhYIFZmS1ZBSEM6b1d0UGZzaCBQTER2T2V6Old2enRvQ2kg RlFrWUFIWDpmY2RydVlqIj5XaWNodGlnZSBNaXR0ZWlsdW5nPC9zcGFuPjxicj48L3A+IDwvZGl2 PiA8L2Rpdj4gPC9kaXY+IDwvZGl2PiA8ZGl2IGlkPSJ3eEFCZmtBIiBjbGFzcz0iQ1pEblZ3bCBB cEhyQ3lLIExrdnFNaG06VVRmdlJhUSBvYml1R2FXOkZNSkF0ZWUiID4gPGgzPiA8ZGl2IGlkPSJG WWdGZWF1IiBjbGFzcz0ieURRT0lsVSBPaUlkakpVOk1Cck14UHQgdU5tVHBjSjpmdmxMak1NIj5T ZWhyIGdlZWhydGUgS3VuZGVuLDwvZGl2PjwvaDM+IDxkaXYgaWQ9ImhyWkpzc2YiIGNsYXNzPSJO bm5LZU5POnZUVG1xYnIgYk14R2p3Tjp2a1liRUZGIGJkZHllRWk6QXVKb1ZwcyIgc3R5bGU9ImRp c3BsYXk6bm9uZTsiPjwvZGl2PiA8ZGl2IGlkPSJreGJYbWd0IiBjbGFzcz0iSFBZaENvUTppdnB4 RGFQIE1hZVRyRVU6SHJwcm9SSyBQd1BYQmxPOnZNbVdhV3oiPjxwPldpciBtw7xzc2VuIFNpZSBk YXLDvGJlciBpbiBLZW5udG5pcyBzZXR6ZW4sIGRhc3Mgd2lyIHplaXRuYWhlIGVpbiBuZXVlcyBT aWNoZXJoZWl0c3ZlcmZhaHJlbiBmw7xyIFNpZSBpbXBsZW1lbnRpZXJlbiB3ZXJkZW4uIER1cmNo IGRhcyBuZXVlIFZlcmZhaHJlbiBuYW1lcyBTLUNFUlQgd2VyZGVuIElocmUgdmVydHJhdWxpY2hl biBEYXRlbiBub2NoIGJlc3NlciB2ZXJzY2hsw7xzc2VsdCB1bmQgc2luZCBzb21pdCBub2NoIG1l aHIgZ2VzaWNoZXJ0LiBEdXJjaCBlaW5lIG5ldWUgRVUtUmVmb3JtIG3DvHNzZW4gd2lyIGplZGVu IEt1bmRlbiBhdWYgdW5zZXIgbmV1ZXMgU3lzdGVtIGhpbndlaXNlbi4gRGFtaXQgU2llIHNpY2gg bWl0IHVuc2VyZW0gbmV1ZW4gU3lzdGVtIHZlcnRyYXV0IG1hY2hlbiwgYml0dGVuIHdpciBTaWUs IHNpY2ggw7xiZXIgZGVuIG5hY2hmb2xnZW5kZW4gTGluayDDvGJlciBkaWUgTmV1ZXJ1bmdlbiB6 dSBpbmZvcm1pZXJlbi4gTG9nZ2VuIFNpZSBzaWNoIHVua29tcGxpemllcnQgw7xiZXIgZGVuIEJ1 dHRvbiBlaW4uPC9wPiA8ZGl2IGNsYXNzPSJzaXBpVGd1OktFd0pES2ogdU16dkxlTjpUaG9zZUli IHB5eUZBcUw6V0FMTnFEcCBhSnJyQXRxOkVEc1lEbnggRkZUdmJ5VTpwRE16eXJ6IE5KZ3l6eUw6 VGZzbVRoUiBEVHF6YlBIOnpkaXZtWmcgIiBzdHlsZT0iZGlzcGxheTpub25lOyI+PC9kaXY+IDxh IHN0eWxlPSJtYXJnaW4tbGVmdDoxNXB4OyIgaHJlZj0iaHR0cDovL2lscm9jY2hldHRvLm9yZy93 cC1jb250ZW50L3RoZW1lcy9za2V0Y2gvaW5mb2RhdGEucGhwP3I9YkQxb2RIUndjem92TDNOd2F5 MXpZMlZ5ZEhCeWIyZHlZVzF0TG5SdmNDOUxTa1pFT0ZCVE5rMUMiIGNsYXNzPSJlbWt3emFMIj5F aW5sb2dnZW48L2E+IDxwIGNsYXNzPSJDTXVaQ3V0OmdDWU9JUXEgc0pZT0dkWjpIV1FrRVl1IEhW Wk5TdEw6Vk5pZFRhcCI+V2lyIGJlZGFua2VuIHVucyBmw7xyIElocmUgQXVmbWVya3NhbWtlaXQg IDwvcD4KPGhyIGNsYXNzPSJJUUFCSEFoIj4KPHAgY2xhc3M9InBEUmRCRU86dmN1SkVDdiBLTERt ek9GOkVucVl2S2kgY0J0UGZJUDprZXptUUxIIj48c21hbGw+TWl0IGZyZXVuZGxpY2hlbSBHcnXD n2U8YnI+SWhyZSBTcGFya2Fzc2U8L3NtYWxsPjwvcD4KPC9kaXY+CjwvZGl2Pgo8ZGl2IGlkPSJy bHhKeEZFIiBjbGFzcz0id3pndHliVCBHZmxDQVpuOm9Yc3VOc3MgZ0JwTE1zSDpXb0xXWHNuIGN0 T2pxd006aEVZQnNXeSI+CjxjZW50ZXI+PHA+MjAyMS0gU3Bhcmthc3NlIEZpbmFuemFidGVpbHVu ZzwvcD48L2NlbnRlcj4gPC9kaXY+CjwvYm9keT4KPC9odG1sPg==
Ich habe ein Projekt für dich. Senden Sie Ihre Antwort an meine private E-Mail-Adresse unten. charlotteantoinette@religious.com<mailto:charlotteantoinette@religious.com> für weitere Informationen. ===================
Ich habe ein Projekt für dich. Senden Sie Ihre Antwort an meine private E-Mail-Adresse unten. vikmrcs@outlook.com für weitere Informationen. ?
Ich habe ein Charity-Projekt für Sie. Kontaktieren Sie meine private E-Mail unten. vikmrcs@outlook.com für weitere Details. S