# How to setup a Git repository



## dennylin93 (Jan 30, 2010)

This howto will describe how to setup a Git repository:

Dedicated user for Git repos
SSH will be used for commits
Enable gitweb for web access (Apache will be used)
Anonymous cloning using the Git protocol

For those who don't know what Git is:

Git
Git (Wikipedia)
Revision control
Distributed revision control
Comparison of revision control software

You should know how to use Git before reading on.

Install devel/git. Select GITWEB. SVN, P4, and CVS are optional. Deselect them if you don't plan to use them.

Create a git user with uid and gid as 9418:

```
# pw groupadd -n git -g 9418
# pw useradd -n git -u 9418 -g git -c git -d /git \
	-s /usr/local/libexec/git-core/git-shell -h -
```

The git-shell is used for this user, and home is set as /git/. The repos will be under /git/base/.

Make sure the permissions of the directory are correct and create /git/base/:

```
# chown git:git /git/
# chmod 755 /git
# mkdir /git/base/
# chown git:git /git/base/
# chmod 775 /git/base/
```

Next, add users to the git group to be able to *create repositories* under /git/base/. This isn't necessary for users who only need commit access.

```
# vi /etc/group
...
git:*:9418:user1,user2
```

We'll be using SSH keys for authenication, so collect the public keys of all the users who need *commit access*. Then, put the public keys into the right place:

```
# mkdir /git/.ssh/
# chmod 700 /git/.ssh/
# touch /git/.ssh/authorized_keys
# chmod 600 /git/.ssh/authorized_keys
(Put the public keys into authorized_keys, one per line)
# chown -R git:git /git/.ssh/
```

Everything should be set now. Let's create a repo for testing (change to a user that has been added to the git group and has commit access).

```
$ mkdir /git/base/test.git
$ cd /git/base/test.git && git init --bare --shared
```

Create a local repo and commit:

```
$ mkdir ~/test
$ cd ~/test && git init
$ echo '123456' > foo
$ git add .
$ git commit
```

Now push it into the remote repo (remember to replace git.example.com with your own hostname):

```
$ git remote add origin git@git.example.com:base/test.git
$ git push origin master
```

Don't delete the test repo yet.

Since the git repo should be up and working by now, let's enable gitweb for web access. Apache's VirtualHost will be used for this.

Copy gitweb files to /home/www/git/:

```
$ cp /usr/local/share/examples/git/gitweb/git* /home/www/git/
```

Modify Apache settings (change the ServerName and the access and error log paths as necessary):

```
<VirtualHost *:80>
  ServerAdmin webmaster@yourhostname
  DocumentRoot "/home/www/git"
  ServerName git.example.com
  ErrorLog "/path/to/errolog"
  CustomLog "/path/to/accesslog" combined

  <Directory "/home/www/git">
    Options ExecCGI
    Order allow,deny
    Allow from all

    DirectoryIndex gitweb.cgi
    AddHandler cgi-script .cgi
  </Directory>
</VirtualHost>
```

Now edit gitweb.cgi:

```
-our $projectroot = "/pub/scm";
+our $projectroot = "/git/base";
...
-our $home_link_str = "projects";
+our $home_link_str = "base";
...
-our $site_name = ""
+our $site_name = "git.example.com"
...
-our $home_text = "indextext.html";
+our $home_text = "content.html"; (Leave empty if unnecessary)
...
-our $projects_list_description_width = 25;
+our $projects_list_description_width = 40; (Give the description a bit more space)
```

Change the $site_header, $home_text, and $site_footer as needed.

Open up your browser and check if it's working.

You might notice that the description of the test repo hasn't been modified yet. You might also want to change the owner.

For the description, edit /git/base/test.git/description. Put this into /git/base/test.git/config to change the owner:

```
[gitweb]
        owner = Your Name
```

Only the Git protocol isn't working now.

Add this to /etc/rc.conf:

```
git_daemon_enable="YES"
git_daemon_directory="/git"
git_daemon_flags="--syslog --base-path=/git --export-all"
```

