I don’t understand git commit at all.
It’s been a week since I’ve been using git and all these git with –a, -m, new files, untracked etc is making me totally confused. Tortoisegit is saving me for the moment, but I would like to understand the essence and use it in a way it’s totally easy.
When I am in the git command line, it’s rather difficult to selectively commit some files and keep the rest for another commit. How do I make this easy?
It is quite simple. You need to add the changes that you want to the index first:
git add file1 file2
then
git commit
if you removed a file, the add does that. Add means "add the change" even though it is a removal.
If you want to add all changes:
git add -A
The -a
parameter on commit says to add all changes of tracked files and commit them. So
git commit -a
will not commit a new file you created. You must explicitly add this.
The -m
parameter allows you to avoid opening the editor to edit your commit message and use what you put in following the -m
option:
git commit -m "Use this message and don't open the editor"
Sometimes this is not a good idea. If you just tried a merge and had conflicts, git caches a very nice message for you once you resolve the conflicts and commit. So there a git commit
is better.
To selectively add files, use the patch modifier on git add:
git add -p
This will now prompt you about the files. This is quite powerful as you can also specify parts of files, or alternatively edit what you want to add to the index. A git commit will only add those.
If you want some gui help that is not tortoisegit (avoid windows shell integration), use git gui
.
Here is a diagram explaining the index (or staged files):
(from http://progit.org/book/ch2-2.html)
hope this helps.
When I am in the git command line, it’s rather difficult to selectively commit some files and keep the rest for another commit. How do I make this easy?
Ironically, this is one of the things that git makes really easy, but you have to learn a concept that other version control systems just don't have. That idea is the "staging area" (technically known as the "index") which essentially keeps track of the content that will be in your next commit. When you say git add somefile
that's not saying "start tracking a file of this name", it means "stage the content of the file, as it is right now". You can do this for just the files you pick in your working tree - then, a plain git commit
just turns the contents of the staging area into your next commit.
Using the -a
parameter to git commit
basically says "I don't care about this staging area / index business, just stage everything that's being tracked before committing". So, until you're happy with the idea of staging particular files, I'd just do a plain "git commit".
It's worth running git status
frequently when you're adding files to get used to this idea - it shows files in up to three sections, although not all will always be present if there's nothing to report in that section:
Changes to be committed:
This lists changes that have been staged, so will be in the next commit. This includes new files, files whose deletion has been staged, and any files with staged changes.
Changed but not updated:
This lists files that have changes that haven't been staged yet.
Untracked files:
These are the files that git doesn't know anything about - typically you'll want to either ignore them, by adding patterns to your .gitignore
file, or add them with git add
.
Note that files can appear in both of the first two sections. For example, you can change your Makefile
, then add it to the index with git add Makefile
. Then if you go on to make more changes to Makefile
, save it, and then run git status
, you'll see that it's listed both in "Changes to be committed" and "Changed but not updated" - that's because (as mentioned above) git add Makefile
just stages the exact content of the file when you ran the command. If you run git add Makefile
again, the stage version will be overwritten by the version in your working tree, so that all the changes you've made to that are staged.
Another couple of tips might be worth adding, about the useful pair of commands git diff
and git diff --cached
- essentially, their meanings are:
git diff
: "Which changes have I not yet staged?"
git diff --cached
: "Which changes have I staged already?"
As you can probably work out from the above, that's because git diff
shows the difference between the staging area and your working tree, while git diff --cached
shows the difference between your last commit and the staging area.
You can view the manual page for git commit
by typing git commit --help
(also here).
In order to add files to commit, use git add
or, if the files are already in the repository, the -a
flag will help you.
-m
tags a message to your commit.
If you want to selectively choose files, use git add
and then git commit
without the -a
tag (which would add all the changes to files that exist in the repository).
I personally use the -s
option as well, which adds signed off by <your.email@gmail.com>
at the end, if you have that in your git config. If not, just use git config --global user.email your.email@google.com
.
It is simple enough to commit files in git.
For adding files, we have following commands
git add file1 file2
Or if you only want to add all files at a time you can do by
git add *
Then, it comes to commit. According to professionals, you are required to add message with commit so that it is easier to track what you have committed. For that you can use
git commit -m "your message"
If you want to commit any files you have added with git add
, and also commit any files you have changed since then. You can use
git commit -a
if you want the list of files you have changed and those you still need to add or commit. You can use
git status
And to send your changes to the master branch of your remote repository. The command is
git push origin master
Hope this would help you in understanding the concept of git add, commit and push. And solve your problem also.