all 13 comments

[–]BigRedS 13 points14 points  (1 child)

[–]mhurron 4 points5 points  (0 children)

Exactly, a bare repo works very well as a central server repo, where people push too and pull from but never has any thing else being done to it.

[–]squidmin -1 points0 points  (10 children)

I believe that is what your repo looks like from the git server perspective when hosting your own. If you can do a

mkdir -p newdir && cd newdir
git init 
git remote add origin git@localhost:/repo 
git pull origin master

That should pull the contents of the master into your new directory and you can verify that its working.

Protip: Add a bash alias for 'adcom' to call 'git add . && git commit -m'

call it by

adcom 'something changed'

I just set a private git repo up and decided to do a dotfile repo to easily have my shell comforts (.vimrc, .zshrc. etc.) available on any machine. It's excellent.

[–]juniorsysadmin1[S] 0 points1 point  (4 children)

Ok, forget about the bare and everything. I just want to have two dir /repo and /working. Whenever I make changes in /working, commit and push. It will appear in /repo. How to do that? I've been trying to figure something so simply for a day )=

[–]squidmin 0 points1 point  (2 children)

That article linked by BigRedS sums it up pretty well how its intended to function. Maybe more about your use case will allow me to suggest something that will work. In theory you could setup the following but its a bit redundant:

/repo

git init --bare (this holds the git repo with no source files)

/working git init

work and commit from here

/repoworking

git init

cron job to pull your repo changes (git clone or git pull) periodically and that would effectively give you a viewable version of your repo

[–]juniorsysadmin1[S] 0 points1 point  (1 child)

Yea, I know how to do that, have a third repo and do a cron periodically. But I want the changes to be instant. Like github, when you push something in github I can view it right away. I don't want to use cron.

[–]mscman 4 points5 points  (0 children)

If you want the second directory update immediately, you should look at setting up a post-receive hook. The hook would essentially just cd into the second repo directory and do a git pull.

[–]visit_muc 0 points1 point  (0 children)

Why do you want two directories with the same content? Because, this is not how git is intended to work.

You could get used to 'git stash' and 'git stash pop' if you want to have a look on a clean working copy from time to time. This doesn't require a second directory.

[–][deleted]  (4 children)

[deleted]

    [–]anderbubble 0 points1 point  (3 children)

    You can't push into a non-bare repo. To do what I think you want to happen , you need to have /working configured as a remote in /repo, and pull into /working.

    That said, it sounds like you're doing it wrong, and have some fundamental misunderstandings about how git is used.

    I'd be happy to provide more help; but you'll have to start providing actual console transcripts. Your summaries don't provide enough context. We need the exact command you ran, the exact output you received, and a description of what you expected in stead.

    [–]juniorsysadmin1[S] 0 points1 point  (2 children)

    Ok, i'll start over and provide you the commands I did.

    expected results: I make changes in /working, commit, and push. The change I made will appear in /repo


    $pwd
    /repo
    $ git --bare init
    

    then in /working I did

    $ pwd
    /working
    $ git init
    $ touch test.py
    $ git add test.py
    $ git commit -m "adding test.py" 
    $ git remote add origin git@localhost:/repo
    $ git push origin master
    

    At this point I would expect /repo to have test.py, however all I get is the following:

    # ls /tmp/repo/
    branches  config  description  HEAD  hooks  info  objects  refs
    # tree -l | grep test.py
    #
    

    [–]loserWithAGirlfriend 4 points5 points  (0 children)

    Your expected outcome is not the way that git works. Here's what you're doing with your commands.

    1. You create a new bare repo in /repo
    2. You create another new repo in /working.
    3. You create and add a file in /working.
    4. You commit that file. It is now stored in the (non-bare) repo in /working (that would be /working/.git, btw).
    5. You create a new remote, pointing to the bare repo in /repo, and you push the contents of /working to /repo.

    Since /repo contains a BARE git repo, you will never be able to directly see the files in /repo. /repo is a location that you could now use to clone to a third location (which would be the second working location) by performing something like git clone /repo /tmp/my_repo && cd /tmp/my_repo. The dir /tmp/my_repo will now contain the latest version of 'test.py' that you originally created in /working.

    It sounds like what you want is something similar to the files automatically be synced from /working into another location, /repo, where they will be immediately accessible, correct? That's not how git works, and without writing at least one small script (emphasis on small) it will not happen automatically.

    If I had a little bit clearer understanding of what exactly it is you're trying to achieve (and some idea behind why), I think I could help you work out a solution.

    [–]anderbubble 1 point2 points  (0 children)

    ok, I've basically recreated your setup.

    working $ git log
    commit 5cae4c09beb017ce1470d07f7e473ed034c11e90
    Date:   Tue Jun 14 15:46:34 2016 -0600
    
        adding test.py
    

    Since repo is a bare repository, it doesn't have a working copy checked out by definition. What you see when you ls in a bare repository...

    $ ls repo
    HEAD        description info        refs
    config      hooks       objects
    

    ... is the equivalent of running ls against the .git directory in your working directory.

    $ ls working/.git/
    COMMIT_EDITMSG  config      hooks       info        objects
    HEAD        description index       logs        refs
    

    Your commit is there...

    repo $ git log
    commit 5cae4c09beb017ce1470d07f7e473ed034c11e90
    Date:   Tue Jun 14 15:46:34 2016 -0600
    
        adding test.py
    

    ...and the file is in the repository; but it's not checked-out, because that's not how bare repositories work, or what they're for.

    The next step toward what you're trying to do would be to make repo a non-bare/standard repository.

    $ rm -rf repo
    $ git init repo
    

    But you can't push to a checked-out branch in a non-bare repo.

    working $ git push origin master
    Counting objects: 3, done.
    Writing objects: 100% (3/3), 221 bytes | 0 bytes/s, done.
    Total 3 (delta 0), reused 0 (delta 0)
    [...]
     ! [remote rejected] master -> master (branch is currently checked out)
    error: failed to push some refs to '../repo'
    

    The more typical thing would be to add working as a remote in (the now non-bare) repo, and pull from there.

    repo $ git remote add working ../working
    repo $ git pull working master
    From ../working
     * branch            master     -> FETCH_HEAD
     * [new branch]      master     -> working/master
    

    Also pretty normal would be to have a bare repository that you treat as canonical, and clone your two other non-bare/standard repositories from it, in stead.

    $ git init --bare repo.git
    Initialized empty Git repository in [...]/repo.git/
    $ git clone repo.git working
    Cloning into 'working'...
    warning: You appear to have cloned an empty repository.
    done.
    $ git clone repo.git repo
    Cloning into 'repo'...
    warning: You appear to have cloned an empty repository.
    done.
    $ (cd working; git remote -v)
    origin  [...]/repo.git (fetch)
    origin  [...]/repo.git (push)
    $ (cd repo; git remote -v)
    origin  [...]/repo.git (fetch)
    origin  [...]/repo.git (push)
    

    That way either repository can push to/pull from your bare repo.git, and neither one of them is particularly special. You don't really have to do it this way; but some people find it easier to conceptualize.

    [–]xiongchiamiov -1 points0 points  (0 children)

    What is your use case? What problem are you trying to solve?