The Linux Page

Creating a new git repository

A treasure chest full of coins, jewels, and ornaments.

As I am now using git, I like to create my own repositories. In most cases the documentation is not that easy to follow. Here are the instructions I use.

First of all, I setup my own personal configuration (it can be used as a global setup for you). This is written in the ~/.getconfig and looks like this:

[user]
    name = AlexisWilke
    email = me@my-top-secret-email-address.com
[core]
    excludesfile = ~/.gitignore
    editor = vim
[push]
    default = simple
[giggle]
    main-window-maximized = false
    main-window-geometry = 1114x789+144+184
    file-view-vpane-position = 389
    main-window-view = FileView
    history-view-vpane-position = 315
    file-view-hpane-position = 190
[branch]
    autosetupmerge = always
    autosetuprebase = always

Note: This will ignore a file named ~/.gitignore in your home directory. In most cases, that's not a good idea to have such a file there. Instead, I suggest you add one in the root of your git repository. That one will be specific to your repository and everyone using it will benefit from that .gitignore file.

The editor line names the text editor that will be used in your console when you don't specify a message on the command line (-m). I like vim but if you prefer to use nano, emacs, etc. change that line. Note that by default the system will use the default editor which often is setup as nano. However, if you would like to change your default editor system wise, not just for git, then run this command instead:

sudo update-alternatives --config editor

And choose your favorite editor in the list. If you do not see your editor in the list, hit Ctrl-C, install it, then try this command again.

Assuming you have a place such as /repo where you place all your CVS, SVN, and GIT repositories...

cd /repo
mkdir my-git
cd my-git
git init --bare
git update-server-info   # Only if you want to use via HTTP

Now we have a repository ready for use. Let's create a project and then add that project to the repository:

cd ~
mkdir my-project
cd my-project
[...create files, sub-directories, more files...]
cd ~/my-project
git init
git add *                # assuming you want to add everything you just created
git commit -a
git remote add origin /repo/my-git
git push -u origin master

After the push the data is in the repository itself. Note that if you want to use it as yourself, then the /repo/my-git repository permissions can be set as you:

chmod -R my-name:my-group /repo/my-git

You'll get an error 13 if the permissions disallow you from doing anything in your new repository (i.e. if you had to use sudo anywhere to create the repository.) Otherwise you need to add yourself to some group and make sure that the repository has read/write access using that group.

Finally, if you were creating that repository so someone else could access it, you probably want to do a clone as in:

git clone /repo/my-git

Obviously, an SSH or HTTP access would probably make it more useful to allow remote connections if you are sharing with lots of people. For example, when I use ssh I have a repo URL which looks like this:

git remote add origin ssh://git-server/repo/my-git/shared-git

The "git-server" part is a domain name. For example, were we to use our m2osw.com domain name for a git repository, we could write:

git.m2osw.com

The path, "/mnt/git" is whatever path makes sense to you on your machine. Some people place git repositories under /opt and others under /var. Just choose something and stick to it.

Then the "shared-git" part is the name of your project.

If you end up moving your remote git to a new server, you want to change the URL with the following command:

git remote set-url origin ssh://new-git-server/repo/my-git/shared-git

The name (origin) may differ on your system or you may be using multiple of them. This is the default and probably correct for 99% of you.

You can verify which remote URL you currently have setup with the -v option:

git remote -v

Allow SSH Access

In order for the SSH protocol to be used, the server should have a git user and your user's public key should be authorized there:

sudo su -
(enter password to become root)
adduser git
cd ~git
mkdir .ssh
chown git:git .ssh
chmod 700 .ssh
cd .ssh
vim authorized_keys
chown git:git authorized_keys
chmod 600 authorized_keys

Then past your users' keys in that file and save.

Make sure that you setup the directory and file as owned by the git used. Also, change the permissions to only allow the owner to access the directory and file. If you don't do that right, the connection won't work because SSH considered your key tainted. Fix the permissions, then try again.

If you have other users on the computer, make double sure to change the .ssh folder ownership and permissions before you create the authorized_keys file.

GitHub

Specifically, if you want to share on GitHub, you have to first create a git repository on github, then run the remote add command as in:

git remote add origin git@github.com:YourName/project.git

The "YourName" could also be a company name, a master project name, etc. The "project.git" part, you will see in the project when you click the "Clone or Download" button.

If you added a READMD.md and/or LICENSE file, then you'll first have to merge by doing a pull before you can check in.

git pull origin master

Fix any conflicts if you ended up with any, and then:

git push origin master

Your code is now on GitHub

Forks

On github you can fork another project, check it out and make changes. Only there are two functions you may want to have access to in order to make this fork really useful.

First, add the upstream URL which gives you a way to access the original code from upstream/master (or some other branch). This gives you the ability to merge changes from the master branch in your version of the project without using a copy. It will automatically merge the changes made on the main branch.

git remote add upstream https://github.com/<owner>/<repo>.git

The remote add command allows you to add any number of remote repository. Here we add the upstream repository, the one you forked from. Since you are likely to not have direct access to the project, we use the HTTPS version (i.e. read-only version.)

To see the results, make sure that you have all the URLs as expected, you can use the -v option like this:

git remote -v

This will list your own remote URLs (if you have such) with git: (i.e. read-write) and then the two upstream URLs.

Next, you can get ready for a merge with a fetch command:

git fetch upstream

Finally, any time you want to merge with the code of the original author, run the following command:

git merge upstream/master

You will get the usual output, with the list of files that changed, how many changes, etc. Assuming you do not have any conflicts, no commit is required.

If you get conflicts, you will have to fix them and commit the fixes.

You should then push those changes to your own remote folder:

git push origin master

Note that merging and pushing to your master is also what is required to create a valid Pull Request. If you forget to merge the upstream, you may offer a Pull Request with code out of date which the authors are likely to reject.

A git repository for /etc

It is possible to make backups of your /etc directory by using a special configuration file using a quite bare definition:

sudo su -
<enter your password>
cd /etc
git init
git add .
git commit .

Then when you make changes to your /etc/ directory, or at least once in a while, make sure to update so that way you have some history:

sudo su -
<enter your password>
cd /etc
git add .
git commit .

If you need to, you can use git diff to compare with the older version. First check your logs to get the UUID and then the diff to see what changed:

git log
<search the point in time you're interested in, copy the UUID>
git diff -r <UUID>

You can do all the other commands as usual, of course. git rm, git mv, git checkout -b <branch-name>, etc. But managing branches in your /etc may not be practical. At least, you'll have a free copy of your files and some history, though.

HEAD-DETACHED Problem

In some cases, you will end up with a project which is "head detached". This means it's not in a real branch.

Especially, I get the problem with I checkout a project that has sub-modules. It is often that all the sub-modules are going to be detached. This is because the cloning will get a version which is not the latest. The version you have would be an intermediate between two other versions...

If you made no other changes, you can easily switch to master and to a

git checkout master
git pull origin master

to be up to date again. If that doesn't seem to work right for you, you can always use the method below skipping the merge step.

If you made changes that you want to add to master, you want to save the data to a named branch and then merge those changes to master. It is often that you don't notice that the git status is HEAD-DETACHED and you start making changes... I've done it many times mysefl.

git checkout -b fixes
git checkout master
git pull origin master
git merge fixes
(fix any issue + git commit if necessary)
git push origin master

This should get you ging now.

Once you are sure it worked, you can delete the intermediate fixes branch with:

git branch -d fixes

Now you should be set.