slindsey3000
slindsey3000

Reputation: 4281

git commit -m vs. git commit -am

Seems easy but I just don't get it. I am in the root of my application.

Here is my workflow.

git add .
git commit -m "added a new feature some files changed"
git push heroku master

This usually works. All my changes are pushed.

But sometimes I have a file that I change but when I push to Heroku the changes are not there for THAT ONE FILE... but for most of the files the changes are there...

But if I do

git add .
git commit -am "added a new feature some files changed"
git push heroku master

Everything (all changes) are pushed to Heroku

Upvotes: 141

Views: 191464

Answers (9)

Rishabh Kakralia
Rishabh Kakralia

Reputation: 36

Suppose you have done working (may have added new files, may have modified the existing ones, or may have deleted some) Now you have made a command that is

git add .

Now this command will stage all the files (newly added, modified or deleted), so at this point you have all your files staged(indexed), ready to be committed

Next thing you do is running the following command which is

git commit -m "added a new feature some files changed"

Now understanding how this command works is very important, so when you give this command, the git will commit all the staged (remember it, very important term, you will know soon) files to the repository, or we can say it will commit only those files which are staged at the time of running this command

Then the next command you give will push all the changes to your server repository and everything is fine mostly as you have mentioned

Now comes the interesting part about why the above method works mostly but sometimes miss the changes in some file and why the other method you have mentioned works every time

To better understand it we should first know the working of the other command which you have used in other method and that is

git commit -am "added a new feature some files changed"

Now when you use the above command, the git will commit not only the staged files (same as git commit -m) but also the files which are not yet staged

So what might be happening is that sometimes you must be modifying any file after you have run the (git add .) command, so now if you see the git status then it will show you all staged files except one which is not staged because you have modified the file after running the (git add .) command

So now when you run the 'git commit -m' command you commit all the staged files but left the change in that one file which was not staged but you think you have made the change and you will push it to just find it later that some change is missing Whereas when you run the other command which is 'git commit -am' it will not only commit the staged files but also the file which is modified but not staged, so in this case no files are left without commit

Now a few points about the 'git commit -am' command --

  • This command is useful to remove the step of staging the files, by using this step you can directly commit the files in a single step without the need of first staging them as required for 'git commit -m' command
  • Caution -- When using the 'git commit -am' command it is very necessary that all the files are tracked (files which are at least staged or committed), if there are some untracked (newly created files mostly) files present then we have to first tracked them by using 'git add' command

Now you might be thinking what are tracked files and untracked files, you can find the answer to this question by visiting the following link - Tracked and Untracked Files

Upvotes: 1

Shubham Jain
Shubham Jain

Reputation: 17563

In layman's words :

if you use only -m, then you need to add any file one by one, if you can't use .(dot) due to avoid adding many unwanted unstaged / untracked files

so you use like below

git add test1.txt
git commit -m "adding test1.txt file"

Now if you know you want to add all files which are modified (not new file or untracked file), you can simply use -am with commit command and all modified files will add and stage together in one command

so if text1.txt is not a new file / untracked file and its a modified file / tracked file then simply do below without using add command

git commit -am "adding test1.txt file"

Source:

https://www.gitkraken.com/learn/git/commit

Upvotes: 1

tinystone
tinystone

Reputation: 644

Imagine there are fileA fileB fileC, and you modify them. Then commit.

git add .
git commit -m "update"

All files are commited and tracked by git.

Imagine fileD is created by you or some toolchain, and you modify fileD and fileA. Then commit.

git add .
git commit -m "update"

fileD gets tracked by git (git add .), and fileA and fileD are tracked by git.


With regarding to "So why does git commit -am "x" work ... but .... git add . git commit -m "x" does not work?"

Ans:

IT IS BECAUSE you did something like this:

