Blog

Git - Basic Commands Explained

by -

tags:git

My previous article about Git (Git Workflow) was too much theoretical, but that was intentional. I believe it’s necessary to understand some of the core concepts of Git to make proper use of it, in an easy and intuitive way. If you haven’t read it yet, I recommend you doing so before proceeding.

Now, we’ll play with some of its basic commands, and hopefully it’ll make those concepts a lot easier to understand.

Do not type the $ sign you see in the command examples. That’s just an indicator that you should run the command that follows it in your command line tool.

Global Settings

The first thing you should do when you install Git is to set your name and e-mail address. This is important because every Git commit uses this information. To do so, please run the following commands:

$ git config --global user.name "Your Name"
$ git config --global user.email youremail@example.com

Using --global option makes it globally available for Git, so available to any repository you work on. If you want to override that information for a specific repo, just go to that repo’s root directory and run the command without --global option.

Creating a new repository

There are two ways to create a new Git repo: using init or clone commands. Let’s start by init.

Go to the directory that will be your repository and run:

$ git init

That starts a new repository and creates a local master branch. Don’t worry about it right now, branching is the subject of our next article about Git.

Cloning an existing repository

To clone an existing remote repository go to the directory that you want to create your new repo and run a command like $ git clone [url], for example:

$ git clone git://github.com/flsilva/as3coreaddendum.git

That will create an as3coreaddendum directory in your file system.

Checking the status of your files

After making changes, adding, and deleting files, you’ll frequently use the status command to check the status of your local repository:

$ git status

When you see a message like nothing to commit, working directory clean, it means that your working directory is fully synchronized with your local repository, i.e., there are no changes to be committed.

When you see a message like Changes not staged for commit, it means that you’ve made changes to tracked files (files already in your local repo) but have not added them to the staging area, which means they will not be committed when you run commit command. Usually, you’ll also see a message like Untracked files, which means there are new files not added to the staging area.

Adding changes to the staging area

After making some changes to your files and checking their status, you’ll want to add your changes to the staging area. There are two main ways to do that, running the add command for individual files (or directories):

$ git add file-name

Or:

$ git add directory-name

Or running add for all your files and directories:

$ git add -A

Or, alternatively:

$ git add .

After that you can check the status of your files again:

$ git status

Now you should see a message like Changes to be committed. That means that you’ve staged your changes, and they are ready to be committed.

Committing changes to your local repository

Every time you run commit command, Git sends the content of your staging area (new files, modified files, etc) to your local repo, so not the content of your file system at the moment you run it. Most of the times they will be the same, but there’s a situation where they may differ. That’s the case if you run add for some modified file, but before you run commit you make more changes to that same modified file, and then run commit without running add again for that later change. In such case, Git will not commit your later changes, only the ones that were added to the staging area using add command. This is a gotcha using Git, and illustrates how it uses its concept of staging area.

To send your changes to your local repository you run:

$ git commit -m "your commit message here"

The commit message is mandatory and you should do it anyway, it’s a best practice. Since you should commit often, your messages should be simple but descriptive.

You can commit how may times you want before sending it to a remote repository.

Pushing changes to a remote repository

The time will come when you want to send your precious changes to a safe and warm remote repository, right? I hope you’ve said yes.

To send changes to a remote repository you should have one, obviously, but you also need a reference to it in your local repository. Assuming you already have a remote repository configured somewhere (you can always setup one for free on GitHub or Bitbucket), there are two ways to create a reference to it in your local repo. The first, and easier one, is cloning an existing repo. In that case, Git automatically creates a reference to your cloned repo, naming it origin. But if you created your local repo from scratch using init, and time has come for you to send your local repo to a remote repo for the first time, you have to set up a reference to it manually by running a command like:

$ git remote add [remote-name] [remote-url]

