Whether you like it or else, this site uses cookies. On this site will rise... something. Words fail me. Thoughts fail me. Give me a kiss and enliven my inspiration. Hold me. Kiss my asinine comments. This is my website, and I am Loloy D.

Random fun stuff:

Git

How To Treat A Local Git Repository Into A Remote One Without Setting Up SSH Or HTTPS Servers

In this article, I will attempt to give insights on how to treat another local repository as a remote one. This could be useful for members in collaborative development teams who would want to work on their own individual repositories and would want to synchronize among themselves in a LAN environment without an explicit Git server. The strategy described in this article does not make use of a bare repository. A bare repository is essentially a repository with only an index and there are no workable files stored that are directly reachable or accessible. In the simplest Git terms, a bare repository contains only the hidden .git subdirectory, with no working copies of the files described by the .git subdirectory. In my view, bare repositories are what's stored inside GitHub and Bitbucket, and inside instances of GitLab servers. Bare repositories also work great with local area network (LAN) sharing as different could people could push and pull at the bare repository without it having to eat more storage space since it is not storing the working tree. The strategy being proposed in this article however, skips the utility of bare repositories in LAN environments altogether to further maximize efficiency by making team members synchronize directly off one another. The use case that I am talking about can be illustrated in the following scenario.

Let's have three developers named Julia, Jeremy and Josh working on a project with a model-view-controller (MVC) architecture. The project's name is Foobaria and so is their chosen name for each of their individual repositories. Let's say that Julia works on the model components of the project, Jeremy works on the view components of the project and Josh works on the controller components of the project. Let's further assume that they share a Linux-based server and they are working on the project with their files hosted in that server, such that Julia has her Git repository stored in /home/julia/foobaria, Jeremy has his Git repository stored in /home/jeremy/foobaria while Josh has his Git repository stored in /home/josh/foobaria. Let's further assume that they have granted complete write access to each other's foobaria repository. To enable synchronizing repositories with her teammates, Julia sets up Jeremy's and Josh's repositories as her remote repositories such that she makes the following commands from within her repository:

/home/julia/foobaria $ git remote add foobaria-jeremy /home/jeremy/foobaria
/home/julia/foobaria $ git remote add foobaria-josh /home/josh/foobaria

Jeremy does the same inside his foobaria repository and makes Julia's and Josh's repositories as his remote repositories that he can push and pull with. Josh does the same thing, making remote repositories out of Julia's and Jeremy's.

The 3 developers work on their own components and sync off each other locally with simple "git push" and "git pull". There's a caveat though, as Julia can't push her changes to Jeremy and Josh unless they switch to another dummy branch first. So, inside Jeremy's repository, he creates a temporary branch and enters that.

/home/jeremy/foobaria $ git branch tempbranch
/home/jeremy/foobaria $ git checkout tempbranch

Josh does the same thing.

/home/josh/foobaria $ git branch tempbranch
/home/josh/foobaria $ git checkout tempbranch

Only then can Julia proceed with pushing through:

/home/julia/foobaria $ git push jeremy master
/home/julia/foobaria $ git push josh master

Oh wait, Jeremy and Josh can't see the changes that Julia made unless they move back in to their master branches.

/home/jeremy/foobaria $ git checkout master
/home/josh/foobaria $ git checkout master

Admittedly, the entire process looks tediously intervening to other developers as they have to always checkout to an alternate branch whenever one of the developers has to push changes. However, on another viewpoint, if all the developers are simply keen on always updating themselves by doing "git status" to check for changes, along with "git fetch" and then checking with "git diff" on the master branch, from other repositories and subsequently doing "git pull" instead, then the interventions would not be that much necessary anymore. And if one of the devs are finding themselves ahead by some commits as possibly that the other devs have just pulled the latest changes from him/her ("Your branch is ahead of 'origin/master' by n commits."), he/she can simply do a "git fetch" to enable the synchronization of their repository index references. While the process continuous to become tedious, the strategy remains to be available and feasible.

Steps:

1. Make a repository out of a directory, say /home/user1/repo1.

$ mkdir /home/user1/repo1
$ cd /home/user1/repo1
$ git init
$ touch newfile.txt
$ git add newfile.txt
$ git commit -m "Add newfile.txt to project"

2. Clone that repository to another directory, say /home/user1/repo2. Note that /repo2's remote origin has been automatically set to /home/user1/repo1

$ git clone /home/user1/repo1 /home/user1/repo2
$ cd /home/user1/repo2
$ git remote -v

3. Now, let us do some changes from inside /repo2 and make a commit.

$ touch newfile2.txt
$ git add newfile2.txt
$ git commit -m "Add newfile2.txt to project"

4. From within /repo2, "git push" will fail because it thinks that origin/master branch is currently mounted or checked out. To resolve this, simply make a temporary branch from within /repo1 and mount that branch by checking it out. Return to /repo2 and you should now be able to "git push" successfully.

$ git push --set-upstream origin master

Git will respond with:

"To /home/user1/repo1
! [remote rejected] master -> master (branch is currently checked out)
error: failed to push some refs to '/home/user1/repo1'"

$ cd /home/user1/repo1
$ git branch tempbranch
$ git checkout tempbranch
$ cd /home/user1/repo2
$ git push

5. The work is not yet completely done. Since /repo1 is still branched out to tempbranch, you will not see the changes in it yet. Go back to /repo1's master branch to see the updates.

$ cd /home/user1/repo1
$ git checkout master

In this example, we have seen how to make a "localized remote" repository which can be useful in some collaborative team environments wherein team members would want to synchronize with each other through their shared network folders without having to setup ssh or https servers on their work machines. They can still maintain synchronizing to a "more central" Git server such as GitHub, GitLab or BitBucket by simply adding a remote reference to those repositories.

Subscribe to RSS - Git