Rationale for Existence
There are several tutorials on git. I am sure that there
are other articles that serve exactly the same purpose as I
do, but there is nothing like an article I write to express
exactly what is in my head.
This article will explain Git for
just one use-case. It aims at being a quick-start-kit for
a bunch of people who are planning to work on a project and
have never used any VCS before. They most certainly aren't
looking to learn about rebasing or cherry-picking. I wouldn't
be able to teach anybody the plumbing given that I am not too
sure of them myself. They need a way to provide file-level
undo and collaborate/merge easily. They also would like to use
github.
I wrote a huge section about why VCSs exist. I found it very
distracting and so I removed it from this article. You can
read it here
I Just Don't Git It
The Config File
This is the first thing you ought to do when you plan to
use git.
In a shell, type out the following
$ git config --global user.name "Your Name"
$ git config --global user.email userid@domain.com
Let me put a couple of "rules" on the table here.
- Do not use Nicknames
for
user.name
. It is generally recommended to
use Firstname Lastname.
- Provide a valid E-Mail id. Preferably
one that you check often. This is the only way most people
can contact you with issues.
This will set your user-name and E-Mail IDs to the values
supplied. The
--global
flag here indicates that
the values are set for all future git invocations.
To do so, you need persistent storage, right? That is where
the $HOME/.gitconfig
kicks in. The commands above
actually went ahead and stored data in a file in your home
directory.
[user]
name = Your Name
email = userid@domain.com
Git groups together different configuration attributes under
different sections. (For instance, [user]
).
For the moment, you are done setting up your config file. Do
look at the manpage for git-config for further options if you
are interested.
Get a Github account
Go to Github and create an
account for yourself. Once you have created an account for
yourself, go to Account-Settings -> Account Admin
Copy your github API Token. Though it is mentioned already in
the site, I re-emphasize Keep it secret.
As before, open a shell and type out
$ git config --global github.user your-github-usernae
$ git config --global github.token yourtoken
Note, as before, that in your $HOME/.gitconfig
file, there are two new fields under a new section, in this
case, [github]
.
You need ssh keys for working with github
This again is a Get-The-Job-Done kinda section. If you are interested, google on creating ssh key-pairs
$ ssh-keygen -C userid@domain.com
That command creates a new RSA keypair for you. Let the
defaults stay. Type in your password when prompted. Remember
this password. There is NO WAY you can
recover it. After this, you get two files in
your $HOME/.ssh
directory. Copy the contents
of id_rsa.pub
. The id_rsa
file is
your private key. Make sure you do not accidentally paste
that instead.
Paste it in the box that you get on
clicking "Account Settings -> SSH Keys -> Add New Key" in
Github and click add key. You can give your key a meaningful
name like Laptop-Fedora or SystemsLab-Debian etc so that you
know which key belongs where.
Congratulations. You
are now github ready.
Initializing a Repository
The best time to start
using Git to manage a project is before you start the project.
$ git init projectName
That creates a new directory with the name supplied. Now
whatever you put into that folder can be controlled by git
[Even here, it won't not until you explicitly ask it to].
This is the directory where you will be working in from now
on. Your project must be contained in this directory
Opening Git's Eyes
Now, let us assume you have a bunch of files in your
project directory. You are worried since Git doesn't seem to
be doing anything magical yet. That is true. Git isn't. It is
blind to new files. It will not monitor any files under its
directory unless you ask it to.
$ git add file1 file2 file3
The command above makes git start monitoring file1 file2
and file3. Most of the time, you would want to recursively
add all the files present in the current directory, its
subdirectories and so on. For this, you can use
$ git add .
The add command has two functions.
- It gets the files under git's surveillance.
- It makes git add the files to the staging area, which
is like the launchpad from where git on
a
commit
command makes a checkpoint
Files once tracked are always tracked unless you ask git to
stop caring about them with the
remove
command.
Staging, however is not a one-time process. You will have to
restage modified/freshly-added files before you commit.
You can unstage file using
git reset HEAD --
filename
. Reset unstages it but does not stop
tracking.
git rm filename
both unstages and
stops tracking the file.
Getting Git's Status
$ git status -s
You can see that the files you just added are marked with
an "A" before them. This A stands for added. Similarly, "M" is
used for Modified, "R" for renamed and "D" is used for
Deleted. The status actually is two characters long. The First
character is the status of the files in the staging area with
respect to the previous commit-point. The second is the status
of the files at the current instant to the files in the
staging area (from the add that occured previously). You see
only one of two characters because you do not have a commit
yet. You will see both the characters only when you have added
a few files to the stage that haven't been committed yet and
also have modified/deleted some files which are currently
staged.
$git status
I ♥ status
The git status command is my
favorite. It is unbelievably helpful. It almost knows what
you should do next. In an empty repository it hints that
you add files. After staging, it shows you how to
unstage. After committing, it shows how you can revert a
file to a checkpoint and prompts you to add new files to
the stage etc.
When you need more detailed
explanation, git help and man are always around
Committing your Changes
The moment has arrived. You have a set of changes that work
and have added the files to the stage. Now you want to make a
permanent mark that you can go back to any time you want.
$ git commit -m "Message"
Commit makes an indelible checkpoint. You can now do
whatever you want with your working directory, even a
rm *
and always get back the files as they where when
you committed.
When Do I commit
A common doubt is when a
commit should be done. Commit is most certainly not
equivalent to the Save Option in your editor. Once you
commit, your commit point will be visible in logs. People
[not only you] can go back to the commit point at will. They
would be pissed if they realize that the commit you made
actually did not work.
The general rule for commit is that you commit when a
particular feature is complete or when a milestone is
achieved. Yes. You could have intermediate commits
too. But mark so in your commit messages so that no one
reverts to them.
At a commit, it should be possible to at the very least
compile the codebase. The features that you aren't
currently editing shouldn't be affected and the feature
that you are editing should have some sane "Not
Implemented Yet" style message.
This is however, more of a guiding sign and not a
rule. git doesn't know anything about compilation. You
might use git for your poetry collection just as
efficiently as you use it to manage your world-domination
application. However, good habits take time to sink
in. Follow the guidelines unless you have a good reason not
to.
Log
Use the
log
command to see the
list of commits till now.
$ git log
UNDO UNDO UNDO!!!
I promised you that git can rever
the state of a file from a checkpoint however badly you messed
it up in the current directory. (Even if you deleted it) This
is how you do it.
$ git checkout -- filename
This list of files is similar to that in add
$ git checkout -- .
will bring the whole repository back to the checkpointed
state. This is like a mega undo button that you have that
works across several reboots, several sessions and several
files
Integrating a Github Repo Into the Project
Now that you have a small codebase working, you would want to
Github it. Create a repository on github. Click
the
New
Repository link . Give your project the same name as you
gave locally, this saves some effort later on. Once you have
done that, it is time to notify our local repo that there is a
remote repository we know that it should collaborate with
now on.
Get the link from the github page of the project (Choose ssh
and copy the link along with the git@ inside the text-box next
to it)
$ git remote add origin linkYouCopied
Pushing changes to Github
You should push your
changes to the repository in github so that others/you can use
it somewhere else.
$ git push origin master
The repository at github now gets the entire history of
changes you made!!!. So if someone else collaborating with you
wants to checkout the code as it was during your second
commit can still do so. AWESOME, right?
Updating the Github Copy
If you are the only person on the project, github still
provides a safe remote copy in case your hard-disk decides to
fail. In this case, you can keep pushing to the remote repo by
using git push origin master
as
before. However, if you are working with others, they would be
working on the code too. So they would be making changes and
pushing to github too. So before you commit, it is imperative
that you pull from github first, ensure that you have no
conflicts, commit and push back. This is done by the commands
below.
$ git pull # I am not going to cover merging here. Look elsewhere.
$ git commit -m"Message"
$ git push origin master
Remember to always pull before you push when working with collaborators