How do you use "git --bare init" repository?
Asked Answered
I

10

384

I need to create a central Git repository but I'm a little confused...

I have created a bare repository (in my git server, machine 2) with:

$ mkdir test_repo
$ git --bare init

Now I need to push files from my local repository (machine 1) to the bare repository (machine 2). I have access to machine 2 by SSH. The thing is that I think I don't understand the concept of a bare repository...

What is the right way of storing my code in the bare repository? How can I push changes from my local repository to the bare repository?

Is the right way of having a central repository to have a bare repository?

I'm a little confused with this subject. Please give me a clue on this.

Ichinomiya answered 3/10, 2011 at 8:5 Comment(0)
E
461

Firstly, just to check, you need to change into the directory you've created before running git init --bare. Also, it's conventional to give bare repositories the extension .git. So you can do

git init --bare test_repo.git

For Git versions < 1.8 you would do

mkdir test_repo.git
cd test_repo.git
git --bare init

To answer your later questions, bare repositories (by definition) don't have a working tree attached to them, so you can't easily add files to them as you would in a normal non-bare repository (e.g. with git add <file> and a subsequent git commit.)

You almost always update a bare repository by pushing to it (using git push) from another repository.

Note that in this case you'll need to first allow people to push to your repository. When inside test_repo.git, do

git config receive.denyCurrentBranch ignore

Community edit

git init --bare --shared=group

As commented by prasanthv, this is what you want if you are doing this at work, rather than for a private home project.

Embrangle answered 3/10, 2011 at 8:10 Comment(10)
You can also add the --shared option for init if you plan on having other people push to this repo. It automatically adds group write permissions to the repository - linkIndefensible
I think these three lines have the same effect than this only one: git --bare init test_repo.git At least with my current git version (1.8.2.2)Merrow
useful if you want to know difference between bare and non-bare repos #7861684Crossopterygian
how does git find stuff if there's not working tree? i thought there is a working tree in the git object store, and that's what the staging SHAs point and commits point toYiyid
@akantoword: git stores all the info on commits and branches somewhere. A commit is probably mostly a diff between the previous version of the files and the new version. The working tree is just a snapshot of its real content at a specific time. Anyway, with a working tree you can go back and forth between commits and branches. You can even checkout on a different working tree if you want.Vlaminck
Do you have to do git config ... if you did --shared=group ?Est
Let's say you push an update from master in same state as tag v2.4 and it's not working good, and you want to rollback the code to v2.3, how to to it with this approach?Uproar
What is as "working tree"? You mean working directory?Vere
@Vlaminck According to the book ProGit a commit is not a diff between versionsVere
@KansaiRobot: yes it should be "working directory". A commit is in itself not a diff between versions, but it will contain info about the differences with the parent.Vlaminck
K
315

I'm adding this answer because after arriving here (with the same question), none of the answers really describe all the required steps needed to go from nothing to a fully usable remote (bare) repo.

Note: this example uses local paths for the location of the bare repo, but other git protocols (like SSH indicated by the OP) should work just fine.

I've tried to add some notes along the way for those less familiar with git.

1. Initialise the bare repo...

> git init --bare /path/to/bare/repo.git
Initialised empty Git repository in /path/to/bare/repo.git/

This creates a folder (repo.git) and populates it with git files representing a git repo. As it stands, this repo is useless - it has no commits and more importantly, no branches. Although you can clone this repo, you cannot pull from it.

Next, we need to create a working folder. There are a couple of ways of doing this, depending upon whether you have existing files.

2a. Create a new working folder (no existing files) by cloning the empty repo

git clone /path/to/bare/repo.git /path/to/work
Cloning into '/path/to/work'...
warning: You appear to have cloned an empty repository.
done.

This command will only work if /path/to/work does not exist or is an empty folder. Take note of the warning - at this stage, you still don't have anything useful. If you cd /path/to/work and run git status, you'll get something like:

On branch master

Initial commit

nothing to commit (create/copy files and use "git add" to track)

but this is a lie. You are not really on branch master (because git branch returns nothing) and so far, there are no commits.

Next, copy/move/create some files in the working folder, add them to git and create the first commit.

> cd /path/to/work
> echo 123 > afile.txt
> git add .
> git config --local user.name adelphus
> git config --local user.email [email protected]
> git commit -m "added afile"
[master (root-commit) 614ab02] added afile
 1 file changed, 1 insertion(+)
 create mode 100644 afile.txt

The git config commands are only needed if you haven't already told git who you are. Note that if you now run git branch, you'll now see the master branch listed. Now run git status:

On branch master
Your branch is based on 'origin/master', but the upstream is gone.
  (use "git branch --unset-upstream" to fixup)

nothing to commit, working directory clean

This is also misleading - upstream has not "gone", it just hasn't been created yet and git branch --unset-upstream will not help. But that's OK, now that we have our first commit, we can push and master will be created on the bare repo.

> git push origin master
Counting objects: 3, done.
Writing objects: 100% (3/3), 207 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To /path/to/bare/repo.git
 * [new branch]      master -> master

At this point, we have a fully functional bare repo which can be cloned elsewhere on a master branch as well as a local working copy which can pull and push.

> git pull
Already up-to-date.
> git push origin master
Everything up-to-date

2b. Create a working folder from existing files If you already have a folder with files in it (so you cannot clone into it), you can initialise a new git repo, add a first commit and then link it to the bare repo afterwards.