remote-name is the name you want to give to that repository, it’s an alias for it.
remote-url is the url to your remote repository, and it depends on the protocol you’ll be using (ssh, https, git://, etc)

Usually, you’ll create an origin alias pointing to your canonical remote repository, like:
$ git remote add origin git@github.com:flsilva/as3coreaddendum.git

That creates a new reference to your remote repository with the origin alias. You can always check all your remote references by running $ git remote -v

Now, to send your local changes to a remote repo you run a command like $ git push [remote] [branch], for example:

$ git push origin master

master is the name of the default main branch in Git. Don’t worry about it right now, branching is the subject of our next article about Git.

You’ll need write permission to a remote repository to successfully run a push command.

Fetching changes from a remote repository

You should always run a fetch command before running push, because if someone else has pushed to the remote repository, you’ll have to fetch it first, then merge it into your local branch, before being able to push your changes. Git enforces it. Also, before fetching changes from a remote repo, you should commit your local ones, if you have any.

To fetch from a remote repository you run a command like $ git fetch [remote], for example:

$ git fetch origin

A fetch command fetches all changes from a target remote repo, creating remote branches in your local repo. Don’t worry about remote branches for now, that’s the subject of this article, you can read it moving forward. After that, you’ll want to run a merge command to merge remote changes to your local ones. After merging you’re up-to-date to your remote repo, so ready to push to it. That makes a basic push flow to look like this:

commitfetchmergepush

But if there are no changes to your remote repo, that could be just:

commitpush

Now, you should really consider using pull instead of fetch. Let’s see why.

Pulling changes from a remote repository

A pull command is pretty much like fetch, but with the advantage that it runs merge for us automatically. To do that, you just need to provide a target branch, alongside remote repo. So instead of using fetch like this:

$ git fetch origin

You can use pull like this:

$ git pull origin master

That way Git knows you want to merge changes from your remote repo’s master branch into your current local branch (that may or may not be pointing to your local master branch).

If there are no conflicts to resolve (don’t worry about it now), you just have to confirm the default merge message (you can change it if you want). After that you’re up-to-date to your remote repo, so ready to push to it. That makes a basic push flow to look like this:

commitpullpush

But if there are no changes to your remote repo, that could be just:

commitpush

Deleting files and directories

One of the things that I love about Git over SVN is that you don’t have to do anything special to delete files and directories. Just delete them the way you want, using your OS’s GUI or command line tool. Git will notice it, and report their status as deleted, so you just need to run $ git add . as usual to prepare your changes to go on the next commmit.

Renaming and moving files and directories

The same is true for renaming and moving files and directories. Just do that the way you want, you don’t have to worry about anything. Lovely, isn’t it?

Viewing the commit history

Sometimes you’ll want to take a look at the commit history. The simplest way is by running:

$ git log

But that prints all commits, so that useful. So, you can limit it:

$ git log -3

That prints only the last 3 commits. If you want to see a bit more info about each commit:

$ git log -3 --stat

You can filter commits by time, for example in the last two weeks:

$ git log --since=2.weeks

Another useful option is to filter commits that has changed a specific directory or file:

$ git log -- path/to/directory-name

$ git log -- path/to/file-name

Or filtering commits by commiter / author:

$ git log --committer=Flavio

$ git log --author=Flavio

A simple and nice GUI tool is distributed with Git and can also show the commit history. To launch it you just run:

$ gitk

And, that’s it! You should now have a much better sense about how Git works, and how to easily use it for most basic tasks. Do you think there’s a basic command not listed here? Please let me know in the comments.

Feeling smart and fearless? Head to Git Branching and Merging to start leaning some advanced yet very useful concepts Git provides us. I put a lot of effort to make it easy to understand, but let me know if I failed somehow.

Git Branching and Merging
Git Remote and Tracking Branches
Git Tagging
Git Workflow
Introduction to Git

Git
Pro Git Book

Bibliography

Chacon, Scott. Pro Git. Apress, 2009.

Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.

comments powered by Disqus