I am new to Git and I am using Git extension. I want to ask that When I commit the directory Whether these file automatically go for staging or these get committed without staging?? Can I commit files without staging??
-
Why do you want to do this? `git add -u` will stage everything for you in one command. – Nix Mar 01 '13 at 15:48
-
possible duplicate of [Git commit -a "untracked files"?](http://stackoverflow.com/questions/8470547/git-commit-a-untracked-files) – Nix Mar 01 '13 at 15:48
-
In git, you can't commit the directory, only files. – Andrejs Cainikovs Mar 01 '13 at 15:50
-
You could easily alias something to do what you want using @David_Tryon s answer. – Nix Mar 01 '13 at 15:51
-
Yes, something like `git config --global alias.yabadabadoo !git add -u && git commit -a` – Andrejs Cainikovs Mar 01 '13 at 16:00
-
that is a really bad practice IMO – Sébastien Dawans Mar 01 '13 at 16:03
-
Bad practice is not checking your commits before pushing, but not committing all your changes if you're keeping the track. – Andrejs Cainikovs Mar 01 '13 at 16:52
2 Answers
It's worth mentioning here that all of these methods do use an index, aka staging area, aka cache.
When Git makes a new commit, it does so using whatever is in "the index". As the phrase the index implies, there is a single, special, distinguished thing: the index, as opposed to an index. But in fact, Git can use some other index. We need to know what "the" index is, and what it means to be the index, versus some other index.
The short version is that the index is what Git uses to build up the next commit. We start out with what's in this commit, i.e., the current or HEAD
commit. You run git checkout master
or git checkout branch
or whatever, and Git fills up your work-tree with a bunch of files. It puts the same files into the (single, special, distinguished) index, also called the staging area. This means the index/staging-area starts out full of many files: mostly, the same ones in your work-tree, where you do your work. The exception is that some work-tree files may be untracked.
An untracked file is one that is not in the index. It's really that simple: any file that is not in the index is untracked; any file that is in the index is tracked. The ones in the index start out being the same as the ones you git checkout
-ed, that git checkout
put in your work-tree.
You then make a bunch of changes to a bunch of files. If you run git commit
right now, though, the index / staging-area still has the original git checkout
versions, not the modified work-tree versions. So you have to git add
the changed files to copy them into the index.
This is kind of a hassle, so Git has git add -u
and also git commit -a
. But both of these just look at what's in the index right now, and copy the new work-tree version of those into the index. So git commit -a -m "commit message"
doesn't add files that are in the work tree but are not in the index—i.e., files that are currently untracked. This is the same as git add -u
: only tracked files get updated.
Here's where it gets a little complicated
Besides the above, git commit
can take path names as arguments:
git commit -m "some message" file1 file2
for instance. But this implies the --only
flag, i.e., commit only changes in file1
and file2
. You can also run:
git commit -m "some message" --include file1 file2
This overrides the --only
.
The way all this works is that Git can use a different index, instead of the standard one. When using --only
, what Git does is build a new temporary index from the HEAD
commit. Then, into this temporary index, Git copies the specified files from the work-tree, replacing the old versions, or adding new files. Then Git makes a commit from this temporary index: the new commit has all the same files as the HEAD
commit, except for whatever it added due to --only file1 file2
.
When you use --include
, Git makes its temporary index by copying the current index, instead of by extracting HEAD
again. So now whatever you have git add
-ed so far is in the temporary index too. Then Git adds the specified files, and makes the new commit.
In all cases, after Git makes the new commit, it has to fix up the real index too, because now you have committed the latest file1
and file2
(and maybe other updates if you used --include
). If you used --include
, the temporary index simply becomes the real index.
If you used --only
, this is the most complicated case. Here Git copies the added files into the real index too, at this point, but otherwise leaves the real index alone. That way, whatever you staged before is still staged. The new commit has in it whatever was in the HEAD
commit (via the temporary index), except for the specified files (that were git add
-ed into the temporary index). And, whatever you specifically committed just now is also git add
-ed to the real index now, as if you ran git add
on those files.

- 448,244
- 59
- 642
- 775
-
1
-
This is a brilliant explanation. Interestingly, it would have been nice to see the temporary index in some way to verify the nuances of the working. – theOne Mar 10 '22 at 08:46
-
@theOne: the temporary index exists only for the duration of the one `git commit` command. You *can* see it in some ways though: for instance, your pre-commit hook is run with environment variable `GIT_INDEX_FILE` set to show the name of the temporary file (the default setup has it unset or set to the standard index). Unfortunately there's no perfect and easy way to *test* for this because `git worktree add` adds a working tree whose standard index is not `.git/index` but rather `.git/worktrees/
/index` for some ID, and there are no promises that this might not change someday. – torek Mar 10 '22 at 21:53 -
1Meanwhile, if you use a `git commit` command that runs an editor, and use a second window or similar to poke around inside the `.git` directory while that editor is waiting for you (the human) to edit the commit message, you can find the temporary index. In the case of `git commit --only` there are in fact *three* index files active; for `git commit --include` there are two. But again these are implementation details with no real promises made. This is a bit unfortunate since it constrains what you can do in a pre-commit hook. – torek Mar 10 '22 at 21:55
-
+1 simply brilliant! I now use `git commit -m "some message" file1` to commit minor changes in `file1` (e.g. fixing whitespace) that are unrelated to the current work, and without disturbing my staging area (before reading this answer, I would unstage all the files, stage the changed `file1`, commit, then restage the previous files to continue...that was tiresome...`git commit --only` is awesome). – Eric Mutta Nov 02 '22 at 02:08
-
1@EricMutta: you can even combine that with `--amend`, which boots the previous tip commit off the branch by making the new commit the tip commit of the branch (by making the new commit's parent(s) be the kicked-out-commit's parent(s)) to fix a glitch in the previous commit. But I generally find that getting too fancy is harmful, that it's better to just make a bunch of smaller commits and use `git rebase -i` to combine things and fix things up. – torek Nov 02 '22 at 02:22
Yes, you can stage and commit using a
and m
in the commit:
git commit -am "my commit message"
However, I tend to use git add -u
anyway because the above command will not stage untracked files.

- 66,517
- 15
- 143
- 132
-
-
My untracked files are not tracked by choice. Don't (mis)use git as a thrash container. – vonbrand Mar 02 '13 at 04:18