Imagine fileE is created by you or some toolchain (let's say it is fileE version1), and you staged it

git add .

and then you modify fileE (let's say it becomes fileE version2). ^ Then commit.

git commit -m "update"

As a result, only version1 of fileE is committed. Although it confuses the user, it is the expected behaviour of git: git doesn't know about fileE version2. ---- for the uncommited fileE, you staged it too early as you forget to let git know about fileE version2 with doing a git add fileE (at ^ mark of moment) after a newer version of fileE, before committing.

So just remember to git add everything of its newest version before commit. (add new version, commit new version)

-

LET'S ROLL BACK the whole story before fileE is created, and do it again so that you don't miss the fileE version2.

Imagine fileE is created by you or some toolchain (let's say it is fileE version1), and you modify fileE (let's say it becomes fileE version2).

Then commit.

git add .
git commit -m "update"

As a result, version2 of fileE is committed.

If you want the version1 fileE to be in a commit in your commit history, simply just commit twice: once for its old version, once for its new version (aka. once before its being modified to version2, once for its version2)


Tip:

Always follow this sequence: (add new version, commit new version)

(file modification) + git add . + git commit -m "update",

(file modification again) + git add . + git commit -m "update",

and you won't run into this problem of missing any changes.

And you don't even need the "convenience" provide by -am. Because using -am is equivalent to asking git to be smart and be lenient about your forgetting git add . With a clear mind to follow the intuitive sequence, you don't need lenience at this level. Sometimes, unnecessary lenience bring more brain load than benefits.

Upvotes: 2

brandonwie
brandonwie

Reputation: 840

git commit -am is a convenient command to stage and commit at once for TRACKED(=STAGED) files.

As Nail answered,

git commit -am = git commit -a + git commit -m 

git commit -m: commit with message (you probably know this part)

git commit -a | git commit --all:

Tell the command to automatically stage files that have been modified and deleted, but new files you have not told Git about are not affected. -from git documentation

new files you have not told Git about are not affected

The bold part is what's important.

the -am flag works only for TRACKED(staged) files that are modified or deleted(b/c "delete" means removing what existed = tracked before)

Therefore, if you add new file(s), and commit with -am flag, those newly create file(s) won't included in the commit because it is not tracked(staged).

If you create new files and want to use -am flag to avoid using

git add .
git commit -m "some commit" // reducing one line makes a big difference, I agree

, stage those new ones first with git add . and you can use git commit -am instead of the commands with two lines above.

Upvotes: 8

The basic difference between them is that:

 git commit -m = send log message (don't work without git add )
 git commit -am = git add -a + git commit -m

and git add -a = stages Everything

Upvotes: 8

Chandu Singh
Chandu Singh

Reputation: 5

it is doing 2 jobs together 1)staging the modified files 2)adding comment in the same line

but it will not add the files from unstage to stage i.e it is not working the job of $git add .

Upvotes: -1

Abideen Muhammed
Abideen Muhammed

Reputation: 96

The difference between git commit -m "first commit" and git commit -am "your first commit" is that in the former, you will need to first of us do "git add ." while you don't need that in the latter. The 'a' in the "-am" flag tell git to first of all add all changes

Upvotes: 2

Juyal Jee
Juyal Jee

Reputation: 537

I would suggest, if you only changed one file then you might do something like this:

git add "Your_file.txt"
git commit -m "added a new feature in a file"
git push heroku master

Or if you changed multiple files then you could do something like this:

git add .
git commit -m "some files changed"
git push heroku master

Similarly, you could add and commit all the files on one line with this command:

git commit -am "added a new feature some files changed"
git push heroku master

Upvotes: 40

Davin Tryon
Davin Tryon

Reputation: 67316

From the docs:

git commit -a automatically stage all tracked, modified files before the commit If you think the git add stage of the workflow is too cumbersome, Git allows you to skip that part with the -a option. This basically tells Git to run git add on any file that is "tracked" - that is, any file that was in your last commit and has been modified. This allows you to do a more Subversion style workflow if you want, simply editing files and then running git commit -a when you want to snapshot everything that has been changed. You still need to run git add to start tracking new files, though, just like Subversion.

Using the option -am allows you to add and create a message for the commit in one command.

Upvotes: 149

Related Questions