make 'git add' a first class user friendly interface to the index

This brings the power of the index up front using a proper mental model
without talking about the index at all. See for example how all the
technical discussion has been evacuated from the git-add man page.

   Any content to be committed must be added together.  Whether that
   content comes from new files or modified files doesn't matter.  You
   just need to "add" it, either with git-add, or by providing
   git-commit with -a (for already known files only of course).

No need for a separate command to distinguish new vs modified files
please. That would only screw the mental model everybody should have
when using GIT.

Signed-off-by: Nicolas Pitre <nico@cam.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
This commit is contained in:
Nicolas Pitre 2006-12-04 11:13:39 -05:00 committed by Junio C Hamano
parent ba988a83f0
commit 366bfcb68f
4 changed files with 72 additions and 35 deletions

View File

@ -3,7 +3,7 @@ git-add(1)
NAME NAME
---- ----
git-add - Add files to the index file git-add - Add file contents to the changeset to be committed next
SYNOPSIS SYNOPSIS
-------- --------
@ -11,16 +11,31 @@ SYNOPSIS
DESCRIPTION DESCRIPTION
----------- -----------
A simple wrapper for git-update-index to add files to the index, All the changed file contents to be committed together in a single set
for people used to do "cvs add". of changes must be "added" with the 'add' command before using the
'commit' command. This is not only for adding new files. Even modified
files must be added to the set of changes about to be committed.
It only adds non-ignored files, to add ignored files use This command can be performed multiple times before a commit. The added
content corresponds to the state of specified file(s) at the time the
'add' command is used. This means the 'commit' command will not consider
subsequent changes to already added content if it is not added again before
the commit.
The 'git status' command can be used to obtain a summary of what is included
for the next commit.
This command only adds non-ignored files, to add ignored files use
"git update-index --add". "git update-index --add".
Please see gitlink:git-commit[1] for alternative ways to add content to a
commit.
OPTIONS OPTIONS
------- -------
<file>...:: <file>...::
Files to add to the index (see gitlink:git-ls-files[1]). Files to add content from.
-n:: -n::
Don't actually add the file(s), just show if they exist. Don't actually add the file(s), just show if they exist.
@ -34,27 +49,12 @@ OPTIONS
for command-line options). for command-line options).
DISCUSSION
----------
The list of <file> given to the command is fed to `git-ls-files`
command to list files that are not registered in the index and
are not ignored/excluded by `$GIT_DIR/info/exclude` file or
`.gitignore` file in each directory. This means two things:
. You can put the name of a directory on the command line, and
the command will add all files in it and its subdirectories;
. Giving the name of a file that is already in index does not
run `git-update-index` on that path.
EXAMPLES EXAMPLES
-------- --------
git-add Documentation/\\*.txt:: git-add Documentation/\\*.txt::
Adds all `\*.txt` files that are not in the index under Adds content from all `\*.txt` files under `Documentation`
`Documentation` directory and its subdirectories. directory and its subdirectories.
+ +
Note that the asterisk `\*` is quoted from the shell in this Note that the asterisk `\*` is quoted from the shell in this
example; this lets the command to include the files from example; this lets the command to include the files from
@ -62,15 +62,18 @@ subdirectories of `Documentation/` directory.
git-add git-*.sh:: git-add git-*.sh::
Adds all git-*.sh scripts that are not in the index. Considers adding content from all git-*.sh scripts.
Because this example lets shell expand the asterisk Because this example lets shell expand the asterisk
(i.e. you are listing the files explicitly), it does not (i.e. you are listing the files explicitly), it does not
add `subdir/git-foo.sh` to the index. consider `subdir/git-foo.sh`.
See Also See Also
-------- --------
gitlink:git-status[1]
gitlink:git-rm[1] gitlink:git-rm[1]
gitlink:git-ls-files[1] gitlink:git-mv[1]
gitlink:git-commit[1]
gitlink:git-update-index[1]
Author Author
------ ------

View File

@ -87,14 +87,48 @@ thorough description. Tools that turn commits into email, for
example, use the first line on the Subject line and the rest of the example, use the first line on the Subject line and the rest of the
commit in the body. commit in the body.
To add a new file, first create the file, then
------------------------------------------------ Git tracks content not files
$ git add path/to/new/file ----------------------------
------------------------------------------------
then commit as usual. No special command is required when removing a With git you have to explicitly "add" all the changed _content_ you
file; just remove it, then tell `commit` about the file as usual. want to commit together. This can be done in a few different ways:
1) By using 'git add <file_spec>...'
This can be performed multiple times before a commit. Note that this
is not only for adding new files. Even modified files must be
added to the set of changes about to be committed. The "git status"
command gives you a summary of what is included so far for the
next commit. When done you should use the 'git commit' command to
make it real.
Note: don't forget to 'add' a file again if you modified it after the
first 'add' and before 'commit'. Otherwise only the previous added
state of that file will be committed. This is because git tracks
content, so what you're really 'add'ing to the commit is the *content*
of the file in the state it is in when you 'add' it.
2) By using 'git commit -a' directly
This is a quick way to automatically 'add' the content from all files
that were modified since the previous commit, and perform the actual
commit without having to separately 'add' them beforehand. This will
not add content from new files i.e. files that were never added before.
Those files still have to be added explicitly before performing a
commit.
But here's a twist. If you do 'git commit <file1> <file2> ...' then only
the changes belonging to those explicitly specified files will be
committed, entirely bypassing the current "added" changes. Those "added"
changes will still remain available for a subsequent commit though.
However, for normal usage you only have to remember 'git add' + 'git commit'
and/or 'git commit -a'.
Viewing the changelog
---------------------
At any point you can view the history of your changes using At any point you can view the history of your changes using

View File

@ -94,9 +94,6 @@ int cmd_add(int argc, const char **argv, const char *prefix)
newfd = hold_lock_file_for_update(&lock_file, get_index_file(), 1); newfd = hold_lock_file_for_update(&lock_file, get_index_file(), 1);
if (read_cache() < 0)
die("index file corrupt");
for (i = 1; i < argc; i++) { for (i = 1; i < argc; i++) {
const char *arg = argv[i]; const char *arg = argv[i];
@ -131,6 +128,9 @@ int cmd_add(int argc, const char **argv, const char *prefix)
return 0; return 0;
} }
if (read_cache() < 0)
die("index file corrupt");
for (i = 0; i < dir.nr; i++) for (i = 0; i < dir.nr; i++)
add_file_to_index(dir.entries[i]->name, verbose); add_file_to_index(dir.entries[i]->name, verbose);

View File

@ -163,7 +163,7 @@ static void wt_status_print_changed_cb(struct diff_queue_struct *q,
int i; int i;
if (q->nr) if (q->nr)
wt_status_print_header("Changed but not updated", wt_status_print_header("Changed but not updated",
"use git-update-index to mark for commit"); "use git-add on files to include for commit");
for (i = 0; i < q->nr; i++) for (i = 0; i < q->nr; i++)
wt_status_print_filepair(WT_STATUS_CHANGED, q->queue[i]); wt_status_print_filepair(WT_STATUS_CHANGED, q->queue[i]);
if (q->nr) if (q->nr)