Videos
- since git uses a system of "snapshots" of the entire codebase, git needs to know history of changes and show to all coders who did what at each moment in time.
It's a reasonable way to phrase it.
- "commit" is like recording the changes in project's memory.
Yes, committing is adding a record of your changes (compared to the previous commit) on top of the branch.
- uploading my changed version of the project,i.e. my branch to main online repo(master) is a different thing?
When you push, the remote server appends your changes to the remote branch provided that your history follows the server history. For example, if anyone has appended any change to the server history before you push, you are both showing divergent versions of the history from a certain point. So you need first to rewrite your local history so that it complies with the server's history. (usually using git pull, which will merge or rebase your branch depending on your choice)
- when I upload my local changes to the main version of the project, my commits(recorded in .git file) become known to others.
Yes, when you push you let other know how you modified the history.
- uploading changes to master branch is "pushing" all my commits, right?
Pushing is "uploading" (if you wish to use that word) your changes to the remote's master branch. As I said earlier, the remote will only accept if your changes are built upon the latest history available at the remote's master.
Note that all of this is true for any branch, you can have as many branches as you want, no only master.
git basically uses these 3 things to store your data:
- A
blobis just a binary blob of stuff (your source code, an image, whatever). The blob does not contain information about the type or name of the content and is just a mass of bytes. - A
treepoints to one or more blobs, think "directory". It contains file names etc. of the blobs it points to. - A
commit(the data object, not the git command) is a separate entity that points to exactly one tree (the state of all files at that point in time) and zero or more other commits (the parent(s), which may be missing for the very first commit in a repository, and which may be multiple in case of merges).
That's it. There's nothing else to it, conceptionally. In practice, there are branches and tags, but these are just special "sticky notes" pointing to commits. There are also mechanisms in place to reduce storage and such, but they are not of interest unless you hack on the code or go real deep.
Answering your question is easy in this context:
- When you checkout a commit into your working directory, you get the files from one specific
commit. Say, the sticky note (branch)masterpoints to a commitafd876123, and you clone the repository into a fresh working directory, then you get the files represented in thetreethat thecommit afd876123points to. - git of course keeps track and creates a special sticky note
HEADwhich stores the information that you are onmasterand on commitafd876123. It also creates anindexwhich you can think of as an anonymoustree. - You edit some files in your working directory.
- When you run
git add, then git updates theindexwith your changes. While internally it works differently, you can think of it as updating thetree "index"with your changes. - No
commitis associated with thistree(yet), so it is not a permanent thing; it does not affect pushes, pulls or whatever. - When you run
git commitit creates a newcommitobject which points to thetreethat is represented by your current index, as well as the previous commitafd876123and other information (like timestamp, log message...). Thiscommitobject is then added to the data store and thus finalized.
The rest of your assumptions about push/pull are basically correct.
When you run git commit with no arguments, it will open your default editor to allow you to type a commit message. Saving the file and quitting the editor will make the commit.
It looks like your default editor is Vi or Vim. The reason "weird stuff" happens when you type is that Vi doesn't start in insert mode - you have to hit i on your keyboard first! If you don't want that, you can change it to something simpler, for example:
git config --global core.editor nano
Then you'll load the Nano editor (assuming it's installed!) when you commit, which is much more intuitive for users who've not used a modal editor such as Vi.
That text you see on your screen is just to remind you what you're about to commit. The lines are preceded by # which means they're comments, i.e. Git ignores those lines when you save your commit message. You don't need to type a message per file - just enter some text at the top of the editor's buffer.
To bypass the editor, you can provide a commit message as an argument, e.g.
git commit -m "Added foo to the bar"
in standart Vi editor in this situation you should
- press Esc
- type ":wq" (without quotes)
- Press Enter