> cd /path/to/work_with_stuff
> git init 
Initialised empty Git repository in /path/to/work_with_stuff
> git add .
# add git config stuff if needed
> git commit -m "added stuff"

[master (root-commit) 614ab02] added stuff
 20 files changed, 1431 insertions(+)
 create mode 100644 stuff.txt
...

At this point we have our first commit and a local master branch which we need to turn into a remote-tracked upstream branch.

> git remote add origin /path/to/bare/repo.git
> git push -u origin master
Counting objects: 31, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (31/31), done.
Writing objects: 100% (31/31), 43.23 KiB | 0 bytes/s, done.
Total 31 (delta 11), reused 0 (delta 0)
To /path/to/bare/repo.git
 * [new branch]      master -> master
Branch master set up to track remote branch master from origin.

Note the -u flag on git push to set the (new) tracked upstream branch. Just as before, we now have a fully functional bare repo which can be cloned elsewhere on a master branch as well as a local working copy which can pull and push.

All this may seem obvious to some, but git confuses me at the best of times (it's error and status messages really need some rework) - hopefully, this will help others.

Kenny answered 23/7, 2015 at 14:54 Comment(3)
What if you plan to work locally, push to a remote AND have that remote being used as a working directory - like an nginx server accessing it? Is the only option to create a non-bare remote repository and simply monitor your own behavior (by not actually working in it)? (Git kind of fights you on that approach.) Or is there a way to push/pull to a bare remote (gaining the protection it affords) while some other method is used to make that repository present a working directory which can be used by a web server? (+1, thanks for the post)Idolah
where should this .git repo be inside of your production server? /home/user/app.git? /var/www/app.git? as best practice?Krill
Excellent, and what if i want to push my local git repo to a bare repo but this repo has master ?Jennifer
B
35

Answering your questions one by one:

Bare repository is the one that has no working tree. It means its whole contents is what you have in .git directory.

You can only commit to bare repository by pushing to it from your local clone. It has no working tree, so it has no files modified, no changes.

To have central repository the only way it is to have a bare repository.

Baulk answered 3/10, 2011 at 8:9 Comment(0)
G
23

You could also ask git to create directory for you:

git init --bare test_repo.git
Gokey answered 17/1, 2014 at 21:39 Comment(0)
H
20

The general practice is to have the central repository to which you push as a bare repo.

If you have SVN background, you can relate an SVN repo to a Git bare repo. It doesn't have the files in the repo in the original form. Whereas your local repo will have the files that form your "code" in addition.

You need to add a remote to the bare repo from your local repo and push your "code" to it.

It will be something like:

git remote add central <url> # url will be ssh based for you
git push --all central
Hep answered 3/10, 2011 at 8:10 Comment(1)
Using git remote add central <url>, in the case of SSH would this include the path too? e.g. git remote add central ssh://user@server/home/user/repo.gitFiltration
C
17

This should be enough:

git remote add origin <url-of-bare-repo>
git push --all origin

See for more details "GIT: How do I update my bare repo?".
Notes:

  • you can use a different name than 'origin' for the bare repo remote reference.
  • this won't push your tags, you need a separate git push --tags origin for that.
Chronicle answered 3/10, 2011 at 8:9 Comment(0)
C
6

Based on Mark Longair & Roboprog answers :

if git version >= 1.8

git init --bare --shared=group .git
git config receive.denyCurrentBranch ignore

Or :

if git version < 1.8

mkdir .git
cd .git
git init --bare --shared=group 
git config receive.denyCurrentBranch ignore
Conklin answered 23/11, 2017 at 17:34 Comment(3)
That config command: how does it end up applying to the .git directory you just created?Est
I'm not sure I understand your question ? Can you be more precise ? Since you have your git repository initialized, you can configure it as much as you want with the command 'git config'..Lengthen
@Est It's because you are still inside the folder of the git repository, so it applies to that (the default of the git config is like the option --local).Lacedaemon
T
5

It is nice to verify that the code you pushed actually got committed.

You can get a log of changes on a bare repository by explicitly setting the path using the --relative option.

$ cd test_repo
$ git log --relative=/

This will show you the committed changes as if this was a regular git repo.

Thickwitted answered 20/10, 2011 at 16:25 Comment(0)
A
3

You can execute the following commands to initialize your local repository

mkdir newProject
cd newProject
touch .gitignore
git init
git add .
git commit -m "Initial Commit"
git remote add origin user@host:~/path_on_server/newProject.git
git push origin master

You should work on your project from your local repository and use the server as the central repository.

You can also follow this article which explains each and every aspect of creating and maintaining a Git repository. Git for Beginners

Ammonia answered 11/7, 2018 at 4:28 Comment(0)
R
2

The --bare flag creates a repository that doesn’t have a working directory. The bare repository is the central repository and you can't edit(store) codes here for avoiding the merging error.

For example, when you add a file in your local repository (machine 1) and push it to the bare repository, you can't see the file in the bare repository for it is always 'empty'. However, you really push something to the repository and you can see it inexplicitly by cloning another repository in your server(machine 2).

Both the local repository in machine 1 and the 'copy' repository in machine 2 are non-bare. relationship between bare and non-bare repositories

The blog will help you understand it. https://www.atlassian.com/git/tutorials/setting-up-a-repository

Roquefort answered 21/3, 2017 at 17:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.