2006-05-17 18:33:32 +02:00
|
|
|
/*
|
|
|
|
* "git add" builtin command
|
|
|
|
*
|
|
|
|
* Copyright (C) 2006 Linus Torvalds
|
|
|
|
*/
|
|
|
|
#include "cache.h"
|
|
|
|
#include "builtin.h"
|
|
|
|
#include "dir.h"
|
2013-01-06 17:58:08 +01:00
|
|
|
#include "pathspec.h"
|
git-add --interactive
A script to be driven when the user says "git add --interactive"
is introduced.
When it is run, first it runs its internal 'status' command to
show the current status, and then goes into its internactive
command loop.
The command loop shows the list of subcommands available, and
gives a prompt "What now> ". In general, when the prompt ends
with a single '>', you can pick only one of the choices given
and type return, like this:
*** Commands ***
1: status 2: update 3: revert 4: add untracked
5: patch 6: diff 7: quit 8: help
What now> 1
You also could say "s" or "sta" or "status" above as long as the
choice is unique.
The main command loop has 6 subcommands (plus help and quit).
* 'status' shows the change between HEAD and index (i.e. what
will be committed if you say "git commit"), and between index
and working tree files (i.e. what you could stage further
before "git commit" using "git-add") for each path. A sample
output looks like this:
staged unstaged path
1: binary nothing foo.png
2: +403/-35 +1/-1 git-add--interactive.perl
It shows that foo.png has differences from HEAD (but that is
binary so line count cannot be shown) and there is no
difference between indexed copy and the working tree
version (if the working tree version were also different,
'binary' would have been shown in place of 'nothing'). The
other file, git-add--interactive.perl, has 403 lines added
and 35 lines deleted if you commit what is in the index, but
working tree file has further modifications (one addition and
one deletion).
* 'update' shows the status information and gives prompt
"Update>>". When the prompt ends with double '>>', you can
make more than one selection, concatenated with whitespace or
comma. Also you can say ranges. E.g. "2-5 7,9" to choose
2,3,4,5,7,9 from the list. You can say '*' to choose
everything.
What you chose are then highlighted with '*', like this:
staged unstaged path
1: binary nothing foo.png
* 2: +403/-35 +1/-1 git-add--interactive.perl
To remove selection, prefix the input with - like this:
Update>> -2
After making the selection, answer with an empty line to
stage the contents of working tree files for selected paths
in the index.
* 'revert' has a very similar UI to 'update', and the staged
information for selected paths are reverted to that of the
HEAD version. Reverting new paths makes them untracked.
* 'add untracked' has a very similar UI to 'update' and
'revert', and lets you add untracked paths to the index.
* 'patch' lets you choose one path out of 'status' like
selection. After choosing the path, it presents diff between
the index and the working tree file and asks you if you want
to stage the change of each hunk. You can say:
y - add the change from that hunk to index
n - do not add the change from that hunk to index
a - add the change from that hunk and all the rest to index
d - do not the change from that hunk nor any of the rest to index
j - do not decide on this hunk now, and view the next
undecided hunk
J - do not decide on this hunk now, and view the next hunk
k - do not decide on this hunk now, and view the previous
undecided hunk
K - do not decide on this hunk now, and view the previous hunk
After deciding the fate for all hunks, if there is any hunk
that was chosen, the index is updated with the selected hunks.
* 'diff' lets you review what will be committed (i.e. between
HEAD and index).
This is still rough, but does everything except a few things I
think are needed.
* 'patch' should be able to allow splitting a hunk into
multiple hunks.
* 'patch' does not adjust the line offsets @@ -k,l +m,n @@
in the hunk header. This does not have major problem in
practice, but it _should_ do the adjustment.
* It does not have any explicit support for a merge in
progress; it may not work at all.
Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-12-11 05:55:50 +01:00
|
|
|
#include "exec_cmd.h"
|
2006-05-20 10:28:49 +02:00
|
|
|
#include "cache-tree.h"
|
2007-09-18 02:06:44 +02:00
|
|
|
#include "run-command.h"
|
2007-10-03 23:45:02 +02:00
|
|
|
#include "parse-options.h"
|
git-add: introduce --edit (to edit the diff vs. the index)
With "git add -e [<files>]", Git will fire up an editor with the current
diff relative to the index (i.e. what you would get with "git diff
[<files>]").
Now you can edit the patch as much as you like, including adding/removing
lines, editing the text, whatever. Make sure, though, that the first
character of the hunk lines is still a space, a plus or a minus.
After you closed the editor, Git will adjust the line counts of the hunks
if necessary, thanks to the --recount option of apply, and commit the
patch. Except if you deleted everything, in which case nothing happens
(for obvious reasons).
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-04-08 23:30:24 +02:00
|
|
|
#include "diff.h"
|
Remove diff machinery dependency from read-cache
Exal Sibeaz pointed out that some git files are way too big, and that
add_files_to_cache() brings in all the diff machinery to any git binary
that needs the basic git SHA1 object operations from read-cache.c. Which
is pretty much all of them.
It's doubly silly, since add_files_to_cache() is only used by builtin
programs (add, checkout and commit), so it's fairly easily fixed by just
moving the thing to builtin-add.c, and avoiding the dependency entirely.
I initially argued to Exal that it would probably be best to try to depend
on smart compilers and linkers, but after spending some time trying to
make -ffunction-sections work and giving up, I think Exal was right, and
the fix is to just do some trivial cleanups like this.
This trivial cleanup results in pretty stunning file size differences.
The diff machinery really is mostly used by just the builtin programs, and
you have things like these trivial before-and-after numbers:
-rwxr-xr-x 1 torvalds torvalds 1727420 2010-01-21 10:53 git-hash-object
-rwxrwxr-x 1 torvalds torvalds 940265 2010-01-21 11:16 git-hash-object
Now, I'm not saying that 940kB is good either, but that's mostly all the
debug information - you can see the real code with 'size':
text data bss dec hex filename
418675 3920 127408 550003 86473 git-hash-object (before)
230650 2288 111728 344666 5425a git-hash-object (after)
ie we have a nice 24% size reduction from this trivial cleanup.
It's not just that one file either. I get:
[torvalds@nehalem git]$ du -s /home/torvalds/libexec/git-core
45640 /home/torvalds/libexec/git-core (before)
33508 /home/torvalds/libexec/git-core (after)
so we're talking 12MB of diskspace here.
(Of course, stripping all the binaries brings the 33MB down to 9MB, so the
whole debug information thing is still the bulk of it all, but that's a
separate issue entirely)
Now, I'm sure there are other things we should do, and changing our
compiler flags from -O2 to -Os would bring the text size down by an
additional almost 20%, but this thing Exal pointed out seems to be some
good low-hanging fruit.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2010-01-21 20:37:38 +01:00
|
|
|
#include "diffcore.h"
|
git-add: introduce --edit (to edit the diff vs. the index)
With "git add -e [<files>]", Git will fire up an editor with the current
diff relative to the index (i.e. what you would get with "git diff
[<files>]").
Now you can edit the patch as much as you like, including adding/removing
lines, editing the text, whatever. Make sure, though, that the first
character of the hunk lines is still a space, a plus or a minus.
After you closed the editor, Git will adjust the line counts of the hunks
if necessary, thanks to the --recount option of apply, and commit the
patch. Except if you deleted everything, in which case nothing happens
(for obvious reasons).
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-04-08 23:30:24 +02:00
|
|
|
#include "revision.h"
|
2011-10-28 23:48:40 +02:00
|
|
|
#include "bulk-checkin.h"
|
2006-05-17 18:33:32 +02:00
|
|
|
|
2007-10-03 23:45:02 +02:00
|
|
|
static const char * const builtin_add_usage[] = {
|
2013-02-12 10:24:44 +01:00
|
|
|
N_("git add [options] [--] <pathspec>..."),
|
2007-10-03 23:45:02 +02:00
|
|
|
NULL
|
|
|
|
};
|
git-add: introduce --edit (to edit the diff vs. the index)
With "git add -e [<files>]", Git will fire up an editor with the current
diff relative to the index (i.e. what you would get with "git diff
[<files>]").
Now you can edit the patch as much as you like, including adding/removing
lines, editing the text, whatever. Make sure, though, that the first
character of the hunk lines is still a space, a plus or a minus.
After you closed the editor, Git will adjust the line counts of the hunks
if necessary, thanks to the --recount option of apply, and commit the
patch. Except if you deleted everything, in which case nothing happens
(for obvious reasons).
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-04-08 23:30:24 +02:00
|
|
|
static int patch_interactive, add_interactive, edit_interactive;
|
2007-05-12 08:42:00 +02:00
|
|
|
static int take_worktree_changes;
|
2007-02-28 04:31:10 +01:00
|
|
|
|
2011-03-16 08:08:34 +01:00
|
|
|
struct update_callback_data {
|
Remove diff machinery dependency from read-cache
Exal Sibeaz pointed out that some git files are way too big, and that
add_files_to_cache() brings in all the diff machinery to any git binary
that needs the basic git SHA1 object operations from read-cache.c. Which
is pretty much all of them.
It's doubly silly, since add_files_to_cache() is only used by builtin
programs (add, checkout and commit), so it's fairly easily fixed by just
moving the thing to builtin-add.c, and avoiding the dependency entirely.
I initially argued to Exal that it would probably be best to try to depend
on smart compilers and linkers, but after spending some time trying to
make -ffunction-sections work and giving up, I think Exal was right, and
the fix is to just do some trivial cleanups like this.
This trivial cleanup results in pretty stunning file size differences.
The diff machinery really is mostly used by just the builtin programs, and
you have things like these trivial before-and-after numbers:
-rwxr-xr-x 1 torvalds torvalds 1727420 2010-01-21 10:53 git-hash-object
-rwxrwxr-x 1 torvalds torvalds 940265 2010-01-21 11:16 git-hash-object
Now, I'm not saying that 940kB is good either, but that's mostly all the
debug information - you can see the real code with 'size':
text data bss dec hex filename
418675 3920 127408 550003 86473 git-hash-object (before)
230650 2288 111728 344666 5425a git-hash-object (after)
ie we have a nice 24% size reduction from this trivial cleanup.
It's not just that one file either. I get:
[torvalds@nehalem git]$ du -s /home/torvalds/libexec/git-core
45640 /home/torvalds/libexec/git-core (before)
33508 /home/torvalds/libexec/git-core (after)
so we're talking 12MB of diskspace here.
(Of course, stripping all the binaries brings the 33MB down to 9MB, so the
whole debug information thing is still the bulk of it all, but that's a
separate issue entirely)
Now, I'm sure there are other things we should do, and changing our
compiler flags from -O2 to -Os would bring the text size down by an
additional almost 20%, but this thing Exal pointed out seems to be some
good low-hanging fruit.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2010-01-21 20:37:38 +01:00
|
|
|
int flags;
|
|
|
|
int add_errors;
|
2013-03-19 23:50:50 +01:00
|
|
|
const char *implicit_dot;
|
|
|
|
size_t implicit_dot_len;
|
git add: rework the logic to warn "git add <pathspec>..." default change
The earlier logic to warn against "git add subdir" that is run
without "-A" or "--no-all" was only to check any <pathspec> given
exactly spells a directory name that (still) exists on the
filesystem. This had number of problems:
* "git add '*dir'" (note that the wildcard is hidden from the
shell) would not trigger the warning.
* "git add '*.py'" would behave differently between the current
version of Git and Git 2.0 for the same reason as "subdir", but
would not trigger the warning.
* "git add dir" for a submodule "dir" would just update the index
entry for the submodule "dir" without ever recursing into it, and
use of "-A" or "--no-all" would matter. But the logic only
checks the directory-ness of "dir" and gives an unnecessary
warning.
Rework the logic to detect the case where the behaviour will be
different in Git 2.0, and issue a warning only when it matters.
Even with the code before this warning, "git add subdir" will have
to traverse the directory in order to find _new_ files the index
does not know about _anyway_, so we can do this check without adding
an extra pass to find if <pathspec> matches any removed file.
This essentially updates the "add_files_to_cache()" public API to
"update_files_in_cache()" API that is internal to "git add", because
with the "--all" option, the function is no longer about "adding"
paths to the cache, but is also used to remove them.
There are other callers of the former from "checkout" (used when
"checkout -m" prepares the temporary tree that represents the local
modifications to be merged) and "commit" ("commit --include" that
picks up local changes in addition to what is in the index). Since
ADD_CACHE_IGNORE_ERRORS (aka "--no-all") is not used by either of
them, once dust settles after Git 2.0 and the warning becomes
unnecessary, we may want to unify these two functions again.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-04-17 21:32:21 +02:00
|
|
|
|
|
|
|
/* only needed for 2.0 transition preparation */
|
|
|
|
int warn_add_would_remove;
|
Remove diff machinery dependency from read-cache
Exal Sibeaz pointed out that some git files are way too big, and that
add_files_to_cache() brings in all the diff machinery to any git binary
that needs the basic git SHA1 object operations from read-cache.c. Which
is pretty much all of them.
It's doubly silly, since add_files_to_cache() is only used by builtin
programs (add, checkout and commit), so it's fairly easily fixed by just
moving the thing to builtin-add.c, and avoiding the dependency entirely.
I initially argued to Exal that it would probably be best to try to depend
on smart compilers and linkers, but after spending some time trying to
make -ffunction-sections work and giving up, I think Exal was right, and
the fix is to just do some trivial cleanups like this.
This trivial cleanup results in pretty stunning file size differences.
The diff machinery really is mostly used by just the builtin programs, and
you have things like these trivial before-and-after numbers:
-rwxr-xr-x 1 torvalds torvalds 1727420 2010-01-21 10:53 git-hash-object
-rwxrwxr-x 1 torvalds torvalds 940265 2010-01-21 11:16 git-hash-object
Now, I'm not saying that 940kB is good either, but that's mostly all the
debug information - you can see the real code with 'size':
text data bss dec hex filename
418675 3920 127408 550003 86473 git-hash-object (before)
230650 2288 111728 344666 5425a git-hash-object (after)
ie we have a nice 24% size reduction from this trivial cleanup.
It's not just that one file either. I get:
[torvalds@nehalem git]$ du -s /home/torvalds/libexec/git-core
45640 /home/torvalds/libexec/git-core (before)
33508 /home/torvalds/libexec/git-core (after)
so we're talking 12MB of diskspace here.
(Of course, stripping all the binaries brings the 33MB down to 9MB, so the
whole debug information thing is still the bulk of it all, but that's a
separate issue entirely)
Now, I'm sure there are other things we should do, and changing our
compiler flags from -O2 to -Os would bring the text size down by an
additional almost 20%, but this thing Exal pointed out seems to be some
good low-hanging fruit.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2010-01-21 20:37:38 +01:00
|
|
|
};
|
|
|
|
|
2013-03-19 23:45:26 +01:00
|
|
|
static const char *option_with_implicit_dot;
|
|
|
|
static const char *short_option_with_implicit_dot;
|
|
|
|
|
|
|
|
static void warn_pathless_add(void)
|
|
|
|
{
|
2013-03-19 23:45:52 +01:00
|
|
|
static int shown;
|
2013-03-19 23:45:26 +01:00
|
|
|
assert(option_with_implicit_dot && short_option_with_implicit_dot);
|
|
|
|
|
2013-03-19 23:45:52 +01:00
|
|
|
if (shown)
|
|
|
|
return;
|
|
|
|
shown = 1;
|
|
|
|
|
2013-03-19 23:45:26 +01:00
|
|
|
/*
|
|
|
|
* To be consistent with "git add -p" and most Git
|
|
|
|
* commands, we should default to being tree-wide, but
|
|
|
|
* this is not the original behavior and can't be
|
|
|
|
* changed until users trained themselves not to type
|
|
|
|
* "git add -u" or "git add -A". For now, we warn and
|
|
|
|
* keep the old behavior. Later, the behavior can be changed
|
|
|
|
* to tree-wide, keeping the warning for a while, and
|
|
|
|
* eventually we can drop the warning.
|
|
|
|
*/
|
|
|
|
warning(_("The behavior of 'git add %s (or %s)' with no path argument from a\n"
|
|
|
|
"subdirectory of the tree will change in Git 2.0 and should not be used anymore.\n"
|
|
|
|
"To add content for the whole tree, run:\n"
|
|
|
|
"\n"
|
|
|
|
" git add %s :/\n"
|
|
|
|
" (or git add %s :/)\n"
|
|
|
|
"\n"
|
|
|
|
"To restrict the command to the current directory, run:\n"
|
|
|
|
"\n"
|
|
|
|
" git add %s .\n"
|
|
|
|
" (or git add %s .)\n"
|
|
|
|
"\n"
|
2013-03-11 09:01:33 +01:00
|
|
|
"With the current Git version, the command is restricted to "
|
|
|
|
"the current directory.\n"
|
|
|
|
""),
|
2013-03-19 23:45:26 +01:00
|
|
|
option_with_implicit_dot, short_option_with_implicit_dot,
|
|
|
|
option_with_implicit_dot, short_option_with_implicit_dot,
|
|
|
|
option_with_implicit_dot, short_option_with_implicit_dot);
|
|
|
|
}
|
|
|
|
|
2011-04-21 03:11:19 +02:00
|
|
|
static int fix_unmerged_status(struct diff_filepair *p,
|
|
|
|
struct update_callback_data *data)
|
|
|
|
{
|
|
|
|
if (p->status != DIFF_STATUS_UNMERGED)
|
|
|
|
return p->status;
|
|
|
|
if (!(data->flags & ADD_CACHE_IGNORE_REMOVAL) && !p->two->mode)
|
|
|
|
/*
|
|
|
|
* This is not an explicit add request, and the
|
|
|
|
* path is missing from the working tree (deleted)
|
|
|
|
*/
|
|
|
|
return DIFF_STATUS_DELETED;
|
|
|
|
else
|
|
|
|
/*
|
|
|
|
* Either an explicit add request, or path exists
|
|
|
|
* in the working tree. An attempt to explicitly
|
|
|
|
* add a path that does not exist in the working tree
|
|
|
|
* will be caught as an error by the caller immediately.
|
|
|
|
*/
|
|
|
|
return DIFF_STATUS_MODIFIED;
|
|
|
|
}
|
|
|
|
|
2013-04-22 06:04:35 +02:00
|
|
|
static const char *add_would_remove_warning = N_(
|
2013-04-22 22:36:51 +02:00
|
|
|
"You ran 'git add' with neither '-A (--all)' or '--ignore-removal',\n"
|
|
|
|
"whose behaviour will change in Git 2.0 with respect to paths you removed.\n"
|
|
|
|
"Paths like '%s' that are\n"
|
|
|
|
"removed from your working tree are ignored with this version of Git.\n"
|
2013-04-22 06:04:35 +02:00
|
|
|
"\n"
|
2013-04-22 22:36:51 +02:00
|
|
|
"* 'git add --ignore-removal <pathspec>', which is the current default,\n"
|
|
|
|
" ignores paths you removed from your working tree.\n"
|
2013-04-22 06:04:35 +02:00
|
|
|
"\n"
|
|
|
|
"* 'git add --all <pathspec>' will let you also record the removals.\n"
|
|
|
|
"\n"
|
|
|
|
"Run 'git status' to check the paths you removed from your working tree.\n");
|
|
|
|
|
git add: rework the logic to warn "git add <pathspec>..." default change
The earlier logic to warn against "git add subdir" that is run
without "-A" or "--no-all" was only to check any <pathspec> given
exactly spells a directory name that (still) exists on the
filesystem. This had number of problems:
* "git add '*dir'" (note that the wildcard is hidden from the
shell) would not trigger the warning.
* "git add '*.py'" would behave differently between the current
version of Git and Git 2.0 for the same reason as "subdir", but
would not trigger the warning.
* "git add dir" for a submodule "dir" would just update the index
entry for the submodule "dir" without ever recursing into it, and
use of "-A" or "--no-all" would matter. But the logic only
checks the directory-ness of "dir" and gives an unnecessary
warning.
Rework the logic to detect the case where the behaviour will be
different in Git 2.0, and issue a warning only when it matters.
Even with the code before this warning, "git add subdir" will have
to traverse the directory in order to find _new_ files the index
does not know about _anyway_, so we can do this check without adding
an extra pass to find if <pathspec> matches any removed file.
This essentially updates the "add_files_to_cache()" public API to
"update_files_in_cache()" API that is internal to "git add", because
with the "--all" option, the function is no longer about "adding"
paths to the cache, but is also used to remove them.
There are other callers of the former from "checkout" (used when
"checkout -m" prepares the temporary tree that represents the local
modifications to be merged) and "commit" ("commit --include" that
picks up local changes in addition to what is in the index). Since
ADD_CACHE_IGNORE_ERRORS (aka "--no-all") is not used by either of
them, once dust settles after Git 2.0 and the warning becomes
unnecessary, we may want to unify these two functions again.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-04-17 21:32:21 +02:00
|
|
|
static void warn_add_would_remove(const char *path)
|
|
|
|
{
|
2013-04-22 06:04:35 +02:00
|
|
|
warning(_(add_would_remove_warning), path);
|
git add: rework the logic to warn "git add <pathspec>..." default change
The earlier logic to warn against "git add subdir" that is run
without "-A" or "--no-all" was only to check any <pathspec> given
exactly spells a directory name that (still) exists on the
filesystem. This had number of problems:
* "git add '*dir'" (note that the wildcard is hidden from the
shell) would not trigger the warning.
* "git add '*.py'" would behave differently between the current
version of Git and Git 2.0 for the same reason as "subdir", but
would not trigger the warning.
* "git add dir" for a submodule "dir" would just update the index
entry for the submodule "dir" without ever recursing into it, and
use of "-A" or "--no-all" would matter. But the logic only
checks the directory-ness of "dir" and gives an unnecessary
warning.
Rework the logic to detect the case where the behaviour will be
different in Git 2.0, and issue a warning only when it matters.
Even with the code before this warning, "git add subdir" will have
to traverse the directory in order to find _new_ files the index
does not know about _anyway_, so we can do this check without adding
an extra pass to find if <pathspec> matches any removed file.
This essentially updates the "add_files_to_cache()" public API to
"update_files_in_cache()" API that is internal to "git add", because
with the "--all" option, the function is no longer about "adding"
paths to the cache, but is also used to remove them.
There are other callers of the former from "checkout" (used when
"checkout -m" prepares the temporary tree that represents the local
modifications to be merged) and "commit" ("commit --include" that
picks up local changes in addition to what is in the index). Since
ADD_CACHE_IGNORE_ERRORS (aka "--no-all") is not used by either of
them, once dust settles after Git 2.0 and the warning becomes
unnecessary, we may want to unify these two functions again.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-04-17 21:32:21 +02:00
|
|
|
}
|
|
|
|
|
Remove diff machinery dependency from read-cache
Exal Sibeaz pointed out that some git files are way too big, and that
add_files_to_cache() brings in all the diff machinery to any git binary
that needs the basic git SHA1 object operations from read-cache.c. Which
is pretty much all of them.
It's doubly silly, since add_files_to_cache() is only used by builtin
programs (add, checkout and commit), so it's fairly easily fixed by just
moving the thing to builtin-add.c, and avoiding the dependency entirely.
I initially argued to Exal that it would probably be best to try to depend
on smart compilers and linkers, but after spending some time trying to
make -ffunction-sections work and giving up, I think Exal was right, and
the fix is to just do some trivial cleanups like this.
This trivial cleanup results in pretty stunning file size differences.
The diff machinery really is mostly used by just the builtin programs, and
you have things like these trivial before-and-after numbers:
-rwxr-xr-x 1 torvalds torvalds 1727420 2010-01-21 10:53 git-hash-object
-rwxrwxr-x 1 torvalds torvalds 940265 2010-01-21 11:16 git-hash-object
Now, I'm not saying that 940kB is good either, but that's mostly all the
debug information - you can see the real code with 'size':
text data bss dec hex filename
418675 3920 127408 550003 86473 git-hash-object (before)
230650 2288 111728 344666 5425a git-hash-object (after)
ie we have a nice 24% size reduction from this trivial cleanup.
It's not just that one file either. I get:
[torvalds@nehalem git]$ du -s /home/torvalds/libexec/git-core
45640 /home/torvalds/libexec/git-core (before)
33508 /home/torvalds/libexec/git-core (after)
so we're talking 12MB of diskspace here.
(Of course, stripping all the binaries brings the 33MB down to 9MB, so the
whole debug information thing is still the bulk of it all, but that's a
separate issue entirely)
Now, I'm sure there are other things we should do, and changing our
compiler flags from -O2 to -Os would bring the text size down by an
additional almost 20%, but this thing Exal pointed out seems to be some
good low-hanging fruit.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2010-01-21 20:37:38 +01:00
|
|
|
static void update_callback(struct diff_queue_struct *q,
|
|
|
|
struct diff_options *opt, void *cbdata)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
struct update_callback_data *data = cbdata;
|
2013-03-19 23:50:50 +01:00
|
|
|
const char *implicit_dot = data->implicit_dot;
|
|
|
|
size_t implicit_dot_len = data->implicit_dot_len;
|
Remove diff machinery dependency from read-cache
Exal Sibeaz pointed out that some git files are way too big, and that
add_files_to_cache() brings in all the diff machinery to any git binary
that needs the basic git SHA1 object operations from read-cache.c. Which
is pretty much all of them.
It's doubly silly, since add_files_to_cache() is only used by builtin
programs (add, checkout and commit), so it's fairly easily fixed by just
moving the thing to builtin-add.c, and avoiding the dependency entirely.
I initially argued to Exal that it would probably be best to try to depend
on smart compilers and linkers, but after spending some time trying to
make -ffunction-sections work and giving up, I think Exal was right, and
the fix is to just do some trivial cleanups like this.
This trivial cleanup results in pretty stunning file size differences.
The diff machinery really is mostly used by just the builtin programs, and
you have things like these trivial before-and-after numbers:
-rwxr-xr-x 1 torvalds torvalds 1727420 2010-01-21 10:53 git-hash-object
-rwxrwxr-x 1 torvalds torvalds 940265 2010-01-21 11:16 git-hash-object
Now, I'm not saying that 940kB is good either, but that's mostly all the
debug information - you can see the real code with 'size':
text data bss dec hex filename
418675 3920 127408 550003 86473 git-hash-object (before)
230650 2288 111728 344666 5425a git-hash-object (after)
ie we have a nice 24% size reduction from this trivial cleanup.
It's not just that one file either. I get:
[torvalds@nehalem git]$ du -s /home/torvalds/libexec/git-core
45640 /home/torvalds/libexec/git-core (before)
33508 /home/torvalds/libexec/git-core (after)
so we're talking 12MB of diskspace here.
(Of course, stripping all the binaries brings the 33MB down to 9MB, so the
whole debug information thing is still the bulk of it all, but that's a
separate issue entirely)
Now, I'm sure there are other things we should do, and changing our
compiler flags from -O2 to -Os would bring the text size down by an
additional almost 20%, but this thing Exal pointed out seems to be some
good low-hanging fruit.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2010-01-21 20:37:38 +01:00
|
|
|
|
|
|
|
for (i = 0; i < q->nr; i++) {
|
|
|
|
struct diff_filepair *p = q->queue[i];
|
|
|
|
const char *path = p->one->path;
|
2013-03-19 23:50:50 +01:00
|
|
|
/*
|
|
|
|
* Check if "git add -A" or "git add -u" was run from a
|
|
|
|
* subdirectory with a modified file outside that directory,
|
|
|
|
* and warn if so.
|
|
|
|
*
|
|
|
|
* "git add -u" will behave like "git add -u :/" instead of
|
|
|
|
* "git add -u ." in the future. This warning prepares for
|
|
|
|
* that change.
|
|
|
|
*/
|
|
|
|
if (implicit_dot &&
|
|
|
|
strncmp_icase(path, implicit_dot, implicit_dot_len)) {
|
|
|
|
warn_pathless_add();
|
|
|
|
continue;
|
|
|
|
}
|
2011-04-21 03:11:19 +02:00
|
|
|
switch (fix_unmerged_status(p, data)) {
|
Remove diff machinery dependency from read-cache
Exal Sibeaz pointed out that some git files are way too big, and that
add_files_to_cache() brings in all the diff machinery to any git binary
that needs the basic git SHA1 object operations from read-cache.c. Which
is pretty much all of them.
It's doubly silly, since add_files_to_cache() is only used by builtin
programs (add, checkout and commit), so it's fairly easily fixed by just
moving the thing to builtin-add.c, and avoiding the dependency entirely.
I initially argued to Exal that it would probably be best to try to depend
on smart compilers and linkers, but after spending some time trying to
make -ffunction-sections work and giving up, I think Exal was right, and
the fix is to just do some trivial cleanups like this.
This trivial cleanup results in pretty stunning file size differences.
The diff machinery really is mostly used by just the builtin programs, and
you have things like these trivial before-and-after numbers:
-rwxr-xr-x 1 torvalds torvalds 1727420 2010-01-21 10:53 git-hash-object
-rwxrwxr-x 1 torvalds torvalds 940265 2010-01-21 11:16 git-hash-object
Now, I'm not saying that 940kB is good either, but that's mostly all the
debug information - you can see the real code with 'size':
text data bss dec hex filename
418675 3920 127408 550003 86473 git-hash-object (before)
230650 2288 111728 344666 5425a git-hash-object (after)
ie we have a nice 24% size reduction from this trivial cleanup.
It's not just that one file either. I get:
[torvalds@nehalem git]$ du -s /home/torvalds/libexec/git-core
45640 /home/torvalds/libexec/git-core (before)
33508 /home/torvalds/libexec/git-core (after)
so we're talking 12MB of diskspace here.
(Of course, stripping all the binaries brings the 33MB down to 9MB, so the
whole debug information thing is still the bulk of it all, but that's a
separate issue entirely)
Now, I'm sure there are other things we should do, and changing our
compiler flags from -O2 to -Os would bring the text size down by an
additional almost 20%, but this thing Exal pointed out seems to be some
good low-hanging fruit.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2010-01-21 20:37:38 +01:00
|
|
|
default:
|
2011-02-23 00:41:29 +01:00
|
|
|
die(_("unexpected diff status %c"), p->status);
|
Remove diff machinery dependency from read-cache
Exal Sibeaz pointed out that some git files are way too big, and that
add_files_to_cache() brings in all the diff machinery to any git binary
that needs the basic git SHA1 object operations from read-cache.c. Which
is pretty much all of them.
It's doubly silly, since add_files_to_cache() is only used by builtin
programs (add, checkout and commit), so it's fairly easily fixed by just
moving the thing to builtin-add.c, and avoiding the dependency entirely.
I initially argued to Exal that it would probably be best to try to depend
on smart compilers and linkers, but after spending some time trying to
make -ffunction-sections work and giving up, I think Exal was right, and
the fix is to just do some trivial cleanups like this.
This trivial cleanup results in pretty stunning file size differences.
The diff machinery really is mostly used by just the builtin programs, and
you have things like these trivial before-and-after numbers:
-rwxr-xr-x 1 torvalds torvalds 1727420 2010-01-21 10:53 git-hash-object
-rwxrwxr-x 1 torvalds torvalds 940265 2010-01-21 11:16 git-hash-object
Now, I'm not saying that 940kB is good either, but that's mostly all the
debug information - you can see the real code with 'size':
text data bss dec hex filename
418675 3920 127408 550003 86473 git-hash-object (before)
230650 2288 111728 344666 5425a git-hash-object (after)
ie we have a nice 24% size reduction from this trivial cleanup.
It's not just that one file either. I get:
[torvalds@nehalem git]$ du -s /home/torvalds/libexec/git-core
45640 /home/torvalds/libexec/git-core (before)
33508 /home/torvalds/libexec/git-core (after)
so we're talking 12MB of diskspace here.
(Of course, stripping all the binaries brings the 33MB down to 9MB, so the
whole debug information thing is still the bulk of it all, but that's a
separate issue entirely)
Now, I'm sure there are other things we should do, and changing our
compiler flags from -O2 to -Os would bring the text size down by an
additional almost 20%, but this thing Exal pointed out seems to be some
good low-hanging fruit.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2010-01-21 20:37:38 +01:00
|
|
|
case DIFF_STATUS_MODIFIED:
|
|
|
|
case DIFF_STATUS_TYPE_CHANGED:
|
|
|
|
if (add_file_to_index(&the_index, path, data->flags)) {
|
|
|
|
if (!(data->flags & ADD_CACHE_IGNORE_ERRORS))
|
2011-02-23 00:41:29 +01:00
|
|
|
die(_("updating files failed"));
|
Remove diff machinery dependency from read-cache
Exal Sibeaz pointed out that some git files are way too big, and that
add_files_to_cache() brings in all the diff machinery to any git binary
that needs the basic git SHA1 object operations from read-cache.c. Which
is pretty much all of them.
It's doubly silly, since add_files_to_cache() is only used by builtin
programs (add, checkout and commit), so it's fairly easily fixed by just
moving the thing to builtin-add.c, and avoiding the dependency entirely.
I initially argued to Exal that it would probably be best to try to depend
on smart compilers and linkers, but after spending some time trying to
make -ffunction-sections work and giving up, I think Exal was right, and
the fix is to just do some trivial cleanups like this.
This trivial cleanup results in pretty stunning file size differences.
The diff machinery really is mostly used by just the builtin programs, and
you have things like these trivial before-and-after numbers:
-rwxr-xr-x 1 torvalds torvalds 1727420 2010-01-21 10:53 git-hash-object
-rwxrwxr-x 1 torvalds torvalds 940265 2010-01-21 11:16 git-hash-object
Now, I'm not saying that 940kB is good either, but that's mostly all the
debug information - you can see the real code with 'size':
text data bss dec hex filename
418675 3920 127408 550003 86473 git-hash-object (before)
230650 2288 111728 344666 5425a git-hash-object (after)
ie we have a nice 24% size reduction from this trivial cleanup.
It's not just that one file either. I get:
[torvalds@nehalem git]$ du -s /home/torvalds/libexec/git-core
45640 /home/torvalds/libexec/git-core (before)
33508 /home/torvalds/libexec/git-core (after)
so we're talking 12MB of diskspace here.
(Of course, stripping all the binaries brings the 33MB down to 9MB, so the
whole debug information thing is still the bulk of it all, but that's a
separate issue entirely)
Now, I'm sure there are other things we should do, and changing our
compiler flags from -O2 to -Os would bring the text size down by an
additional almost 20%, but this thing Exal pointed out seems to be some
good low-hanging fruit.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2010-01-21 20:37:38 +01:00
|
|
|
data->add_errors++;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case DIFF_STATUS_DELETED:
|
git add: rework the logic to warn "git add <pathspec>..." default change
The earlier logic to warn against "git add subdir" that is run
without "-A" or "--no-all" was only to check any <pathspec> given
exactly spells a directory name that (still) exists on the
filesystem. This had number of problems:
* "git add '*dir'" (note that the wildcard is hidden from the
shell) would not trigger the warning.
* "git add '*.py'" would behave differently between the current
version of Git and Git 2.0 for the same reason as "subdir", but
would not trigger the warning.
* "git add dir" for a submodule "dir" would just update the index
entry for the submodule "dir" without ever recursing into it, and
use of "-A" or "--no-all" would matter. But the logic only
checks the directory-ness of "dir" and gives an unnecessary
warning.
Rework the logic to detect the case where the behaviour will be
different in Git 2.0, and issue a warning only when it matters.
Even with the code before this warning, "git add subdir" will have
to traverse the directory in order to find _new_ files the index
does not know about _anyway_, so we can do this check without adding
an extra pass to find if <pathspec> matches any removed file.
This essentially updates the "add_files_to_cache()" public API to
"update_files_in_cache()" API that is internal to "git add", because
with the "--all" option, the function is no longer about "adding"
paths to the cache, but is also used to remove them.
There are other callers of the former from "checkout" (used when
"checkout -m" prepares the temporary tree that represents the local
modifications to be merged) and "commit" ("commit --include" that
picks up local changes in addition to what is in the index). Since
ADD_CACHE_IGNORE_ERRORS (aka "--no-all") is not used by either of
them, once dust settles after Git 2.0 and the warning becomes
unnecessary, we may want to unify these two functions again.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-04-17 21:32:21 +02:00
|
|
|
if (data->warn_add_would_remove) {
|
|
|
|
warn_add_would_remove(path);
|
|
|
|
data->warn_add_would_remove = 0;
|
|
|
|
}
|
Remove diff machinery dependency from read-cache
Exal Sibeaz pointed out that some git files are way too big, and that
add_files_to_cache() brings in all the diff machinery to any git binary
that needs the basic git SHA1 object operations from read-cache.c. Which
is pretty much all of them.
It's doubly silly, since add_files_to_cache() is only used by builtin
programs (add, checkout and commit), so it's fairly easily fixed by just
moving the thing to builtin-add.c, and avoiding the dependency entirely.
I initially argued to Exal that it would probably be best to try to depend
on smart compilers and linkers, but after spending some time trying to
make -ffunction-sections work and giving up, I think Exal was right, and
the fix is to just do some trivial cleanups like this.
This trivial cleanup results in pretty stunning file size differences.
The diff machinery really is mostly used by just the builtin programs, and
you have things like these trivial before-and-after numbers:
-rwxr-xr-x 1 torvalds torvalds 1727420 2010-01-21 10:53 git-hash-object
-rwxrwxr-x 1 torvalds torvalds 940265 2010-01-21 11:16 git-hash-object
Now, I'm not saying that 940kB is good either, but that's mostly all the
debug information - you can see the real code with 'size':
text data bss dec hex filename
418675 3920 127408 550003 86473 git-hash-object (before)
230650 2288 111728 344666 5425a git-hash-object (after)
ie we have a nice 24% size reduction from this trivial cleanup.
It's not just that one file either. I get:
[torvalds@nehalem git]$ du -s /home/torvalds/libexec/git-core
45640 /home/torvalds/libexec/git-core (before)
33508 /home/torvalds/libexec/git-core (after)
so we're talking 12MB of diskspace here.
(Of course, stripping all the binaries brings the 33MB down to 9MB, so the
whole debug information thing is still the bulk of it all, but that's a
separate issue entirely)
Now, I'm sure there are other things we should do, and changing our
compiler flags from -O2 to -Os would bring the text size down by an
additional almost 20%, but this thing Exal pointed out seems to be some
good low-hanging fruit.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2010-01-21 20:37:38 +01:00
|
|
|
if (data->flags & ADD_CACHE_IGNORE_REMOVAL)
|
|
|
|
break;
|
|
|
|
if (!(data->flags & ADD_CACHE_PRETEND))
|
|
|
|
remove_file_from_index(&the_index, path);
|
|
|
|
if (data->flags & (ADD_CACHE_PRETEND|ADD_CACHE_VERBOSE))
|
2011-02-23 00:41:32 +01:00
|
|
|
printf(_("remove '%s'\n"), path);
|
Remove diff machinery dependency from read-cache
Exal Sibeaz pointed out that some git files are way too big, and that
add_files_to_cache() brings in all the diff machinery to any git binary
that needs the basic git SHA1 object operations from read-cache.c. Which
is pretty much all of them.
It's doubly silly, since add_files_to_cache() is only used by builtin
programs (add, checkout and commit), so it's fairly easily fixed by just
moving the thing to builtin-add.c, and avoiding the dependency entirely.
I initially argued to Exal that it would probably be best to try to depend
on smart compilers and linkers, but after spending some time trying to
make -ffunction-sections work and giving up, I think Exal was right, and
the fix is to just do some trivial cleanups like this.
This trivial cleanup results in pretty stunning file size differences.
The diff machinery really is mostly used by just the builtin programs, and
you have things like these trivial before-and-after numbers:
-rwxr-xr-x 1 torvalds torvalds 1727420 2010-01-21 10:53 git-hash-object
-rwxrwxr-x 1 torvalds torvalds 940265 2010-01-21 11:16 git-hash-object
Now, I'm not saying that 940kB is good either, but that's mostly all the
debug information - you can see the real code with 'size':
text data bss dec hex filename
418675 3920 127408 550003 86473 git-hash-object (before)
230650 2288 111728 344666 5425a git-hash-object (after)
ie we have a nice 24% size reduction from this trivial cleanup.
It's not just that one file either. I get:
[torvalds@nehalem git]$ du -s /home/torvalds/libexec/git-core
45640 /home/torvalds/libexec/git-core (before)
33508 /home/torvalds/libexec/git-core (after)
so we're talking 12MB of diskspace here.
(Of course, stripping all the binaries brings the 33MB down to 9MB, so the
whole debug information thing is still the bulk of it all, but that's a
separate issue entirely)
Now, I'm sure there are other things we should do, and changing our
compiler flags from -O2 to -Os would bring the text size down by an
additional almost 20%, but this thing Exal pointed out seems to be some
good low-hanging fruit.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2010-01-21 20:37:38 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-07-14 10:35:56 +02:00
|
|
|
static void update_files_in_cache(const char *prefix,
|
|
|
|
const struct pathspec *pathspec,
|
git add: rework the logic to warn "git add <pathspec>..." default change
The earlier logic to warn against "git add subdir" that is run
without "-A" or "--no-all" was only to check any <pathspec> given
exactly spells a directory name that (still) exists on the
filesystem. This had number of problems:
* "git add '*dir'" (note that the wildcard is hidden from the
shell) would not trigger the warning.
* "git add '*.py'" would behave differently between the current
version of Git and Git 2.0 for the same reason as "subdir", but
would not trigger the warning.
* "git add dir" for a submodule "dir" would just update the index
entry for the submodule "dir" without ever recursing into it, and
use of "-A" or "--no-all" would matter. But the logic only
checks the directory-ness of "dir" and gives an unnecessary
warning.
Rework the logic to detect the case where the behaviour will be
different in Git 2.0, and issue a warning only when it matters.
Even with the code before this warning, "git add subdir" will have
to traverse the directory in order to find _new_ files the index
does not know about _anyway_, so we can do this check without adding
an extra pass to find if <pathspec> matches any removed file.
This essentially updates the "add_files_to_cache()" public API to
"update_files_in_cache()" API that is internal to "git add", because
with the "--all" option, the function is no longer about "adding"
paths to the cache, but is also used to remove them.
There are other callers of the former from "checkout" (used when
"checkout -m" prepares the temporary tree that represents the local
modifications to be merged) and "commit" ("commit --include" that
picks up local changes in addition to what is in the index). Since
ADD_CACHE_IGNORE_ERRORS (aka "--no-all") is not used by either of
them, once dust settles after Git 2.0 and the warning becomes
unnecessary, we may want to unify these two functions again.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-04-17 21:32:21 +02:00
|
|
|
struct update_callback_data *data)
|
Remove diff machinery dependency from read-cache
Exal Sibeaz pointed out that some git files are way too big, and that
add_files_to_cache() brings in all the diff machinery to any git binary
that needs the basic git SHA1 object operations from read-cache.c. Which
is pretty much all of them.
It's doubly silly, since add_files_to_cache() is only used by builtin
programs (add, checkout and commit), so it's fairly easily fixed by just
moving the thing to builtin-add.c, and avoiding the dependency entirely.
I initially argued to Exal that it would probably be best to try to depend
on smart compilers and linkers, but after spending some time trying to
make -ffunction-sections work and giving up, I think Exal was right, and
the fix is to just do some trivial cleanups like this.
This trivial cleanup results in pretty stunning file size differences.
The diff machinery really is mostly used by just the builtin programs, and
you have things like these trivial before-and-after numbers:
-rwxr-xr-x 1 torvalds torvalds 1727420 2010-01-21 10:53 git-hash-object
-rwxrwxr-x 1 torvalds torvalds 940265 2010-01-21 11:16 git-hash-object
Now, I'm not saying that 940kB is good either, but that's mostly all the
debug information - you can see the real code with 'size':
text data bss dec hex filename
418675 3920 127408 550003 86473 git-hash-object (before)
230650 2288 111728 344666 5425a git-hash-object (after)
ie we have a nice 24% size reduction from this trivial cleanup.
It's not just that one file either. I get:
[torvalds@nehalem git]$ du -s /home/torvalds/libexec/git-core
45640 /home/torvalds/libexec/git-core (before)
33508 /home/torvalds/libexec/git-core (after)
so we're talking 12MB of diskspace here.
(Of course, stripping all the binaries brings the 33MB down to 9MB, so the
whole debug information thing is still the bulk of it all, but that's a
separate issue entirely)
Now, I'm sure there are other things we should do, and changing our
compiler flags from -O2 to -Os would bring the text size down by an
additional almost 20%, but this thing Exal pointed out seems to be some
good low-hanging fruit.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2010-01-21 20:37:38 +01:00
|
|
|
{
|
|
|
|
struct rev_info rev;
|
2013-03-19 23:50:50 +01:00
|
|
|
|
Remove diff machinery dependency from read-cache
Exal Sibeaz pointed out that some git files are way too big, and that
add_files_to_cache() brings in all the diff machinery to any git binary
that needs the basic git SHA1 object operations from read-cache.c. Which
is pretty much all of them.
It's doubly silly, since add_files_to_cache() is only used by builtin
programs (add, checkout and commit), so it's fairly easily fixed by just
moving the thing to builtin-add.c, and avoiding the dependency entirely.
I initially argued to Exal that it would probably be best to try to depend
on smart compilers and linkers, but after spending some time trying to
make -ffunction-sections work and giving up, I think Exal was right, and
the fix is to just do some trivial cleanups like this.
This trivial cleanup results in pretty stunning file size differences.
The diff machinery really is mostly used by just the builtin programs, and
you have things like these trivial before-and-after numbers:
-rwxr-xr-x 1 torvalds torvalds 1727420 2010-01-21 10:53 git-hash-object
-rwxrwxr-x 1 torvalds torvalds 940265 2010-01-21 11:16 git-hash-object
Now, I'm not saying that 940kB is good either, but that's mostly all the
debug information - you can see the real code with 'size':
text data bss dec hex filename
418675 3920 127408 550003 86473 git-hash-object (before)
230650 2288 111728 344666 5425a git-hash-object (after)
ie we have a nice 24% size reduction from this trivial cleanup.
It's not just that one file either. I get:
[torvalds@nehalem git]$ du -s /home/torvalds/libexec/git-core
45640 /home/torvalds/libexec/git-core (before)
33508 /home/torvalds/libexec/git-core (after)
so we're talking 12MB of diskspace here.
(Of course, stripping all the binaries brings the 33MB down to 9MB, so the
whole debug information thing is still the bulk of it all, but that's a
separate issue entirely)
Now, I'm sure there are other things we should do, and changing our
compiler flags from -O2 to -Os would bring the text size down by an
additional almost 20%, but this thing Exal pointed out seems to be some
good low-hanging fruit.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2010-01-21 20:37:38 +01:00
|
|
|
init_revisions(&rev, prefix);
|
|
|
|
setup_revisions(0, NULL, &rev, NULL);
|
2013-07-14 10:35:56 +02:00
|
|
|
if (pathspec)
|
|
|
|
copy_pathspec(&rev.prune_data, pathspec);
|
Remove diff machinery dependency from read-cache
Exal Sibeaz pointed out that some git files are way too big, and that
add_files_to_cache() brings in all the diff machinery to any git binary
that needs the basic git SHA1 object operations from read-cache.c. Which
is pretty much all of them.
It's doubly silly, since add_files_to_cache() is only used by builtin
programs (add, checkout and commit), so it's fairly easily fixed by just
moving the thing to builtin-add.c, and avoiding the dependency entirely.
I initially argued to Exal that it would probably be best to try to depend
on smart compilers and linkers, but after spending some time trying to
make -ffunction-sections work and giving up, I think Exal was right, and
the fix is to just do some trivial cleanups like this.
This trivial cleanup results in pretty stunning file size differences.
The diff machinery really is mostly used by just the builtin programs, and
you have things like these trivial before-and-after numbers:
-rwxr-xr-x 1 torvalds torvalds 1727420 2010-01-21 10:53 git-hash-object
-rwxrwxr-x 1 torvalds torvalds 940265 2010-01-21 11:16 git-hash-object
Now, I'm not saying that 940kB is good either, but that's mostly all the
debug information - you can see the real code with 'size':
text data bss dec hex filename
418675 3920 127408 550003 86473 git-hash-object (before)
230650 2288 111728 344666 5425a git-hash-object (after)
ie we have a nice 24% size reduction from this trivial cleanup.
It's not just that one file either. I get:
[torvalds@nehalem git]$ du -s /home/torvalds/libexec/git-core
45640 /home/torvalds/libexec/git-core (before)
33508 /home/torvalds/libexec/git-core (after)
so we're talking 12MB of diskspace here.
(Of course, stripping all the binaries brings the 33MB down to 9MB, so the
whole debug information thing is still the bulk of it all, but that's a
separate issue entirely)
Now, I'm sure there are other things we should do, and changing our
compiler flags from -O2 to -Os would bring the text size down by an
additional almost 20%, but this thing Exal pointed out seems to be some
good low-hanging fruit.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2010-01-21 20:37:38 +01:00
|
|
|
rev.diffopt.output_format = DIFF_FORMAT_CALLBACK;
|
|
|
|
rev.diffopt.format_callback = update_callback;
|
git add: rework the logic to warn "git add <pathspec>..." default change
The earlier logic to warn against "git add subdir" that is run
without "-A" or "--no-all" was only to check any <pathspec> given
exactly spells a directory name that (still) exists on the
filesystem. This had number of problems:
* "git add '*dir'" (note that the wildcard is hidden from the
shell) would not trigger the warning.
* "git add '*.py'" would behave differently between the current
version of Git and Git 2.0 for the same reason as "subdir", but
would not trigger the warning.
* "git add dir" for a submodule "dir" would just update the index
entry for the submodule "dir" without ever recursing into it, and
use of "-A" or "--no-all" would matter. But the logic only
checks the directory-ness of "dir" and gives an unnecessary
warning.
Rework the logic to detect the case where the behaviour will be
different in Git 2.0, and issue a warning only when it matters.
Even with the code before this warning, "git add subdir" will have
to traverse the directory in order to find _new_ files the index
does not know about _anyway_, so we can do this check without adding
an extra pass to find if <pathspec> matches any removed file.
This essentially updates the "add_files_to_cache()" public API to
"update_files_in_cache()" API that is internal to "git add", because
with the "--all" option, the function is no longer about "adding"
paths to the cache, but is also used to remove them.
There are other callers of the former from "checkout" (used when
"checkout -m" prepares the temporary tree that represents the local
modifications to be merged) and "commit" ("commit --include" that
picks up local changes in addition to what is in the index). Since
ADD_CACHE_IGNORE_ERRORS (aka "--no-all") is not used by either of
them, once dust settles after Git 2.0 and the warning becomes
unnecessary, we may want to unify these two functions again.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-04-17 21:32:21 +02:00
|
|
|
rev.diffopt.format_callback_data = data;
|
2011-04-21 03:11:19 +02:00
|
|
|
rev.max_count = 0; /* do not compare unmerged paths with stage #2 */
|
Remove diff machinery dependency from read-cache
Exal Sibeaz pointed out that some git files are way too big, and that
add_files_to_cache() brings in all the diff machinery to any git binary
that needs the basic git SHA1 object operations from read-cache.c. Which
is pretty much all of them.
It's doubly silly, since add_files_to_cache() is only used by builtin
programs (add, checkout and commit), so it's fairly easily fixed by just
moving the thing to builtin-add.c, and avoiding the dependency entirely.
I initially argued to Exal that it would probably be best to try to depend
on smart compilers and linkers, but after spending some time trying to
make -ffunction-sections work and giving up, I think Exal was right, and
the fix is to just do some trivial cleanups like this.
This trivial cleanup results in pretty stunning file size differences.
The diff machinery really is mostly used by just the builtin programs, and
you have things like these trivial before-and-after numbers:
-rwxr-xr-x 1 torvalds torvalds 1727420 2010-01-21 10:53 git-hash-object
-rwxrwxr-x 1 torvalds torvalds 940265 2010-01-21 11:16 git-hash-object
Now, I'm not saying that 940kB is good either, but that's mostly all the
debug information - you can see the real code with 'size':
text data bss dec hex filename
418675 3920 127408 550003 86473 git-hash-object (before)
230650 2288 111728 344666 5425a git-hash-object (after)
ie we have a nice 24% size reduction from this trivial cleanup.
It's not just that one file either. I get:
[torvalds@nehalem git]$ du -s /home/torvalds/libexec/git-core
45640 /home/torvalds/libexec/git-core (before)
33508 /home/torvalds/libexec/git-core (after)
so we're talking 12MB of diskspace here.
(Of course, stripping all the binaries brings the 33MB down to 9MB, so the
whole debug information thing is still the bulk of it all, but that's a
separate issue entirely)
Now, I'm sure there are other things we should do, and changing our
compiler flags from -O2 to -Os would bring the text size down by an
additional almost 20%, but this thing Exal pointed out seems to be some
good low-hanging fruit.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2010-01-21 20:37:38 +01:00
|
|
|
run_diff_files(&rev, DIFF_RACY_IS_MODIFIED);
|
git add: rework the logic to warn "git add <pathspec>..." default change
The earlier logic to warn against "git add subdir" that is run
without "-A" or "--no-all" was only to check any <pathspec> given
exactly spells a directory name that (still) exists on the
filesystem. This had number of problems:
* "git add '*dir'" (note that the wildcard is hidden from the
shell) would not trigger the warning.
* "git add '*.py'" would behave differently between the current
version of Git and Git 2.0 for the same reason as "subdir", but
would not trigger the warning.
* "git add dir" for a submodule "dir" would just update the index
entry for the submodule "dir" without ever recursing into it, and
use of "-A" or "--no-all" would matter. But the logic only
checks the directory-ness of "dir" and gives an unnecessary
warning.
Rework the logic to detect the case where the behaviour will be
different in Git 2.0, and issue a warning only when it matters.
Even with the code before this warning, "git add subdir" will have
to traverse the directory in order to find _new_ files the index
does not know about _anyway_, so we can do this check without adding
an extra pass to find if <pathspec> matches any removed file.
This essentially updates the "add_files_to_cache()" public API to
"update_files_in_cache()" API that is internal to "git add", because
with the "--all" option, the function is no longer about "adding"
paths to the cache, but is also used to remove them.
There are other callers of the former from "checkout" (used when
"checkout -m" prepares the temporary tree that represents the local
modifications to be merged) and "commit" ("commit --include" that
picks up local changes in addition to what is in the index). Since
ADD_CACHE_IGNORE_ERRORS (aka "--no-all") is not used by either of
them, once dust settles after Git 2.0 and the warning becomes
unnecessary, we may want to unify these two functions again.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-04-17 21:32:21 +02:00
|
|
|
}
|
|
|
|
|
2013-07-14 10:35:56 +02:00
|
|
|
int add_files_to_cache(const char *prefix,
|
|
|
|
const struct pathspec *pathspec, int flags)
|
git add: rework the logic to warn "git add <pathspec>..." default change
The earlier logic to warn against "git add subdir" that is run
without "-A" or "--no-all" was only to check any <pathspec> given
exactly spells a directory name that (still) exists on the
filesystem. This had number of problems:
* "git add '*dir'" (note that the wildcard is hidden from the
shell) would not trigger the warning.
* "git add '*.py'" would behave differently between the current
version of Git and Git 2.0 for the same reason as "subdir", but
would not trigger the warning.
* "git add dir" for a submodule "dir" would just update the index
entry for the submodule "dir" without ever recursing into it, and
use of "-A" or "--no-all" would matter. But the logic only
checks the directory-ness of "dir" and gives an unnecessary
warning.
Rework the logic to detect the case where the behaviour will be
different in Git 2.0, and issue a warning only when it matters.
Even with the code before this warning, "git add subdir" will have
to traverse the directory in order to find _new_ files the index
does not know about _anyway_, so we can do this check without adding
an extra pass to find if <pathspec> matches any removed file.
This essentially updates the "add_files_to_cache()" public API to
"update_files_in_cache()" API that is internal to "git add", because
with the "--all" option, the function is no longer about "adding"
paths to the cache, but is also used to remove them.
There are other callers of the former from "checkout" (used when
"checkout -m" prepares the temporary tree that represents the local
modifications to be merged) and "commit" ("commit --include" that
picks up local changes in addition to what is in the index). Since
ADD_CACHE_IGNORE_ERRORS (aka "--no-all") is not used by either of
them, once dust settles after Git 2.0 and the warning becomes
unnecessary, we may want to unify these two functions again.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-04-17 21:32:21 +02:00
|
|
|
{
|
|
|
|
struct update_callback_data data;
|
|
|
|
|
|
|
|
memset(&data, 0, sizeof(data));
|
|
|
|
data.flags = flags;
|
|
|
|
update_files_in_cache(prefix, pathspec, &data);
|
Remove diff machinery dependency from read-cache
Exal Sibeaz pointed out that some git files are way too big, and that
add_files_to_cache() brings in all the diff machinery to any git binary
that needs the basic git SHA1 object operations from read-cache.c. Which
is pretty much all of them.
It's doubly silly, since add_files_to_cache() is only used by builtin
programs (add, checkout and commit), so it's fairly easily fixed by just
moving the thing to builtin-add.c, and avoiding the dependency entirely.
I initially argued to Exal that it would probably be best to try to depend
on smart compilers and linkers, but after spending some time trying to
make -ffunction-sections work and giving up, I think Exal was right, and
the fix is to just do some trivial cleanups like this.
This trivial cleanup results in pretty stunning file size differences.
The diff machinery really is mostly used by just the builtin programs, and
you have things like these trivial before-and-after numbers:
-rwxr-xr-x 1 torvalds torvalds 1727420 2010-01-21 10:53 git-hash-object
-rwxrwxr-x 1 torvalds torvalds 940265 2010-01-21 11:16 git-hash-object
Now, I'm not saying that 940kB is good either, but that's mostly all the
debug information - you can see the real code with 'size':
text data bss dec hex filename
418675 3920 127408 550003 86473 git-hash-object (before)
230650 2288 111728 344666 5425a git-hash-object (after)
ie we have a nice 24% size reduction from this trivial cleanup.
It's not just that one file either. I get:
[torvalds@nehalem git]$ du -s /home/torvalds/libexec/git-core
45640 /home/torvalds/libexec/git-core (before)
33508 /home/torvalds/libexec/git-core (after)
so we're talking 12MB of diskspace here.
(Of course, stripping all the binaries brings the 33MB down to 9MB, so the
whole debug information thing is still the bulk of it all, but that's a
separate issue entirely)
Now, I'm sure there are other things we should do, and changing our
compiler flags from -O2 to -Os would bring the text size down by an
additional almost 20%, but this thing Exal pointed out seems to be some
good low-hanging fruit.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2010-01-21 20:37:38 +01:00
|
|
|
return !!data.add_errors;
|
|
|
|
}
|
|
|
|
|
2013-03-19 23:51:34 +01:00
|
|
|
#define WARN_IMPLICIT_DOT (1u << 0)
|
2013-07-14 10:36:00 +02:00
|
|
|
static char *prune_directory(struct dir_struct *dir, struct pathspec *pathspec,
|
2013-03-19 23:51:34 +01:00
|
|
|
int prefix, unsigned flag)
|
2006-05-17 18:33:32 +02:00
|
|
|
{
|
2006-05-17 22:23:19 +02:00
|
|
|
char *seen;
|
2013-07-14 10:36:00 +02:00
|
|
|
int i;
|
2006-05-17 18:33:32 +02:00
|
|
|
struct dir_entry **src, **dst;
|
|
|
|
|
2013-07-14 10:36:00 +02:00
|
|
|
seen = xcalloc(pathspec->nr, 1);
|
2006-05-17 22:23:19 +02:00
|
|
|
|
2006-05-17 18:33:32 +02:00
|
|
|
src = dst = dir->entries;
|
|
|
|
i = dir->nr;
|
|
|
|
while (--i >= 0) {
|
|
|
|
struct dir_entry *entry = *src++;
|
2013-07-14 10:36:00 +02:00
|
|
|
if (match_pathspec_depth(pathspec, entry->name, entry->len,
|
|
|
|
prefix, seen))
|
2006-12-29 20:01:31 +01:00
|
|
|
*dst++ = entry;
|
2013-03-19 23:51:34 +01:00
|
|
|
else if (flag & WARN_IMPLICIT_DOT)
|
|
|
|
/*
|
|
|
|
* "git add -A" was run from a subdirectory with a
|
|
|
|
* new file outside that directory.
|
|
|
|
*
|
|
|
|
* "git add -A" will behave like "git add -A :/"
|
|
|
|
* instead of "git add -A ." in the future.
|
|
|
|
* Warn about the coming behavior change.
|
|
|
|
*/
|
|
|
|
warn_pathless_add();
|
2006-05-17 18:33:32 +02:00
|
|
|
}
|
|
|
|
dir->nr = dst - dir->entries;
|
2013-07-14 10:36:00 +02:00
|
|
|
add_pathspec_matches_against_index(pathspec, seen);
|
2010-02-09 23:30:49 +01:00
|
|
|
return seen;
|
2006-05-17 18:33:32 +02:00
|
|
|
}
|
|
|
|
|
2013-07-14 10:35:54 +02:00
|
|
|
static void refresh(int verbose, const struct pathspec *pathspec)
|
2007-08-11 23:59:01 +02:00
|
|
|
{
|
|
|
|
char *seen;
|
2013-07-14 10:35:54 +02:00
|
|
|
int i;
|
2007-08-11 23:59:01 +02:00
|
|
|
|
2013-07-14 10:35:54 +02:00
|
|
|
seen = xcalloc(pathspec->nr, 1);
|
2009-08-21 10:57:58 +02:00
|
|
|
refresh_index(&the_index, verbose ? REFRESH_IN_PORCELAIN : REFRESH_QUIET,
|
2011-02-23 00:41:33 +01:00
|
|
|
pathspec, seen, _("Unstaged changes after refreshing the index:"));
|
2013-07-14 10:35:54 +02:00
|
|
|
for (i = 0; i < pathspec->nr; i++) {
|
2007-08-11 23:59:01 +02:00
|
|
|
if (!seen[i])
|
2013-07-14 10:35:54 +02:00
|
|
|
die(_("pathspec '%s' did not match any files"),
|
|
|
|
pathspec->items[i].match);
|
2007-08-11 23:59:01 +02:00
|
|
|
}
|
2007-10-29 08:00:33 +01:00
|
|
|
free(seen);
|
2007-08-11 23:59:01 +02:00
|
|
|
}
|
|
|
|
|
2009-08-13 14:29:41 +02:00
|
|
|
int run_add_interactive(const char *revision, const char *patch_mode,
|
2013-07-14 10:35:50 +02:00
|
|
|
const struct pathspec *pathspec)
|
2007-09-18 02:06:44 +02:00
|
|
|
{
|
2013-07-14 10:35:50 +02:00
|
|
|
int status, ac, i;
|
2007-11-25 19:10:10 +01:00
|
|
|
const char **args;
|
|
|
|
|
2013-07-14 10:35:50 +02:00
|
|
|
args = xcalloc(sizeof(const char *), (pathspec->nr + 6));
|
2007-11-25 14:15:42 +01:00
|
|
|
ac = 0;
|
|
|
|
args[ac++] = "add--interactive";
|
2009-08-13 14:29:41 +02:00
|
|
|
if (patch_mode)
|
|
|
|
args[ac++] = patch_mode;
|
|
|
|
if (revision)
|
|
|
|
args[ac++] = revision;
|
2007-11-25 14:15:42 +01:00
|
|
|
args[ac++] = "--";
|
2013-07-14 10:35:50 +02:00
|
|
|
for (i = 0; i < pathspec->nr; i++)
|
|
|
|
/* pass original pathspec, to be re-parsed */
|
|
|
|
args[ac++] = pathspec->items[i].original;
|
2007-11-22 01:02:52 +01:00
|
|
|
|
|
|
|
status = run_command_v_opt(args, RUN_GIT_CMD);
|
|
|
|
free(args);
|
|
|
|
return status;
|
2007-09-18 02:06:44 +02:00
|
|
|
}
|
|
|
|
|
2011-05-07 19:58:07 +02:00
|
|
|
int interactive_add(int argc, const char **argv, const char *prefix, int patch)
|
2009-08-13 14:29:41 +02:00
|
|
|
{
|
2013-07-14 10:35:46 +02:00
|
|
|
struct pathspec pathspec;
|
2009-08-13 14:29:41 +02:00
|
|
|
|
2013-07-14 10:35:46 +02:00
|
|
|
/*
|
|
|
|
* git-add--interactive itself does not parse pathspec. It
|
|
|
|
* simply passes the pathspec to other builtin commands. Let's
|
|
|
|
* hope all of them support all magic, or we'll need to limit
|
2013-07-14 10:35:50 +02:00
|
|
|
* the magic here.
|
2013-07-14 10:35:46 +02:00
|
|
|
*/
|
|
|
|
parse_pathspec(&pathspec, PATHSPEC_ALL_MAGIC & ~PATHSPEC_FROMTOP,
|
|
|
|
PATHSPEC_PREFER_FULL |
|
2013-07-14 10:35:50 +02:00
|
|
|
PATHSPEC_SYMLINK_LEADING_PATH |
|
|
|
|
PATHSPEC_PREFIX_ORIGIN,
|
2013-07-14 10:35:46 +02:00
|
|
|
prefix, argv);
|
2009-08-13 14:29:41 +02:00
|
|
|
|
|
|
|
return run_add_interactive(NULL,
|
2011-05-07 19:58:07 +02:00
|
|
|
patch ? "--patch" : NULL,
|
2013-07-14 10:35:50 +02:00
|
|
|
&pathspec);
|
2009-08-13 14:29:41 +02:00
|
|
|
}
|
|
|
|
|
2009-06-18 19:28:43 +02:00
|
|
|
static int edit_patch(int argc, const char **argv, const char *prefix)
|
git-add: introduce --edit (to edit the diff vs. the index)
With "git add -e [<files>]", Git will fire up an editor with the current
diff relative to the index (i.e. what you would get with "git diff
[<files>]").
Now you can edit the patch as much as you like, including adding/removing
lines, editing the text, whatever. Make sure, though, that the first
character of the hunk lines is still a space, a plus or a minus.
After you closed the editor, Git will adjust the line counts of the hunks
if necessary, thanks to the --recount option of apply, and commit the
patch. Except if you deleted everything, in which case nothing happens
(for obvious reasons).
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-04-08 23:30:24 +02:00
|
|
|
{
|
2012-09-04 19:30:21 +02:00
|
|
|
char *file = git_pathdup("ADD_EDIT.patch");
|
git-add: introduce --edit (to edit the diff vs. the index)
With "git add -e [<files>]", Git will fire up an editor with the current
diff relative to the index (i.e. what you would get with "git diff
[<files>]").
Now you can edit the patch as much as you like, including adding/removing
lines, editing the text, whatever. Make sure, though, that the first
character of the hunk lines is still a space, a plus or a minus.
After you closed the editor, Git will adjust the line counts of the hunks
if necessary, thanks to the --recount option of apply, and commit the
patch. Except if you deleted everything, in which case nothing happens
(for obvious reasons).
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-04-08 23:30:24 +02:00
|
|
|
const char *apply_argv[] = { "apply", "--recount", "--cached",
|
2010-05-14 11:31:33 +02:00
|
|
|
NULL, NULL };
|
git-add: introduce --edit (to edit the diff vs. the index)
With "git add -e [<files>]", Git will fire up an editor with the current
diff relative to the index (i.e. what you would get with "git diff
[<files>]").
Now you can edit the patch as much as you like, including adding/removing
lines, editing the text, whatever. Make sure, though, that the first
character of the hunk lines is still a space, a plus or a minus.
After you closed the editor, Git will adjust the line counts of the hunks
if necessary, thanks to the --recount option of apply, and commit the
patch. Except if you deleted everything, in which case nothing happens
(for obvious reasons).
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-04-08 23:30:24 +02:00
|
|
|
struct child_process child;
|
|
|
|
struct rev_info rev;
|
|
|
|
int out;
|
|
|
|
struct stat st;
|
|
|
|
|
2010-05-14 11:31:33 +02:00
|
|
|
apply_argv[3] = file;
|
|
|
|
|
git-add: introduce --edit (to edit the diff vs. the index)
With "git add -e [<files>]", Git will fire up an editor with the current
diff relative to the index (i.e. what you would get with "git diff
[<files>]").
Now you can edit the patch as much as you like, including adding/removing
lines, editing the text, whatever. Make sure, though, that the first
character of the hunk lines is still a space, a plus or a minus.
After you closed the editor, Git will adjust the line counts of the hunks
if necessary, thanks to the --recount option of apply, and commit the
patch. Except if you deleted everything, in which case nothing happens
(for obvious reasons).
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-04-08 23:30:24 +02:00
|
|
|
git_config(git_diff_basic_config, NULL); /* no "diff" UI options */
|
|
|
|
|
|
|
|
if (read_cache() < 0)
|
2011-02-23 00:41:29 +01:00
|
|
|
die (_("Could not read the index"));
|
git-add: introduce --edit (to edit the diff vs. the index)
With "git add -e [<files>]", Git will fire up an editor with the current
diff relative to the index (i.e. what you would get with "git diff
[<files>]").
Now you can edit the patch as much as you like, including adding/removing
lines, editing the text, whatever. Make sure, though, that the first
character of the hunk lines is still a space, a plus or a minus.
After you closed the editor, Git will adjust the line counts of the hunks
if necessary, thanks to the --recount option of apply, and commit the
patch. Except if you deleted everything, in which case nothing happens
(for obvious reasons).
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-04-08 23:30:24 +02:00
|
|
|
|
|
|
|
init_revisions(&rev, prefix);
|
|
|
|
rev.diffopt.context = 7;
|
|
|
|
|
|
|
|
argc = setup_revisions(argc, argv, &rev, NULL);
|
|
|
|
rev.diffopt.output_format = DIFF_FORMAT_PATCH;
|
2012-02-07 05:05:48 +01:00
|
|
|
DIFF_OPT_SET(&rev.diffopt, IGNORE_DIRTY_SUBMODULES);
|
2012-07-10 08:37:22 +02:00
|
|
|
out = open(file, O_CREAT | O_WRONLY, 0666);
|
git-add: introduce --edit (to edit the diff vs. the index)
With "git add -e [<files>]", Git will fire up an editor with the current
diff relative to the index (i.e. what you would get with "git diff
[<files>]").
Now you can edit the patch as much as you like, including adding/removing
lines, editing the text, whatever. Make sure, though, that the first
character of the hunk lines is still a space, a plus or a minus.
After you closed the editor, Git will adjust the line counts of the hunks
if necessary, thanks to the --recount option of apply, and commit the
patch. Except if you deleted everything, in which case nothing happens
(for obvious reasons).
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-04-08 23:30:24 +02:00
|
|
|
if (out < 0)
|
2011-02-23 00:41:29 +01:00
|
|
|
die (_("Could not open '%s' for writing."), file);
|
2009-09-12 10:43:27 +02:00
|
|
|
rev.diffopt.file = xfdopen(out, "w");
|
git-add: introduce --edit (to edit the diff vs. the index)
With "git add -e [<files>]", Git will fire up an editor with the current
diff relative to the index (i.e. what you would get with "git diff
[<files>]").
Now you can edit the patch as much as you like, including adding/removing
lines, editing the text, whatever. Make sure, though, that the first
character of the hunk lines is still a space, a plus or a minus.
After you closed the editor, Git will adjust the line counts of the hunks
if necessary, thanks to the --recount option of apply, and commit the
patch. Except if you deleted everything, in which case nothing happens
(for obvious reasons).
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-04-08 23:30:24 +02:00
|
|
|
rev.diffopt.close_file = 1;
|
|
|
|
if (run_diff_files(&rev, 0))
|
2011-02-23 00:41:29 +01:00
|
|
|
die (_("Could not write patch"));
|
git-add: introduce --edit (to edit the diff vs. the index)
With "git add -e [<files>]", Git will fire up an editor with the current
diff relative to the index (i.e. what you would get with "git diff
[<files>]").
Now you can edit the patch as much as you like, including adding/removing
lines, editing the text, whatever. Make sure, though, that the first
character of the hunk lines is still a space, a plus or a minus.
After you closed the editor, Git will adjust the line counts of the hunks
if necessary, thanks to the --recount option of apply, and commit the
patch. Except if you deleted everything, in which case nothing happens
(for obvious reasons).
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-04-08 23:30:24 +02:00
|
|
|
|
|
|
|
launch_editor(file, NULL, NULL);
|
|
|
|
|
|
|
|
if (stat(file, &st))
|
2011-02-23 00:41:29 +01:00
|
|
|
die_errno(_("Could not stat '%s'"), file);
|
git-add: introduce --edit (to edit the diff vs. the index)
With "git add -e [<files>]", Git will fire up an editor with the current
diff relative to the index (i.e. what you would get with "git diff
[<files>]").
Now you can edit the patch as much as you like, including adding/removing
lines, editing the text, whatever. Make sure, though, that the first
character of the hunk lines is still a space, a plus or a minus.
After you closed the editor, Git will adjust the line counts of the hunks
if necessary, thanks to the --recount option of apply, and commit the
patch. Except if you deleted everything, in which case nothing happens
(for obvious reasons).
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-04-08 23:30:24 +02:00
|
|
|
if (!st.st_size)
|
2011-02-23 00:41:29 +01:00
|
|
|
die(_("Empty patch. Aborted."));
|
git-add: introduce --edit (to edit the diff vs. the index)
With "git add -e [<files>]", Git will fire up an editor with the current
diff relative to the index (i.e. what you would get with "git diff
[<files>]").
Now you can edit the patch as much as you like, including adding/removing
lines, editing the text, whatever. Make sure, though, that the first
character of the hunk lines is still a space, a plus or a minus.
After you closed the editor, Git will adjust the line counts of the hunks
if necessary, thanks to the --recount option of apply, and commit the
patch. Except if you deleted everything, in which case nothing happens
(for obvious reasons).
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-04-08 23:30:24 +02:00
|
|
|
|
|
|
|
memset(&child, 0, sizeof(child));
|
|
|
|
child.git_cmd = 1;
|
|
|
|
child.argv = apply_argv;
|
|
|
|
if (run_command(&child))
|
2011-02-23 00:41:29 +01:00
|
|
|
die (_("Could not apply '%s'"), file);
|
git-add: introduce --edit (to edit the diff vs. the index)
With "git add -e [<files>]", Git will fire up an editor with the current
diff relative to the index (i.e. what you would get with "git diff
[<files>]").
Now you can edit the patch as much as you like, including adding/removing
lines, editing the text, whatever. Make sure, though, that the first
character of the hunk lines is still a space, a plus or a minus.
After you closed the editor, Git will adjust the line counts of the hunks
if necessary, thanks to the --recount option of apply, and commit the
patch. Except if you deleted everything, in which case nothing happens
(for obvious reasons).
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-04-08 23:30:24 +02:00
|
|
|
|
|
|
|
unlink(file);
|
2012-09-04 19:30:21 +02:00
|
|
|
free(file);
|
git-add: introduce --edit (to edit the diff vs. the index)
With "git add -e [<files>]", Git will fire up an editor with the current
diff relative to the index (i.e. what you would get with "git diff
[<files>]").
Now you can edit the patch as much as you like, including adding/removing
lines, editing the text, whatever. Make sure, though, that the first
character of the hunk lines is still a space, a plus or a minus.
After you closed the editor, Git will adjust the line counts of the hunks
if necessary, thanks to the --recount option of apply, and commit the
patch. Except if you deleted everything, in which case nothing happens
(for obvious reasons).
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-04-08 23:30:24 +02:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2006-06-06 21:51:49 +02:00
|
|
|
static struct lock_file lock_file;
|
2006-05-17 18:33:32 +02:00
|
|
|
|
2007-08-29 00:41:23 +02:00
|
|
|
static const char ignore_error[] =
|
2011-02-23 00:41:30 +01:00
|
|
|
N_("The following paths are ignored by one of your .gitignore files:\n");
|
2006-12-26 02:46:38 +01:00
|
|
|
|
2013-03-09 07:21:13 +01:00
|
|
|
static int verbose, show_only, ignored_too, refresh_only;
|
2011-04-19 21:18:20 +02:00
|
|
|
static int ignore_add_errors, intent_to_add, ignore_missing;
|
|
|
|
|
|
|
|
#define ADDREMOVE_DEFAULT 0 /* Change to 1 in Git 2.0 */
|
|
|
|
static int addremove = ADDREMOVE_DEFAULT;
|
|
|
|
static int addremove_explicit = -1; /* unspecified */
|
2007-10-03 23:45:02 +02:00
|
|
|
|
2013-04-22 22:29:20 +02:00
|
|
|
static int ignore_removal_cb(const struct option *opt, const char *arg, int unset)
|
|
|
|
{
|
|
|
|
/* if we are told to ignore, we are not adding removals */
|
|
|
|
*(int *)opt->value = !unset ? 0 : 1;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2007-10-03 23:45:02 +02:00
|
|
|
static struct option builtin_add_options[] = {
|
2012-08-20 14:31:52 +02:00
|
|
|
OPT__DRY_RUN(&show_only, N_("dry run")),
|
|
|
|
OPT__VERBOSE(&verbose, N_("be verbose")),
|
2007-10-03 23:45:02 +02:00
|
|
|
OPT_GROUP(""),
|
2013-03-09 07:21:13 +01:00
|
|
|
OPT_BOOL('i', "interactive", &add_interactive, N_("interactive picking")),
|
|
|
|
OPT_BOOL('p', "patch", &patch_interactive, N_("select hunks interactively")),
|
|
|
|
OPT_BOOL('e', "edit", &edit_interactive, N_("edit current diff and apply")),
|
2012-08-20 14:31:52 +02:00
|
|
|
OPT__FORCE(&ignored_too, N_("allow adding otherwise ignored files")),
|
2013-03-09 07:21:13 +01:00
|
|
|
OPT_BOOL('u', "update", &take_worktree_changes, N_("update tracked files")),
|
|
|
|
OPT_BOOL('N', "intent-to-add", &intent_to_add, N_("record only the fact that the path will be added later")),
|
2011-04-19 21:18:20 +02:00
|
|
|
OPT_BOOL('A', "all", &addremove_explicit, N_("add changes from all tracked and untracked files")),
|
2013-04-22 22:29:20 +02:00
|
|
|
{ OPTION_CALLBACK, 0, "ignore-removal", &addremove_explicit,
|
|
|
|
NULL /* takes no arguments */,
|
|
|
|
N_("ignore paths removed in the working tree (same as --no-all)"),
|
|
|
|
PARSE_OPT_NOARG, ignore_removal_cb },
|
2013-03-09 07:21:13 +01:00
|
|
|
OPT_BOOL( 0 , "refresh", &refresh_only, N_("don't add, only refresh the index")),
|
|
|
|
OPT_BOOL( 0 , "ignore-errors", &ignore_add_errors, N_("just skip files which cannot be added because of errors")),
|
|
|
|
OPT_BOOL( 0 , "ignore-missing", &ignore_missing, N_("check if - even missing - files are ignored in dry run")),
|
2007-10-03 23:45:02 +02:00
|
|
|
OPT_END(),
|
|
|
|
};
|
|
|
|
|
2008-05-25 23:25:02 +02:00
|
|
|
static int add_config(const char *var, const char *value, void *cb)
|
2008-05-12 19:59:23 +02:00
|
|
|
{
|
2011-05-14 22:19:21 +02:00
|
|
|
if (!strcmp(var, "add.ignoreerrors") ||
|
|
|
|
!strcmp(var, "add.ignore-errors")) {
|
2008-05-12 19:59:23 +02:00
|
|
|
ignore_add_errors = git_config_bool(var, value);
|
|
|
|
return 0;
|
|
|
|
}
|
2008-05-25 23:25:02 +02:00
|
|
|
return git_default_config(var, value, cb);
|
2008-05-12 19:59:23 +02:00
|
|
|
}
|
|
|
|
|
2008-07-20 04:22:25 +02:00
|
|
|
static int add_files(struct dir_struct *dir, int flags)
|
|
|
|
{
|
|
|
|
int i, exit_status = 0;
|
|
|
|
|
|
|
|
if (dir->ignored_nr) {
|
2011-02-23 00:41:30 +01:00
|
|
|
fprintf(stderr, _(ignore_error));
|
2008-07-20 04:22:25 +02:00
|
|
|
for (i = 0; i < dir->ignored_nr; i++)
|
|
|
|
fprintf(stderr, "%s\n", dir->ignored[i]->name);
|
2011-02-23 00:41:30 +01:00
|
|
|
fprintf(stderr, _("Use -f if you really want to add them.\n"));
|
|
|
|
die(_("no files added"));
|
2008-07-20 04:22:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 0; i < dir->nr; i++)
|
|
|
|
if (add_file_to_cache(dir->entries[i]->name, flags)) {
|
|
|
|
if (!ignore_add_errors)
|
2011-02-23 00:41:29 +01:00
|
|
|
die(_("adding files failed"));
|
2008-07-20 04:22:25 +02:00
|
|
|
exit_status = 1;
|
|
|
|
}
|
|
|
|
return exit_status;
|
|
|
|
}
|
|
|
|
|
2006-07-29 07:44:25 +02:00
|
|
|
int cmd_add(int argc, const char **argv, const char *prefix)
|
2006-05-17 18:33:32 +02:00
|
|
|
{
|
2008-05-12 19:58:10 +02:00
|
|
|
int exit_status = 0;
|
2008-07-20 04:22:25 +02:00
|
|
|
int newfd;
|
2013-07-14 10:35:46 +02:00
|
|
|
struct pathspec pathspec;
|
2006-05-17 18:33:32 +02:00
|
|
|
struct dir_struct dir;
|
2008-05-22 23:59:42 +02:00
|
|
|
int flags;
|
2008-07-20 04:22:25 +02:00
|
|
|
int add_new_files;
|
|
|
|
int require_pathspec;
|
2010-02-09 23:30:49 +01:00
|
|
|
char *seen = NULL;
|
2013-03-19 23:50:50 +01:00
|
|
|
int implicit_dot = 0;
|
git add: rework the logic to warn "git add <pathspec>..." default change
The earlier logic to warn against "git add subdir" that is run
without "-A" or "--no-all" was only to check any <pathspec> given
exactly spells a directory name that (still) exists on the
filesystem. This had number of problems:
* "git add '*dir'" (note that the wildcard is hidden from the
shell) would not trigger the warning.
* "git add '*.py'" would behave differently between the current
version of Git and Git 2.0 for the same reason as "subdir", but
would not trigger the warning.
* "git add dir" for a submodule "dir" would just update the index
entry for the submodule "dir" without ever recursing into it, and
use of "-A" or "--no-all" would matter. But the logic only
checks the directory-ness of "dir" and gives an unnecessary
warning.
Rework the logic to detect the case where the behaviour will be
different in Git 2.0, and issue a warning only when it matters.
Even with the code before this warning, "git add subdir" will have
to traverse the directory in order to find _new_ files the index
does not know about _anyway_, so we can do this check without adding
an extra pass to find if <pathspec> matches any removed file.
This essentially updates the "add_files_to_cache()" public API to
"update_files_in_cache()" API that is internal to "git add", because
with the "--all" option, the function is no longer about "adding"
paths to the cache, but is also used to remove them.
There are other callers of the former from "checkout" (used when
"checkout -m" prepares the temporary tree that represents the local
modifications to be merged) and "commit" ("commit --include" that
picks up local changes in addition to what is in the index). Since
ADD_CACHE_IGNORE_ERRORS (aka "--no-all") is not used by either of
them, once dust settles after Git 2.0 and the warning becomes
unnecessary, we may want to unify these two functions again.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-04-17 21:32:21 +02:00
|
|
|
struct update_callback_data update_data;
|
git-add --interactive
A script to be driven when the user says "git add --interactive"
is introduced.
When it is run, first it runs its internal 'status' command to
show the current status, and then goes into its internactive
command loop.
The command loop shows the list of subcommands available, and
gives a prompt "What now> ". In general, when the prompt ends
with a single '>', you can pick only one of the choices given
and type return, like this:
*** Commands ***
1: status 2: update 3: revert 4: add untracked
5: patch 6: diff 7: quit 8: help
What now> 1
You also could say "s" or "sta" or "status" above as long as the
choice is unique.
The main command loop has 6 subcommands (plus help and quit).
* 'status' shows the change between HEAD and index (i.e. what
will be committed if you say "git commit"), and between index
and working tree files (i.e. what you could stage further
before "git commit" using "git-add") for each path. A sample
output looks like this:
staged unstaged path
1: binary nothing foo.png
2: +403/-35 +1/-1 git-add--interactive.perl
It shows that foo.png has differences from HEAD (but that is
binary so line count cannot be shown) and there is no
difference between indexed copy and the working tree
version (if the working tree version were also different,
'binary' would have been shown in place of 'nothing'). The
other file, git-add--interactive.perl, has 403 lines added
and 35 lines deleted if you commit what is in the index, but
working tree file has further modifications (one addition and
one deletion).
* 'update' shows the status information and gives prompt
"Update>>". When the prompt ends with double '>>', you can
make more than one selection, concatenated with whitespace or
comma. Also you can say ranges. E.g. "2-5 7,9" to choose
2,3,4,5,7,9 from the list. You can say '*' to choose
everything.
What you chose are then highlighted with '*', like this:
staged unstaged path
1: binary nothing foo.png
* 2: +403/-35 +1/-1 git-add--interactive.perl
To remove selection, prefix the input with - like this:
Update>> -2
After making the selection, answer with an empty line to
stage the contents of working tree files for selected paths
in the index.
* 'revert' has a very similar UI to 'update', and the staged
information for selected paths are reverted to that of the
HEAD version. Reverting new paths makes them untracked.
* 'add untracked' has a very similar UI to 'update' and
'revert', and lets you add untracked paths to the index.
* 'patch' lets you choose one path out of 'status' like
selection. After choosing the path, it presents diff between
the index and the working tree file and asks you if you want
to stage the change of each hunk. You can say:
y - add the change from that hunk to index
n - do not add the change from that hunk to index
a - add the change from that hunk and all the rest to index
d - do not the change from that hunk nor any of the rest to index
j - do not decide on this hunk now, and view the next
undecided hunk
J - do not decide on this hunk now, and view the next hunk
k - do not decide on this hunk now, and view the previous
undecided hunk
K - do not decide on this hunk now, and view the previous hunk
After deciding the fate for all hunks, if there is any hunk
that was chosen, the index is updated with the selected hunks.
* 'diff' lets you review what will be committed (i.e. between
HEAD and index).
This is still rough, but does everything except a few things I
think are needed.
* 'patch' should be able to allow splitting a hunk into
multiple hunks.
* 'patch' does not adjust the line offsets @@ -k,l +m,n @@
in the hunk header. This does not have major problem in
practice, but it _should_ do the adjustment.
* It does not have any explicit support for a merge in
progress; it may not work at all.
Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-12-11 05:55:50 +01:00
|
|
|
|
2009-06-18 11:17:54 +02:00
|
|
|
git_config(add_config, NULL);
|
|
|
|
|
2009-05-23 20:53:12 +02:00
|
|
|
argc = parse_options(argc, argv, prefix, builtin_add_options,
|
git-add: introduce --edit (to edit the diff vs. the index)
With "git add -e [<files>]", Git will fire up an editor with the current
diff relative to the index (i.e. what you would get with "git diff
[<files>]").
Now you can edit the patch as much as you like, including adding/removing
lines, editing the text, whatever. Make sure, though, that the first
character of the hunk lines is still a space, a plus or a minus.
After you closed the editor, Git will adjust the line counts of the hunks
if necessary, thanks to the --recount option of apply, and commit the
patch. Except if you deleted everything, in which case nothing happens
(for obvious reasons).
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-04-08 23:30:24 +02:00
|
|
|
builtin_add_usage, PARSE_OPT_KEEP_ARGV0);
|
2007-11-25 14:15:42 +01:00
|
|
|
if (patch_interactive)
|
|
|
|
add_interactive = 1;
|
2007-11-22 01:02:52 +01:00
|
|
|
if (add_interactive)
|
2011-05-07 19:58:07 +02:00
|
|
|
exit(interactive_add(argc - 1, argv + 1, prefix, patch_interactive));
|
2006-05-17 18:33:32 +02:00
|
|
|
|
git-add: introduce --edit (to edit the diff vs. the index)
With "git add -e [<files>]", Git will fire up an editor with the current
diff relative to the index (i.e. what you would get with "git diff
[<files>]").
Now you can edit the patch as much as you like, including adding/removing
lines, editing the text, whatever. Make sure, though, that the first
character of the hunk lines is still a space, a plus or a minus.
After you closed the editor, Git will adjust the line counts of the hunks
if necessary, thanks to the --recount option of apply, and commit the
patch. Except if you deleted everything, in which case nothing happens
(for obvious reasons).
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-04-08 23:30:24 +02:00
|
|
|
if (edit_interactive)
|
|
|
|
return(edit_patch(argc, argv, prefix));
|
|
|
|
argc--;
|
|
|
|
argv++;
|
|
|
|
|
2011-04-19 21:18:20 +02:00
|
|
|
if (0 <= addremove_explicit)
|
|
|
|
addremove = addremove_explicit;
|
|
|
|
else if (take_worktree_changes && ADDREMOVE_DEFAULT)
|
|
|
|
addremove = 0; /* "-u" was given but not "-A" */
|
|
|
|
|
git-add --all: add all files
People sometimes find that "git add -u && git add ." are 13 keystrokes too
many. This reduces it by nine.
The support of this has been very low priority for me personally, because
I almost never do "git add ." in a directory with already tracked files,
and in a new directory, there is no point saying "git add -u".
However, for two types of people (that are very different from me), this
mode of operation may make sense and there is no reason to leave it
unsupported. That is:
(1) If you are extremely well disciplined and keep perfect .gitignore, it
always is safe to say "git add ."; or
(2) If you are extremely undisciplined and do not even know what files
you created, and you do not very much care what goes in your history,
it does not matter if "git add ." included everything.
So there it is, although I suspect I will not use it myself, ever.
It will be too much of a change that is against the expectation of the
existing users to allow "git commit -a" to include untracked files, and
it would be inconsistent if we named this new option "-a", so the short
option is "-A". We _might_ want to later add "git commit -A" but that is
a separate topic.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-07-20 04:51:11 +02:00
|
|
|
if (addremove && take_worktree_changes)
|
2011-02-23 00:41:29 +01:00
|
|
|
die(_("-A and -u are mutually incompatible"));
|
2011-04-19 21:18:20 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Warn when "git add pathspec..." was given without "-u" or "-A"
|
git add: rework the logic to warn "git add <pathspec>..." default change
The earlier logic to warn against "git add subdir" that is run
without "-A" or "--no-all" was only to check any <pathspec> given
exactly spells a directory name that (still) exists on the
filesystem. This had number of problems:
* "git add '*dir'" (note that the wildcard is hidden from the
shell) would not trigger the warning.
* "git add '*.py'" would behave differently between the current
version of Git and Git 2.0 for the same reason as "subdir", but
would not trigger the warning.
* "git add dir" for a submodule "dir" would just update the index
entry for the submodule "dir" without ever recursing into it, and
use of "-A" or "--no-all" would matter. But the logic only
checks the directory-ness of "dir" and gives an unnecessary
warning.
Rework the logic to detect the case where the behaviour will be
different in Git 2.0, and issue a warning only when it matters.
Even with the code before this warning, "git add subdir" will have
to traverse the directory in order to find _new_ files the index
does not know about _anyway_, so we can do this check without adding
an extra pass to find if <pathspec> matches any removed file.
This essentially updates the "add_files_to_cache()" public API to
"update_files_in_cache()" API that is internal to "git add", because
with the "--all" option, the function is no longer about "adding"
paths to the cache, but is also used to remove them.
There are other callers of the former from "checkout" (used when
"checkout -m" prepares the temporary tree that represents the local
modifications to be merged) and "commit" ("commit --include" that
picks up local changes in addition to what is in the index). Since
ADD_CACHE_IGNORE_ERRORS (aka "--no-all") is not used by either of
them, once dust settles after Git 2.0 and the warning becomes
unnecessary, we may want to unify these two functions again.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-04-17 21:32:21 +02:00
|
|
|
* and pathspec... covers a removed path.
|
2011-04-19 21:18:20 +02:00
|
|
|
*/
|
git add: rework the logic to warn "git add <pathspec>..." default change
The earlier logic to warn against "git add subdir" that is run
without "-A" or "--no-all" was only to check any <pathspec> given
exactly spells a directory name that (still) exists on the
filesystem. This had number of problems:
* "git add '*dir'" (note that the wildcard is hidden from the
shell) would not trigger the warning.
* "git add '*.py'" would behave differently between the current
version of Git and Git 2.0 for the same reason as "subdir", but
would not trigger the warning.
* "git add dir" for a submodule "dir" would just update the index
entry for the submodule "dir" without ever recursing into it, and
use of "-A" or "--no-all" would matter. But the logic only
checks the directory-ness of "dir" and gives an unnecessary
warning.
Rework the logic to detect the case where the behaviour will be
different in Git 2.0, and issue a warning only when it matters.
Even with the code before this warning, "git add subdir" will have
to traverse the directory in order to find _new_ files the index
does not know about _anyway_, so we can do this check without adding
an extra pass to find if <pathspec> matches any removed file.
This essentially updates the "add_files_to_cache()" public API to
"update_files_in_cache()" API that is internal to "git add", because
with the "--all" option, the function is no longer about "adding"
paths to the cache, but is also used to remove them.
There are other callers of the former from "checkout" (used when
"checkout -m" prepares the temporary tree that represents the local
modifications to be merged) and "commit" ("commit --include" that
picks up local changes in addition to what is in the index). Since
ADD_CACHE_IGNORE_ERRORS (aka "--no-all") is not used by either of
them, once dust settles after Git 2.0 and the warning becomes
unnecessary, we may want to unify these two functions again.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-04-17 21:32:21 +02:00
|
|
|
memset(&update_data, 0, sizeof(update_data));
|
|
|
|
if (!take_worktree_changes && addremove_explicit < 0)
|
|
|
|
update_data.warn_add_would_remove = 1;
|
2011-04-19 21:18:20 +02:00
|
|
|
|
|
|
|
if (!take_worktree_changes && addremove_explicit < 0 && argc)
|
|
|
|
/*
|
|
|
|
* Turn "git add pathspec..." to "git add -A pathspec..."
|
|
|
|
* in Git 2.0 but not yet
|
|
|
|
*/
|
|
|
|
; /* addremove = 1; */
|
|
|
|
|
2010-07-10 00:18:38 +02:00
|
|
|
if (!show_only && ignore_missing)
|
2011-02-23 00:41:29 +01:00
|
|
|
die(_("Option --ignore-missing can only be used together with --dry-run"));
|
add: warn when -u or -A is used without pathspec
Most Git commands that can be used with or without pathspec operate
tree-wide by default, the pathspec being used to restrict their
scope. A few exceptions are: 'git grep', 'git clean', 'git add -u'
and 'git add -A'. When run in a subdirectory without pathspec, they
operate only on paths in the current directory.
The inconsistency of 'git add -u' and 'git add -A' is particularly
problematic since other 'git add' subcommands (namely 'git add -p'
and 'git add -e') are tree-wide by default. It also means that "git
add -u && git commit" will record a state that is different from
what is recorded with "git commit -a".
Flipping the default now is unacceptable, so let's start training
users to type 'git add -u|-A :/' or 'git add -u|-A .' explicitly, to
prepare for the next steps:
* forbid 'git add -u|-A' without pathspec (like 'git add' without
option)
* much later, maybe, re-allow 'git add -u|-A' without pathspec, that
will add all tracked and modified files, or all files, tree-wide.
A nice side effect of this patch is that it makes the :/ magic
pathspec easier to discover for users.
When the command is called from the root of the tree, there is no
ambiguity and no need to change the behavior, hence no need to warn.
Signed-off-by: Matthieu Moy <Matthieu.Moy@imag.fr>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-01-28 10:16:33 +01:00
|
|
|
if (addremove) {
|
|
|
|
option_with_implicit_dot = "--all";
|
|
|
|
short_option_with_implicit_dot = "-A";
|
|
|
|
}
|
|
|
|
if (take_worktree_changes) {
|
|
|
|
option_with_implicit_dot = "--update";
|
|
|
|
short_option_with_implicit_dot = "-u";
|
|
|
|
}
|
|
|
|
if (option_with_implicit_dot && !argc) {
|
git-add --all: add all files
People sometimes find that "git add -u && git add ." are 13 keystrokes too
many. This reduces it by nine.
The support of this has been very low priority for me personally, because
I almost never do "git add ." in a directory with already tracked files,
and in a new directory, there is no point saying "git add -u".
However, for two types of people (that are very different from me), this
mode of operation may make sense and there is no reason to leave it
unsupported. That is:
(1) If you are extremely well disciplined and keep perfect .gitignore, it
always is safe to say "git add ."; or
(2) If you are extremely undisciplined and do not even know what files
you created, and you do not very much care what goes in your history,
it does not matter if "git add ." included everything.
So there it is, although I suspect I will not use it myself, ever.
It will be too much of a change that is against the expectation of the
existing users to allow "git commit -a" to include untracked files, and
it would be inconsistent if we named this new option "-a", so the short
option is "-A". We _might_ want to later add "git commit -A" but that is
a separate topic.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-07-20 04:51:11 +02:00
|
|
|
static const char *here[2] = { ".", NULL };
|
|
|
|
argc = 1;
|
|
|
|
argv = here;
|
2013-03-19 23:50:50 +01:00
|
|
|
implicit_dot = 1;
|
git-add --all: add all files
People sometimes find that "git add -u && git add ." are 13 keystrokes too
many. This reduces it by nine.
The support of this has been very low priority for me personally, because
I almost never do "git add ." in a directory with already tracked files,
and in a new directory, there is no point saying "git add -u".
However, for two types of people (that are very different from me), this
mode of operation may make sense and there is no reason to leave it
unsupported. That is:
(1) If you are extremely well disciplined and keep perfect .gitignore, it
always is safe to say "git add ."; or
(2) If you are extremely undisciplined and do not even know what files
you created, and you do not very much care what goes in your history,
it does not matter if "git add ." included everything.
So there it is, although I suspect I will not use it myself, ever.
It will be too much of a change that is against the expectation of the
existing users to allow "git commit -a" to include untracked files, and
it would be inconsistent if we named this new option "-a", so the short
option is "-A". We _might_ want to later add "git commit -A" but that is
a separate topic.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-07-20 04:51:11 +02:00
|
|
|
}
|
|
|
|
|
2008-07-20 04:22:25 +02:00
|
|
|
add_new_files = !take_worktree_changes && !refresh_only;
|
|
|
|
require_pathspec = !take_worktree_changes;
|
|
|
|
|
_GIT_INDEX_OUTPUT: allow plumbing to output to an alternative index file.
When defined, this allows plumbing commands that update the
index (add, apply, checkout-index, merge-recursive, mv,
read-tree, rm, update-index, and write-tree) to write their
resulting index to an alternative index file while holding a
lock to the original index file. With this, git-commit that
jumps the index does not have to make an extra copy of the index
file, and more importantly, it can do the update while holding
the lock on the index.
However, I think the interface to let an environment variable
specify the output is a mistake, as shown in the documentation.
If a curious user has the environment variable set to something
other than the file GIT_INDEX_FILE points at, almost everything
will break. This should instead be a command line parameter to
tell these plumbing commands to write the result in the named
file, to prevent stupid mistakes.
Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-04-01 08:09:02 +02:00
|
|
|
newfd = hold_locked_index(&lock_file, 1);
|
2006-05-17 18:33:32 +02:00
|
|
|
|
2008-05-22 23:59:42 +02:00
|
|
|
flags = ((verbose ? ADD_CACHE_VERBOSE : 0) |
|
2008-05-25 23:03:50 +02:00
|
|
|
(show_only ? ADD_CACHE_PRETEND : 0) |
|
2008-08-21 10:44:53 +02:00
|
|
|
(intent_to_add ? ADD_CACHE_INTENT : 0) |
|
builtin-add.c: optimize -A option and "git add ."
The earlier "git add -A" change was done in a quite inefficient
way (i.e. it is as unefficient as "git add -u && git add ." modulo
one fork/exec and read/write index).
When the user asks "git add .", we do not have to examine all paths
we encounter and perform the excluded() and dir_add_name()
processing, both of which are slower code and use slower data structure
by git standards, especially when the index is already populated.
Instead, we implement "git add $pathspec..." as:
- read the index;
- read_directory() to process untracked, unignored files the current
way, that is, recursively doing readdir(), filtering them by pathspec
and excluded(), queueing them via dir_add_name() and finally do
add_files(); and
- iterate over the index, filtering them by pathspec, and update only
the modified/type changed paths but not deleted ones.
And "git add -A" becomes exactly the same as above, modulo:
- missing $pathspec means "." instead of being an error; and
- "iterate over the index" part handles deleted ones as well,
i.e. exactly what the current update_callback() in builtin-add.c does.
In either case, because fill_directory() does not use read_directory() to
read everything in, we need to add an extra logic to iterate over the
index to catch mistyped pathspec.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-07-23 07:30:40 +02:00
|
|
|
(ignore_add_errors ? ADD_CACHE_IGNORE_ERRORS : 0) |
|
|
|
|
(!(addremove || take_worktree_changes)
|
2013-03-19 23:50:50 +01:00
|
|
|
? ADD_CACHE_IGNORE_REMOVAL : 0)) |
|
|
|
|
(implicit_dot ? ADD_CACHE_IMPLICIT_DOT : 0);
|
2008-05-22 23:59:42 +02:00
|
|
|
|
2008-07-20 04:22:25 +02:00
|
|
|
if (require_pathspec && argc == 0) {
|
2011-02-23 00:41:29 +01:00
|
|
|
fprintf(stderr, _("Nothing specified, nothing added.\n"));
|
|
|
|
fprintf(stderr, _("Maybe you wanted to say 'git add .'?\n"));
|
2006-12-20 22:06:46 +01:00
|
|
|
return 0;
|
|
|
|
}
|
2006-05-17 18:33:32 +02:00
|
|
|
|
2006-12-04 17:13:39 +01:00
|
|
|
if (read_cache() < 0)
|
2011-02-23 00:41:29 +01:00
|
|
|
die(_("index file corrupt"));
|
2013-07-14 10:35:46 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Check the "pathspec '%s' did not match any files" block
|
|
|
|
* below before enabling new magic.
|
|
|
|
*/
|
|
|
|
parse_pathspec(&pathspec, 0,
|
|
|
|
PATHSPEC_PREFER_FULL |
|
|
|
|
PATHSPEC_SYMLINK_LEADING_PATH |
|
|
|
|
PATHSPEC_STRIP_SUBMODULE_SLASH_EXPENSIVE,
|
|
|
|
prefix, argv);
|
2006-12-04 17:13:39 +01:00
|
|
|
|
2009-05-14 22:22:36 +02:00
|
|
|
if (add_new_files) {
|
|
|
|
int baselen;
|
2013-07-14 10:35:55 +02:00
|
|
|
struct pathspec empty_pathspec;
|
2009-05-14 22:22:36 +02:00
|
|
|
|
|
|
|
/* Set up the default git porcelain excludes */
|
|
|
|
memset(&dir, 0, sizeof(dir));
|
|
|
|
if (!ignored_too) {
|
|
|
|
dir.flags |= DIR_COLLECT_IGNORED;
|
|
|
|
setup_standard_excludes(&dir);
|
|
|
|
}
|
|
|
|
|
2013-07-14 10:35:55 +02:00
|
|
|
memset(&empty_pathspec, 0, sizeof(empty_pathspec));
|
builtin-add.c: optimize -A option and "git add ."
The earlier "git add -A" change was done in a quite inefficient
way (i.e. it is as unefficient as "git add -u && git add ." modulo
one fork/exec and read/write index).
When the user asks "git add .", we do not have to examine all paths
we encounter and perform the excluded() and dir_add_name()
processing, both of which are slower code and use slower data structure
by git standards, especially when the index is already populated.
Instead, we implement "git add $pathspec..." as:
- read the index;
- read_directory() to process untracked, unignored files the current
way, that is, recursively doing readdir(), filtering them by pathspec
and excluded(), queueing them via dir_add_name() and finally do
add_files(); and
- iterate over the index, filtering them by pathspec, and update only
the modified/type changed paths but not deleted ones.
And "git add -A" becomes exactly the same as above, modulo:
- missing $pathspec means "." instead of being an error; and
- "iterate over the index" part handles deleted ones as well,
i.e. exactly what the current update_callback() in builtin-add.c does.
In either case, because fill_directory() does not use read_directory() to
read everything in, we need to add an extra logic to iterate over the
index to catch mistyped pathspec.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-07-23 07:30:40 +02:00
|
|
|
/* This picks up the paths that are not tracked */
|
2013-07-14 10:35:55 +02:00
|
|
|
baselen = fill_directory(&dir, implicit_dot ? &empty_pathspec : &pathspec);
|
2013-07-14 10:35:46 +02:00
|
|
|
if (pathspec.nr)
|
2013-07-14 10:36:00 +02:00
|
|
|
seen = prune_directory(&dir, &pathspec, baselen,
|
2013-03-19 23:51:34 +01:00
|
|
|
implicit_dot ? WARN_IMPLICIT_DOT : 0);
|
2009-05-14 22:22:36 +02:00
|
|
|
}
|
builtin-add.c: optimize -A option and "git add ."
The earlier "git add -A" change was done in a quite inefficient
way (i.e. it is as unefficient as "git add -u && git add ." modulo
one fork/exec and read/write index).
When the user asks "git add .", we do not have to examine all paths
we encounter and perform the excluded() and dir_add_name()
processing, both of which are slower code and use slower data structure
by git standards, especially when the index is already populated.
Instead, we implement "git add $pathspec..." as:
- read the index;
- read_directory() to process untracked, unignored files the current
way, that is, recursively doing readdir(), filtering them by pathspec
and excluded(), queueing them via dir_add_name() and finally do
add_files(); and
- iterate over the index, filtering them by pathspec, and update only
the modified/type changed paths but not deleted ones.
And "git add -A" becomes exactly the same as above, modulo:
- missing $pathspec means "." instead of being an error; and
- "iterate over the index" part handles deleted ones as well,
i.e. exactly what the current update_callback() in builtin-add.c does.
In either case, because fill_directory() does not use read_directory() to
read everything in, we need to add an extra logic to iterate over the
index to catch mistyped pathspec.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-07-23 07:30:40 +02:00
|
|
|
|
2008-07-20 04:22:25 +02:00
|
|
|
if (refresh_only) {
|
2013-07-14 10:35:54 +02:00
|
|
|
refresh(verbose, &pathspec);
|
2008-07-20 04:22:25 +02:00
|
|
|
goto finish;
|
2006-12-26 02:46:38 +01:00
|
|
|
}
|
2013-04-26 22:44:35 +02:00
|
|
|
if (implicit_dot && prefix)
|
|
|
|
refresh_cache(REFRESH_QUIET);
|
2006-12-26 02:46:38 +01:00
|
|
|
|
2013-07-14 10:35:46 +02:00
|
|
|
if (pathspec.nr) {
|
2010-02-09 23:30:49 +01:00
|
|
|
int i;
|
2012-06-06 06:44:22 +02:00
|
|
|
|
2010-02-09 23:30:49 +01:00
|
|
|
if (!seen)
|
2013-07-14 10:36:00 +02:00
|
|
|
seen = find_pathspecs_matching_against_index(&pathspec);
|
2013-07-14 10:35:46 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
* file_exists() assumes exact match
|
|
|
|
*/
|
2013-07-14 10:36:08 +02:00
|
|
|
GUARD_PATHSPEC(&pathspec,
|
|
|
|
PATHSPEC_FROMTOP |
|
|
|
|
PATHSPEC_LITERAL |
|
2013-07-14 10:36:09 +02:00
|
|
|
PATHSPEC_GLOB |
|
|
|
|
PATHSPEC_ICASE);
|
2013-07-14 10:35:46 +02:00
|
|
|
|
2013-07-14 10:36:00 +02:00
|
|
|
for (i = 0; i < pathspec.nr; i++) {
|
|
|
|
const char *path = pathspec.items[i].match;
|
2013-07-14 10:36:08 +02:00
|
|
|
if (!seen[i] &&
|
2013-07-14 10:36:09 +02:00
|
|
|
((pathspec.items[i].magic &
|
|
|
|
(PATHSPEC_GLOB | PATHSPEC_ICASE)) ||
|
2013-07-14 10:36:08 +02:00
|
|
|
!file_exists(path))) {
|
2010-07-10 00:18:38 +02:00
|
|
|
if (ignore_missing) {
|
2010-11-11 14:03:22 +01:00
|
|
|
int dtype = DT_UNKNOWN;
|
2013-07-14 10:36:00 +02:00
|
|
|
if (is_excluded(&dir, path, &dtype))
|
|
|
|
dir_add_ignored(&dir, path, pathspec.items[i].len);
|
2010-07-10 00:18:38 +02:00
|
|
|
} else
|
2011-02-23 00:41:31 +01:00
|
|
|
die(_("pathspec '%s' did not match any files"),
|
2013-07-14 10:36:00 +02:00
|
|
|
pathspec.items[i].original);
|
2010-07-10 00:18:38 +02:00
|
|
|
}
|
2010-02-09 23:30:49 +01:00
|
|
|
}
|
|
|
|
free(seen);
|
|
|
|
}
|
|
|
|
|
2011-10-28 23:48:40 +02:00
|
|
|
plug_bulk_checkin();
|
|
|
|
|
2013-04-22 20:11:45 +02:00
|
|
|
if ((flags & ADD_CACHE_IMPLICIT_DOT) && prefix) {
|
|
|
|
/*
|
|
|
|
* Check for modified files throughout the worktree so
|
|
|
|
* update_callback has a chance to warn about changes
|
|
|
|
* outside the cwd.
|
|
|
|
*/
|
|
|
|
update_data.implicit_dot = prefix;
|
|
|
|
update_data.implicit_dot_len = strlen(prefix);
|
2013-07-14 10:35:46 +02:00
|
|
|
free_pathspec(&pathspec);
|
|
|
|
memset(&pathspec, 0, sizeof(pathspec));
|
2013-04-22 20:11:45 +02:00
|
|
|
}
|
|
|
|
update_data.flags = flags & ~ADD_CACHE_IMPLICIT_DOT;
|
2013-07-14 10:35:56 +02:00
|
|
|
update_files_in_cache(prefix, &pathspec, &update_data);
|
2008-07-20 04:22:25 +02:00
|
|
|
|
git add: rework the logic to warn "git add <pathspec>..." default change
The earlier logic to warn against "git add subdir" that is run
without "-A" or "--no-all" was only to check any <pathspec> given
exactly spells a directory name that (still) exists on the
filesystem. This had number of problems:
* "git add '*dir'" (note that the wildcard is hidden from the
shell) would not trigger the warning.
* "git add '*.py'" would behave differently between the current
version of Git and Git 2.0 for the same reason as "subdir", but
would not trigger the warning.
* "git add dir" for a submodule "dir" would just update the index
entry for the submodule "dir" without ever recursing into it, and
use of "-A" or "--no-all" would matter. But the logic only
checks the directory-ness of "dir" and gives an unnecessary
warning.
Rework the logic to detect the case where the behaviour will be
different in Git 2.0, and issue a warning only when it matters.
Even with the code before this warning, "git add subdir" will have
to traverse the directory in order to find _new_ files the index
does not know about _anyway_, so we can do this check without adding
an extra pass to find if <pathspec> matches any removed file.
This essentially updates the "add_files_to_cache()" public API to
"update_files_in_cache()" API that is internal to "git add", because
with the "--all" option, the function is no longer about "adding"
paths to the cache, but is also used to remove them.
There are other callers of the former from "checkout" (used when
"checkout -m" prepares the temporary tree that represents the local
modifications to be merged) and "commit" ("commit --include" that
picks up local changes in addition to what is in the index). Since
ADD_CACHE_IGNORE_ERRORS (aka "--no-all") is not used by either of
them, once dust settles after Git 2.0 and the warning becomes
unnecessary, we may want to unify these two functions again.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-04-17 21:32:21 +02:00
|
|
|
exit_status |= !!update_data.add_errors;
|
2008-07-20 04:22:25 +02:00
|
|
|
if (add_new_files)
|
|
|
|
exit_status |= add_files(&dir, flags);
|
2006-05-17 18:33:32 +02:00
|
|
|
|
2011-10-28 23:48:40 +02:00
|
|
|
unplug_bulk_checkin();
|
|
|
|
|
2007-04-20 10:39:39 +02:00
|
|
|
finish:
|
2006-05-17 18:33:32 +02:00
|
|
|
if (active_cache_changed) {
|
|
|
|
if (write_cache(newfd, active_cache, active_nr) ||
|
2008-01-16 20:12:46 +01:00
|
|
|
commit_locked_index(&lock_file))
|
2011-02-23 00:41:29 +01:00
|
|
|
die(_("Unable to write new index file"));
|
2006-05-17 18:33:32 +02:00
|
|
|
}
|
|
|
|
|
2008-05-12 19:58:10 +02:00
|
|
|
return exit_status;
|
2006-05-17 18:33:32 +02:00
|
|
|
}
|