1

I am trying to setup git using a shared network drive as the main repository.

I did the following on cmd:

pushd //networkdrive/myrepo/
git init samplegitrepo --shared
popd
git clone //networkdrive/myrepo/samplegitrepo

I created a new sample text file in C:/localfolder/samplegitrepo. Then using TortoiseGit, I performed an add->commit->push and prompted that these were successful.

However, when I check //networkdrive/myrepo/samplegitrepo, I do not see my sample text file I committed. Am I missing something?

kzaiwo
  • 1,558
  • 1
  • 16
  • 45
  • When you tried cloning the repo again (in a separate folder), do you see the sample text file? – Gino Mempin Dec 23 '19 at 04:40
  • @GinoMempin Yes, I can see the sample text file when cloning to a new folder. Any thoughts why? Where is it actually saved if I can't see it in my shared folder? – kzaiwo Dec 23 '19 at 05:52

1 Answers1

0

TL;DR: you may want to configure the shared Git to have receive.denyCurrentBranch set to updateInstead. Be sure you know precisely what this means, before doing it! It's more likely that you should configure the shared repository as a bare repository. See also What are the consequences of using receive.denyCurrentBranch in Git?

Long-ish

git init samplerepo creates a new, empty directory named samplerepo, then creates a new empty repository within that directory, so that samplerepo is the work-tree for the new empty repository. This new empty repository has no commits and therefore has no branches (yet). The samplerepo directory will contain just one sub-directory, .git, holding the repository proper.

Having created this empty repository, you then cloned it. The cloning process will give you a warning about having cloned an empty repository, because various things tend to be a little weird when working with empty repositories. In any case this clone also has no branches, because a branch name like master can only exist by containing the hash ID of some existing, valid commit. The empty repository has no commits.

Despite the lack of branches, the empty repository is still on a branch. It's just on a branch that does not exist. This is where the weirdness comes in.

Next, you created a file in your work-tree in the clone, used git add to copy the file into the index for this clone, and ran git commit. This created the very first commit in the clone, which is now non-empty. Creating this commit allowed the branch master to come into existence, which it did. (You could now create an infinite number of additional branch names, if you like: all must, necessarily, identify this one commit that exists.)

Finally, you told your Git to contact another Git on the shared area, //networkdrive/myrepo/samplegitrepo.1 Your Git gave to this other Git this one commit that you have made, which that Git stored in that repository—the one on the shared drive. Then your Git asked that Git to create or update its branch name master to identify the one commit. It did so.

Creating the commit in the other Git had no effect on that Git's work-tree. This is the normal behavior of a Git repository: putting new commits into it via git push does not affect its work-tree. In fact, in general, putting new commits into it, into the branch that it has checked out, is normally denied entirely. The reason it was allowed here is that the branch that it had checked out—its master—did not exist, for the same reason that your clone's master did not exist initially.

Now that the branch does exist, future attempts to push to master will be rejected due to receive.denyCurrentBranch being unset, which results in the same behavior as if you set it to true. There is a lot of discussion in the various answers to What are the consequences of using receive.denyCurrentBranch in Git? You should read it.


1More typically, you would contact a whole separate host via some https:// or ssh:// URL. The other host would then have a way of authenticating you and deciding whether to give you access to the Git repository over there. In this case, your own Git fires up a second Git instance to work in the shared drive. That allows Git to keep working as if you're talking to another machine, even though it's just talking to another copy of itself running over in the shared drive. Your OS takes care of authentication automatically, through the shared drive.

This is where the --shared stuff becomes important, if you plan to let other users on other machine let their OS take care of the sharing. The Linux-oriented Git --shared=true or --shared=group setting—that's what --shared defaults to—depends on Linux-style group permissions. You're showing various Windows-ish paths, and Windows permissions are typically very different from Linux's, so this may not accomplish what you want. I don't "do" Windows, so don't know how to accomplish what you want, but it's worth some attention.

torek
  • 448,244
  • 59
  • 642
  • 775
  • Thank you for your detailed response. Shed me some light. However, I still do not see my "pushed" files on the shared repository. I have already modified ```denyCurrentBranch``` and this allows me to push but changes are still not seen on the shared folder. Help please – kzaiwo Dec 23 '19 at 09:23
  • Assuming that, by "the shared folder", you mean `//networkdrive/myrepo/samplegitrepo` rather than `//networkdrive/myrepo/samplegitrepo/.git`, the only way files can appear there is for some Git to do a `git checkout` *in* there. That's what setting `updateInstead` should do, but perhaps there's an initialization step that has to run first (to fill in the index there), in which case, navigate to `//networkdrive/myrepo/samplegitrepo` and run `git checkout master` once. – torek Dec 23 '19 at 16:20
  • In any case, I strongly recommend *against* trying to use Git as a deployment system, which is really what you're doing here. Git is not designed as a deployment system and does a terrible job of it. – torek Dec 23 '19 at 16:23