Start the daemon:

```
# /usr/local/etc/rc.d/git_daemon start
```

You should now be able to clone using the Git protocol. Try it out:

```
$ cd /tmp/
$ git clone git://git.example.com/base/test.git
```

One last thing. You might want to list URLs for cloning repos on the summary page of test.git in gitweb. Just add this line (the url line) to the [gitweb] section of /git/base/test.git/config:

```
[gitweb]
        owner = Your Name
        url = git://git.example.com/base/test.git
```

This line can appear more than once if there are multiple URLs:

```
[gitweb]
        owner = Your Name
        url = git://git.example.com/base/test.git
        url = git@git.example.com:base/test.git
```


----------



## VictorGT (Oct 21, 2010)

Thanks a lot for this useful article!

I've noticed one problem on my FreeBSD 7.2 - looks like it is better to add one more flag (--detach) to the rc.conf:

```
git_daemon_flags="--syslog --base-path=/git --export-all --detach"
```


----------



## graudeejs (Oct 21, 2010)

You can use devel/py-gitosis to manage git users.
This way system only needs 1 git user. Other users will be virtual users (authorization with ssh public/private keys)

It is very nice peace of software...
I use gitosis & cgit at git.bsdroot.lv


----------



## blaize (May 25, 2012)

VictorGT said:
			
		

> Thanks a lot for this useful article!
> 
> I've noticed one problem on my FreeBSD 7.2 - looks like it is better to add one more flag (--detach) to the rc.conf:
> 
> ...



I have the same problem on FreeBSD 9, if you don't add --detach in rc.conf, the daemon is started in the foreground and the boot process is stuck at launching the daemon (before SSH :/)

Except that, everything works very well ! Thank you.


----------



## maks (Aug 24, 2018)

On that stage it doesn't work on my FBSD 11.1 server.


```
$ git remote add origin git@git.example.com:base/test.git
$ git push origin master
```

I've got

```
[user@freebsd /usr/home/user/test]$ git push origin master
Password for git@freebsd64.work:
fatal: '/test.git' does not appear to be a git repository
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.
[user@freebsd /usr/home/user/test]$
```

Access rights is fine. I've checked them. And repository exist as well.


----------



## ShelLuser (Aug 24, 2018)

maks said:


> On that stage it doesn't work on my FBSD 11.1 server.


Keep in mind that the tutorial is over 8 years old, many things could have changed in the mean time.



maks said:


> ```
> $ git remote add origin git@git.example.com:base/test.git
> $ git push origin master
> ```


Solely judging from the errors I'm tempted to blame the repository (or URL) instead of the command. How sure are you that you're using a legit repository? Also: what is master supposed to be?

If you cloned it then I don't understand why you'd need to manually add it as remote. And you also don't really need to do this in two steps either. `git push -u git@git.example.com:base/test.git +HEAD`, this would also work. You push the current branch onto a remote repository and define it as the upstream in one go.

(edit) I also couldn't help notice that you didn't specify a protocol while adding the remote. That too could have some influence here.


----------



## maks (Aug 24, 2018)

Thank you for response. Below is a sequence of commands that I'm used and some part of configs.
All this is stored on same machine.

```
[git] $ cd ~ && cd repositories
[git] $ mkdir test.git && cd test.git && git init --bare
...or
[git] $ git init --bare test.git
```

...then add to gitosis.conf

```
[group blah]
members = user@freebsd.work
writable = test
```

...then create local repository

```
[user] $ cd ~
[user] $ mkdir test && cd test
[user] $ git init
[user] $ echo "12345" > ./abc.txt
[user] $ git add .
[user] $ git commit (save and exit. Commit successful)
...then add to local repo's config the remote url but on local machine
[user] $ git remote add origin ssh://git@localhost/test.git
[user] $ git push origin master
```

...and got

