Git part 2: interacting with your project

In part 1, we set up a git server and created a blank project. Now let’s write some code on our development box and commit it to our git repo.

Create your working directory

First, on your development machine, create a new directory where you’ll be doing your work and initialize the client side of the repository.

dan@devbox:~ $ mkdir project_dev
dan@devbox:~ $ cd project_dev/
dan@devbox:project_dev $ git init  
Initialized empty Git repository in /home/dan/project_dev/.git/

Note that the git init command is similar to what was run on the server; however, the setup that occurs is different. Plain old git init will initialize the working directory of a repository either from a empty directory or from a directory of existing files. You’ll be editing code directly in this directory.

git init –bare on the other hand, initializes a repository on the server side of a repository and creates a framework directory structure for where the git application is going to store your project and the metadata for commits, changes, branches, and tags. You cannot use this directory as a working directory to write code, and its contents should only be interacted with using the git tools.

Write some code and store it with git

Now let’s write some code we want to manage with git:

dan@devbox:project_dev $ echo -e '#!/bin/bash\necho "Hello world!"' >
dan@devbox:project_dev $ sh
Hello world!

There are two steps to getting your changes into your git server. First you have to tell git about the files to be tracked within your project directory. Typically that is everything in the project directory. Add them and check the status using these commands:

dan@devbox:project_dev $ git add .  #  add everything in the working directory to be tracked by git. Contents of subdirectories are also added. Alternatively you could specify a specific file, directory, or wildcard.
dan@devbox:project_dev $ git status  #  see the current state of your working directory from git’s perspective
# On branch master
# Initial commit
# Changes to be committed:
#   (use "git rm --cached <file>..." to unstage)
#       new file:

Now that git knows about the file, we can check in our changes, which is called a commit. You do not need to commit after every single change to a file but would typically want to after you have finished a particular feature in your code. One of the goals of source control is to keep track of the features you add, so what easier way to do it than to just commit after you’ve completed a feature. Since we have an initial file, let’s commit it:

dan@devbox:project_dev $ git commit -m "Initial commit - adding the first script"
[master (root-commit) 53ca451] Initial commit - adding the first script
1 files changed, 2 insertions(+), 0 deletions(-)
create mode 100644

Every commit requires a comment about the changes that were made, which I have specified with the -m flag. I suggest keeping this as descriptive as possible so when you’re writing your changelog for the application later you will have a place to look that has all the information. Note that you can run git commit without the -m flag and git will display a text editor for your to enter your comment on the first line. On save and close, the commit will occur. After running the command, you can see the summary of the changes git detected in our file; one file was changed, and two lines were added.

Push our code to our git server

Note that so far we have only been working on our local development box. To get it up to our git server so other developers can interact with it and users can download new versions, we have to first tell git about our remote repository:

dan@devbox:project_dev $ git remote add origin dan@git:/git/awesome_new_project.git

The git remote command manages your remote repositories and only needs to be used when you’re adding a new remote repository. Here we are adding a new one that we call origin which is the standard default name everyone uses in git. You can have multiple remote repositories if you’d like, such as a personal repository and a github repository, and you can manage what is published to each separately. You just need each one to have a different name. So instead of origin, you could name one homeserver and other github to keep things more clear when you’re committing your code.

Now that the remote repo is added, push the code. Note that by default git will use SSH to talk to your git server, so you will need port 22 open on any firewalls.

dan@devbox:project_dev $ git push origin master
The authenticity of host 'git (' can't be established.
RSA key fingerprint is f2:2f:5a:98:fc:ee:e1:90:0b:a1:aa:a2:3b:f4:e0:4f.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'git,' (RSA) to the list of known hosts.
dan@git's password:
Counting objects: 3, done.
Writing objects: 100% (3/3), 278 bytes, done.
Total 3 (delta 0), reused 0 (delta 0)
To dan@git:/git/awesome_new_project
* [new branch]      master -> master

Here origin is the remote repo where our code is to be pushed. master is the branch of your code that you want to push. We’ll get more into branches in part 3, but know for now that master is the default development path in git and is where we made our first changes.

Now you can continue writing code in your project directory. As you make changes, run git status every now and then to see what it knows about your activities. When you’re done for the day or have completed a feature, be sure to commit your changes with what we discussed earlier:

git add .
git commit -m “Description of changes”
git push origin master

Continue on to part 3 for a primer on git branching and conflict resolution.


git –help

6 thoughts on “Git part 2: interacting with your project”

  1. Hi, With this conf I will need type the root password every time I need push. How configure the “auth” by public key?

  2. I seem to have made a mistake. I don’t have permission. Here is what I got:
    [dthiessen@ast180ua381b TestProj]$ git push origin master
    The authenticity of host ‘ast180ua381b (’ can’t be established.
    ECDSA key fingerprint is 54:9f:4c:cc:c4:8d:9f:1c:86:ff:63:11:b3:5f:d8:cd.
    Are you sure you want to continue connecting (yes/no)? yes
    Warning: Permanently added ‘ast180ua381b,’ (ECDSA) to the list of known hosts.
    dthiessen@ast180ua381b’s password:
    Counting objects: 6, done.
    Delta compression using up to 2 threads.
    Compressing objects: 100% (5/5), done.
    Writing objects: 100% (6/6), 1.21 KiB | 0 bytes/s, done.
    Total 6 (delta 0), reused 0 (delta 0)
    remote: error: insufficient permission for adding an object to repository database ./objects
    remote: fatal: failed to write object
    error: unpack failed: unpack-objects abnormal exit
    To ast180ua381b:/git/test_proj_1.git
    ! [remote rejected] master -> master (unpacker error)
    error: failed to push some refs to ‘ast180ua381b:/git/test_proj_1.git’
    [dthiessen@ast180ua381b TestProj]$

    How do I do the permissions? I am sure this is a very stupid question. Should it be rw-rw-rw- ? Look forward to any help.

  3. I fixed it! 🙂 Google! I did this:

    [dthiessen@ast180ua381b TestProj]$ cd /git
    [dthiessen@ast180ua381b git]$ sudo chmod -R g+ws *
    [sudo] password for dthiessen:
    [dthiessen@ast180ua381b git]$ sudo chgrp -R dthiessen *
    [dthiessen@ast180ua381b git]$

    Oh, and I also created SSK keys…

    1. I’m glad you got it figured out! That is one way to solve it. It looks like the root of your problem was that you were logged into your server as a user other than dthiessen when you initially set up the repo. Then on your client when you set up the remote repository, you used dthiessen. So linux permissions weren’t letting the remote client update files on the server since they were owned by a different user account.

      The other solution that is a little cleaner and more complete is to:
      cd /git
      sudo chown dthiessen *
      so your account is the full owner of all the git repo files.

      Glad the article was useful to you!

Leave a Reply

Your email address will not be published. Required fields are marked *