```
[user@freebsd /usr/home/user/test]$ git push origin master
Password for git@freebsd64.work:
fatal: '/test.git' does not appear to be a git repository
fatal: Could not read from remote repository.

Please make sure you have the correct access rights and the repository exists.
[user@freebsd /usr/home/user/test]$
```

Where I'm doing wrong ?


----------



## maks (Aug 24, 2018)

I already figured it out myself. After creation of bare repository we was need to create a CLONE of the bare repository. Use the 'git clone' instead 'git init' if you need to create git on local server.

```
[user] $ mkdir test && cd test
[user] $ git clone /home/git/repositories/test.git
[user] $ echo "12345" > ./abc.txt
[user] $ git add .
[user] $ git commit
[user] $ git remote add origin ssh://git@localhost/test.git
[user] $ git push origin master
```
And it works now.


----------



## ShelLuser (Aug 24, 2018)

maks said:


> I figured this out itself. After creation of bare repository we was need to create a CLONE of the bare repository. Why this is wasn't explained above ?


Because there's no real need to do that.

Something else in between must have gone wrong for you. I still suspect that your refspec was wrong, where did you get the idea of using master from anyway? The regular notation would be HEAD which indicates the current status of your repository. See also gitrevisions(7). Notice how master could also have double meanings?

And I say this after having written / shared this piece (more recent even):

https://forums.freebsd.org/threads/using-git-on-freebsd-why-and-how.64898/

After you made a bare clone available you can immediately push onto it when done right.


----------



## maks (Aug 24, 2018)

Sorry I'd modified my post a little bit. 

Actually I'm disagree because if thread called like "how to setup a git..." then it means thread should explain different scenarios. But this is not a complain. I would like to help improve it.



ShelLuser said:


> ...where did you get the idea of using master from anyway?


I don't understand this question. Not from anyway, but master branch should be accessible at least within local host, isn't ?

What *refspec* do you mean? 

p.s. This is did not work as well `git push -u git@git.example.com:base/test.git +HEAD`

I believe this is should works. But it doesn't on my particular server.

```
$ git remote add origin git@localhost/test.git
```
And I have no idea why.


----------



## maks (Aug 28, 2018)

I'm figured out a problem with using `$ git remote add origin git@localhost/test.git` within local server.
It was necessary to create a ssh key for user `user` and append a key to `git`.
Need to do follow:

```
$ cd /home/user/.ssh && ssh-keygen
$ cat /home/user/.ssh/id_rsa.pub >> /home/git/.ssh/authorized_keys 
$ nano /home/git/.ssh/authorized_keys

...should look inside like this

command="gitosis-serve user@freebsd.work",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty ssh-rsa PUBLIC_KEY_STRING_HERE user@freebsd.work
```

So it works fine now for both. For clone and local remote


----------



## maks (Aug 30, 2018)

And this is was not a final solution as it turned out. Also you gonna need to change permissions and replace some accesses.

after this `# pw useradd -n git -u 12345 -g git -c git -d /home/git -s /bin/sh -h -` we need to edit two files


```
/etc/passwd
git:*:1001:12345:git:/home/git:/bin/sh

1001 - is ID of the user which should has access to the editable folder. In each particular case may differ.

/etc/master.passwd
git:*:1001:12345::0:0:git:/home/git:/bin/sh
```

You also could set 'git' user password by `# passwd git`, but this is not necessary.

Then run command below (It will update pwd.db).

```
# pwd_mkdb /etc/master.passwd
```

Then check the permissions for all files and folders and especially for /home/git/.ssh/authorized_keys


----------



## dudzorg (Sep 8, 2018)

maks said:


> ```
> [user@freebsd /usr/home/user/test]$ git push origin master
> Password for git@freebsd64.work:
> fatal: '/test.git' does not appear to be a git repository
> ...



I believe you are going wrong here:

```
git remote add origin git@git.example.com:base/test.git
```

The same fatal message appeared for me until I changed the path to "/git/base/test.git" after creating the local repository.


```
git remote remove origin
```


```
git remote add origin git@git.example.com:/git/base/test.git
```


----------

